Cloned from git.kolab.org/git/roundcubemail-plugins-kolab
661
LICENSE
Normal file
|
@ -0,0 +1,661 @@
|
|||
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/>.
|
24
README
Normal file
|
@ -0,0 +1,24 @@
|
|||
A calendar module for Roundcube
|
||||
-------------------------------
|
||||
|
||||
This plugin currently supports a local database as well as a Kolab groupware
|
||||
server as backends for calendar and event storage. For both drivers, some
|
||||
initialization of the local database is necessary. To do so, execute the
|
||||
SQL commands in drivers/<yourchoice>/SQL/<yourdatabase>.initial.sql
|
||||
|
||||
The client-side calendar UI relies on the "fullcalendar" project by Adam Arshaw
|
||||
with extensions made for the use in Roundcube. All changes are published in
|
||||
an official fork at https://github.com/roundcube/fullcalendar
|
||||
|
||||
For some general calendar-based operations such as alarms handling or iCal
|
||||
parsing/exporting this plugins requires the `libcalendaring` plugin which
|
||||
is also part of the Kolab Roundcube Plugins repository. Make sure that plugin
|
||||
is installed and configured correctly.
|
||||
|
||||
For recurring event computation, some utility classes from the Horde project
|
||||
are used. They are packaged in a slightly modified version with this plugin.
|
||||
|
||||
IMPORTANT
|
||||
---------
|
||||
The calendar module makes heavy use of PHP's DateTime as well as DateInterval
|
||||
classes. The latter one requires at least PHP 5.3.0 to run.
|
17
UPGRADING
Normal file
|
@ -0,0 +1,17 @@
|
|||
UPGRADING instructions
|
||||
======================
|
||||
|
||||
To update database schema, depending on the driver you're using,
|
||||
please run in Roundcube bin/ directory:
|
||||
|
||||
updatedb.sh --package=calendar-<driver> --version=<version> \
|
||||
--dir=../plugins/calendar/drivers/<driver>/SQL
|
||||
|
||||
[*] Replace <driver> with "database" or "kolab" (without quotes)
|
||||
[*] Replace <version> with Roundcube version e.g. 0.7.3
|
||||
[*] Roundcube should be upgraded before plugin upgrades
|
||||
|
||||
Example:
|
||||
|
||||
updatedb.sh --package=calendar-kolab --version=0.8.0 \
|
||||
--dir=../plugins/calendar/drivers/kolab/SQL
|
2199
calendar.php
Normal file
182
calendar_base.js
Normal file
|
@ -0,0 +1,182 @@
|
|||
/**
|
||||
* Base Javascript class for the Calendar plugin
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof <hello@lazlo.me>
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
// Basic setup for Roundcube calendar client class
|
||||
function rcube_calendar(settings)
|
||||
{
|
||||
// extend base class
|
||||
rcube_libcalendaring.call(this, settings);
|
||||
|
||||
// member vars
|
||||
this.ui;
|
||||
this.ui_loaded = false;
|
||||
|
||||
// private vars
|
||||
var me = this;
|
||||
|
||||
// create new event from current mail message
|
||||
this.create_from_mail = function()
|
||||
{
|
||||
var uid;
|
||||
if ((uid = rcmail.get_single_uid())) {
|
||||
// load calendar UI (scripts and edit dialog template)
|
||||
if (!this.ui_loaded) {
|
||||
$.when(
|
||||
$.getScript('./plugins/calendar/calendar_ui.js'),
|
||||
$.getScript('./plugins/calendar/lib/js/fullcalendar.js'),
|
||||
$.get(rcmail.url('calendar/inlineui'), function(html){ $(document.body).append(html); }, 'html')
|
||||
).then(function() {
|
||||
// disable attendees feature (autocompletion and stuff is not initialized)
|
||||
for (var c in rcmail.env.calendars)
|
||||
rcmail.env.calendars[c].attendees = false;
|
||||
|
||||
me.ui_loaded = true;
|
||||
me.ui = new rcube_calendar_ui(me.settings);
|
||||
me.create_from_mail(); // start over
|
||||
});
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// get message contents for event dialog
|
||||
var lock = rcmail.set_busy(true, 'loading');
|
||||
rcmail.http_post('calendar/mailtoevent', {
|
||||
'_mbox': rcmail.env.mailbox,
|
||||
'_uid': uid
|
||||
}, lock);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// callback function triggered from server with contents for the new event
|
||||
this.mail2event_dialog = function(event)
|
||||
{
|
||||
if (event.title) {
|
||||
this.ui.add_event(event);
|
||||
rcmail.message_list.blur();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// static methods
|
||||
rcube_calendar.add_event_from_mail = function(mime_id, status)
|
||||
{
|
||||
// ask user to delete the declined event from the local calendar (#1670)
|
||||
var del = false;
|
||||
if (rcmail.env.rsvp_saved && status == 'declined') {
|
||||
del = confirm(rcmail.gettext('calendar.declinedeleteconfirm'));
|
||||
}
|
||||
|
||||
var lock = rcmail.set_busy(true, 'calendar.savingdata');
|
||||
rcmail.http_post('calendar/mailimportevent', {
|
||||
'_uid': rcmail.env.uid,
|
||||
'_mbox': rcmail.env.mailbox,
|
||||
'_part': mime_id,
|
||||
'_calendar': $('#calendar-saveto').val(),
|
||||
'_status': status,
|
||||
'_del': del?1:0
|
||||
}, lock);
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
rcube_calendar.remove_event_from_mail = function(uid, title)
|
||||
{
|
||||
if (confirm(rcmail.gettext('calendar.deleteventconfirm'))) {
|
||||
var lock = rcmail.set_busy(true, 'calendar.savingdata');
|
||||
rcmail.http_post('calendar/event', {
|
||||
e:{ uid:uid },
|
||||
action: 'remove'
|
||||
}, lock);
|
||||
}
|
||||
};
|
||||
|
||||
rcube_calendar.fetch_event_rsvp_status = function(event)
|
||||
{
|
||||
/*
|
||||
var id = event.uid.replace(rcmail.identifier_expr, '');
|
||||
$('#import-'+id+', #rsvp-'+id+', div.rsvp-status').hide();
|
||||
$('#loading-'+id).show();
|
||||
*/
|
||||
rcmail.http_post('calendar/event', {
|
||||
e:event,
|
||||
action:'rsvp-status'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/* calendar plugin initialization (for non-calendar tasks) */
|
||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
if (rcmail.task != 'calendar') {
|
||||
var cal = new rcube_calendar($.extend(rcmail.env.calendar_settings, rcmail.env.libcal_settings));
|
||||
|
||||
rcmail.addEventListener('plugin.update_event_rsvp_status', function(p){
|
||||
rcmail.env.rsvp_saved = p.saved;
|
||||
|
||||
if (p.html) {
|
||||
// append/replace rsvp status display
|
||||
$('#loading-'+p.id).next('.rsvp-status').remove();
|
||||
$('#loading-'+p.id).hide().after(p.html);
|
||||
}
|
||||
else {
|
||||
$('#loading-'+p.id).hide();
|
||||
}
|
||||
|
||||
// enable/disable rsvp buttons
|
||||
$('.rsvp-buttons input.button').prop('disabled', false)
|
||||
.filter('.'+String(p.status).toLowerCase()).prop('disabled', p.latest);
|
||||
|
||||
// show rsvp/import buttons with or without calendar selector
|
||||
if (!p.select)
|
||||
$('#rsvp-'+p.id+' .calendar-select').remove();
|
||||
$('#'+p.action+'-'+p.id).show().append(p.select);
|
||||
});
|
||||
|
||||
rcmail.addEventListener('plugin.fetch_event_rsvp_status', rcube_calendar.fetch_event_rsvp_status);
|
||||
|
||||
// register create-from-mail command to message_commands array
|
||||
if (rcmail.env.task == 'mail') {
|
||||
// place link above 'view source'
|
||||
$('#messagemenu a.calendarlink').parent().insertBefore($('#messagemenu a.sourcelink').parent());
|
||||
|
||||
rcmail.register_command('calendar-create-from-mail', function() { cal.create_from_mail() });
|
||||
rcmail.addEventListener('plugin.mail2event_dialog', function(p){ cal.mail2event_dialog(p) });
|
||||
rcmail.addEventListener('plugin.unlock_saving', function(p){ cal.ui && cal.ui.unlock_saving(); });
|
||||
|
||||
if (rcmail.env.action != 'show') {
|
||||
rcmail.env.message_commands.push('calendar-create-from-mail');
|
||||
rcmail.add_element($('<a>'));
|
||||
}
|
||||
else
|
||||
rcmail.enable_command('calendar-create-from-mail', true);
|
||||
}
|
||||
}
|
||||
|
||||
rcmail.register_command('plugin.calendar', function() { rcmail.switch_task('calendar'); }, true);
|
||||
|
||||
rcmail.addEventListener('plugin.ping_url', function(p){
|
||||
var action = p.action;
|
||||
p.action = p.event = null;
|
||||
new Image().src = rcmail.url(action, p);
|
||||
});
|
||||
});
|
2758
calendar_ui.js
Normal file
31
composer.json
Normal file
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"name": "kolab/calendar",
|
||||
"type": "roundcube-plugin",
|
||||
"description": "Calendar module for Roundcube",
|
||||
"keywords": ["apps","calendar"],
|
||||
"homepage": "http://git.kolab.org/roundcubemail-plugins-kolab/",
|
||||
"license": "GPL-3.0+",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Thomas Bruederli",
|
||||
"email": "bruederli@kolabsys.com",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"repositories": [
|
||||
{
|
||||
"type": "composer",
|
||||
"url": "http://33.33.108.2"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0",
|
||||
"roundcube/plugin-installer": "dev-master"
|
||||
},
|
||||
"extra": {
|
||||
"roundcube": {
|
||||
"min-version": "0.9.2",
|
||||
"sql-dir": "drivers/database/SQL"
|
||||
}
|
||||
}
|
||||
}
|
123
config.inc.php.dist
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?php
|
||||
/*
|
||||
+-------------------------------------------------------------------------+
|
||||
| Configuration for the Calendar plugin |
|
||||
| Version 0.7-beta |
|
||||
| |
|
||||
| Copyright (C) 2010, Lazlo Westerhof - Netherlands |
|
||||
| Copyright (C) 2011, Kolab Systems AG |
|
||||
| |
|
||||
| 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/>. |
|
||||
| |
|
||||
+-------------------------------------------------------------------------+
|
||||
| Author: Lazlo Westerhof <hello@lazlo.me> |
|
||||
| Thomas Bruederli <bruederli@kolabsys.com> |
|
||||
+-------------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
// backend type (database, google, kolab)
|
||||
$rcmail_config['calendar_driver'] = "database";
|
||||
|
||||
// default calendar view (agendaDay, agendaWeek, month)
|
||||
$rcmail_config['calendar_default_view'] = "agendaWeek";
|
||||
|
||||
// mapping of Roundcube date formats to calendar formats (long/short/agenda)
|
||||
// should be in sync with 'date_formats' in main config
|
||||
$rcmail_config['calendar_date_format_sets'] = array(
|
||||
'yyyy-MM-dd' => array('MMM d yyyy', 'M-d', 'ddd MM-dd'),
|
||||
'dd-MM-yyyy' => array('d MMM yyyy', 'd-M', 'ddd dd-MM'),
|
||||
'yyyy/MM/dd' => array('MMM d yyyy', 'M/d', 'ddd MM/dd'),
|
||||
'MM/dd/yyyy' => array('MMM d yyyy', 'M/d', 'ddd MM/dd'),
|
||||
'dd/MM/yyyy' => array('d MMM yyyy', 'd/M', 'ddd dd/MM'),
|
||||
'dd.MM.yyyy' => array('dd. MMM yyyy', 'd.M', 'ddd dd.MM.'),
|
||||
'd.M.yyyy' => array('d. MMM yyyy', 'd.M', 'ddd d.MM.'),
|
||||
);
|
||||
|
||||
// general date format (only set if different from default date format and not user configurable)
|
||||
// $rcmail_config['calendar_date_format'] = "yyyy-MM-dd";
|
||||
|
||||
// time format (only set if different from default date format)
|
||||
// $rcmail_config['calendar_time_format'] = "HH:mm";
|
||||
|
||||
// short date format (used for column titles)
|
||||
// $rcmail_config['calendar_date_short'] = 'M-d';
|
||||
|
||||
// long date format (used for calendar title)
|
||||
// $rcmail_config['calendar_date_long'] = 'MMM d yyyy';
|
||||
|
||||
// date format used for agenda view
|
||||
// $rcmail_config['calendar_date_agenda'] = 'ddd MM-dd';
|
||||
|
||||
// timeslots per hour (1, 2, 3, 4, 6)
|
||||
$rcmail_config['calendar_timeslots'] = 2;
|
||||
|
||||
// show this number of days in agenda view
|
||||
$rcmail_config['calendar_agenda_range'] = 60;
|
||||
|
||||
// first day of the week (0-6)
|
||||
$rcmail_config['calendar_first_day'] = 1;
|
||||
|
||||
// first hour of the calendar (0-23)
|
||||
$rcmail_config['calendar_first_hour'] = 6;
|
||||
|
||||
// working hours begin
|
||||
$rcmail_config['calendar_work_start'] = 6;
|
||||
|
||||
// working hours end
|
||||
$rcmail_config['calendar_work_end'] = 18;
|
||||
|
||||
// show line at current time of the day
|
||||
$rcmail_config['calendar_time_indicator'] = true;
|
||||
|
||||
// default alarm settings for new events.
|
||||
// this is only a preset when a new event dialog opens
|
||||
// possible values are <empty>, DISPLAY, EMAIL
|
||||
$rcmail_config['calendar_default_alarm_type'] = '';
|
||||
|
||||
// default alarm offset for new events.
|
||||
// use ical-style offset values like "-1H" (one hour before) or "+30M" (30 minutes after)
|
||||
$rcmail_config['calendar_default_alarm_offset'] = '-15M';
|
||||
|
||||
// how to colorize events:
|
||||
// 0: according to calendar color
|
||||
// 1: according to category color
|
||||
// 2: calendar for outer, category for inner color
|
||||
// 3: category for outer, calendar for inner color
|
||||
$rcmail_config['calendar_event_coloring'] = 0;
|
||||
|
||||
// event categories
|
||||
$rcmail_config['calendar_categories'] = array(
|
||||
'Personal' => 'c0c0c0',
|
||||
'Work' => 'ff0000',
|
||||
'Family' => '00ff00',
|
||||
'Holiday' => 'ff6600',
|
||||
);
|
||||
|
||||
// enable users to invite/edit attendees for shared events organized by others
|
||||
$rcmail_config['calendar_allow_invite_shared'] = false;
|
||||
|
||||
// enable asynchronous free-busy triggering after data changed
|
||||
$rcmail_config['calendar_freebusy_trigger'] = false;
|
||||
|
||||
// SMTP username used to send (anonymous) itip messages
|
||||
$rcmail_config['calendar_itip_smtp_server'] = null;
|
||||
|
||||
// SMTP username used to send (anonymous) itip messages
|
||||
$rcmail_config['calendar_itip_smtp_user'] = 'smtpauth';
|
||||
|
||||
// SMTP password used to send (anonymous) itip messages
|
||||
$rcmail_config['calendar_itip_smtp_pass'] = '123456';
|
||||
|
||||
|
||||
?>
|
402
drivers/calendar_driver.php
Normal file
|
@ -0,0 +1,402 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Driver interface for the Calendar plugin
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof <hello@lazlo.me>
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Struct of an internal event object how it is passed from/to the driver classes:
|
||||
*
|
||||
* $event = array(
|
||||
* 'id' => 'Event ID used for editing',
|
||||
* 'uid' => 'Unique identifier of this event',
|
||||
* 'calendar' => 'Calendar identifier to add event to or where the event is stored',
|
||||
* 'start' => DateTime, // Event start date/time as DateTime object
|
||||
* 'end' => DateTime, // Event end date/time as DateTime object
|
||||
* 'allday' => true|false, // Boolean flag if this is an all-day event
|
||||
* 'changed' => DateTime, // Last modification date of event
|
||||
* 'title' => 'Event title/summary',
|
||||
* 'location' => 'Location string',
|
||||
* 'description' => 'Event description',
|
||||
* 'url' => 'URL to more information',
|
||||
* 'recurrence' => array( // Recurrence definition according to iCalendar (RFC 2445) specification as list of key-value pairs
|
||||
* 'FREQ' => 'DAILY|WEEKLY|MONTHLY|YEARLY',
|
||||
* 'INTERVAL' => 1...n,
|
||||
* 'UNTIL' => DateTime,
|
||||
* 'COUNT' => 1..n, // number of times
|
||||
* // + more properties (see http://www.kanzaki.com/docs/ical/recur.html)
|
||||
* 'EXDATE' => array(), // list of DateTime objects of exception Dates/Times
|
||||
* 'EXCEPTIONS' => array(<event>), list of event objects which denote exceptions in the recurrence chain
|
||||
* ),
|
||||
* 'recurrence_id' => 'ID of the recurrence group', // usually the ID of the starting event
|
||||
* 'categories' => 'Event category',
|
||||
* 'free_busy' => 'free|busy|outofoffice|tentative', // Show time as
|
||||
* 'priority' => 0-9, // Event priority (0=undefined, 1=highest, 9=lowest)
|
||||
* 'sensitivity' => 'public|private|confidential', // Event sensitivity
|
||||
* 'alarms' => '-15M:DISPLAY', // Reminder settings inspired by valarm definition (e.g. display alert 15 minutes before event)
|
||||
* 'attachments' => array( // List of attachments
|
||||
* 'name' => 'File name',
|
||||
* 'mimetype' => 'Content type',
|
||||
* 'size' => 1..n, // in bytes
|
||||
* 'id' => 'Attachment identifier'
|
||||
* ),
|
||||
* 'deleted_attachments' => array(), // array of attachment identifiers to delete when event is updated
|
||||
* 'attendees' => array( // List of event participants
|
||||
* 'name' => 'Participant name',
|
||||
* 'email' => 'Participant e-mail address', // used as identifier
|
||||
* 'role' => 'ORGANIZER|REQ-PARTICIPANT|OPT-PARTICIPANT|CHAIR',
|
||||
* 'status' => 'NEEDS-ACTION|UNKNOWN|ACCEPTED|TENTATIVE|DECLINED'
|
||||
* 'rsvp' => true|false,
|
||||
* ),
|
||||
*
|
||||
* '_savemode' => 'all|future|current|new', // How changes on recurring event should be handled
|
||||
* '_notify' => true|false, // whether to notify event attendees about changes
|
||||
* '_fromcalendar' => 'Calendar identifier where the event was stored before',
|
||||
* );
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface definition for calendar driver classes
|
||||
*/
|
||||
abstract class calendar_driver
|
||||
{
|
||||
// features supported by backend
|
||||
public $alarms = false;
|
||||
public $attendees = false;
|
||||
public $freebusy = false;
|
||||
public $attachments = false;
|
||||
public $undelete = false; // event undelete action
|
||||
public $categoriesimmutable = false;
|
||||
public $alarm_types = array('DISPLAY');
|
||||
public $alarm_absolute = true;
|
||||
public $last_error;
|
||||
|
||||
protected $default_categories = array(
|
||||
'Personal' => 'c0c0c0',
|
||||
'Work' => 'ff0000',
|
||||
'Family' => '00ff00',
|
||||
'Holiday' => 'ff6600',
|
||||
);
|
||||
|
||||
/**
|
||||
* Get a list of available calendars from this source
|
||||
*
|
||||
* @param bool $active Return only active calendars
|
||||
* @param bool $personal Return only personal calendars
|
||||
*
|
||||
* @return array List of calendars
|
||||
*/
|
||||
abstract function list_calendars($active = false, $personal = false);
|
||||
|
||||
/**
|
||||
* Create a new calendar assigned to the current user
|
||||
*
|
||||
* @param array Hash array with calendar properties
|
||||
* name: Calendar name
|
||||
* color: The color of the calendar
|
||||
* showalarms: True if alarms are enabled
|
||||
* @return mixed ID of the calendar on success, False on error
|
||||
*/
|
||||
abstract function create_calendar($prop);
|
||||
|
||||
/**
|
||||
* Update properties of an existing calendar
|
||||
*
|
||||
* @param array Hash array with calendar properties
|
||||
* id: Calendar Identifier
|
||||
* name: Calendar name
|
||||
* color: The color of the calendar
|
||||
* showalarms: True if alarms are enabled (if supported)
|
||||
* @return boolean True on success, Fales on failure
|
||||
*/
|
||||
abstract function edit_calendar($prop);
|
||||
|
||||
/**
|
||||
* Set active/subscribed state of a calendar
|
||||
*
|
||||
* @param array Hash array with calendar properties
|
||||
* id: Calendar Identifier
|
||||
* active: True if calendar is active, false if not
|
||||
* @return boolean True on success, Fales on failure
|
||||
*/
|
||||
abstract function subscribe_calendar($prop);
|
||||
|
||||
/**
|
||||
* Delete the given calendar with all its contents
|
||||
*
|
||||
* @param array Hash array with calendar properties
|
||||
* id: Calendar Identifier
|
||||
* @return boolean True on success, Fales on failure
|
||||
*/
|
||||
abstract function remove_calendar($prop);
|
||||
|
||||
/**
|
||||
* Add a single event to the database
|
||||
*
|
||||
* @param array Hash array with event properties (see header of this file)
|
||||
* @return mixed New event ID on success, False on error
|
||||
*/
|
||||
abstract function new_event($event);
|
||||
|
||||
/**
|
||||
* Update an event entry with the given data
|
||||
*
|
||||
* @param array Hash array with event properties (see header of this file)
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
abstract function edit_event($event);
|
||||
|
||||
/**
|
||||
* Move a single event
|
||||
*
|
||||
* @param array Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* start: Event start date/time as DateTime object
|
||||
* end: Event end date/time as DateTime object
|
||||
* allday: Boolean flag if this is an all-day event
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
abstract function move_event($event);
|
||||
|
||||
/**
|
||||
* Resize a single event
|
||||
*
|
||||
* @param array Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* start: Event start date/time as DateTime object with timezone
|
||||
* end: Event end date/time as DateTime object with timezone
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
abstract function resize_event($event);
|
||||
|
||||
/**
|
||||
* Remove a single event from the database
|
||||
*
|
||||
* @param array Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* @param boolean Remove event irreversible (mark as deleted otherwise,
|
||||
* if supported by the backend)
|
||||
*
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
abstract function remove_event($event, $force = true);
|
||||
|
||||
/**
|
||||
* Restores a single deleted event (if supported)
|
||||
*
|
||||
* @param array Hash array with event properties:
|
||||
* id: Event identifier
|
||||
*
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
public function restore_event($event)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return data of a single event
|
||||
*
|
||||
* @param mixed UID string or hash array with event properties:
|
||||
* id: Event identifier
|
||||
* calendar: Calendar identifier (optional)
|
||||
* @param boolean If true, only writeable calendars shall be searched
|
||||
* @param boolean If true, only active calendars shall be searched
|
||||
* @param boolean If true, only personal calendars shall be searched
|
||||
*
|
||||
* @return array Event object as hash array
|
||||
*/
|
||||
abstract function get_event($event, $writeable = false, $active = false, $personal = false);
|
||||
|
||||
/**
|
||||
* Get events from source.
|
||||
*
|
||||
* @param integer Event's new start (unix timestamp)
|
||||
* @param integer Event's new end (unix timestamp)
|
||||
* @param string Search query (optional)
|
||||
* @param mixed List of calendar IDs to load events from (either as array or comma-separated string)
|
||||
* @return array A list of event objects (see header of this file for struct of an event)
|
||||
*/
|
||||
abstract function load_events($start, $end, $query = null, $calendars = null);
|
||||
|
||||
/**
|
||||
* Get a list of pending alarms to be displayed to the user
|
||||
*
|
||||
* @param integer Current time (unix timestamp)
|
||||
* @param mixed List of calendar IDs to show alarms for (either as array or comma-separated string)
|
||||
* @return array A list of alarms, each encoded as hash array:
|
||||
* id: Event identifier
|
||||
* uid: Unique identifier of this event
|
||||
* start: Event start date/time as DateTime object
|
||||
* end: Event end date/time as DateTime object
|
||||
* allday: Boolean flag if this is an all-day event
|
||||
* title: Event title/summary
|
||||
* location: Location string
|
||||
*/
|
||||
abstract function pending_alarms($time, $calendars = null);
|
||||
|
||||
/**
|
||||
* (User) feedback after showing an alarm notification
|
||||
* This should mark the alarm as 'shown' or snooze it for the given amount of time
|
||||
*
|
||||
* @param string Event identifier
|
||||
* @param integer Suspend the alarm for this number of seconds
|
||||
*/
|
||||
abstract function dismiss_alarm($event_id, $snooze = 0);
|
||||
|
||||
/**
|
||||
* Check the given event object for validity
|
||||
*
|
||||
* @param array Event object as hash array
|
||||
* @return boolean True if valid, false if not
|
||||
*/
|
||||
public function validate($event)
|
||||
{
|
||||
$valid = true;
|
||||
|
||||
if (!is_object($event['start']) || !is_a($event['start'], 'DateTime'))
|
||||
$valid = false;
|
||||
if (!is_object($event['end']) || !is_a($event['end'], 'DateTime'))
|
||||
$valid = false;
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get list of event's attachments.
|
||||
* Drivers can return list of attachments as event property.
|
||||
* If they will do not do this list_attachments() method will be used.
|
||||
*
|
||||
* @param array $event Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* calendar: Calendar identifier
|
||||
*
|
||||
* @return array List of attachments, each as hash array:
|
||||
* id: Attachment identifier
|
||||
* name: Attachment name
|
||||
* mimetype: MIME content type of the attachment
|
||||
* size: Attachment size
|
||||
*/
|
||||
public function list_attachments($event) { }
|
||||
|
||||
/**
|
||||
* Get attachment properties
|
||||
*
|
||||
* @param string $id Attachment identifier
|
||||
* @param array $event Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* calendar: Calendar identifier
|
||||
*
|
||||
* @return array Hash array with attachment properties:
|
||||
* id: Attachment identifier
|
||||
* name: Attachment name
|
||||
* mimetype: MIME content type of the attachment
|
||||
* size: Attachment size
|
||||
*/
|
||||
public function get_attachment($id, $event) { }
|
||||
|
||||
/**
|
||||
* Get attachment body
|
||||
*
|
||||
* @param string $id Attachment identifier
|
||||
* @param array $event Hash array with event properties:
|
||||
* id: Event identifier
|
||||
* calendar: Calendar identifier
|
||||
*
|
||||
* @return string Attachment body
|
||||
*/
|
||||
public function get_attachment_body($id, $event) { }
|
||||
|
||||
/**
|
||||
* List availabale categories
|
||||
* The default implementation reads them from config/user prefs
|
||||
*/
|
||||
public function list_categories()
|
||||
{
|
||||
$rcmail = rcube::get_instance();
|
||||
return $rcmail->config->get('calendar_categories', $this->default_categories);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new category
|
||||
*/
|
||||
public function add_category($name, $color) { }
|
||||
|
||||
/**
|
||||
* Remove the given category
|
||||
*/
|
||||
public function remove_category($name) { }
|
||||
|
||||
/**
|
||||
* Update/replace a category
|
||||
*/
|
||||
public function replace_category($oldname, $name, $color) { }
|
||||
|
||||
/**
|
||||
* Fetch free/busy information from a person within the given range
|
||||
*
|
||||
* @param string E-mail address of attendee
|
||||
* @param integer Requested period start date/time as unix timestamp
|
||||
* @param integer Requested period end date/time as unix timestamp
|
||||
*
|
||||
* @return array List of busy timeslots within the requested range
|
||||
*/
|
||||
public function get_freebusy_list($email, $start, $end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback function to produce driver-specific calendar create/edit form
|
||||
*
|
||||
* @param string Request action 'form-edit|form-new'
|
||||
* @param array Calendar properties (e.g. id, color)
|
||||
* @param array Edit form fields
|
||||
*
|
||||
* @return string HTML content of the form
|
||||
*/
|
||||
public function calendar_form($action, $calendar, $formfields)
|
||||
{
|
||||
$html = '';
|
||||
foreach ($formfields as $field) {
|
||||
$html .= html::div('form-section',
|
||||
html::label($field['id'], $field['label']) .
|
||||
$field['value']);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a (limited) list of color values to be used for calendar and category coloring
|
||||
*
|
||||
* @return mixed List for colors as hex values or false if no presets should be shown
|
||||
*/
|
||||
public function get_color_values()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
83
drivers/database/SQL/mysql.initial.sql
Normal file
|
@ -0,0 +1,83 @@
|
|||
/**
|
||||
* Roundcube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to Roundcube.
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof
|
||||
* @author Thomas Bruederli
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU AGPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `calendars` (
|
||||
`calendar_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`name` varchar(255) NOT NULL,
|
||||
`color` varchar(8) NOT NULL,
|
||||
`showalarms` tinyint(1) NOT NULL DEFAULT '1',
|
||||
PRIMARY KEY(`calendar_id`),
|
||||
INDEX `user_name_idx` (`user_id`, `name`),
|
||||
CONSTRAINT `fk_calendars_user_id` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `events` (
|
||||
`event_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`calendar_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`recurrence_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`uid` varchar(255) NOT NULL DEFAULT '',
|
||||
`created` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`changed` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`sequence` int(1) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`start` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`end` datetime NOT NULL DEFAULT '1000-01-01 00:00:00',
|
||||
`recurrence` varchar(255) DEFAULT NULL,
|
||||
`title` varchar(255) NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`location` varchar(255) NOT NULL DEFAULT '',
|
||||
`categories` varchar(255) NOT NULL DEFAULT '',
|
||||
`url` varchar(255) NOT NULL DEFAULT '',
|
||||
`all_day` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`free_busy` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`priority` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`sensitivity` tinyint(1) NOT NULL DEFAULT '0',
|
||||
`alarms` varchar(255) DEFAULT NULL,
|
||||
`attendees` text DEFAULT NULL,
|
||||
`notifyat` datetime DEFAULT NULL,
|
||||
PRIMARY KEY(`event_id`),
|
||||
INDEX `uid_idx` (`uid`),
|
||||
INDEX `recurrence_idx` (`recurrence_id`),
|
||||
INDEX `calendar_notify_idx` (`calendar_id`,`notifyat`),
|
||||
CONSTRAINT `fk_events_calendar_id` FOREIGN KEY (`calendar_id`)
|
||||
REFERENCES `calendars`(`calendar_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `attachments` (
|
||||
`attachment_id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`event_id` int(11) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`filename` varchar(255) NOT NULL DEFAULT '',
|
||||
`mimetype` varchar(255) NOT NULL DEFAULT '',
|
||||
`size` int(11) NOT NULL DEFAULT '0',
|
||||
`data` longtext NOT NULL DEFAULT '',
|
||||
PRIMARY KEY(`attachment_id`),
|
||||
CONSTRAINT `fk_attachments_event_id` FOREIGN KEY (`event_id`)
|
||||
REFERENCES `events`(`event_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `itipinvitations` (
|
||||
`token` VARCHAR(64) NOT NULL,
|
||||
`event_uid` VARCHAR(255) NOT NULL,
|
||||
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`event` TEXT NOT NULL,
|
||||
`expires` DATETIME DEFAULT NULL,
|
||||
`cancelled` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY(`token`),
|
||||
INDEX `uid_idx` (`user_id`,`event_uid`),
|
||||
CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
REPLACE INTO system (name, value) VALUES ('calendar-database-version', '2013051600');
|
3
drivers/database/SQL/mysql/2012080600.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- MySQL database updates since version 0.7/0.8
|
||||
|
||||
ALTER TABLE `events` ADD `sequence` int(1) UNSIGNED NOT NULL DEFAULT '0' AFTER `changed`;
|
1
drivers/database/SQL/mysql/2013011000.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
1
drivers/database/SQL/mysql/2013042700.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
3
drivers/database/SQL/mysql/2013051600.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- MySQL database updates since version 0.9-beta
|
||||
|
||||
ALTER TABLE `events` ADD `url` VARCHAR(255) NOT NULL AFTER `categories`;
|
3
drivers/database/SQL/mysql/2013071800.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- MySQL database updates since version 0.9.1
|
||||
|
||||
ALTER TABLE `events` ADD `custom` TEXT NULL AFTER `attendees`;
|
107
drivers/database/SQL/postgres.initial.sql
Normal file
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof
|
||||
* @author Albert Lee
|
||||
* @author Aleksander Machniak <machniak@kolabsys.com>
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU AGPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
|
||||
CREATE SEQUENCE calendars_seq
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE calendars (
|
||||
calendar_id integer DEFAULT nextval('calendars_seq'::regclass) NOT NULL,
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
name varchar(255) NOT NULL,
|
||||
color varchar(8) NOT NULL,
|
||||
showalarms smallint NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (calendar_id)
|
||||
);
|
||||
|
||||
CREATE INDEX calendars_user_id_idx ON calendars (user_id, name);
|
||||
|
||||
|
||||
CREATE SEQUENCE events_seq
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE events (
|
||||
event_id integer DEFAULT nextval('events_seq'::regclass) NOT NULL,
|
||||
calendar_id integer NOT NULL
|
||||
REFERENCES calendars (calendar_id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
recurrence_id integer NOT NULL DEFAULT 0,
|
||||
uid varchar(255) NOT NULL DEFAULT '',
|
||||
created timestamp without time zone DEFAULT now() NOT NULL,
|
||||
changed timestamp without time zone DEFAULT now(),
|
||||
sequence integer NOT NULL DEFAULT 0,
|
||||
"start" timestamp without time zone DEFAULT now() NOT NULL,
|
||||
"end" timestamp without time zone DEFAULT now() NOT NULL,
|
||||
recurrence varchar(255) DEFAULT NULL,
|
||||
title character varying(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location character varying(255) NOT NULL,
|
||||
categories character varying(255) NOT NULL,
|
||||
url character varying(255) NOT NULL,
|
||||
all_day smallint NOT NULL DEFAULT 0,
|
||||
free_busy smallint NOT NULL DEFAULT 0,
|
||||
priority smallint NOT NULL DEFAULT 0,
|
||||
sensitivity smallint NOT NULL DEFAULT 0,
|
||||
alarms varchar(255) DEFAULT NULL,
|
||||
attendees text DEFAULT NULL,
|
||||
notifyat timestamp without time zone DEFAULT NULL,
|
||||
PRIMARY KEY (event_id)
|
||||
);
|
||||
|
||||
CREATE INDEX events_calendar_id_notifyat_idx ON events (calendar_id, notifyat);
|
||||
CREATE INDEX events_uid_idx ON events (uid);
|
||||
CREATE INDEX events_recurrence_id_idx ON events (recurrence_id);
|
||||
|
||||
|
||||
CREATE SEQUENCE attachments_seq
|
||||
INCREMENT BY 1
|
||||
NO MAXVALUE
|
||||
NO MINVALUE
|
||||
CACHE 1;
|
||||
|
||||
CREATE TABLE attachments (
|
||||
attachment_id integer DEFAULT nextval('attachments_seq'::regclass) NOT NULL,
|
||||
event_id integer NOT NULL
|
||||
REFERENCES events (event_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
filename varchar(255) NOT NULL DEFAULT '',
|
||||
mimetype varchar(255) NOT NULL DEFAULT '',
|
||||
size integer NOT NULL DEFAULT 0,
|
||||
data text NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (attachment_id)
|
||||
);
|
||||
|
||||
CREATE INDEX attachments_user_id_idx ON attachments (event_id);
|
||||
|
||||
|
||||
CREATE TABLE itipinvitations (
|
||||
token varchar(64) NOT NULL,
|
||||
event_uid varchar(255) NOT NULL,
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
event TEXT NOT NULL,
|
||||
expires timestamp without time zone DEFAULT NULL,
|
||||
cancelled smallint NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (token)
|
||||
);
|
||||
|
||||
CREATE INDEX itipinvitations_user_id_event_uid_idx ON itipinvitations (user_id, event_uid);
|
||||
|
||||
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2013051600');
|
3
drivers/database/SQL/postgres/2012080600.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- Postgres database updates since version 0.7/0.8
|
||||
|
||||
ALTER TABLE events ADD sequence integer NOT NULL DEFAULT 0;
|
1
drivers/database/SQL/postgres/2013011000.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
8
drivers/database/SQL/postgres/2013042700.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
ALTER SEQUENCE calendar_ids RENAME TO calendars_seq;
|
||||
ALTER TABLE calendars ALTER COLUMN calendar_id SET DEFAULT nextval('calendars_seq'::text);
|
||||
|
||||
ALTER SEQUENCE event_ids RENAME TO events_seq;
|
||||
ALTER TABLE events ALTER COLUMN event_id SET DEFAULT nextval('events_seq'::text);
|
||||
|
||||
ALTER SEQUENCE attachment_ids RENAME TO attachments_seq;
|
||||
ALTER TABLE attachments ALTER COLUMN attachment_id SET DEFAULT nextval('attachments_seq'::text);
|
3
drivers/database/SQL/postgres/2013051600.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- Postgres database updates since version 0.9-beta
|
||||
|
||||
ALTER TABLE events ADD url character varying(255) NOT NULL;
|
3
drivers/database/SQL/postgres/2013071800.sql
Normal file
|
@ -0,0 +1,3 @@
|
|||
-- Postgres database updates since version 0.9.1
|
||||
|
||||
ALTER TABLE events ADD custom text DEFAULT NULL;
|
77
drivers/database/SQL/sqlite.initial.sql
Normal file
|
@ -0,0 +1,77 @@
|
|||
/**
|
||||
* Roundcube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to Roundcube.
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof
|
||||
* @author Thomas Bruederli
|
||||
* @author Albert Lee
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU AGPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
CREATE TABLE calendars (
|
||||
calendar_id integer NOT NULL PRIMARY KEY,
|
||||
user_id integer NOT NULL default '0',
|
||||
name varchar(255) NOT NULL default '',
|
||||
color varchar(255) NOT NULL default '',
|
||||
showalarms tinyint(1) NOT NULL default '1',
|
||||
CONSTRAINT fk_calendars_user_id FOREIGN KEY (user_id)
|
||||
REFERENCES users(user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE events (
|
||||
event_id integer NOT NULL PRIMARY KEY,
|
||||
calendar_id integer NOT NULL default '0',
|
||||
recurrence_id integer NOT NULL default '0',
|
||||
uid varchar(255) NOT NULL default '',
|
||||
created datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
changed datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
sequence integer NOT NULL default '0',
|
||||
start datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
end datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
recurrence varchar(255) default NULL,
|
||||
title varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location varchar(255) NOT NULL default '',
|
||||
categories varchar(255) NOT NULL default '',
|
||||
url varchar(255) NOT NULL default '',
|
||||
all_day tinyint(1) NOT NULL default '0',
|
||||
free_busy tinyint(1) NOT NULL default '0',
|
||||
priority tinyint(1) NOT NULL default '0',
|
||||
sensitivity tinyint(1) NOT NULL default '0',
|
||||
alarms varchar(255) default NULL,
|
||||
attendees text default NULL,
|
||||
notifyat datetime default NULL,
|
||||
CONSTRAINT fk_events_calendar_id FOREIGN KEY (calendar_id)
|
||||
REFERENCES calendars(calendar_id)
|
||||
);
|
||||
|
||||
CREATE TABLE attachments (
|
||||
attachment_id integer NOT NULL PRIMARY KEY,
|
||||
event_id integer NOT NULL default '0',
|
||||
filename varchar(255) NOT NULL default '',
|
||||
mimetype varchar(255) NOT NULL default '',
|
||||
size integer NOT NULL default '0',
|
||||
data text NOT NULL default '',
|
||||
CONSTRAINT fk_attachment_event_id FOREIGN KEY (event_id)
|
||||
REFERENCES events(event_id)
|
||||
);
|
||||
|
||||
CREATE TABLE itipinvitations (
|
||||
token varchar(64) NOT NULL PRIMARY KEY,
|
||||
event_uid varchar(255) NOT NULL,
|
||||
user_id integer NOT NULL default '0',
|
||||
event text NOT NULL,
|
||||
expires datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
cancelled tinyint(1) NOT NULL default '0',
|
||||
CONSTRAINT fk_itipinvitations_user_id FOREIGN KEY (user_id)
|
||||
REFERENCES users(user_id)
|
||||
);
|
||||
|
||||
CREATE INDEX ix_itipinvitations_uid ON itipinvitations(user_id, event_uid);
|
||||
|
||||
INSERT INTO system (name, value) VALUES ('calendar-database-version', '2013051600');
|
1
drivers/database/SQL/sqlite/2013011000.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
1
drivers/database/SQL/sqlite/2013042700.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
63
drivers/database/SQL/sqlite/2013051600.sql
Normal file
|
@ -0,0 +1,63 @@
|
|||
-- SQLite database updates since version 0.9-beta
|
||||
|
||||
-- ALTER TABLE events ADD url varchar(255) NOT NULL AFTER categories;
|
||||
|
||||
CREATE TABLE temp_events (
|
||||
event_id integer NOT NULL PRIMARY KEY,
|
||||
calendar_id integer NOT NULL default '0',
|
||||
recurrence_id integer NOT NULL default '0',
|
||||
uid varchar(255) NOT NULL default '',
|
||||
created datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
changed datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
sequence integer NOT NULL default '0',
|
||||
start datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
end datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
recurrence varchar(255) default NULL,
|
||||
title varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location varchar(255) NOT NULL default '',
|
||||
categories varchar(255) NOT NULL default '',
|
||||
all_day tinyint(1) NOT NULL default '0',
|
||||
free_busy tinyint(1) NOT NULL default '0',
|
||||
priority tinyint(1) NOT NULL default '0',
|
||||
sensitivity tinyint(1) NOT NULL default '0',
|
||||
alarms varchar(255) default NULL,
|
||||
attendees text default NULL,
|
||||
notifyat datetime default NULL
|
||||
);
|
||||
|
||||
INSERT INTO temp_events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
|
||||
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat FROM events;
|
||||
|
||||
DROP TABLE events;
|
||||
|
||||
CREATE TABLE events (
|
||||
event_id integer NOT NULL PRIMARY KEY,
|
||||
calendar_id integer NOT NULL default '0',
|
||||
recurrence_id integer NOT NULL default '0',
|
||||
uid varchar(255) NOT NULL default '',
|
||||
created datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
changed datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
sequence integer NOT NULL default '0',
|
||||
start datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
end datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
recurrence varchar(255) default NULL,
|
||||
title varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location varchar(255) NOT NULL default '',
|
||||
categories varchar(255) NOT NULL default '',
|
||||
url varchar(255) NOT NULL default '',
|
||||
all_day tinyint(1) NOT NULL default '0',
|
||||
free_busy tinyint(1) NOT NULL default '0',
|
||||
priority tinyint(1) NOT NULL default '0',
|
||||
sensitivity tinyint(1) NOT NULL default '0',
|
||||
alarms varchar(255) default NULL,
|
||||
attendees text default NULL,
|
||||
notifyat datetime default NULL,
|
||||
CONSTRAINT fk_events_calendar_id FOREIGN KEY (calendar_id)
|
||||
REFERENCES calendars(calendar_id)
|
||||
);
|
||||
|
||||
INSERT INTO events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
|
||||
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat FROM temp_events;
|
||||
|
64
drivers/database/SQL/sqlite/2013071800.sql
Normal file
|
@ -0,0 +1,64 @@
|
|||
-- SQLite database updates since version 0.9.1
|
||||
|
||||
-- ALTER TABLE events ADD custom text DEFAULT NULL AFTER attendees;
|
||||
|
||||
CREATE TABLE temp_events (
|
||||
event_id integer NOT NULL PRIMARY KEY,
|
||||
calendar_id integer NOT NULL default '0',
|
||||
recurrence_id integer NOT NULL default '0',
|
||||
uid varchar(255) NOT NULL default '',
|
||||
created datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
changed datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
sequence integer NOT NULL default '0',
|
||||
start datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
end datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
recurrence varchar(255) default NULL,
|
||||
title varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location varchar(255) NOT NULL default '',
|
||||
categories varchar(255) NOT NULL default '',
|
||||
all_day tinyint(1) NOT NULL default '0',
|
||||
free_busy tinyint(1) NOT NULL default '0',
|
||||
priority tinyint(1) NOT NULL default '0',
|
||||
sensitivity tinyint(1) NOT NULL default '0',
|
||||
alarms varchar(255) default NULL,
|
||||
attendees text default NULL,
|
||||
notifyat datetime default NULL
|
||||
);
|
||||
|
||||
INSERT INTO temp_events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
|
||||
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat FROM events;
|
||||
|
||||
DROP TABLE events;
|
||||
|
||||
CREATE TABLE events (
|
||||
event_id integer NOT NULL PRIMARY KEY,
|
||||
calendar_id integer NOT NULL default '0',
|
||||
recurrence_id integer NOT NULL default '0',
|
||||
uid varchar(255) NOT NULL default '',
|
||||
created datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
changed datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
sequence integer NOT NULL default '0',
|
||||
start datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
end datetime NOT NULL default '1000-01-01 00:00:00',
|
||||
recurrence varchar(255) default NULL,
|
||||
title varchar(255) NOT NULL,
|
||||
description text NOT NULL,
|
||||
location varchar(255) NOT NULL default '',
|
||||
categories varchar(255) NOT NULL default '',
|
||||
url varchar(255) NOT NULL default '',
|
||||
all_day tinyint(1) NOT NULL default '0',
|
||||
free_busy tinyint(1) NOT NULL default '0',
|
||||
priority tinyint(1) NOT NULL default '0',
|
||||
sensitivity tinyint(1) NOT NULL default '0',
|
||||
alarms varchar(255) default NULL,
|
||||
attendees text default NULL,
|
||||
custom text default NULL,
|
||||
notifyat datetime default NULL,
|
||||
CONSTRAINT fk_events_calendar_id FOREIGN KEY (calendar_id)
|
||||
REFERENCES calendars(calendar_id)
|
||||
);
|
||||
|
||||
INSERT INTO events (event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat)
|
||||
SELECT event_id, calendar_id, recurrence_id, uid, created, changed, sequence, start, end, recurrence, title, description, location, categories, all_day, free_busy, priority, sensitivity, alarms, attendees, notifyat FROM temp_events;
|
||||
|
1028
drivers/database/database_driver.php
Normal file
32
drivers/kolab/SQL/mysql.initial.sql
Normal file
|
@ -0,0 +1,32 @@
|
|||
/**
|
||||
* Roundcube Calendar Kolab backend
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli
|
||||
* @licence GNU AGPL
|
||||
**/
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `kolab_alarms` (
|
||||
`event_id` VARCHAR(255) NOT NULL,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`notifyat` DATETIME DEFAULT NULL,
|
||||
`dismissed` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY(`event_id`),
|
||||
CONSTRAINT `fk_kolab_alarms_user_id` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `itipinvitations` (
|
||||
`token` VARCHAR(64) NOT NULL,
|
||||
`event_uid` VARCHAR(255) NOT NULL,
|
||||
`user_id` int(10) UNSIGNED NOT NULL DEFAULT '0',
|
||||
`event` TEXT NOT NULL,
|
||||
`expires` DATETIME DEFAULT NULL,
|
||||
`cancelled` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY(`token`),
|
||||
INDEX `uid_idx` (`event_uid`,`user_id`),
|
||||
CONSTRAINT `fk_itipinvitations_user_id` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
|
||||
|
||||
REPLACE INTO system (name, value) VALUES ('calendar-kolab-version', '2013011000');
|
11
drivers/kolab/SQL/mysql/2012080600.sql
Normal file
|
@ -0,0 +1,11 @@
|
|||
DROP TABLE IF EXISTS `kolab_alarms`;
|
||||
|
||||
CREATE TABLE `kolab_alarms` (
|
||||
`event_id` VARCHAR(255) NOT NULL,
|
||||
`user_id` int(10) UNSIGNED NOT NULL,
|
||||
`notifyat` DATETIME DEFAULT NULL,
|
||||
`dismissed` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY(`event_id`),
|
||||
CONSTRAINT `fk_kolab_alarms_user_id` FOREIGN KEY (`user_id`)
|
||||
REFERENCES `users`(`user_id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) /*!40000 ENGINE=INNODB */;
|
1
drivers/kolab/SQL/mysql/2013011000.sql
Normal file
|
@ -0,0 +1 @@
|
|||
-- empty
|
30
drivers/kolab/SQL/postgres.initial.sql
Normal file
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* Roundcube Calendar Kolab backend
|
||||
*
|
||||
* @author Sergey Sidlyarenko
|
||||
* @licence GNU AGPL
|
||||
**/
|
||||
|
||||
CREATE TABLE IF NOT EXISTS kolab_alarms (
|
||||
event_id character varying(255) NOT NULL,
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
notifyat timestamp without time zone DEFAULT NULL,
|
||||
dismissed smallint NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(event_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS itipinvitations (
|
||||
token character varying(64) NOT NULL,
|
||||
event_uid character varying(255) NOT NULL,
|
||||
user_id integer NOT NULL
|
||||
REFERENCES users (user_id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
event text NOT NULL,
|
||||
expires timestamp without time zone DEFAULT NULL,
|
||||
cancelled smallint NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY(token)
|
||||
);
|
||||
|
||||
CREATE INDEX itipinvitations_event_uid_user_id_idx ON itipinvitations (event_uid, user_id);
|
||||
|
||||
INSERT INTO system (name, value) VALUES ('calendar-kolab-version', '2013011000');
|
656
drivers/kolab/kolab_calendar.php
Normal file
|
@ -0,0 +1,656 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Kolab calendar storage class
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
* @author Aleksander Machniak <machniak@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
class kolab_calendar
|
||||
{
|
||||
public $id;
|
||||
public $ready = false;
|
||||
public $readonly = true;
|
||||
public $attachments = true;
|
||||
public $alarms = false;
|
||||
public $categories = array();
|
||||
public $storage;
|
||||
|
||||
private $cal;
|
||||
private $events = array();
|
||||
private $imap_folder = 'INBOX/Calendar';
|
||||
private $search_fields = array('title', 'description', 'location', 'attendees');
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public function __construct($imap_folder, $calendar)
|
||||
{
|
||||
$this->cal = $calendar;
|
||||
|
||||
if (strlen($imap_folder))
|
||||
$this->imap_folder = $imap_folder;
|
||||
|
||||
// ID is derrived from folder name
|
||||
$this->id = kolab_storage::folder_id($this->imap_folder);
|
||||
|
||||
// fetch objects from the given IMAP folder
|
||||
$this->storage = kolab_storage::get_folder($this->imap_folder);
|
||||
$this->ready = $this->storage && !PEAR::isError($this->storage);
|
||||
|
||||
// Set readonly and alarms flags according to folder permissions
|
||||
if ($this->ready) {
|
||||
if ($this->storage->get_namespace() == 'personal') {
|
||||
$this->readonly = false;
|
||||
$this->alarms = true;
|
||||
}
|
||||
else {
|
||||
$rights = $this->storage->get_myrights();
|
||||
if ($rights && !PEAR::isError($rights)) {
|
||||
if (strpos($rights, 'i') !== false)
|
||||
$this->readonly = false;
|
||||
}
|
||||
}
|
||||
|
||||
// user-specific alarms settings win
|
||||
$prefs = $this->cal->rc->config->get('kolab_calendars', array());
|
||||
if (isset($prefs[$this->id]['showalarms']))
|
||||
$this->alarms = $prefs[$this->id]['showalarms'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for a nice and human readable name for this calendar
|
||||
* See http://wiki.kolab.org/UI-Concepts/Folder-Listing for reference
|
||||
*
|
||||
* @return string Name of this calendar
|
||||
*/
|
||||
public function get_name()
|
||||
{
|
||||
$folder = kolab_storage::object_name($this->imap_folder, $this->namespace);
|
||||
return $folder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the IMAP folder name
|
||||
*
|
||||
* @return string Name of the IMAP folder
|
||||
*/
|
||||
public function get_realname()
|
||||
{
|
||||
return $this->imap_folder;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the IMAP folder owner
|
||||
*
|
||||
* @return string Name of the folder owner
|
||||
*/
|
||||
public function get_owner()
|
||||
{
|
||||
return $this->storage->get_owner();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the name of the namespace to which the IMAP folder belongs
|
||||
*
|
||||
* @return string Name of the namespace (personal, other, shared)
|
||||
*/
|
||||
public function get_namespace()
|
||||
{
|
||||
return $this->storage->get_namespace();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for the top-end calendar folder name (not the entire path)
|
||||
*
|
||||
* @return string Name of this calendar
|
||||
*/
|
||||
public function get_foldername()
|
||||
{
|
||||
$parts = explode('/', $this->imap_folder);
|
||||
return rcube_charset::convert(end($parts), 'UTF7-IMAP');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return color to display this calendar
|
||||
*/
|
||||
public function get_color()
|
||||
{
|
||||
// color is defined in folder METADATA
|
||||
if ($color = $this->storage->get_color()) {
|
||||
return $color;
|
||||
}
|
||||
|
||||
// calendar color is stored in user prefs (temporary solution)
|
||||
$prefs = $this->cal->rc->config->get('kolab_calendars', array());
|
||||
|
||||
if (!empty($prefs[$this->id]) && !empty($prefs[$this->id]['color']))
|
||||
return $prefs[$this->id]['color'];
|
||||
|
||||
return 'cc0000';
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the corresponding kolab_storage_folder instance
|
||||
*/
|
||||
public function get_folder()
|
||||
{
|
||||
return $this->storage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Getter for a single event object
|
||||
*/
|
||||
public function get_event($id)
|
||||
{
|
||||
// directly access storage object
|
||||
if (!$this->events[$id] && ($record = $this->storage->get_object($id)))
|
||||
$this->events[$id] = $this->_to_rcube_event($record);
|
||||
|
||||
// event not found, maybe a recurring instance is requested
|
||||
if (!$this->events[$id]) {
|
||||
$master_id = preg_replace('/-\d+$/', '', $id);
|
||||
if ($master_id != $id && ($record = $this->storage->get_object($master_id)))
|
||||
$this->events[$master_id] = $this->_to_rcube_event($record);
|
||||
|
||||
if (($master = $this->events[$master_id]) && $master['recurrence']) {
|
||||
$this->_get_recurring_events($record, $master['start'], null, $id);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->events[$id];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param integer Event's new start (unix timestamp)
|
||||
* @param integer Event's new end (unix timestamp)
|
||||
* @param string Search query (optional)
|
||||
* @param boolean Include virtual events (optional)
|
||||
* @param array Additional parameters to query storage
|
||||
* @return array A list of event records
|
||||
*/
|
||||
public function list_events($start, $end, $search = null, $virtual = 1, $query = array())
|
||||
{
|
||||
// convert to DateTime for comparisons
|
||||
$start = new DateTime('@'.$start);
|
||||
$end = new DateTime('@'.$end);
|
||||
|
||||
// query Kolab storage
|
||||
$query[] = array('dtstart', '<=', $end);
|
||||
$query[] = array('dtend', '>=', $start);
|
||||
|
||||
if (!empty($search)) {
|
||||
$search = mb_strtolower($search);
|
||||
foreach (rcube_utils::normalize_string($search, true) as $word) {
|
||||
$query[] = array('words', 'LIKE', $word);
|
||||
}
|
||||
}
|
||||
|
||||
$events = array();
|
||||
foreach ((array)$this->storage->select($query) as $record) {
|
||||
$event = $this->_to_rcube_event($record);
|
||||
$this->events[$event['id']] = $event;
|
||||
|
||||
// remember seen categories
|
||||
if ($event['categories'])
|
||||
$this->categories[$event['categories']]++;
|
||||
|
||||
// filter events by search query
|
||||
if (!empty($search)) {
|
||||
$hit = false;
|
||||
foreach ($this->search_fields as $col) {
|
||||
$sval = is_array($event[$col]) ? self::_complex2string($event[$col]) : $event[$col];
|
||||
if (empty($sval))
|
||||
continue;
|
||||
|
||||
// do a simple substring matching (to be improved)
|
||||
$val = mb_strtolower($sval);
|
||||
if (strpos($val, $search) !== false) {
|
||||
$hit = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$hit) // skip this event if not match with search term
|
||||
continue;
|
||||
}
|
||||
|
||||
// list events in requested time window
|
||||
if ($event['start'] <= $end && $event['end'] >= $start) {
|
||||
unset($event['_attendees']);
|
||||
$add = true;
|
||||
|
||||
// skip the first instance of a recurring event if listed in exdate
|
||||
if ($virtual && !empty($event['recurrence']['EXDATE'])) {
|
||||
$event_date = $event['start']->format('Ymd');
|
||||
foreach ($event['recurrence']['EXDATE'] as $exdate) {
|
||||
if ($exdate->format('Ymd') == $event_date) {
|
||||
$add = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($add)
|
||||
$events[] = $event;
|
||||
}
|
||||
|
||||
// resolve recurring events
|
||||
if ($record['recurrence'] && $virtual == 1) {
|
||||
$events = array_merge($events, $this->_get_recurring_events($record, $start, $end));
|
||||
}
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new event record
|
||||
*
|
||||
* @see calendar_driver::new_event()
|
||||
*
|
||||
* @return mixed The created record ID on success, False on error
|
||||
*/
|
||||
public function insert_event($event)
|
||||
{
|
||||
if (!is_array($event))
|
||||
return false;
|
||||
|
||||
//generate new event from RC input
|
||||
$object = $this->_from_rcube_event($event);
|
||||
$saved = $this->storage->save($object, 'event');
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to Kolab server"),
|
||||
true, false);
|
||||
$saved = false;
|
||||
}
|
||||
else {
|
||||
$event['id'] = $event['uid'];
|
||||
$this->events[$event['uid']] = $this->_to_rcube_event($object);
|
||||
}
|
||||
|
||||
return $saved;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a specific event record
|
||||
*
|
||||
* @see calendar_driver::new_event()
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
|
||||
public function update_event($event, $exception_id = null)
|
||||
{
|
||||
$updated = false;
|
||||
$old = $this->storage->get_object($event['id']);
|
||||
if (!$old || PEAR::isError($old))
|
||||
return false;
|
||||
|
||||
$old['recurrence'] = ''; # clear old field, could have been removed in new, too
|
||||
$object = $this->_from_rcube_event($event, $old);
|
||||
$saved = $this->storage->save($object, 'event', $event['id']);
|
||||
|
||||
if (!$saved) {
|
||||
rcube::raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error saving event object to Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
else {
|
||||
$updated = true;
|
||||
$this->events[$event['id']] = $this->_to_rcube_event($object);
|
||||
|
||||
// refresh local cache with recurring instances
|
||||
if ($exception_id) {
|
||||
$this->_get_recurring_events($object, $event['start'], $event['end'], $exception_id);
|
||||
}
|
||||
}
|
||||
|
||||
return $updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an event record
|
||||
*
|
||||
* @see calendar_driver::remove_event()
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
public function delete_event($event, $force = true)
|
||||
{
|
||||
$deleted = $this->storage->delete($event['id'], $force);
|
||||
|
||||
if (!$deleted) {
|
||||
rcube::raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error deleting event object from Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
|
||||
return $deleted;
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore deleted event record
|
||||
*
|
||||
* @see calendar_driver::undelete_event()
|
||||
* @return boolean True on success, False on error
|
||||
*/
|
||||
public function restore_event($event)
|
||||
{
|
||||
if ($this->storage->undelete($event['id'])) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
rcube::raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Error undeleting the event object $event[id] from the Kolab server"),
|
||||
true, false);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create instances of a recurring event
|
||||
*
|
||||
* @param array Hash array with event properties
|
||||
* @param object DateTime Start date of the recurrence window
|
||||
* @param object DateTime End date of the recurrence window
|
||||
* @param string ID of a specific recurring event instance
|
||||
* @return array List of recurring event instances
|
||||
*/
|
||||
public function _get_recurring_events($event, $start, $end = null, $event_id = null)
|
||||
{
|
||||
$object = $event['_formatobj'];
|
||||
if (!$object) {
|
||||
$rec = $this->storage->get_object($event['id']);
|
||||
$object = $rec['_formatobj'];
|
||||
}
|
||||
if (!is_object($object))
|
||||
return array();
|
||||
|
||||
// determine a reasonable end date if none given
|
||||
if (!$end) {
|
||||
switch ($event['recurrence']['FREQ']) {
|
||||
case 'YEARLY': $intvl = 'P100Y'; break;
|
||||
case 'MONTHLY': $intvl = 'P20Y'; break;
|
||||
default: $intvl = 'P10Y'; break;
|
||||
}
|
||||
|
||||
$end = clone $event['start'];
|
||||
$end->add(new DateInterval($intvl));
|
||||
}
|
||||
|
||||
// add recurrence exceptions to output
|
||||
$i = 0;
|
||||
$events = array();
|
||||
$exdates = array();
|
||||
$futuredata = array();
|
||||
if (is_array($event['recurrence']['EXCEPTIONS'])) {
|
||||
// copy the recurrence rule from the master event (to be used in the UI)
|
||||
$recurrence_rule = $event['recurrence'];
|
||||
unset($recurrence_rule['EXCEPTIONS'], $recurrence_rule['EXDATE']);
|
||||
|
||||
foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
|
||||
$rec_event = $this->_to_rcube_event($exception);
|
||||
$rec_event['id'] = $event['uid'] . '-' . ++$i;
|
||||
$rec_event['recurrence_id'] = $event['uid'];
|
||||
$rec_event['recurrence'] = $recurrence_rule;
|
||||
$rec_event['_instance'] = $i;
|
||||
$rec_event['isexception'] = 1;
|
||||
$events[] = $rec_event;
|
||||
|
||||
// found the specifically requested instance, exiting...
|
||||
if ($rec_event['id'] == $event_id) {
|
||||
$this->events[$rec_event['id']] = $rec_event;
|
||||
return $events;
|
||||
}
|
||||
|
||||
// remember this exception's date
|
||||
$exdate = $rec_event['start']->format('Y-m-d');
|
||||
$exdates[$exdate] = $rec_event['id'];
|
||||
if ($rec_event['thisandfuture']) {
|
||||
$futuredata[$exdate] = $rec_event;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// use libkolab to compute recurring events
|
||||
if (class_exists('kolabcalendaring')) {
|
||||
$recurrence = new kolab_date_recurrence($object);
|
||||
}
|
||||
else {
|
||||
// fallback to local recurrence implementation
|
||||
require_once($this->cal->home . '/lib/calendar_recurrence.php');
|
||||
$recurrence = new calendar_recurrence($this->cal, $event);
|
||||
}
|
||||
|
||||
while ($next_event = $recurrence->next_instance()) {
|
||||
// skip if there's an exception at this date
|
||||
$datestr = $next_event['start']->format('Y-m-d');
|
||||
if ($exdates[$datestr]) {
|
||||
// use this event data for future recurring instances
|
||||
if ($futuredata[$datestr])
|
||||
$overlay_data = $futuredata[$datestr];
|
||||
continue;
|
||||
}
|
||||
|
||||
// add to output if in range
|
||||
$rec_id = $event['uid'] . '-' . ++$i;
|
||||
if (($next_event['start'] <= $end && $next_event['end'] >= $start) || ($event_id && $rec_id == $event_id)) {
|
||||
$rec_event = $this->_to_rcube_event($next_event);
|
||||
|
||||
if ($overlay_data) // copy data from a 'this-and-future' exception
|
||||
$this->_merge_event_data($rec_event, $overlay_data);
|
||||
|
||||
$rec_event['id'] = $rec_id;
|
||||
$rec_event['recurrence_id'] = $event['uid'];
|
||||
$rec_event['_instance'] = $i;
|
||||
unset($rec_event['_attendees']);
|
||||
$events[] = $rec_event;
|
||||
|
||||
if ($rec_id == $event_id) {
|
||||
$this->events[$rec_id] = $rec_event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if ($next_event['start'] > $end) // stop loop if out of range
|
||||
break;
|
||||
|
||||
// avoid endless recursion loops
|
||||
if ($i > 1000)
|
||||
break;
|
||||
}
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge certain properties from the overlay event to the base event object
|
||||
*
|
||||
* @param array The event object to be altered
|
||||
* @param array The overlay event object to be merged over $event
|
||||
*/
|
||||
private function _merge_event_data(&$event, $overlay)
|
||||
{
|
||||
static $forbidden = array('id','uid','created','changed','recurrence','organizer','attendees','sequence');
|
||||
|
||||
foreach ($overlay as $prop => $value) {
|
||||
// adjust time of the recurring event instance
|
||||
if ($prop == 'start' || $prop == 'end') {
|
||||
if (is_object($event[$prop]) && is_a($event[$prop], 'DateTime'))
|
||||
$event[$prop]->setTime($value->format('G'), intval($value->format('i')), intval($value->format('s')));
|
||||
}
|
||||
else if ($prop[0] != '_' && !in_array($prop, $forbidden))
|
||||
$event[$prop] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert from Kolab_Format to internal representation
|
||||
*/
|
||||
private function _to_rcube_event($record)
|
||||
{
|
||||
$record['id'] = $record['uid'];
|
||||
$record['calendar'] = $this->id;
|
||||
/*
|
||||
// convert from DateTime to unix timestamp
|
||||
if (is_a($record['start'], 'DateTime'))
|
||||
$record['start'] = $record['start']->format('U');
|
||||
if (is_a($record['end'], 'DateTime'))
|
||||
$record['end'] = $record['end']->format('U');
|
||||
*/
|
||||
// all-day events go from 12:00 - 13:00
|
||||
if ($record['end'] <= $record['start'] && $record['allday']) {
|
||||
$record['end'] = clone $record['start'];
|
||||
$record['end']->add(new DateInterval('PT1H'));
|
||||
}
|
||||
|
||||
if (!empty($record['_attachments'])) {
|
||||
foreach ($record['_attachments'] as $key => $attachment) {
|
||||
if ($attachment !== false) {
|
||||
if (!$attachment['name'])
|
||||
$attachment['name'] = $key;
|
||||
|
||||
unset($attachment['path'], $attachment['content']);
|
||||
$attachments[] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
$record['attachments'] = $attachments;
|
||||
}
|
||||
|
||||
// Roundcube only supports one category assignment
|
||||
if (is_array($record['categories']))
|
||||
$record['categories'] = $record['categories'][0];
|
||||
|
||||
// remove empty recurrence array
|
||||
if (empty($record['recurrence']))
|
||||
unset($record['recurrence']);
|
||||
|
||||
// remove internals
|
||||
unset($record['_mailbox'], $record['_msguid'], $record['_formatobj'], $record['_attachments']);
|
||||
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given event record into a data structure that can be passed to Kolab_Storage backend for saving
|
||||
* (opposite of self::_to_rcube_event())
|
||||
*/
|
||||
private function _from_rcube_event($event, $old = array())
|
||||
{
|
||||
// in kolab_storage attachments are indexed by content-id
|
||||
$event['_attachments'] = array();
|
||||
if (is_array($event['attachments'])) {
|
||||
foreach ($event['attachments'] as $attachment) {
|
||||
$key = null;
|
||||
// Roundcube ID has nothing to do with the storage ID, remove it
|
||||
if ($attachment['content']) {
|
||||
unset($attachment['id']);
|
||||
}
|
||||
else {
|
||||
foreach ((array)$old['_attachments'] as $cid => $oldatt) {
|
||||
if ($attachment['id'] == $oldatt['id'])
|
||||
$key = $cid;
|
||||
}
|
||||
}
|
||||
|
||||
// flagged for deletion => set to false
|
||||
if ($attachment['_deleted']) {
|
||||
$event['_attachments'][$key] = false;
|
||||
}
|
||||
// replace existing entry
|
||||
else if ($key) {
|
||||
$event['_attachments'][$key] = $attachment;
|
||||
}
|
||||
// append as new attachment
|
||||
else {
|
||||
$event['_attachments'][] = $attachment;
|
||||
}
|
||||
}
|
||||
|
||||
unset($event['attachments']);
|
||||
}
|
||||
|
||||
// set current user as ORGANIZER
|
||||
$identity = $this->cal->rc->user->get_identity();
|
||||
if (empty($event['attendees']) && $identity['email'])
|
||||
$event['attendees'] = array(array('role' => 'ORGANIZER', 'name' => $identity['name'], 'email' => $identity['email']));
|
||||
|
||||
$event['_owner'] = $identity['email'];
|
||||
|
||||
// remove some internal properties which should not be saved
|
||||
unset($event['_savemode'], $event['_fromcalendar'], $event['_identity']);
|
||||
|
||||
// copy meta data (starting with _) from old object
|
||||
foreach ((array)$old as $key => $val) {
|
||||
if (!isset($event[$key]) && $key[0] == '_')
|
||||
$event[$key] = $val;
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a complex event attribute to a string value
|
||||
*/
|
||||
private static function _complex2string($prop)
|
||||
{
|
||||
static $ignorekeys = array('role','status','rsvp');
|
||||
|
||||
$out = '';
|
||||
if (is_array($prop)) {
|
||||
foreach ($prop as $key => $val) {
|
||||
if (is_numeric($key)) {
|
||||
$out .= self::_complex2string($val);
|
||||
}
|
||||
else if (!in_array($key, $ignorekeys)) {
|
||||
$out .= $val . ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (is_string($prop) || is_numeric($prop)) {
|
||||
$out .= $prop . ' ';
|
||||
}
|
||||
|
||||
return rtrim($out);
|
||||
}
|
||||
|
||||
}
|
1229
drivers/kolab/kolab_driver.php
Normal file
1304
lib/Horde_Date.php
Normal file
1673
lib/Horde_Date_Recurrence.php
Normal file
374
lib/calendar_itip.php
Normal file
|
@ -0,0 +1,374 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* iTIP functions for the Calendar plugin
|
||||
*
|
||||
* Class providing functionality to manage iTIP invitations
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
* @package @package_name@
|
||||
*
|
||||
* Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
class calendar_itip
|
||||
{
|
||||
private $rc;
|
||||
private $cal;
|
||||
private $sender;
|
||||
private $itip_send = false;
|
||||
|
||||
function __construct($cal, $identity = null)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
$this->sender = $identity ? $identity : $this->rc->user->get_identity();
|
||||
|
||||
$this->cal->add_hook('smtp_connect', array($this, 'smtp_connect_hook'));
|
||||
}
|
||||
|
||||
function set_sender_email($email)
|
||||
{
|
||||
if (!empty($email))
|
||||
$this->sender['email'] = $email;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send an iTip mail message
|
||||
*
|
||||
* @param array Event object to send
|
||||
* @param string iTip method (REQUEST|REPLY|CANCEL)
|
||||
* @param array Hash array with recipient data (name, email)
|
||||
* @param string Mail subject
|
||||
* @param string Mail body text label
|
||||
* @param object Mail_mime object with message data
|
||||
* @return boolean True on success, false on failure
|
||||
*/
|
||||
public function send_itip_message($event, $method, $recipient, $subject, $bodytext, $message = null)
|
||||
{
|
||||
if (!$this->sender['name'])
|
||||
$this->sender['name'] = $this->sender['email'];
|
||||
|
||||
if (!$message)
|
||||
$message = $this->compose_itip_message($event, $method);
|
||||
|
||||
$mailto = rcube_idn_to_ascii($recipient['email']);
|
||||
|
||||
$headers = $message->headers();
|
||||
$headers['To'] = format_email_recipient($mailto, $recipient['name']);
|
||||
$headers['Subject'] = $this->cal->gettext(array(
|
||||
'name' => $subject,
|
||||
'vars' => array('title' => $event['title'], 'name' => $this->sender['name'])
|
||||
));
|
||||
|
||||
// compose a list of all event attendees
|
||||
$attendees_list = array();
|
||||
foreach ((array)$event['attendees'] as $attendee) {
|
||||
$attendees_list[] = ($attendee['name'] && $attendee['email']) ?
|
||||
$attendee['name'] . ' <' . $attendee['email'] . '>' :
|
||||
($attendee['name'] ? $attendee['name'] : $attendee['email']);
|
||||
}
|
||||
|
||||
$mailbody = $this->cal->gettext(array(
|
||||
'name' => $bodytext,
|
||||
'vars' => array(
|
||||
'title' => $event['title'],
|
||||
'date' => $this->cal->lib->event_date_text($event, true),
|
||||
'attendees' => join(', ', $attendees_list),
|
||||
'sender' => $this->sender['name'],
|
||||
'organizer' => $this->sender['name'],
|
||||
)
|
||||
));
|
||||
|
||||
// append links for direct invitation replies
|
||||
if ($method == 'REQUEST' && ($token = $this->store_invitation($event, $recipient['email']))) {
|
||||
$mailbody .= "\n\n" . $this->cal->gettext(array(
|
||||
'name' => 'invitationattendlinks',
|
||||
'vars' => array('url' => $this->cal->get_url(array('action' => 'attend', 't' => $token))),
|
||||
));
|
||||
}
|
||||
else if ($method == 'CANCEL') {
|
||||
$this->cancel_itip_invitation($event);
|
||||
}
|
||||
|
||||
$message->headers($headers, true);
|
||||
$message->setTXTBody(rcube_mime::format_flowed($mailbody, 79));
|
||||
|
||||
// finally send the message
|
||||
$this->itip_send = true;
|
||||
$sent = $this->rc->deliver_message($message, $headers['X-Sender'], $mailto, $smtp_error);
|
||||
$this->itip_send = false;
|
||||
|
||||
return $sent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin hook to alter SMTP authentication.
|
||||
* This is used if iTip messages are to be sent from an unauthenticated session
|
||||
*/
|
||||
public function smtp_connect_hook($p)
|
||||
{
|
||||
// replace smtp auth settings if we're not in an authenticated session
|
||||
if ($this->itip_send && !$this->rc->user->ID) {
|
||||
foreach (array('smtp_server', 'smtp_user', 'smtp_pass') as $prop) {
|
||||
$p[$prop] = $this->rc->config->get("calendar_itip_$prop", $p[$prop]);
|
||||
}
|
||||
}
|
||||
|
||||
return $p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to build a Mail_mime object to send an iTip message
|
||||
*
|
||||
* @param array Event object to send
|
||||
* @param string iTip method (REQUEST|REPLY|CANCEL)
|
||||
* @return object Mail_mime object with message data
|
||||
*/
|
||||
public function compose_itip_message($event, $method)
|
||||
{
|
||||
$from = rcube_idn_to_ascii($this->sender['email']);
|
||||
$from_utf = rcube_idn_to_utf8($from);
|
||||
$sender = format_email_recipient($from, $this->sender['name']);
|
||||
|
||||
// truncate list attendees down to the recipient of the iTip Reply.
|
||||
// constraints for a METHOD:REPLY according to RFC 5546
|
||||
if ($method == 'REPLY') {
|
||||
$replying_attendee = null; $reply_attendees = array();
|
||||
foreach ($event['attendees'] as $attendee) {
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$reply_attendees[] = $attendee;
|
||||
}
|
||||
else if (strcasecmp($attedee['email'], $from) == 0 || strcasecmp($attendee['email'], $from_utf) == 0) {
|
||||
$replying_attendee = $attendee;
|
||||
}
|
||||
}
|
||||
if ($replying_attendee) {
|
||||
$reply_attendees[] = $replying_attendee;
|
||||
$event['attendees'] = $reply_attendees;
|
||||
}
|
||||
}
|
||||
|
||||
// compose multipart message using PEAR:Mail_Mime
|
||||
$message = new Mail_mime("\r\n");
|
||||
$message->setParam('text_encoding', 'quoted-printable');
|
||||
$message->setParam('head_encoding', 'quoted-printable');
|
||||
$message->setParam('head_charset', RCMAIL_CHARSET);
|
||||
$message->setParam('text_charset', RCMAIL_CHARSET . ";\r\n format=flowed");
|
||||
$message->setContentType('multipart/alternative');
|
||||
|
||||
// compose common headers array
|
||||
$headers = array(
|
||||
'From' => $sender,
|
||||
'Date' => $this->rc->user_date(),
|
||||
'Message-ID' => $this->rc->gen_message_id(),
|
||||
'X-Sender' => $from,
|
||||
);
|
||||
if ($agent = $this->rc->config->get('useragent'))
|
||||
$headers['User-Agent'] = $agent;
|
||||
|
||||
$message->headers($headers);
|
||||
|
||||
// attach ics file for this event
|
||||
$ical = $this->cal->get_ical();
|
||||
$ics = $ical->export(array($event), $method, false, $method == 'REQUEST' ? array($this->cal->driver, 'get_attachment_body') : false);
|
||||
$message->addAttachment($ics, 'text/calendar', 'event.ics', false, '8bit', '', RCMAIL_CHARSET . "; method=" . $method);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find invitation record by token
|
||||
*
|
||||
* @param string Invitation token
|
||||
* @return mixed Invitation record as hash array or False if not found
|
||||
*/
|
||||
public function get_invitation($token)
|
||||
{
|
||||
if ($parts = $this->decode_token($token)) {
|
||||
$result = $this->rc->db->query("SELECT * FROM itipinvitations WHERE token=?", $parts['base']);
|
||||
if ($result && ($rec = $this->rc->db->fetch_assoc($result))) {
|
||||
$rec['event'] = unserialize($rec['event']);
|
||||
$rec['attendee'] = $parts['attendee'];
|
||||
return $rec;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the attendee status of the given invitation record
|
||||
*
|
||||
* @param array Invitation record as fetched with calendar_itip::get_invitation()
|
||||
* @param string Attendee email address
|
||||
* @param string New attendee status
|
||||
*/
|
||||
public function update_invitation($invitation, $email, $newstatus)
|
||||
{
|
||||
if (is_string($invitation))
|
||||
$invitation = $this->get_invitation($invitation);
|
||||
|
||||
if ($invitation['token'] && $invitation['event']) {
|
||||
// update attendee record in event data
|
||||
foreach ($invitation['event']['attendees'] as $i => $attendee) {
|
||||
if ($attendee['role'] == 'ORGANIZER') {
|
||||
$organizer = $attendee;
|
||||
}
|
||||
else if ($attendee['email'] == $email) {
|
||||
// nothing to be done here
|
||||
if ($attendee['status'] == $newstatus)
|
||||
return true;
|
||||
|
||||
$invitation['event']['attendees'][$i]['status'] = $newstatus;
|
||||
$this->sender = $attendee;
|
||||
}
|
||||
}
|
||||
$invitation['event']['changed'] = new DateTime();
|
||||
|
||||
// send iTIP REPLY message to organizer
|
||||
if ($organizer) {
|
||||
$status = strtolower($newstatus);
|
||||
if ($this->send_itip_message($invitation['event'], 'REPLY', $organizer, 'itipsubject' . $status, 'itipmailbody' . $status))
|
||||
$this->rc->output->command('display_message', $this->cal->gettext(array('name' => 'sentresponseto', 'vars' => array('mailto' => $organizer['name'] ? $organizer['name'] : $organizer['email']))), 'confirmation');
|
||||
else
|
||||
$this->rc->output->command('display_message', $this->cal->gettext('itipresponseerror'), 'error');
|
||||
}
|
||||
|
||||
// update record in DB
|
||||
$query = $this->rc->db->query(
|
||||
"UPDATE itipinvitations
|
||||
SET event=?
|
||||
WHERE token=?",
|
||||
self::serialize_event($invitation['event']),
|
||||
$invitation['token']
|
||||
);
|
||||
|
||||
if ($this->rc->db->affected_rows($query))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create iTIP invitation token for later replies via URL
|
||||
*
|
||||
* @param array Hash array with event properties
|
||||
* @param string Attendee email address
|
||||
* @return string Invitation token
|
||||
*/
|
||||
public function store_invitation($event, $attendee)
|
||||
{
|
||||
static $stored = array();
|
||||
|
||||
if (!$event['uid'] || !$attendee)
|
||||
return false;
|
||||
|
||||
// generate token for this invitation
|
||||
$token = $this->generate_token($event, $attendee);
|
||||
$base = substr($token, 0, 40);
|
||||
|
||||
// already stored this
|
||||
if ($stored[$base])
|
||||
return $token;
|
||||
|
||||
// delete old entry
|
||||
$this->rc->db->query("DELETE FROM itipinvitations WHERE token=?", $base);
|
||||
|
||||
$query = $this->rc->db->query(
|
||||
"INSERT INTO itipinvitations
|
||||
(token, event_uid, user_id, event, expires)
|
||||
VALUES(?, ?, ?, ?, ?)",
|
||||
$base,
|
||||
$event['uid'],
|
||||
$this->rc->user->ID,
|
||||
self::serialize_event($event),
|
||||
date('Y-m-d H:i:s', $event['end'] + 86400 * 2)
|
||||
);
|
||||
|
||||
if ($this->rc->db->affected_rows($query)) {
|
||||
$stored[$base] = 1;
|
||||
return $token;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark invitations for the given event as cancelled
|
||||
*
|
||||
* @param array Hash array with event properties
|
||||
*/
|
||||
public function cancel_itip_invitation($event)
|
||||
{
|
||||
// flag invitation record as cancelled
|
||||
$this->rc->db->query(
|
||||
"UPDATE itipinvitations
|
||||
SET cancelled=1
|
||||
WHERE event_uid=? AND user_id=?",
|
||||
$event['uid'],
|
||||
$this->rc->user->ID
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate an invitation request token for the given event and attendee
|
||||
*
|
||||
* @param array Event hash array
|
||||
* @param string Attendee email address
|
||||
*/
|
||||
public function generate_token($event, $attendee)
|
||||
{
|
||||
$base = sha1($event['uid'] . ';' . $this->rc->user->ID);
|
||||
$mail = base64_encode($attendee);
|
||||
$hash = substr(md5($base . $mail . $this->rc->config->get('des_key')), 0, 6);
|
||||
|
||||
return "$base.$mail.$hash";
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given iTIP request token and return its parts
|
||||
*
|
||||
* @param string Request token to decode
|
||||
* @return mixed Hash array with parts or False if invalid
|
||||
*/
|
||||
public function decode_token($token)
|
||||
{
|
||||
list($base, $mail, $hash) = explode('.', $token);
|
||||
|
||||
// validate and return parts
|
||||
if ($mail && $hash && $hash == substr(md5($base . $mail . $this->rc->config->get('des_key')), 0, 6)) {
|
||||
return array('base' => $base, 'attendee' => base64_decode($mail));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to serialize the given event for storing in invitations table
|
||||
*/
|
||||
private static function serialize_event($event)
|
||||
{
|
||||
$ev = $event;
|
||||
$ev['description'] = abbreviate_string($ev['description'], 100);
|
||||
unset($ev['attachments']);
|
||||
return serialize($ev);
|
||||
}
|
||||
|
||||
}
|
115
lib/calendar_recurrence.php
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* Recurrence computation class for the Calendar plugin
|
||||
*
|
||||
* Uitility class to compute instances of recurring events.
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
* @package @package_name@
|
||||
*
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
class calendar_recurrence
|
||||
{
|
||||
private $cal;
|
||||
private $event;
|
||||
private $next;
|
||||
private $engine;
|
||||
private $duration;
|
||||
private $hour = 0;
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*
|
||||
* @param object calendar The calendar plugin instance
|
||||
* @param array The event object to operate on
|
||||
*/
|
||||
function __construct($cal, $event)
|
||||
{
|
||||
// use Horde classes to compute recurring instances
|
||||
// TODO: replace with something that has less than 6'000 lines of code
|
||||
require_once(__DIR__ . '/Horde_Date_Recurrence.php');
|
||||
|
||||
$this->cal = $cal;
|
||||
$this->event = $event;
|
||||
$this->next = new Horde_Date($event['start'], $cal->timezone->getName());
|
||||
$this->hour = $this->next->hour;
|
||||
|
||||
if (is_object($event['start']) && is_object($event['end']))
|
||||
$this->duration = $event['start']->diff($event['end']);
|
||||
|
||||
$this->engine = new Horde_Date_Recurrence($event['start']);
|
||||
$this->engine->fromRRule20(libcalendaring::to_rrule($event['recurrence']));
|
||||
|
||||
if (is_array($event['recurrence']['EXDATE'])) {
|
||||
foreach ($event['recurrence']['EXDATE'] as $exdate)
|
||||
$this->engine->addException($exdate->format('Y'), $exdate->format('n'), $exdate->format('j'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date/time of the next occurence of this event
|
||||
*
|
||||
* @return mixed DateTime object or False if recurrence ended
|
||||
*/
|
||||
public function next_start()
|
||||
{
|
||||
$time = false;
|
||||
$after = clone $this->next;
|
||||
$after->mday = $after->mday + 1;
|
||||
if ($this->next && ($next = $this->engine->nextActiveRecurrence($after))) {
|
||||
if (!$next->after($this->next)) {
|
||||
// avoid endless loops if recurrence computation fails
|
||||
return false;
|
||||
}
|
||||
if ($this->event['allday']) {
|
||||
$next->hour = $this->hour; # fix time for all-day events
|
||||
$next->min = 0;
|
||||
}
|
||||
|
||||
$time = $next->toDateTime();
|
||||
$this->next = $next;
|
||||
}
|
||||
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next recurring instance of this event
|
||||
*
|
||||
* @return mixed Array with event properties or False if recurrence ended
|
||||
*/
|
||||
public function next_instance()
|
||||
{
|
||||
if ($next_start = $this->next_start()) {
|
||||
$next_end = clone $next_start;
|
||||
$next_end->add($this->duration);
|
||||
|
||||
$next = $this->event;
|
||||
$next['recurrence_id'] = $next_start->format('Y-m-d');
|
||||
$next['start'] = $next_start;
|
||||
$next['end'] = $next_end;
|
||||
unset($next['_formatobj']);
|
||||
|
||||
return $next;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
771
lib/calendar_ui.php
Normal file
|
@ -0,0 +1,771 @@
|
|||
<?php
|
||||
/**
|
||||
* User Interface class for the Calendar plugin
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Lazlo Westerhof <hello@lazlo.me>
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2010, Lazlo Westerhof <hello@lazlo.me>
|
||||
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
class calendar_ui
|
||||
{
|
||||
private $rc;
|
||||
private $cal;
|
||||
private $ready = false;
|
||||
public $screen;
|
||||
|
||||
function __construct($cal)
|
||||
{
|
||||
$this->cal = $cal;
|
||||
$this->rc = $cal->rc;
|
||||
$this->screen = $this->rc->task == 'calendar' ? ($this->rc->action ? $this->rc->action: 'calendar') : 'other';
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar UI initialization and requests handlers
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if ($this->ready) // already done
|
||||
return;
|
||||
|
||||
// add taskbar button
|
||||
$this->cal->add_button(array(
|
||||
'command' => 'calendar',
|
||||
'class' => 'button-calendar',
|
||||
'classsel' => 'button-calendar button-selected',
|
||||
'innerclass' => 'button-inner',
|
||||
'label' => 'calendar.calendar',
|
||||
), 'taskbar');
|
||||
|
||||
// load basic client script
|
||||
$this->cal->include_script('calendar_base.js');
|
||||
|
||||
$skin_path = $this->cal->local_skin_path();
|
||||
$this->cal->include_stylesheet($skin_path . '/calendar.css');
|
||||
|
||||
$this->ready = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register handler methods for the template engine
|
||||
*/
|
||||
public function init_templates()
|
||||
{
|
||||
$this->cal->register_handler('plugin.calendar_css', array($this, 'calendar_css'));
|
||||
$this->cal->register_handler('plugin.calendar_list', array($this, 'calendar_list'));
|
||||
$this->cal->register_handler('plugin.calendar_select', array($this, 'calendar_select'));
|
||||
$this->cal->register_handler('plugin.identity_select', array($this, 'identity_select'));
|
||||
$this->cal->register_handler('plugin.category_select', array($this, 'category_select'));
|
||||
$this->cal->register_handler('plugin.freebusy_select', array($this, 'freebusy_select'));
|
||||
$this->cal->register_handler('plugin.priority_select', array($this, 'priority_select'));
|
||||
$this->cal->register_handler('plugin.sensitivity_select', array($this, 'sensitivity_select'));
|
||||
$this->cal->register_handler('plugin.alarm_select', array($this, 'alarm_select'));
|
||||
$this->cal->register_handler('plugin.recurrence_form', array($this, 'recurrence_form'));
|
||||
$this->cal->register_handler('plugin.attachments_form', array($this, 'attachments_form'));
|
||||
$this->cal->register_handler('plugin.attachments_list', array($this, 'attachments_list'));
|
||||
$this->cal->register_handler('plugin.filedroparea', array($this, 'file_drop_area'));
|
||||
$this->cal->register_handler('plugin.attendees_list', array($this, 'attendees_list'));
|
||||
$this->cal->register_handler('plugin.attendees_form', array($this, 'attendees_form'));
|
||||
$this->cal->register_handler('plugin.attendees_freebusy_table', array($this, 'attendees_freebusy_table'));
|
||||
$this->cal->register_handler('plugin.edit_attendees_notify', array($this, 'edit_attendees_notify'));
|
||||
$this->cal->register_handler('plugin.edit_recurring_warning', array($this, 'recurring_event_warning'));
|
||||
$this->cal->register_handler('plugin.event_rsvp_buttons', array($this, 'event_rsvp_buttons'));
|
||||
$this->cal->register_handler('plugin.angenda_options', array($this, 'angenda_options'));
|
||||
$this->cal->register_handler('plugin.events_import_form', array($this, 'events_import_form'));
|
||||
$this->cal->register_handler('plugin.searchform', array($this->rc->output, 'search_form')); // use generic method from rcube_template
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds CSS stylesheets to the page header
|
||||
*/
|
||||
public function addCSS()
|
||||
{
|
||||
$skin_path = $this->cal->local_skin_path();
|
||||
$this->cal->include_stylesheet($skin_path . '/fullcalendar.css');
|
||||
$this->cal->include_stylesheet($skin_path . '/jquery.miniColors.css');
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds JS files to the page header
|
||||
*/
|
||||
public function addJS()
|
||||
{
|
||||
$this->cal->include_script('calendar_ui.js');
|
||||
$this->cal->include_script('lib/js/fullcalendar.js');
|
||||
$this->cal->include_script('lib/js/jquery.miniColors.min.js');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function calendar_css($attrib = array())
|
||||
{
|
||||
$mode = $this->rc->config->get('calendar_event_coloring', $this->cal->defaults['calendar_event_coloring']);
|
||||
$categories = $this->cal->driver->list_categories();
|
||||
$css = "\n";
|
||||
|
||||
foreach ((array)$categories as $class => $color) {
|
||||
if (empty($color))
|
||||
continue;
|
||||
|
||||
$class = 'cat-' . asciiwords(strtolower($class), true);
|
||||
$css .= ".$class { color: #$color }\n";
|
||||
if ($mode > 0) {
|
||||
if ($mode == 2) {
|
||||
$css .= ".fc-event-$class .fc-event-bg {";
|
||||
$css .= " opacity: 0.9;";
|
||||
$css .= " filter: alpha(opacity=90);";
|
||||
}
|
||||
else {
|
||||
$css .= ".fc-event-$class.fc-event-skin, ";
|
||||
$css .= ".fc-event-$class .fc-event-skin, ";
|
||||
$css .= ".fc-event-$class .fc-event-inner {";
|
||||
}
|
||||
$css .= " background-color: #" . $color . ";";
|
||||
if ($mode % 2)
|
||||
$css .= " border-color: #$color;";
|
||||
$css .= "}\n";
|
||||
}
|
||||
}
|
||||
|
||||
$calendars = $this->cal->driver->list_calendars();
|
||||
foreach ((array)$calendars as $id => $prop) {
|
||||
if (!$prop['color'])
|
||||
continue;
|
||||
$color = $prop['color'];
|
||||
$class = 'cal-' . asciiwords($id, true);
|
||||
$css .= "li.$class, #eventshow .$class { color: #$color }\n";
|
||||
if ($mode != 1) {
|
||||
if ($mode == 3) {
|
||||
$css .= ".fc-event-$class .fc-event-bg {";
|
||||
$css .= " opacity: 0.9;";
|
||||
$css .= " filter: alpha(opacity=90);";
|
||||
}
|
||||
else {
|
||||
$css .= ".fc-event-$class, ";
|
||||
$css .= ".fc-event-$class .fc-event-inner {";
|
||||
}
|
||||
if (!$attrib['printmode'])
|
||||
$css .= " background-color: #$color;";
|
||||
if ($mode % 2 == 0)
|
||||
$css .= " border-color: #$color;";
|
||||
$css .= "}\n";
|
||||
}
|
||||
$css .= ".$class .handle { background-color: #$color; }";
|
||||
}
|
||||
|
||||
return html::tag('style', array('type' => 'text/css'), $css);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function calendar_list($attrib = array())
|
||||
{
|
||||
$calendars = $this->cal->driver->list_calendars();
|
||||
|
||||
$li = '';
|
||||
foreach ((array)$calendars as $id => $prop) {
|
||||
if ($attrib['activeonly'] && !$prop['active'])
|
||||
continue;
|
||||
|
||||
unset($prop['user_id']);
|
||||
$prop['alarms'] = $this->cal->driver->alarms;
|
||||
$prop['attendees'] = $this->cal->driver->attendees;
|
||||
$prop['freebusy'] = $this->cal->driver->freebusy;
|
||||
$prop['attachments'] = $this->cal->driver->attachments;
|
||||
$prop['undelete'] = $this->cal->driver->undelete;
|
||||
$prop['feedurl'] = $this->cal->get_url(array('_cal' => $this->cal->ical_feed_hash($id) . '.ics', 'action' => 'feed'));
|
||||
$jsenv[$id] = $prop;
|
||||
|
||||
$html_id = html_identifier($id);
|
||||
$class = 'cal-' . asciiwords($id, true);
|
||||
|
||||
if ($prop['readonly'])
|
||||
$class .= ' readonly';
|
||||
if ($prop['class_name'])
|
||||
$class .= ' '.$prop['class_name'];
|
||||
|
||||
$li .= html::tag('li', array('id' => 'rcmlical' . $html_id, 'class' => $class),
|
||||
html::tag('input', array('type' => 'checkbox', 'name' => '_cal[]', 'value' => $id, 'checked' => $prop['active']), '') .
|
||||
html::span('handle', ' ') .
|
||||
html::span('calname', $prop['name']));
|
||||
}
|
||||
|
||||
$this->rc->output->set_env('calendars', $jsenv);
|
||||
$this->rc->output->add_gui_object('folderlist', $attrib['id']);
|
||||
|
||||
return html::tag('ul', $attrib, $li, html::$common_attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function angenda_options($attrib = array())
|
||||
{
|
||||
$attrib += array('id' => 'agendaoptions');
|
||||
$attrib['style'] .= 'display:none';
|
||||
|
||||
$select_range = new html_select(array('name' => 'listrange', 'id' => 'agenda-listrange'));
|
||||
$select_range->add(1 . ' ' . preg_replace('/\(.+\)/', '', $this->cal->gettext('days')), $days);
|
||||
foreach (array(2,5,7,14,30,60,90) as $days)
|
||||
$select_range->add($days . ' ' . preg_replace('/\(|\)/', '', $this->cal->gettext('days')), $days);
|
||||
|
||||
$html .= html::label('agenda-listrange', $this->cal->gettext('listrange'));
|
||||
$html .= $select_range->show($this->rc->config->get('calendar_agenda_range', $this->cal->defaults['calendar_agenda_range']));
|
||||
|
||||
$select_sections = new html_select(array('name' => 'listsections', 'id' => 'agenda-listsections'));
|
||||
$select_sections->add('---', '');
|
||||
foreach (array('day' => 'days', 'week' => 'weeks', 'month' => 'months', 'smart' => 'smartsections') as $val => $label)
|
||||
$select_sections->add(preg_replace('/\(|\)/', '', ucfirst($this->cal->gettext($label))), $val);
|
||||
|
||||
$html .= html::span('spacer', ' ');
|
||||
$html .= html::label('agenda-listsections', $this->cal->gettext('listsections'));
|
||||
$html .= $select_sections->show($this->rc->config->get('calendar_agenda_sections', $this->cal->defaults['calendar_agenda_sections']));
|
||||
|
||||
return html::div($attrib, $html);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select box for calendar selection
|
||||
*/
|
||||
function calendar_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'calendar';
|
||||
$attrib['is_escaped'] = true;
|
||||
$select = new html_select($attrib);
|
||||
|
||||
foreach ((array)$this->cal->driver->list_calendars() as $id => $prop) {
|
||||
if (!$prop['readonly'])
|
||||
$select->add($prop['name'], $id);
|
||||
}
|
||||
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select box for user identity selection
|
||||
*/
|
||||
function identity_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'identity';
|
||||
$select = new html_select($attrib);
|
||||
$identities = $this->rc->user->list_identities();
|
||||
|
||||
foreach ($identities as $ident) {
|
||||
$select->add(format_email_recipient($ident['email'], $ident['name']), $ident['identity_id']);
|
||||
}
|
||||
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select box to select an event category
|
||||
*/
|
||||
function category_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'categories';
|
||||
$select = new html_select($attrib);
|
||||
$select->add('---', '');
|
||||
foreach (array_keys((array)$this->cal->driver->list_categories()) as $cat) {
|
||||
$select->add($cat, $cat);
|
||||
}
|
||||
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select box for free/busy/out-of-office property
|
||||
*/
|
||||
function freebusy_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'freebusy';
|
||||
$select = new html_select($attrib);
|
||||
$select->add($this->cal->gettext('free'), 'free');
|
||||
$select->add($this->cal->gettext('busy'), 'busy');
|
||||
$select->add($this->cal->gettext('outofoffice'), 'outofoffice');
|
||||
$select->add($this->cal->gettext('tentative'), 'tentative');
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render a HTML select for event priorities
|
||||
*/
|
||||
function priority_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'priority';
|
||||
$select = new html_select($attrib);
|
||||
$select->add('---', '0');
|
||||
$select->add('1 '.$this->cal->gettext('highest'), '1');
|
||||
$select->add('2 '.$this->cal->gettext('high'), '2');
|
||||
$select->add('3 ', '3');
|
||||
$select->add('4 ', '4');
|
||||
$select->add('5 '.$this->cal->gettext('normal'), '5');
|
||||
$select->add('6 ', '6');
|
||||
$select->add('7 ', '7');
|
||||
$select->add('8 '.$this->cal->gettext('low'), '8');
|
||||
$select->add('9 '.$this->cal->gettext('lowest'), '9');
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render HTML input for sensitivity selection
|
||||
*/
|
||||
function sensitivity_select($attrib = array())
|
||||
{
|
||||
$attrib['name'] = 'sensitivity';
|
||||
$select = new html_select($attrib);
|
||||
$select->add($this->cal->gettext('public'), 'public');
|
||||
$select->add($this->cal->gettext('private'), 'private');
|
||||
$select->add($this->cal->gettext('confidential'), 'confidential');
|
||||
return $select->show(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render HTML form for alarm configuration
|
||||
*/
|
||||
function alarm_select($attrib = array())
|
||||
{
|
||||
return $this->cal->lib->alarm_select($attrib, $this->cal->driver->alarm_types, $this->cal->driver->alarm_absolute);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function edit_attendees_notify($attrib = array())
|
||||
{
|
||||
$checkbox = new html_checkbox(array('name' => '_notify', 'id' => 'edit-attendees-donotify', 'value' => 1));
|
||||
return html::div($attrib, html::label(null, $checkbox->show(1) . ' ' . $this->cal->gettext('sendnotifications')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the form for recurrence settings
|
||||
*/
|
||||
function recurring_event_warning($attrib = array())
|
||||
{
|
||||
$attrib['id'] = 'edit-recurring-warning';
|
||||
|
||||
$radio = new html_radiobutton(array('name' => '_savemode', 'class' => 'edit-recurring-savemode'));
|
||||
$form = html::label(null, $radio->show('', array('value' => 'current')) . $this->cal->gettext('currentevent')) . ' ' .
|
||||
html::label(null, $radio->show('', array('value' => 'future')) . $this->cal->gettext('futurevents')) . ' ' .
|
||||
html::label(null, $radio->show('all', array('value' => 'all')) . $this->cal->gettext('allevents')) . ' ' .
|
||||
html::label(null, $radio->show('', array('value' => 'new')) . $this->cal->gettext('saveasnew'));
|
||||
|
||||
return html::div($attrib, html::div('message', html::span('ui-icon ui-icon-alert', '') . $this->cal->gettext('changerecurringeventwarning')) . html::div('savemode', $form));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the form for recurrence settings
|
||||
*/
|
||||
function recurrence_form($attrib = array())
|
||||
{
|
||||
switch ($attrib['part']) {
|
||||
// frequency selector
|
||||
case 'frequency':
|
||||
$select = new html_select(array('name' => 'frequency', 'id' => 'edit-recurrence-frequency'));
|
||||
$select->add($this->cal->gettext('never'), '');
|
||||
$select->add($this->cal->gettext('daily'), 'DAILY');
|
||||
$select->add($this->cal->gettext('weekly'), 'WEEKLY');
|
||||
$select->add($this->cal->gettext('monthly'), 'MONTHLY');
|
||||
$select->add($this->cal->gettext('yearly'), 'YEARLY');
|
||||
$html = html::label('edit-frequency', $this->cal->gettext('frequency')) . $select->show('');
|
||||
break;
|
||||
|
||||
// daily recurrence
|
||||
case 'daily':
|
||||
$select = $this->interval_selector(array('name' => 'interval', 'class' => 'edit-recurrence-interval', 'id' => 'edit-recurrence-interval-daily'));
|
||||
$html = html::div($attrib, html::label(null, $this->cal->gettext('every')) . $select->show(1) . html::span('label-after', $this->cal->gettext('days')));
|
||||
break;
|
||||
|
||||
// weekly recurrence form
|
||||
case 'weekly':
|
||||
$select = $this->interval_selector(array('name' => 'interval', 'class' => 'edit-recurrence-interval', 'id' => 'edit-recurrence-interval-weekly'));
|
||||
$html = html::div($attrib, html::label(null, $this->cal->gettext('every')) . $select->show(1) . html::span('label-after', $this->cal->gettext('weeks')));
|
||||
// weekday selection
|
||||
$daymap = array('sun','mon','tue','wed','thu','fri','sat');
|
||||
$checkbox = new html_checkbox(array('name' => 'byday', 'class' => 'edit-recurrence-weekly-byday'));
|
||||
$first = $this->rc->config->get('calendar_first_day', 1);
|
||||
for ($weekdays = '', $j = $first; $j <= $first+6; $j++) {
|
||||
$d = $j % 7;
|
||||
$weekdays .= html::label(array('class' => 'weekday'), $checkbox->show('', array('value' => strtoupper(substr($daymap[$d], 0, 2)))) . $this->cal->gettext($daymap[$d])) . ' ';
|
||||
}
|
||||
$html .= html::div($attrib, html::label(null, $this->cal->gettext('bydays')) . $weekdays);
|
||||
break;
|
||||
|
||||
// monthly recurrence form
|
||||
case 'monthly':
|
||||
$select = $this->interval_selector(array('name' => 'interval', 'class' => 'edit-recurrence-interval', 'id' => 'edit-recurrence-interval-monthly'));
|
||||
$html = html::div($attrib, html::label(null, $this->cal->gettext('every')) . $select->show(1) . html::span('label-after', $this->cal->gettext('months')));
|
||||
|
||||
$checkbox = new html_checkbox(array('name' => 'bymonthday', 'class' => 'edit-recurrence-monthly-bymonthday'));
|
||||
for ($monthdays = '', $d = 1; $d <= 31; $d++) {
|
||||
$monthdays .= html::label(array('class' => 'monthday'), $checkbox->show('', array('value' => $d)) . $d);
|
||||
$monthdays .= $d % 7 ? ' ' : html::br();
|
||||
}
|
||||
|
||||
// rule selectors
|
||||
$radio = new html_radiobutton(array('name' => 'repeatmode', 'class' => 'edit-recurrence-monthly-mode'));
|
||||
$table = new html_table(array('cols' => 2, 'border' => 0, 'cellpadding' => 0, 'class' => 'formtable'));
|
||||
$table->add('label', html::label(null, $radio->show('BYMONTHDAY', array('value' => 'BYMONTHDAY')) . ' ' . $this->cal->gettext('each')));
|
||||
$table->add(null, $monthdays);
|
||||
$table->add('label', html::label(null, $radio->show('', array('value' => 'BYDAY')) . ' ' . $this->cal->gettext('onevery')));
|
||||
$table->add(null, $this->rrule_selectors($attrib['part']));
|
||||
|
||||
$html .= html::div($attrib, $table->show());
|
||||
|
||||
break;
|
||||
|
||||
// annually recurrence form
|
||||
case 'yearly':
|
||||
$select = $this->interval_selector(array('name' => 'interval', 'class' => 'edit-recurrence-interval', 'id' => 'edit-recurrence-interval-yearly'));
|
||||
$html = html::div($attrib, html::label(null, $this->cal->gettext('every')) . $select->show(1) . html::span('label-after', $this->cal->gettext('years')));
|
||||
// month selector
|
||||
$monthmap = array('','jan','feb','mar','apr','may','jun','jul','aug','sep','oct','nov','dec');
|
||||
$checkbox = new html_checkbox(array('name' => 'bymonth', 'class' => 'edit-recurrence-yearly-bymonth'));
|
||||
for ($months = '', $m = 1; $m <= 12; $m++) {
|
||||
$months .= html::label(array('class' => 'month'), $checkbox->show(null, array('value' => $m)) . $this->cal->gettext($monthmap[$m]));
|
||||
$months .= $m % 4 ? ' ' : html::br();
|
||||
}
|
||||
$html .= html::div($attrib + array('id' => 'edit-recurrence-yearly-bymonthblock'), $months);
|
||||
|
||||
// day rule selection
|
||||
$html .= html::div($attrib, html::label(null, $this->cal->gettext('onevery')) . $this->rrule_selectors($attrib['part'], '---'));
|
||||
break;
|
||||
|
||||
// end of recurrence form
|
||||
case 'until':
|
||||
$radio = new html_radiobutton(array('name' => 'repeat', 'class' => 'edit-recurrence-until'));
|
||||
$select = $this->interval_selector(array('name' => 'times', 'id' => 'edit-recurrence-repeat-times'));
|
||||
$input = new html_inputfield(array('name' => 'untildate', 'id' => 'edit-recurrence-enddate', 'size' => "10"));
|
||||
|
||||
$table = new html_table(array('cols' => 2, 'border' => 0, 'cellpadding' => 0, 'class' => 'formtable'));
|
||||
|
||||
$table->add('label', ucfirst($this->cal->gettext('recurrencend')));
|
||||
$table->add(null, html::label(null, $radio->show('', array('value' => '', 'id' => 'edit-recurrence-repeat-forever')) . ' ' .
|
||||
$this->cal->gettext('forever')));
|
||||
|
||||
$table->add('label', '');
|
||||
$table->add(null, $radio->show('', array('value' => 'count', 'id' => 'edit-recurrence-repeat-count')) . ' ' .
|
||||
$this->cal->gettext(array(
|
||||
'name' => 'forntimes',
|
||||
'vars' => array('nr' => $select->show(1)))
|
||||
));
|
||||
|
||||
$table->add('label', '');
|
||||
$table->add(null, $radio->show('', array('value' => 'until', 'id' => 'edit-recurrence-repeat-until')) . ' ' .
|
||||
$this->cal->gettext('untildate') . ' ' . $input->show(''));
|
||||
$html = $table->show();
|
||||
break;
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* Input field for interval selection
|
||||
*/
|
||||
private function interval_selector($attrib)
|
||||
{
|
||||
$select = new html_select($attrib);
|
||||
$select->add(range(1,30), range(1,30));
|
||||
return $select;
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop-down menus for recurrence rules like "each last sunday of"
|
||||
*/
|
||||
private function rrule_selectors($part, $noselect = null)
|
||||
{
|
||||
// rule selectors
|
||||
$select_prefix = new html_select(array('name' => 'bydayprefix', 'id' => "edit-recurrence-$part-prefix"));
|
||||
if ($noselect) $select_prefix->add($noselect, '');
|
||||
$select_prefix->add(array(
|
||||
$this->cal->gettext('first'),
|
||||
$this->cal->gettext('second'),
|
||||
$this->cal->gettext('third'),
|
||||
$this->cal->gettext('fourth'),
|
||||
$this->cal->gettext('last')
|
||||
),
|
||||
array(1, 2, 3, 4, -1));
|
||||
|
||||
$select_wday = new html_select(array('name' => 'byday', 'id' => "edit-recurrence-$part-byday"));
|
||||
if ($noselect) $select_wday->add($noselect, '');
|
||||
|
||||
$daymap = array('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
|
||||
$first = $this->rc->config->get('calendar_first_day', 1);
|
||||
for ($j = $first; $j <= $first+6; $j++) {
|
||||
$d = $j % 7;
|
||||
$select_wday->add($this->cal->gettext($daymap[$d]), strtoupper(substr($daymap[$d], 0, 2)));
|
||||
}
|
||||
|
||||
return $select_prefix->show() . ' ' . $select_wday->show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Form for uploading and importing events
|
||||
*/
|
||||
function events_import_form($attrib = array())
|
||||
{
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'rcmImportForm';
|
||||
|
||||
// Get max filesize, enable upload progress bar
|
||||
$max_filesize = rcube_upload_init();
|
||||
|
||||
$input = new html_inputfield(array(
|
||||
'type' => 'file', 'name' => '_data', 'size' => $attrib['uploadfieldsize']));
|
||||
|
||||
$select = new html_select(array('name' => '_range', 'id' => 'event-import-range'));
|
||||
$select->add(array(
|
||||
$this->cal->gettext('onemonthback'),
|
||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>2))),
|
||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>6))),
|
||||
$this->cal->gettext(array('name' => 'nmonthsback', 'vars' => array('nr'=>12))),
|
||||
$this->cal->gettext('all'),
|
||||
),
|
||||
array('1','2','6','12',0));
|
||||
|
||||
$html .= html::div('form-section',
|
||||
html::div(null, $input->show()) .
|
||||
html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))
|
||||
);
|
||||
|
||||
$html .= html::div('form-section',
|
||||
html::label('event-import-calendar', $this->cal->gettext('calendar')) .
|
||||
$this->calendar_select(array('name' => 'calendar', 'id' => 'event-import-calendar'))
|
||||
);
|
||||
|
||||
$html .= html::div('form-section',
|
||||
html::label('event-import-range', $this->cal->gettext('importrange')) .
|
||||
$select->show(1)
|
||||
);
|
||||
|
||||
$this->rc->output->add_gui_object('importform', $attrib['id']);
|
||||
$this->rc->output->add_label('import');
|
||||
|
||||
return html::tag('form', array('action' => $this->rc->url(array('task' => 'calendar', 'action' => 'import_events')),
|
||||
'method' => "post", 'enctype' => 'multipart/form-data', 'id' => $attrib['id']),
|
||||
$html
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the form for event attachments upload
|
||||
*/
|
||||
function attachments_form($attrib = array())
|
||||
{
|
||||
// add ID if not given
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'rcmUploadForm';
|
||||
|
||||
// Get max filesize, enable upload progress bar
|
||||
$max_filesize = rcube_upload_init();
|
||||
|
||||
$button = new html_inputfield(array('type' => 'button'));
|
||||
$input = new html_inputfield(array(
|
||||
'type' => 'file', 'name' => '_attachments[]',
|
||||
'multiple' => 'multiple', 'size' => $attrib['attachmentfieldsize']));
|
||||
|
||||
return html::div($attrib,
|
||||
html::div(null, $input->show()) .
|
||||
html::div('formbuttons', $button->show(rcube_label('upload'), array('class' => 'button mainaction',
|
||||
'onclick' => JS_OBJECT_NAME . ".upload_file(this.form)"))) .
|
||||
html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register UI object for HTML5 drag & drop file upload
|
||||
*/
|
||||
function file_drop_area($attrib = array())
|
||||
{
|
||||
if ($attrib['id']) {
|
||||
$this->rc->output->add_gui_object('filedrop', $attrib['id']);
|
||||
$this->rc->output->set_env('filedrop', array('action' => 'upload', 'fieldname' => '_attachments'));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate HTML element for attachments list
|
||||
*/
|
||||
function attachments_list($attrib = array())
|
||||
{
|
||||
if (!$attrib['id'])
|
||||
$attrib['id'] = 'rcmAttachmentList';
|
||||
|
||||
$skin_path = $this->cal->local_skin_path();
|
||||
if ($attrib['deleteicon']) {
|
||||
$_SESSION[calendar::SESSION_KEY . '_deleteicon'] = $skin_path . $attrib['deleteicon'];
|
||||
$this->rc->output->set_env('deleteicon', $skin_path . $attrib['deleteicon']);
|
||||
}
|
||||
if ($attrib['cancelicon'])
|
||||
$this->rc->output->set_env('cancelicon', $skin_path . $attrib['cancelicon']);
|
||||
if ($attrib['loadingicon'])
|
||||
$this->rc->output->set_env('loadingicon', $skin_path . $attrib['loadingicon']);
|
||||
|
||||
$this->rc->output->add_gui_object('attachmentlist', $attrib['id']);
|
||||
$this->attachmentlist_id = $attrib['id'];
|
||||
|
||||
return html::tag('ul', $attrib, '', html::$common_attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for calendar form template.
|
||||
* The form content could be overriden by the driver
|
||||
*/
|
||||
function calendar_editform($action, $calendar = array())
|
||||
{
|
||||
// compose default calendar form fields
|
||||
$input_name = new html_inputfield(array('name' => 'name', 'id' => 'calendar-name', 'size' => 20));
|
||||
$input_color = new html_inputfield(array('name' => 'color', 'id' => 'calendar-color', 'size' => 6));
|
||||
|
||||
$formfields = array(
|
||||
'name' => array(
|
||||
'label' => $this->cal->gettext('name'),
|
||||
'value' => $input_name->show($calendar['name']),
|
||||
'id' => 'calendar-name',
|
||||
),
|
||||
'color' => array(
|
||||
'label' => $this->cal->gettext('color'),
|
||||
'value' => $input_color->show($calendar['color']),
|
||||
'id' => 'calendar-color',
|
||||
),
|
||||
);
|
||||
|
||||
if ($this->cal->driver->alarms) {
|
||||
$checkbox = new html_checkbox(array('name' => 'showalarms', 'id' => 'calendar-showalarms', 'value' => 1));
|
||||
$formfields['showalarms'] = array(
|
||||
'label' => $this->cal->gettext('showalarms'),
|
||||
'value' => $checkbox->show($calendar['showalarms']?1:0),
|
||||
'id' => 'calendar-showalarms',
|
||||
);
|
||||
}
|
||||
|
||||
// allow driver to extend or replace the form content
|
||||
return html::tag('form', array('action' => "#", 'method' => "get", 'id' => 'calendarpropform'),
|
||||
$this->cal->driver->calendar_form($action, $calendar, $formfields)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function attendees_list($attrib = array())
|
||||
{
|
||||
$table = new html_table(array('cols' => 5, 'border' => 0, 'cellpadding' => 0, 'class' => 'rectable'));
|
||||
$table->add_header('role', $this->cal->gettext('role'));
|
||||
$table->add_header('name', $this->cal->gettext('attendee'));
|
||||
$table->add_header('availability', $this->cal->gettext('availability'));
|
||||
$table->add_header('confirmstate', $this->cal->gettext('confirmstate'));
|
||||
$table->add_header('options', '');
|
||||
|
||||
return $table->show($attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function attendees_form($attrib = array())
|
||||
{
|
||||
$input = new html_inputfield(array('name' => 'participant', 'id' => 'edit-attendee-name', 'size' => 30));
|
||||
$checkbox = new html_checkbox(array('name' => 'invite', 'id' => 'edit-attendees-invite', 'value' => 1));
|
||||
|
||||
return html::div($attrib,
|
||||
html::div(null, $input->show() . " " .
|
||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-attendee-add', 'value' => $this->cal->gettext('addattendee'))) . " " .
|
||||
html::tag('input', array('type' => 'button', 'class' => 'button', 'id' => 'edit-attendee-schedule', 'value' => $this->cal->gettext('scheduletime').'...'))) .
|
||||
html::p('attendees-invitebox', html::label(null, $checkbox->show(1) . $this->cal->gettext('sendinvitations')))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function attendees_freebusy_table($attrib = array())
|
||||
{
|
||||
$table = new html_table(array('cols' => 2, 'border' => 0, 'cellspacing' => 0));
|
||||
$table->add('attendees',
|
||||
html::tag('h3', 'boxtitle', $this->cal->gettext('tabattendees')) .
|
||||
html::div('timesheader', ' ') .
|
||||
html::div(array('id' => 'schedule-attendees-list', 'class' => 'attendees-list'), '')
|
||||
);
|
||||
$table->add('times',
|
||||
html::div('scroll',
|
||||
html::tag('table', array('id' => 'schedule-freebusy-times', 'border' => 0, 'cellspacing' => 0), html::tag('thead') . html::tag('tbody')) .
|
||||
html::div(array('id' => 'schedule-event-time', 'style' => 'display:none'), ' ')
|
||||
)
|
||||
);
|
||||
|
||||
return $table->show($attrib);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render event details in a table
|
||||
*/
|
||||
function event_details_table($event, $title)
|
||||
{
|
||||
$table = new html_table(array('cols' => 2, 'border' => 0, 'class' => 'calendar-eventdetails'));
|
||||
$table->add('ititle', $title);
|
||||
$table->add('title', Q($event['title']));
|
||||
$table->add('label', $this->cal->gettext('date'));
|
||||
$table->add('location', Q($this->cal->lib->event_date_text($event)));
|
||||
if ($event['location']) {
|
||||
$table->add('label', $this->cal->gettext('location'));
|
||||
$table->add('location', Q($event['location']));
|
||||
}
|
||||
|
||||
return $table->show();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
function event_invitebox($attrib = array())
|
||||
{
|
||||
if ($this->cal->event) {
|
||||
return html::div($attrib,
|
||||
$this->event_details_table($this->cal->event, $this->cal->gettext('itipinvitation')) .
|
||||
$this->cal->invitestatus
|
||||
);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
function event_rsvp_buttons($attrib = array())
|
||||
{
|
||||
$attrib += array('type' => 'button');
|
||||
foreach (array('accepted','tentative','declined') as $method) {
|
||||
$buttons .= html::tag('input', array(
|
||||
'type' => $attrib['type'],
|
||||
'name' => $attrib['iname'],
|
||||
'class' => 'button',
|
||||
'rel' => $method,
|
||||
'value' => $this->cal->gettext('itip' . $method),
|
||||
));
|
||||
}
|
||||
|
||||
return html::div($attrib,
|
||||
html::div('label', $this->cal->gettext('acceptinvitation')) .
|
||||
html::div('rsvp-buttons', $buttons));
|
||||
}
|
||||
|
||||
}
|
5917
lib/js/fullcalendar.js
Normal file
16
lib/js/jquery.miniColors.min.js
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
// http://plugins.jquery.com/project/jQueryMiniColors
|
||||
jQuery&&function(d){d.extend(d.fn,{miniColors:function(j,k){var x=function(a,b){var e=l(a.val());e||(e="FFFFFF");var c=p(e),e=d('<a class="miniColors-trigger" style="background-color: #'+e+'" href="#"></a>');e.insertAfter(a);a.addClass("miniColors").attr("maxlength",7).attr("autocomplete","off");a.data("trigger",e);a.data("hsb",c);b.change&&a.data("change",b.change);b.readonly&&a.attr("readonly",true);b.disabled&&q(a);b.colorValues&&a.data("colorValues",b.colorValues);e.bind("click.miniColors",function(b){b.preventDefault();
|
||||
a.trigger("focus")});a.bind("focus.miniColors",function(){w(a)});a.bind("blur.miniColors",function(){var b=l(a.val());a.val(b?"#"+b:"")});a.bind("keydown.miniColors",function(b){b.keyCode===9&&i(a)});a.bind("keyup.miniColors",function(){var b=a.val().replace(/[^A-F0-9#]/ig,"");a.val(b);r(a)||a.data("trigger").css("backgroundColor","#FFF")});a.bind("paste.miniColors",function(){setTimeout(function(){a.trigger("keyup")},5)})},q=function(a){i(a);a.attr("disabled",true);a.data("trigger").css("opacity",
|
||||
0.5)},w=function(a){if(a.attr("disabled"))return false;i();var b=d('<div class="miniColors-selector"></div>');b.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"></div></div>');b.append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>');b.css({top:a.is(":visible")?a.offset().top+a.outerHeight():a.data("trigger").offset().top+a.data("trigger").outerHeight(),left:a.is(":visible")?a.offset().left:a.data("trigger").offset().left,
|
||||
display:"none"}).addClass(a.attr("class"));var e=a.data("colorValues");if(e&&e.length){var c,f='<div class="miniColors-presets">',g;for(g in e)c=l(e[g]),f+='<div class="miniColors-colorPreset" style="background-color:#'+c+'" rel="'+c+'"></div>';f+="</div>";b.append(f);c=Math.ceil(e.length/7)*24;b.css("width",b.width()+c+5+"px");b.find(".miniColors-presets").css("width",c+"px")}c=a.data("hsb");b.find(".miniColors-colors").css("backgroundColor","#"+n(m({h:c.h,s:100,b:100})));(f=a.data("colorPosition"))||
|
||||
(f=s(c));b.find(".miniColors-colorPicker").css("top",f.y+"px").css("left",f.x+"px");(f=a.data("huePosition"))||(f=t(c));b.find(".miniColors-huePicker").css("top",f.y+"px");a.data("selector",b);a.data("huePicker",b.find(".miniColors-huePicker"));a.data("colorPicker",b.find(".miniColors-colorPicker"));a.data("mousebutton",0);d("BODY").append(b);b.fadeIn(100);b.bind("selectstart",function(){return false});d(document).bind("mousedown.miniColors",function(b){a.data("mousebutton",1);d(b.target).parents().andSelf().hasClass("miniColors-colors")&&
|
||||
(b.preventDefault(),a.data("moving","colors"),u(a,b));d(b.target).parents().andSelf().hasClass("miniColors-hues")&&(b.preventDefault(),a.data("moving","hues"),v(a,b));d(b.target).parents().andSelf().hasClass("miniColors-selector")?b.preventDefault():d(b.target).parents().andSelf().hasClass("miniColors")||i(a)});d(document).bind("mouseup.miniColors",function(){a.data("mousebutton",0);a.removeData("moving")});d(document).bind("mousemove.miniColors",function(b){a.data("mousebutton")===1&&(a.data("moving")===
|
||||
"colors"&&u(a,b),a.data("moving")==="hues"&&v(a,b))});e&&(b.find(".miniColors-colorPreset").click(function(){a.val(d(this).attr("rel"));r(a)}),b.find('.miniColors-presets div[rel="'+a.val().replace(/#/,"")+'"]').addClass("miniColors-colorPreset-active"))},i=function(a){a||(a=".miniColors");d(a).each(function(){var a=d(this).data("selector");d(this).removeData("selector");d(a).fadeOut(100,function(){d(this).remove()})});d(document).unbind("mousedown.miniColors");d(document).unbind("mousemove.miniColors")},
|
||||
u=function(a,b){var e=a.data("colorPicker");e.hide();var c={x:b.clientX-a.data("selector").find(".miniColors-colors").offset().left+d(document).scrollLeft()-5,y:b.clientY-a.data("selector").find(".miniColors-colors").offset().top+d(document).scrollTop()-5};if(c.x<=-5)c.x=-5;if(c.x>=144)c.x=144;if(c.y<=-5)c.y=-5;if(c.y>=144)c.y=144;a.data("colorPosition",c);e.css("left",c.x).css("top",c.y).show();e=Math.round((c.x+5)*0.67);e<0&&(e=0);e>100&&(e=100);c=100-Math.round((c.y+5)*0.67);c<0&&(c=0);c>100&&
|
||||
(c=100);var f=a.data("hsb");f.s=e;f.b=c;o(a,f,true)},v=function(a,b){var e=a.data("huePicker");e.hide();var c={y:b.clientY-a.data("selector").find(".miniColors-colors").offset().top+d(document).scrollTop()-1};if(c.y<=-1)c.y=-1;if(c.y>=149)c.y=149;a.data("huePosition",c);e.css("top",c.y).show();e=Math.round((150-c.y-1)*2.4);e<0&&(e=0);e>360&&(e=360);c=a.data("hsb");c.h=e;o(a,c,true)},o=function(a,b,e){a.data("hsb",b);var c=n(m(b));e&&a.val("#"+c);a.data("trigger").css("backgroundColor","#"+c);a.data("selector")&&
|
||||
a.data("selector").find(".miniColors-colors").css("backgroundColor","#"+n(m({h:b.h,s:100,b:100})));a.data("change")&&a.data("change").call(a,"#"+c,m(b));a.data("colorValues")&&(a.data("selector").find(".miniColors-colorPreset-active").removeClass("miniColors-colorPreset-active"),a.data("selector").find('.miniColors-presets div[rel="'+c+'"]').addClass("miniColors-colorPreset-active"))},r=function(a){var b=l(a.val());if(!b)return false;var b=p(b),e=a.data("hsb");if(b.h===e.h&&b.s===e.s&&b.b===e.b)return true;
|
||||
e=s(b);d(a.data("colorPicker")).css("top",e.y+"px").css("left",e.x+"px");e=t(b);d(a.data("huePicker")).css("top",e.y+"px");o(a,b,false);return true},s=function(a){var b=Math.ceil(a.s/0.67);b<0&&(b=0);b>150&&(b=150);a=150-Math.ceil(a.b/0.67);a<0&&(a=0);a>150&&(a=150);return{x:b-5,y:a-5}},t=function(a){a=150-a.h/2.4;a<0&&(h=0);a>150&&(h=150);return{y:a-1}},l=function(a){a=a.replace(/[^A-Fa-f0-9]/,"");a.length==3&&(a=a[0]+a[0]+a[1]+a[1]+a[2]+a[2]);return a.length===6?a:null},m=function(a){var b,e,c;
|
||||
b=Math.round(a.h);var d=Math.round(a.s*255/100),a=Math.round(a.b*255/100);if(d==0)b=e=c=a;else{var d=(255-d)*a/255,g=(a-d)*(b%60)/60;b==360&&(b=0);b<60?(b=a,c=d,e=d+g):b<120?(e=a,c=d,b=a-g):b<180?(e=a,b=d,c=d+g):b<240?(c=a,b=d,e=a-g):b<300?(c=a,e=d,b=d+g):b<360?(b=a,e=d,c=a-g):c=e=b=0}return{r:Math.round(b),g:Math.round(e),b:Math.round(c)}},n=function(a){var b=[a.r.toString(16),a.g.toString(16),a.b.toString(16)];d.each(b,function(a,c){c.length==1&&(b[a]="0"+c)});return b.join("")},p=function(a){var b=
|
||||
a,b=parseInt(b.indexOf("#")>-1?b.substring(1):b,16),a=b>>16,d=(b&65280)>>8;b&=255;var c={h:0,s:0,b:0},f=Math.min(a,d,b),g=Math.max(a,d,b),f=g-f;c.b=g;c.s=g!=0?255*f/g:0;c.h=c.s!=0?a==g?(d-b)/f:d==g?2+(b-a)/f:4+(a-d)/f:-1;c.h*=60;c.h<0&&(c.h+=360);c.s*=100/255;c.b*=100/255;if(c.s===0)c.h=360;return c};switch(j){case "readonly":return d(this).each(function(){d(this).attr("readonly",k)}),d(this);case "disabled":return d(this).each(function(){if(k)q(d(this));else{var a=d(this);a.attr("disabled",false);
|
||||
a.data("trigger").css("opacity",1)}}),d(this);case "value":return d(this).each(function(){d(this).val(k).trigger("keyup")}),d(this);case "destroy":return d(this).each(function(){var a=d(this);i();a=d(a);a.data("trigger").remove();a.removeAttr("autocomplete");a.removeData("trigger");a.removeData("selector");a.removeData("hsb");a.removeData("huePicker");a.removeData("colorPicker");a.removeData("mousebutton");a.removeData("moving");a.unbind("click.miniColors");a.unbind("focus.miniColors");a.unbind("blur.miniColors");
|
||||
a.unbind("keyup.miniColors");a.unbind("keydown.miniColors");a.unbind("paste.miniColors");d(document).unbind("mousedown.miniColors");d(document).unbind("mousemove.miniColors")}),d(this);default:return j||(j={}),d(this).each(function(){d(this)[0].tagName.toLowerCase()==="input"&&(d(this).data("trigger")||x(d(this),j,k))}),d(this)}}})}(jQuery);
|
38
localization/bg_BG.inc
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Изглед';
|
||||
$labels['time_format'] = 'Формат на часовете';
|
||||
$labels['timeslots'] = 'Полета на час';
|
||||
$labels['first_day'] = 'Първи ден от седмицата';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Календар';
|
||||
$labels['day'] = 'Ден';
|
||||
$labels['week'] = 'Седмица';
|
||||
$labels['month'] = 'Месец';
|
||||
$labels['new_event'] = 'Добавяне на събитие';
|
||||
$labels['edit_event'] = 'Промяна на събитие';
|
||||
$labels['save'] = 'Запис';
|
||||
$labels['remove'] = 'Изтриване';
|
||||
$labels['cancel'] = 'Отказ';
|
||||
$labels['title'] = 'Заглавие';
|
||||
$labels['description'] = 'Описание';
|
||||
$labels['all-day'] = 'цял ден';
|
||||
$labels['export'] = 'Запази като ICS';
|
||||
$labels['category'] = 'Категория';
|
||||
?>
|
235
localization/cs_CZ.inc
Normal file
|
@ -0,0 +1,235 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Výchozí pohled';
|
||||
$labels['time_format'] = 'Formát data';
|
||||
$labels['timeslots'] = 'Slotů na hodinu';
|
||||
$labels['first_day'] = 'První den v týdnu';
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Výchozí pohled';
|
||||
$labels['time_format'] = 'Formát času';
|
||||
$labels['timeslots'] = 'Slotů na hodinu';
|
||||
$labels['first_day'] = 'První den týdne';
|
||||
$labels['first_hour'] = 'První hodina k zobrazení';
|
||||
$labels['workinghours'] = 'Pracovní hodiny';
|
||||
$labels['add_category'] = 'Přidat kategorii';
|
||||
$labels['remove_category'] = 'Odstranit kategorii';
|
||||
$labels['defaultcalendar'] = 'Vytvářet nové události v';
|
||||
$labels['eventcoloring'] = 'Barvy událostí';
|
||||
$labels['coloringmode0'] = 'Podle kalendáře';
|
||||
$labels['coloringmode1'] = 'Podle kategorie';
|
||||
$labels['coloringmode2'] = 'Kalendář pro orámování, kategorie pro obsah';
|
||||
$labels['coloringmode3'] = 'Kategorie pro orámování, kalendář pro obsah';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Kalendář';
|
||||
$labels['calendars'] = 'Kalendáře';
|
||||
$labels['category'] = 'Kategorie';
|
||||
$labels['categories'] = 'Kategorie';
|
||||
$labels['createcalendar'] = 'Vytvořit nový kalendář';
|
||||
$labels['editcalendar'] = 'Upravit vlastnosti kalendáře';
|
||||
$labels['name'] = 'Název';
|
||||
$labels['color'] = 'Barva';
|
||||
$labels['day'] = 'Den';
|
||||
$labels['week'] = 'Týden';
|
||||
$labels['month'] = 'Měsíc';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'Nová';
|
||||
$labels['new_event'] = 'Nová událost';
|
||||
$labels['edit_event'] = 'Upravit událost';
|
||||
$labels['edit'] = 'Upravit';
|
||||
$labels['save'] = 'Uložit';
|
||||
$labels['remove'] = 'Odstranit';
|
||||
$labels['cancel'] = 'Storno';
|
||||
$labels['select'] = 'Vybrat';
|
||||
$labels['print'] = 'Tisk';
|
||||
$labels['printtitle'] = 'Vytisknout kalendáře';
|
||||
$labels['title'] = 'Souhrn';
|
||||
$labels['description'] = 'Popis';
|
||||
$labels['all-day'] = 'celý den';
|
||||
$labels['export'] = 'Exportovat do ICS';
|
||||
$labels['exporttitle'] = 'Exportovat souhrn do ICS';
|
||||
$labels['location'] = 'Místo';
|
||||
$labels['date'] = 'Datum';
|
||||
$labels['start'] = 'Začátek';
|
||||
$labels['end'] = 'Konec';
|
||||
$labels['selectdate'] = 'Vyberte datum';
|
||||
$labels['freebusy'] = 'Zobrazovat časový úsek jako';
|
||||
$labels['free'] = 'volno';
|
||||
$labels['busy'] = 'obsazeno';
|
||||
$labels['outofoffice'] = 'mimo kancelář';
|
||||
$labels['tentative'] = 'nezávazně';
|
||||
$labels['priority'] = 'Priorita';
|
||||
$labels['sensitivity'] = 'Soukromí';
|
||||
$labels['public'] = 'veřejné';
|
||||
$labels['private'] = 'soukromé';
|
||||
$labels['confidential'] = 'důvěrné';
|
||||
$labels['alarms'] = 'Připomenutí';
|
||||
$labels['generated'] = 'vygenerováno';
|
||||
$labels['printdescriptions'] = 'Vytisknout popisy';
|
||||
$labels['parentcalendar'] = 'Vložit dovnitř';
|
||||
$labels['searchearlierdates'] = '« Hledat dřívější události';
|
||||
$labels['searchlaterdates'] = 'Hledat pozdější události »';
|
||||
$labels['andnmore'] = 'dalších $nr...';
|
||||
$labels['togglerole'] = 'Klikněte k přepnutí role';
|
||||
$labels['createfrommail'] = 'Uložit jako událost';
|
||||
$labels['importevents'] = 'Importovat události';
|
||||
$labels['importrange'] = 'Události od';
|
||||
$labels['onemonthback'] = '1 měsíc nazpátek';
|
||||
$labels['nmonthsback'] = '$nr měsíců nazpátek';
|
||||
$labels['showurl'] = 'Ukázat URL kalendáře';
|
||||
$labels['showurldescription'] = 'Tuto adresu použijte pro přístup (jen ke čtení) ke kalendáři z jiných aplikací. Můžete ji zkopírovat a vložit do jakéhokoli kalendářového softwaru, který podporuje formát iCal.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Rozsah k zobrazení:';
|
||||
$labels['listsections'] = 'Rozdělit na:';
|
||||
$labels['smartsections'] = 'Chytré sekce';
|
||||
$labels['until'] = 'do';
|
||||
$labels['today'] = 'Dnes';
|
||||
$labels['tomorrow'] = 'Zítra';
|
||||
$labels['thisweek'] = 'Tento týden';
|
||||
$labels['nextweek'] = 'Příští týden';
|
||||
$labels['thismonth'] = 'Tento měsíc';
|
||||
$labels['nextmonth'] = 'Příští měsíc';
|
||||
$labels['weekofyear'] = 'Týden';
|
||||
$labels['pastevents'] = 'Minulost';
|
||||
$labels['futureevents'] = 'Budoucnost';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Zobrazit upozornění';
|
||||
$labels['defaultalarmtype'] = 'Výchozí nastavení připomenutí';
|
||||
$labels['defaultalarmoffset'] = 'Výchozí čas připomenutí';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Účastník';
|
||||
$labels['role'] = 'Role';
|
||||
$labels['availability'] = 'Dost.';
|
||||
$labels['confirmstate'] = 'Stav';
|
||||
$labels['addattendee'] = 'Přidat účastníka';
|
||||
$labels['roleorganizer'] = 'Organizátor';
|
||||
$labels['rolerequired'] = 'Povinný';
|
||||
$labels['roleoptional'] = 'Nepovinný';
|
||||
$labels['roleresource'] = 'Prostředek';
|
||||
$labels['availfree'] = 'volno';
|
||||
$labels['availbusy'] = 'obsazeno';
|
||||
$labels['availunknown'] = 'neznámý';
|
||||
$labels['availtentative'] = 'nezávazně';
|
||||
$labels['availoutofoffice'] = 'mimo kancelář';
|
||||
$labels['scheduletime'] = 'Najít dostupnost';
|
||||
$labels['sendinvitations'] = 'Poslat pozvánky';
|
||||
$labels['sendnotifications'] = 'Uvědomit účastníky o změnách';
|
||||
$labels['sendcancellation'] = 'Uvědomit účastníky o zrušení události';
|
||||
$labels['onlyworkinghours'] = 'Najít dostupnost v mé pracovní době';
|
||||
$labels['reqallattendees'] = 'Povinní/všichni účastníci';
|
||||
$labels['prevslot'] = 'Předchozí slot';
|
||||
$labels['nextslot'] = 'Další slot';
|
||||
$labels['noslotfound'] = 'Nelze najít volný slot';
|
||||
$labels['invitationsubject'] = 'Byl(a) jste pozván(a) na událost "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees\n\nPodrobnosti o události najdete v přiloženém souboru typu iCalendar. Můžete si ho naimportovat do kalendářového programu.";
|
||||
$labels['invitationattendlinks'] = "Pokud váš poštovní klient nepodporuje pozvánky iTip, použijte prosím následující odkaz k potvrzení nebo odmítnutí pozvání:\n\$url";
|
||||
$labels['eventupdatesubject'] = 'Událost "$title" byla aktualizována';
|
||||
$labels['eventupdatesubjectempty'] = 'Událost, která se vás týká, byla aktualizována';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees\n\nPodrobnosti o aktualizované události najdete v přiloženém souboru typu iCalendar. Můžete si ho naimportovat do kalendářového programu.";
|
||||
$labels['eventcancelsubject'] = 'Událost "$title" byla zrušena';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees\n\nUdálost byla zrušena organizátorem (\$organizer).\n\nPodrobnosti najdete v přiloženém souboru ve formátu iCalendar.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Pozvání na událost';
|
||||
$labels['itipupdate'] = 'Aktualizace události';
|
||||
$labels['itipcancellation'] = 'Zrušeno:';
|
||||
$labels['itipreply'] = 'Odpověď na';
|
||||
$labels['itipaccepted'] = 'Potvrdit';
|
||||
$labels['itiptentative'] = 'Možná';
|
||||
$labels['itipdeclined'] = 'Odmítnout';
|
||||
$labels['itipsubjectaccepted'] = '$name potvrdil(a) účas na události "$title"';
|
||||
$labels['itipsubjecttentative'] = '$name nezávazně potvrdil(a) účast na události "$title"';
|
||||
$labels['itipsubjectdeclined'] = '$name odmítl(a) účast na události "$title"';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender přijal(a) pozvání na tuto událost:\n\n*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender nezávazně přijal(a) pozvání na tuto událost:\n\n*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender odmítl(a) pozvání na tuto událost:\n\n*\$title*\n\nKdy: \$date\n\nPozváni: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Opravdu chcete odmítnout pozvání na tuto událost?';
|
||||
$labels['importtocalendar'] = 'Uložit do kalendáře';
|
||||
$labels['removefromcalendar'] = 'Odstranit z kalendáře';
|
||||
$labels['updateattendeestatus'] = 'Aktualizovat stav účastníka';
|
||||
$labels['acceptinvitation'] = 'Chcete přijmout toto pozvání (potvrdit účast)?';
|
||||
$labels['youhaveaccepted'] = 'Přijal(a) jste toto pozvání';
|
||||
$labels['youhavetentative'] = 'Nezávazně jste přijal(a) toto pozvání';
|
||||
$labels['youhavedeclined'] = 'Odmítl(a) jste toto pozvání';
|
||||
$labels['notanattendee'] = 'Nejste na seznamu účastníků této události';
|
||||
$labels['eventcancelled'] = 'Tato událost byla zrušena';
|
||||
$labels['saveincalendar'] = 'uložit do';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Souhrn';
|
||||
$labels['tabrecurrence'] = 'Opakování';
|
||||
$labels['tabattendees'] = 'Účastníci';
|
||||
$labels['tabattachments'] = 'Přílohy';
|
||||
$labels['tabsharing'] = 'Sdílení';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Opravdu chcete smazat tuto událost?';
|
||||
$labels['deletecalendarconfirm'] = 'Opravdu chcete smazat tento kalendář se všemi událostmi?';
|
||||
$labels['savingdata'] = 'Ukládám data...';
|
||||
$labels['errorsaving'] = 'Nelze uložit změny.';
|
||||
$labels['operationfailed'] = 'Požavovaná operace selhala.';
|
||||
$labels['invalideventdates'] = 'Vložená data nejsou platná! Zkontrolujte prosím zadávané údaje.';
|
||||
$labels['invalidcalendarproperties'] = 'Neplatné vlastnosti kalendáře! Vložte prosím platné jméno.';
|
||||
$labels['searchnoresults'] = 'Ve vybraných kalendářích nebyly nalezeny žádné události.';
|
||||
$labels['successremoval'] = 'Událost byla úspěšně smazána.';
|
||||
$labels['successrestore'] = 'Událost byla úspěšně obnovena.';
|
||||
$labels['errornotifying'] = 'Nelze odeslat notifikace účastníkům události';
|
||||
$labels['errorimportingevent'] = 'Nelze naimportovat událost';
|
||||
$labels['newerversionexists'] = 'Existuje již novější verze této události! Operace byla zrušena.';
|
||||
$labels['nowritecalendarfound'] = 'Nebyl nalezen žádný kalendář, do kterého by šlo uložit tuto událost.';
|
||||
$labels['importedsuccessfully'] = 'Událost byla úspěšně přidána do kalendáře \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Stav účastníka byl úspěšně aktualizován';
|
||||
$labels['itipsendsuccess'] = 'Pozvánky byly rozeslány účastníkům.';
|
||||
$labels['itipresponseerror'] = 'Nelze odeslat odpověď na tuto pozvánku';
|
||||
$labels['itipinvalidrequest'] = 'Tato pozvánka již není platná';
|
||||
$labels['sentresponseto'] = 'Odpověď na pozvánku byla úspěšně odeslána na adresu $mailto';
|
||||
$labels['localchangeswarning'] = 'Chystáte se provést změny, které se projeví jen ve vašem vlastním kalendáři a nelze je poslat organizátorovi události.';
|
||||
$labels['importsuccess'] = 'Úspěšně importováno $nr událostí';
|
||||
$labels['importnone'] = 'Nebyly nalezeny žádné události k importu';
|
||||
$labels['importerror'] = 'Při importu došlo k chybě';
|
||||
$labels['aclnorights'] = 'Nemáte administrátorská práva k tomuto kalendáři.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Opakování';
|
||||
$labels['frequency'] = 'Opakovat';
|
||||
$labels['never'] = 'nikdy';
|
||||
$labels['daily'] = 'denně';
|
||||
$labels['weekly'] = 'týdně';
|
||||
$labels['monthly'] = 'měsíčně';
|
||||
$labels['yearly'] = 'ročně';
|
||||
$labels['every'] = 'Každý';
|
||||
$labels['days'] = 'den (dny)';
|
||||
$labels['weeks'] = 'týden (týdny)';
|
||||
$labels['months'] = 'měsíc(e/ů)';
|
||||
$labels['years'] = 'rok(y/ů) v:';
|
||||
$labels['bydays'] = ' ';
|
||||
$labels['untildate'] = 'do';
|
||||
$labels['each'] = 'Každý';
|
||||
$labels['onevery'] = 'Vždy v';
|
||||
$labels['onsamedate'] = 'Ve stejné datum';
|
||||
$labels['forever'] = 'trvale';
|
||||
$labels['recurrencend'] = 'do';
|
||||
$labels['forntimes'] = 'jen $nrkrát';
|
||||
$labels['first'] = 'první';
|
||||
$labels['second'] = 'druhý';
|
||||
$labels['third'] = 'třetí';
|
||||
$labels['fourth'] = 'čtvrtý';
|
||||
$labels['last'] = 'poslední';
|
||||
$labels['dayofmonth'] = 'Den v měsíci';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Změnit událost';
|
||||
$labels['removeeventconfirm'] = 'Odstranit událost';
|
||||
$labels['changerecurringeventwarning'] = 'Toto je opakovaná událost. Chcete upravit jen toto konání, toto a všechna následující konání, úplně všechna konání nebo uložit událost jako novou?';
|
||||
$labels['removerecurringeventwarning'] = 'Toto je opakovaná událost. Chcete odstranit jen toto konání, toto a následující konání nebo úplně všechna konání této události?';
|
||||
$labels['currentevent'] = 'Aktuální';
|
||||
$labels['futurevents'] = 'Budoucí';
|
||||
$labels['allevents'] = 'Všechny';
|
||||
$labels['saveasnew'] = 'Uložit jako novou';
|
||||
|
229
localization/de_CH.inc
Normal file
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Ansicht';
|
||||
$labels['time_format'] = 'Zeitformatierung';
|
||||
$labels['timeslots'] = 'Zeitraster pro Stunde';
|
||||
$labels['first_day'] = 'Erster Wochentag';
|
||||
$labels['first_hour'] = 'Erste angezeigte Stunde';
|
||||
$labels['workinghours'] = 'Arbeitszeiten';
|
||||
$labels['add_category'] = 'Katgorie hinzufügen';
|
||||
$labels['remove_category'] = 'Katgorie entfernen';
|
||||
$labels['defaultcalendar'] = 'Neue Termine erstellen in';
|
||||
$labels['eventcoloring'] = 'Färbung der Termine';
|
||||
$labels['coloringmode0'] = 'Farbe des Kalenders';
|
||||
$labels['coloringmode1'] = 'Farbe der Kategorie';
|
||||
$labels['coloringmode2'] = 'Kalenderfarbe aussen, Kategoriefarbe innen';
|
||||
$labels['coloringmode3'] = 'Kategoriefarbe aussen, Kalenderfarbe innen';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Kalender';
|
||||
$labels['calendars'] = 'Kalender';
|
||||
$labels['category'] = 'Kategorie';
|
||||
$labels['categories'] = 'Kategorien';
|
||||
$labels['createcalendar'] = 'Neuen Kalender erstellen';
|
||||
$labels['editcalendar'] = 'Kalendereigenschaften bearbeiten';
|
||||
$labels['name'] = 'Name';
|
||||
$labels['color'] = 'Farbe';
|
||||
$labels['day'] = 'Tag';
|
||||
$labels['week'] = 'Woche';
|
||||
$labels['month'] = 'Monat';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'Neu';
|
||||
$labels['new_event'] = 'Neuer Termin';
|
||||
$labels['edit_event'] = 'Termin bearbeiten';
|
||||
$labels['edit'] = 'Bearbeiten';
|
||||
$labels['save'] = 'Speichern';
|
||||
$labels['remove'] = 'Entfernen';
|
||||
$labels['cancel'] = 'Abbrechen';
|
||||
$labels['select'] = 'Auswählen';
|
||||
$labels['print'] = 'Drucken';
|
||||
$labels['printtitle'] = 'Kalender drucken';
|
||||
$labels['title'] = 'Titel';
|
||||
$labels['description'] = 'Beschrieb';
|
||||
$labels['all-day'] = 'ganztägig';
|
||||
$labels['export'] = 'Exportieren';
|
||||
$labels['exporttitle'] = 'Kalender als iCalendar exportieren';
|
||||
$labels['location'] = 'Ort';
|
||||
$labels['date'] = 'Datum';
|
||||
$labels['start'] = 'Beginn';
|
||||
$labels['end'] = 'Ende';
|
||||
$labels['selectdate'] = 'Datum auswählen';
|
||||
$labels['freebusy'] = 'Zeige mich als';
|
||||
$labels['free'] = 'Frei';
|
||||
$labels['busy'] = 'Gebucht';
|
||||
$labels['outofoffice'] = 'Abwesend';
|
||||
$labels['tentative'] = 'Mit Vorbehalt';
|
||||
$labels['priority'] = 'Priorität';
|
||||
$labels['sensitivity'] = 'Sichtbarkeit';
|
||||
$labels['public'] = 'öffentlich';
|
||||
$labels['private'] = 'privat';
|
||||
$labels['confidential'] = 'vertraulich';
|
||||
$labels['alarms'] = 'Erinnerung';
|
||||
$labels['generated'] = 'erstellt am';
|
||||
$labels['printdescriptions'] = 'Beschrieb drucken';
|
||||
$labels['parentcalendar'] = 'Erstellen in';
|
||||
$labels['searchearlierdates'] = '« Frühere Termine suchen';
|
||||
$labels['searchlaterdates'] = 'Spätere Termine suchen »';
|
||||
$labels['andnmore'] = '$nr weitere...';
|
||||
$labels['togglerole'] = 'Zum Ändern der Rolle klicken';
|
||||
$labels['createfrommail'] = 'Als Termin speichern';
|
||||
$labels['importevents'] = 'Termine importieren';
|
||||
$labels['importrange'] = 'Termine ab';
|
||||
$labels['onemonthback'] = '1 Monat zurück';
|
||||
$labels['nmonthsback'] = '$nr Monate zurück';
|
||||
$labels['showurl'] = 'URL anzeigen';
|
||||
$labels['showurldescription'] = 'Über die folgende Adresse können Sie mit einem beliebigen Kalenderprogramm Ihren Kalender abrufen (nur lesend), sofern dieses das iCal-Format unterstützt.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Angezeigter Bereich:';
|
||||
$labels['listsections'] = 'Unterteilung:';
|
||||
$labels['smartsections'] = 'Intelligent';
|
||||
$labels['until'] = 'bis';
|
||||
$labels['today'] = 'Heute';
|
||||
$labels['tomorrow'] = 'Morgen';
|
||||
$labels['thisweek'] = 'Diese Woche';
|
||||
$labels['nextweek'] = 'Nächste Woche';
|
||||
$labels['thismonth'] = 'Diesen Monat';
|
||||
$labels['nextmonth'] = 'Nächsten Monat';
|
||||
$labels['weekofyear'] = 'KW';
|
||||
$labels['pastevents'] = 'Vergangene';
|
||||
$labels['futureevents'] = 'Zukünftige';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Erinnerungen anzeigen';
|
||||
$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung';
|
||||
$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Teilnehmer';
|
||||
$labels['role'] = 'Rolle';
|
||||
$labels['availability'] = 'Verfüg.';
|
||||
$labels['confirmstate'] = 'Status';
|
||||
$labels['addattendee'] = 'Hinzufügen';
|
||||
$labels['roleorganizer'] = 'Organisator';
|
||||
$labels['rolerequired'] = 'Erforderlich';
|
||||
$labels['roleoptional'] = 'Optional';
|
||||
$labels['rolechair'] = 'Vorsitz';
|
||||
$labels['availfree'] = 'Frei';
|
||||
$labels['availbusy'] = 'Gebucht';
|
||||
$labels['availunknown'] = 'Unbekannt';
|
||||
$labels['availtentative'] = 'Mit Vorbehalt';
|
||||
$labels['availoutofoffice'] = 'Abwesend';
|
||||
$labels['scheduletime'] = 'Verfügbarkeit anzeigen';
|
||||
$labels['sendinvitations'] = 'Einladungen versenden';
|
||||
$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren';
|
||||
$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren';
|
||||
$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen';
|
||||
$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer';
|
||||
$labels['prevslot'] = 'Vorheriger Vorschlag';
|
||||
$labels['nextslot'] = 'Nächster Vorschlag';
|
||||
$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden';
|
||||
$labels['invitationsubject'] = 'Sie wurden zu "$title" eingeladen';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren.";
|
||||
$labels['invitationattendlinks'] = "Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" wurde aktualisiert';
|
||||
$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren.";
|
||||
$labels['eventcancelsubject'] = '"$title" wurde abgesagt';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nDer Termin wurde von \$organizer abgesagt.\n\nIm Anhang finden Sie eine iCalendar-Datei mit den Termindaten.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Einladung zu';
|
||||
$labels['itipreply'] = 'Antwort zu';
|
||||
$labels['itipupdate'] = 'Aktialisiert:';
|
||||
$labels['itipcancellation'] = 'Abgesagt:';
|
||||
$labels['itipaccepted'] = 'Akzeptieren';
|
||||
$labels['itiptentative'] = 'Mit Vorbehalt';
|
||||
$labels['itipdeclined'] = 'Ablehnen';
|
||||
$labels['itipsubjectaccepted'] = 'Einladung zu "$title" wurde von $name angenommen';
|
||||
$labels['itipsubjecttentative'] = 'Einladung zu "$title" wurde von $name mit Vorbehalt angenommen';
|
||||
$labels['itipsubjectdeclined'] = 'Einladung zu "$title" wurde von $name abgelehnt';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender hat die Einladung zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender hat die Einladung zum folgenden Termin abgelehnt:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?';
|
||||
$labels['declinedeleteconfirm'] = 'Möchten Sie den abgelehnten Termin ebenfalls aus Ihrem Kalender löschen?';
|
||||
$labels['importtocalendar'] = 'In Kalender übernehmen';
|
||||
$labels['removefromcalendar'] = 'Aus meinem Kalender löschen';
|
||||
$labels['updateattendeestatus'] = 'Teilnehmerstatus aktualisieren';
|
||||
$labels['acceptinvitation'] = 'Möchten Sie die Einladung zu diesem Termin annehmen?';
|
||||
$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen';
|
||||
$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen';
|
||||
$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt';
|
||||
$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt';
|
||||
$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt';
|
||||
$labels['saveincalendar'] = 'speichern in';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Übersicht';
|
||||
$labels['tabrecurrence'] = 'Wiederholung';
|
||||
$labels['tabattendees'] = 'Teilnehmer';
|
||||
$labels['tabattachments'] = 'Anhänge';
|
||||
$labels['tabsharing'] = 'Freigabe';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?';
|
||||
$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?';
|
||||
$labels['savingdata'] = 'Speichere Daten...';
|
||||
$labels['errorsaving'] = 'Fehler beim Speichern.';
|
||||
$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.';
|
||||
$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.';
|
||||
$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.';
|
||||
$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.';
|
||||
$labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.';
|
||||
$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.';
|
||||
$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden';
|
||||
$labels['errorimportingevent'] = 'Fehler beim Importieren';
|
||||
$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.';
|
||||
$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden';
|
||||
$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in \'$calendar\' gespeichert';
|
||||
$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert';
|
||||
$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.';
|
||||
$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden';
|
||||
$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet';
|
||||
$labels['localchangeswarning'] = 'Änderungen an diesem Termin werden nur in Ihrem Kalender gespeichert und nicht an den Organisator des Termins gesendet.';
|
||||
$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert';
|
||||
$labels['importnone'] = 'Keine Termine zum Importieren gefunden';
|
||||
$labels['importerror'] = 'Fehler beim Importieren';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Wiederholung';
|
||||
$labels['frequency'] = 'Wiederholung';
|
||||
$labels['never'] = 'nie';
|
||||
$labels['daily'] = 'täglich';
|
||||
$labels['weekly'] = 'wöchentlich';
|
||||
$labels['monthly'] = 'monatlich';
|
||||
$labels['yearly'] = 'jährlich';
|
||||
$labels['every'] = 'Alle';
|
||||
$labels['days'] = 'Tag(e)';
|
||||
$labels['weeks'] = 'Woche(n)';
|
||||
$labels['months'] = 'Monat(e)';
|
||||
$labels['years'] = 'Jahre(e) im:';
|
||||
$labels['bydays'] = 'Am';
|
||||
$labels['untildate'] = 'am';
|
||||
$labels['each'] = 'Jeden';
|
||||
$labels['onevery'] = 'An jedem';
|
||||
$labels['onsamedate'] = 'Am gleichen Tag';
|
||||
$labels['forever'] = 'unendlich';
|
||||
$labels['recurrencend'] = 'bis';
|
||||
$labels['forntimes'] = '$nr Wiederholungen';
|
||||
$labels['first'] = 'erster';
|
||||
$labels['second'] = 'zweiter';
|
||||
$labels['third'] = 'dritter';
|
||||
$labels['fourth'] = 'vierter';
|
||||
$labels['last'] = 'letzter';
|
||||
$labels['dayofmonth'] = 'Tag des Montats';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Termin ändern';
|
||||
$labels['removeeventconfirm'] = 'Termin löschen';
|
||||
$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?';
|
||||
$labels['removerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine löschen?';
|
||||
$labels['currentevent'] = 'Aktuellen';
|
||||
$labels['futurevents'] = 'Zukünftige';
|
||||
$labels['allevents'] = 'Alle';
|
||||
$labels['saveasnew'] = 'Als neu speichern';
|
||||
|
||||
?>
|
229
localization/de_DE.inc
Normal file
|
@ -0,0 +1,229 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Ansicht';
|
||||
$labels['time_format'] = 'Zeitformatierung';
|
||||
$labels['timeslots'] = 'Zeitraster pro Stunde';
|
||||
$labels['first_day'] = 'Erster Wochentag';
|
||||
$labels['first_hour'] = 'Erste angezeigte Stunde';
|
||||
$labels['workinghours'] = 'Arbeitszeiten';
|
||||
$labels['add_category'] = 'Katgorie hinzufügen';
|
||||
$labels['remove_category'] = 'Katgorie entfernen';
|
||||
$labels['defaultcalendar'] = 'Neue Termine erstellen in';
|
||||
$labels['eventcoloring'] = 'Färbung der Termine';
|
||||
$labels['coloringmode0'] = 'Farbe des Kalenders';
|
||||
$labels['coloringmode1'] = 'Farbe der Kategorie';
|
||||
$labels['coloringmode2'] = 'Kalenderfarbe außen, Kategoriefarbe innen';
|
||||
$labels['coloringmode3'] = 'Kategoriefarbe außen, Kalenderfarbe innen';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Kalender';
|
||||
$labels['calendars'] = 'Kalender';
|
||||
$labels['category'] = 'Kategorie';
|
||||
$labels['categories'] = 'Kategorien';
|
||||
$labels['createcalendar'] = 'Neuen Kalender erstellen';
|
||||
$labels['editcalendar'] = 'Kalendereigenschaften bearbeiten';
|
||||
$labels['name'] = 'Name';
|
||||
$labels['color'] = 'Farbe';
|
||||
$labels['day'] = 'Tag';
|
||||
$labels['week'] = 'Woche';
|
||||
$labels['month'] = 'Monat';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'Neu';
|
||||
$labels['new_event'] = 'Neuer Termin';
|
||||
$labels['edit_event'] = 'Termin bearbeiten';
|
||||
$labels['edit'] = 'Bearbeiten';
|
||||
$labels['save'] = 'Speichern';
|
||||
$labels['remove'] = 'Entfernen';
|
||||
$labels['cancel'] = 'Abbrechen';
|
||||
$labels['select'] = 'Auswählen';
|
||||
$labels['print'] = 'Drucken';
|
||||
$labels['printtitle'] = 'Kalender drucken';
|
||||
$labels['title'] = 'Titel';
|
||||
$labels['description'] = 'Beschreibung';
|
||||
$labels['all-day'] = 'ganztägig';
|
||||
$labels['export'] = 'Exportieren';
|
||||
$labels['exporttitle'] = 'Kalender als iCalendar exportieren';
|
||||
$labels['location'] = 'Ort';
|
||||
$labels['date'] = 'Datum';
|
||||
$labels['start'] = 'Beginn';
|
||||
$labels['end'] = 'Ende';
|
||||
$labels['selectdate'] = 'Datum auswählen';
|
||||
$labels['freebusy'] = 'Zeige mich als';
|
||||
$labels['free'] = 'Frei';
|
||||
$labels['busy'] = 'Gebucht';
|
||||
$labels['outofoffice'] = 'Abwesend';
|
||||
$labels['tentative'] = 'Mit Vorbehalt';
|
||||
$labels['priority'] = 'Priorität';
|
||||
$labels['sensitivity'] = 'Sichtbarkeit';
|
||||
$labels['public'] = 'öffentlich';
|
||||
$labels['private'] = 'privat';
|
||||
$labels['confidential'] = 'vertraulich';
|
||||
$labels['alarms'] = 'Erinnerung';
|
||||
$labels['generated'] = 'erstellt am';
|
||||
$labels['printdescriptions'] = 'Beschreibung drucken';
|
||||
$labels['parentcalendar'] = 'Erstellen in';
|
||||
$labels['searchearlierdates'] = '« Frühere Termine suchen';
|
||||
$labels['searchlaterdates'] = 'Spätere Termine suchen »';
|
||||
$labels['andnmore'] = '$nr weitere...';
|
||||
$labels['togglerole'] = 'Zum Ändern der Rolle klicken';
|
||||
$labels['createfrommail'] = 'Als Termin speichern';
|
||||
$labels['importevents'] = 'Termine importieren';
|
||||
$labels['importrange'] = 'Termine ab';
|
||||
$labels['onemonthback'] = '1 Monat zurück';
|
||||
$labels['nmonthsback'] = '$nr Monate zurück';
|
||||
$labels['showurl'] = 'URL anzeigen';
|
||||
$labels['showurldescription'] = 'Über die folgende Adresse können Sie mit einem beliebigen Kalenderprogramm Ihren Kalender abrufen (nur lesend), sofern dieses das iCal-Format unterstützt.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Angezeigter Bereich:';
|
||||
$labels['listsections'] = 'Unterteilung:';
|
||||
$labels['smartsections'] = 'Intelligent';
|
||||
$labels['until'] = 'bis';
|
||||
$labels['today'] = 'Heute';
|
||||
$labels['tomorrow'] = 'Morgen';
|
||||
$labels['thisweek'] = 'Diese Woche';
|
||||
$labels['nextweek'] = 'Nächste Woche';
|
||||
$labels['thismonth'] = 'Diesen Monat';
|
||||
$labels['nextmonth'] = 'Nächsten Monat';
|
||||
$labels['weekofyear'] = 'Woche';
|
||||
$labels['pastevents'] = 'Vergangene';
|
||||
$labels['futureevents'] = 'Zukünftige';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Erinnerungen anzeigen';
|
||||
$labels['defaultalarmtype'] = 'Standard-Erinnerungseinstellung';
|
||||
$labels['defaultalarmoffset'] = 'Standard-Erinnerungszeit';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Teilnehmer';
|
||||
$labels['role'] = 'Rolle';
|
||||
$labels['availability'] = 'Verfüg.';
|
||||
$labels['confirmstate'] = 'Status';
|
||||
$labels['addattendee'] = 'Hinzufügen';
|
||||
$labels['roleorganizer'] = 'Organisator';
|
||||
$labels['rolerequired'] = 'Erforderlich';
|
||||
$labels['roleoptional'] = 'Optional';
|
||||
$labels['rolechair'] = 'Vorsitz';
|
||||
$labels['availfree'] = 'Frei';
|
||||
$labels['availbusy'] = 'Gebucht';
|
||||
$labels['availunknown'] = 'Unbekannt';
|
||||
$labels['availtentative'] = 'Mit Vorbehalt';
|
||||
$labels['availoutofoffice'] = 'Abwesend';
|
||||
$labels['scheduletime'] = 'Verfügbarkeit anzeigen';
|
||||
$labels['sendinvitations'] = 'Einladungen versenden';
|
||||
$labels['sendnotifications'] = 'Teilnehmer über die Änderungen informieren';
|
||||
$labels['sendcancellation'] = 'Teilnehmer über die Terminabsage informieren';
|
||||
$labels['onlyworkinghours'] = 'Verfügbarkeit innerhalb meiner Arbeitszeiten suchen';
|
||||
$labels['reqallattendees'] = 'Erforderliche/alle Teilnehmer';
|
||||
$labels['prevslot'] = 'Vorheriger Vorschlag';
|
||||
$labels['nextslot'] = 'Nächster Vorschlag';
|
||||
$labels['noslotfound'] = 'Es konnten keine freien Zeiten gefunden werden';
|
||||
$labels['invitationsubject'] = 'Sie wurden zu "$title" eingeladen';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit allen Details des Termins. Diese können Sie in Ihre Kalenderanwendung importieren.";
|
||||
$labels['invitationattendlinks'] = "Falls Ihr E-Mail-Programm keine iTip-Anfragen unterstützt, können Sie den folgenden Link verwenden, um den Termin zu bestätigen oder abzulehnen:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" wurde aktualisiert';
|
||||
$labels['eventupdatesubjectempty'] = 'Termin wurde aktualisiert';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nIm Anhang finden Sie eine iCalendar-Datei mit den aktualisiereten Termindaten. Diese können Sie in Ihre Kalenderanwendung importieren.";
|
||||
$labels['eventcancelsubject'] = '"$title" wurde abgesagt';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees\n\nDer Termin wurde von \$organizer abgesagt.\n\nIm Anhang finden Sie eine iCalendar-Datei mit den Termindaten.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Einladung zu';
|
||||
$labels['itipreply'] = 'Antwort zu';
|
||||
$labels['itipupdate'] = 'Aktialisiert:';
|
||||
$labels['itipcancellation'] = 'Abgesagt:';
|
||||
$labels['itipaccepted'] = 'Akzeptieren';
|
||||
$labels['itiptentative'] = 'Mit Vorbehalt';
|
||||
$labels['itipdeclined'] = 'Ablehnen';
|
||||
$labels['itipsubjectaccepted'] = 'Einladung zu "$title" wurde von $name angenommen';
|
||||
$labels['itipsubjecttentative'] = 'Einladung zu "$title" wurde von $name mit Vorbehalt angenommen';
|
||||
$labels['itipsubjectdeclined'] = 'Einladung zu "$title" wurde von $name abgelehnt';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender hat die Einladung zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender hat die Einladung mit Vorbehalt zum folgenden Termin angenommen:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender hat die Einladung zum folgenden Termin abgelehnt:\n\n*\$title*\n\nWann: \$date\n\nTeilnehmer: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Möchten Sie die Einladung zu diesem Termin ablehnen?';
|
||||
$labels['declinedeleteconfirm'] = 'Möchten Sie den abgelehnten Termin ebenfalls aus Ihrem Kalender löschen?';
|
||||
$labels['importtocalendar'] = 'In Kalender übernehmen';
|
||||
$labels['removefromcalendar'] = 'Aus meinem Kalender löschen';
|
||||
$labels['updateattendeestatus'] = 'Teilnehmerstatus aktualisieren';
|
||||
$labels['acceptinvitation'] = 'Möchten Sie die Einladung zu diesem Termin annehmen?';
|
||||
$labels['youhaveaccepted'] = 'Sie haben die Einladung angenommen';
|
||||
$labels['youhavetentative'] = 'Sie haben die Einladung mit Vorbehalt angenommen';
|
||||
$labels['youhavedeclined'] = 'Sie haben die Einladung abgelehnt';
|
||||
$labels['notanattendee'] = 'Sie sind nicht in der Liste der Teilnehmer aufgeführt';
|
||||
$labels['eventcancelled'] = 'Der Termin wurde vom Organisator abgesagt';
|
||||
$labels['saveincalendar'] = 'speichern in';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Übersicht';
|
||||
$labels['tabrecurrence'] = 'Wiederholung';
|
||||
$labels['tabattendees'] = 'Teilnehmer';
|
||||
$labels['tabattachments'] = 'Anhänge';
|
||||
$labels['tabsharing'] = 'Freigabe';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Möchten Sie diesen Termin wirklich löschen?';
|
||||
$labels['deletecalendarconfirm'] = 'Möchten Sie diesen Kalender mit allen Terminen wirklich löschen?';
|
||||
$labels['savingdata'] = 'Speichere Daten...';
|
||||
$labels['errorsaving'] = 'Fehler beim Speichern.';
|
||||
$labels['operationfailed'] = 'Die Aktion ist fehlgeschlagen.';
|
||||
$labels['invalideventdates'] = 'Ungültige Daten eingegeben! Bitte überprüfen Sie die Eingaben.';
|
||||
$labels['invalidcalendarproperties'] = 'Ungültige Kalenderinformationen! Bitte geben Sie einen Namen ein.';
|
||||
$labels['searchnoresults'] = 'Keine Termine in den gewählten Kalendern gefunden.';
|
||||
$labels['successremoval'] = 'Der Termin wurde erfolgreich gelöscht.';
|
||||
$labels['successrestore'] = 'Der Termin wurde erfolgreich wieder hergestellt.';
|
||||
$labels['errornotifying'] = 'Benachrichtigung an die Teilnehmer konnten nicht gesendet werden';
|
||||
$labels['errorimportingevent'] = 'Fehler beim Importieren';
|
||||
$labels['newerversionexists'] = 'Eine neuere Version dieses Termins exisitert bereits! Import abgebrochen.';
|
||||
$labels['nowritecalendarfound'] = 'Kein Kalender zum Speichern gefunden';
|
||||
$labels['importedsuccessfully'] = 'Der Termin wurde erfolgreich in \'$calendar\' gespeichert';
|
||||
$labels['attendeupdateesuccess'] = 'Teilnehmerstatus erfolgreich aktualisiert';
|
||||
$labels['itipsendsuccess'] = 'Einladung an Teilnehmer versendet.';
|
||||
$labels['itipresponseerror'] = 'Die Antwort auf diese Einladung konnte nicht versendet werden';
|
||||
$labels['sentresponseto'] = 'Antwort auf diese Einladung erfolgreich an $mailto gesendet';
|
||||
$labels['localchangeswarning'] = 'Änderungen an diesem Termin werden nur in Ihrem Kalender gespeichert und nicht an den Organisator des Termins gesendet.';
|
||||
$labels['importsuccess'] = 'Es wurden $nr Termine erfolgreich importiert';
|
||||
$labels['importnone'] = 'Keine Termine zum Importieren gefunden';
|
||||
$labels['importerror'] = 'Fehler beim Importieren';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Wiederholung';
|
||||
$labels['frequency'] = 'Wiederholung';
|
||||
$labels['never'] = 'nie';
|
||||
$labels['daily'] = 'täglich';
|
||||
$labels['weekly'] = 'wöchentlich';
|
||||
$labels['monthly'] = 'monatlich';
|
||||
$labels['yearly'] = 'jährlich';
|
||||
$labels['every'] = 'Alle';
|
||||
$labels['days'] = 'Tag(e)';
|
||||
$labels['weeks'] = 'Woche(n)';
|
||||
$labels['months'] = 'Monat(e)';
|
||||
$labels['years'] = 'Jahre(e) im:';
|
||||
$labels['bydays'] = 'Am';
|
||||
$labels['untildate'] = 'am';
|
||||
$labels['each'] = 'Jeden';
|
||||
$labels['onevery'] = 'An jedem';
|
||||
$labels['onsamedate'] = 'Am gleichen Tag';
|
||||
$labels['forever'] = 'unendlich';
|
||||
$labels['recurrencend'] = 'bis';
|
||||
$labels['forntimes'] = '$nr Wiederholungen';
|
||||
$labels['first'] = 'erster';
|
||||
$labels['second'] = 'zweiter';
|
||||
$labels['third'] = 'dritter';
|
||||
$labels['fourth'] = 'vierter';
|
||||
$labels['last'] = 'letzter';
|
||||
$labels['dayofmonth'] = 'Tag des Montats';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Termin ändern';
|
||||
$labels['removeeventconfirm'] = 'Termin löschen';
|
||||
$labels['changerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine bearbeiten oder die Änderungen als neuen Termin speichern?';
|
||||
$labels['removerecurringeventwarning'] = 'Dies ist eine Terminreihe. Möchten Sie nur den aktuellen, diesen und alle zukünftigen oder alle Termine löschen?';
|
||||
$labels['currentevent'] = 'Aktuellen';
|
||||
$labels['futurevents'] = 'Zukünftige';
|
||||
$labels['allevents'] = 'Alle';
|
||||
$labels['saveasnew'] = 'Als neu speichern';
|
||||
|
||||
?>
|
236
localization/en_US.inc
Normal file
|
@ -0,0 +1,236 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Default view';
|
||||
$labels['time_format'] = 'Time format';
|
||||
$labels['timeslots'] = 'Timeslots per hour';
|
||||
$labels['first_day'] = 'First weekday';
|
||||
$labels['first_hour'] = 'First hour to show';
|
||||
$labels['workinghours'] = 'Working hours';
|
||||
$labels['add_category'] = 'Add category';
|
||||
$labels['remove_category'] = 'Remove category';
|
||||
$labels['defaultcalendar'] = 'Create new events in';
|
||||
$labels['eventcoloring'] = 'Event coloring';
|
||||
$labels['coloringmode0'] = 'According to calendar';
|
||||
$labels['coloringmode1'] = 'According to category';
|
||||
$labels['coloringmode2'] = 'Calendar for outline, category for content';
|
||||
$labels['coloringmode3'] = 'Category for outline, calendar for content';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Calendar';
|
||||
$labels['calendars'] = 'Calendars';
|
||||
$labels['category'] = 'Category';
|
||||
$labels['categories'] = 'Categories';
|
||||
$labels['createcalendar'] = 'Create new calendar';
|
||||
$labels['editcalendar'] = 'Edit calendar properties';
|
||||
$labels['name'] = 'Name';
|
||||
$labels['color'] = 'Color';
|
||||
$labels['day'] = 'Day';
|
||||
$labels['week'] = 'Week';
|
||||
$labels['month'] = 'Month';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'New';
|
||||
$labels['new_event'] = 'New event';
|
||||
$labels['edit_event'] = 'Edit event';
|
||||
$labels['edit'] = 'Edit';
|
||||
$labels['save'] = 'Save';
|
||||
$labels['remove'] = 'Remove';
|
||||
$labels['cancel'] = 'Cancel';
|
||||
$labels['select'] = 'Select';
|
||||
$labels['print'] = 'Print';
|
||||
$labels['printtitle'] = 'Print calendars';
|
||||
$labels['title'] = 'Summary';
|
||||
$labels['description'] = 'Description';
|
||||
$labels['all-day'] = 'all-day';
|
||||
$labels['export'] = 'Export';
|
||||
$labels['exporttitle'] = 'Export to iCalendar';
|
||||
$labels['location'] = 'Location';
|
||||
$labels['url'] = 'URL';
|
||||
$labels['date'] = 'Date';
|
||||
$labels['start'] = 'Start';
|
||||
$labels['end'] = 'End';
|
||||
$labels['selectdate'] = 'Choose date';
|
||||
$labels['freebusy'] = 'Show me as';
|
||||
$labels['free'] = 'Free';
|
||||
$labels['busy'] = 'Busy';
|
||||
$labels['outofoffice'] = 'Out of Office';
|
||||
$labels['tentative'] = 'Tentative';
|
||||
$labels['priority'] = 'Priority';
|
||||
$labels['sensitivity'] = 'Privacy';
|
||||
$labels['public'] = 'public';
|
||||
$labels['private'] = 'private';
|
||||
$labels['confidential'] = 'confidential';
|
||||
$labels['alarms'] = 'Reminder';
|
||||
$labels['generated'] = 'generated at';
|
||||
$labels['printdescriptions'] = 'Print descriptions';
|
||||
$labels['parentcalendar'] = 'Insert inside';
|
||||
$labels['searchearlierdates'] = '« Search for earlier events';
|
||||
$labels['searchlaterdates'] = 'Search for later events »';
|
||||
$labels['andnmore'] = '$nr more...';
|
||||
$labels['togglerole'] = 'Click to toggle role';
|
||||
$labels['createfrommail'] = 'Save as event';
|
||||
$labels['importevents'] = 'Import events';
|
||||
$labels['importrange'] = 'Events from';
|
||||
$labels['onemonthback'] = '1 month back';
|
||||
$labels['nmonthsback'] = '$nr months back';
|
||||
$labels['showurl'] = 'Show calendar URL';
|
||||
$labels['showurldescription'] = 'Use the following address to access (read only) your calendar from other applications. You can copy and paste this into any calendar software that supports the iCal format.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Range to display:';
|
||||
$labels['listsections'] = 'Divide into:';
|
||||
$labels['smartsections'] = 'Smart sections';
|
||||
$labels['until'] = 'until';
|
||||
$labels['today'] = 'Today';
|
||||
$labels['tomorrow'] = 'Tomorrow';
|
||||
$labels['thisweek'] = 'This week';
|
||||
$labels['nextweek'] = 'Next week';
|
||||
$labels['thismonth'] = 'This month';
|
||||
$labels['nextmonth'] = 'Next month';
|
||||
$labels['weekofyear'] = 'Week';
|
||||
$labels['pastevents'] = 'Past';
|
||||
$labels['futureevents'] = 'Future';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Show alarms';
|
||||
$labels['defaultalarmtype'] = 'Default reminder setting';
|
||||
$labels['defaultalarmoffset'] = 'Default reminder time';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Participant';
|
||||
$labels['role'] = 'Role';
|
||||
$labels['availability'] = 'Avail.';
|
||||
$labels['confirmstate'] = 'Status';
|
||||
$labels['addattendee'] = 'Add participant';
|
||||
$labels['roleorganizer'] = 'Organizer';
|
||||
$labels['rolerequired'] = 'Required';
|
||||
$labels['roleoptional'] = 'Optional';
|
||||
$labels['rolechair'] = 'Chair';
|
||||
$labels['cutypeindividual'] = 'Individual';
|
||||
$labels['cutypegroup'] = 'Group';
|
||||
$labels['cutyperesource'] = 'Resource';
|
||||
$labels['cutyperoom'] = 'Room';
|
||||
$labels['availfree'] = 'Free';
|
||||
$labels['availbusy'] = 'Busy';
|
||||
$labels['availunknown'] = 'Unknown';
|
||||
$labels['availtentative'] = 'Tentative';
|
||||
$labels['availoutofoffice'] = 'Out of Office';
|
||||
$labels['scheduletime'] = 'Find availability';
|
||||
$labels['sendinvitations'] = 'Send invitations';
|
||||
$labels['sendnotifications'] = 'Notify participants about modifications';
|
||||
$labels['sendcancellation'] = 'Notify participants about event cancellation';
|
||||
$labels['onlyworkinghours'] = 'Find availability within my working hours';
|
||||
$labels['reqallattendees'] = 'Required/all participants';
|
||||
$labels['prevslot'] = 'Previous Slot';
|
||||
$labels['nextslot'] = 'Next Slot';
|
||||
$labels['noslotfound'] = 'Unable to find a free time slot';
|
||||
$labels['invitationsubject'] = 'You\'ve been invited to "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with all the event details which you can import to your calendar application.";
|
||||
$labels['invitationattendlinks'] = "In case your email client doesn't support iTip requests you can use the following link to either accept or decline this invitation:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" has been updated';
|
||||
$labels['eventupdatesubjectempty'] = 'An event that concerns you has been updated';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with the updated event details which you can import to your calendar application.";
|
||||
$labels['eventcancelsubject'] = '"$title" has been canceled';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nThe event has been cancelled by \$organizer.\n\nPlease find attached an iCalendar file with the updated event details.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Invitation to';
|
||||
$labels['itipupdate'] = 'Update of';
|
||||
$labels['itipcancellation'] = 'Cancelled:';
|
||||
$labels['itipreply'] = 'Reply to';
|
||||
$labels['itipaccepted'] = 'Accept';
|
||||
$labels['itiptentative'] = 'Maybe';
|
||||
$labels['itipdeclined'] = 'Decline';
|
||||
$labels['itipsubjectaccepted'] = '"$title" has been accepted by $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" has been tentatively accepted by $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" has been declined by $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender has accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender has tentatively accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender has declined the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Do you want to decline your invitation to this event?';
|
||||
$labels['declinedeleteconfirm'] = 'Do you also want to delete this declined event from your calendar?';
|
||||
$labels['importtocalendar'] = 'Save to my calendar';
|
||||
$labels['removefromcalendar'] = 'Remove from my calendar';
|
||||
$labels['updateattendeestatus'] = 'Update the participant\'s status';
|
||||
$labels['acceptinvitation'] = 'Do you accept this invitation?';
|
||||
$labels['youhaveaccepted'] = 'You have accepted this invitation';
|
||||
$labels['youhavetentative'] = 'You have tentatively accepted this invitation';
|
||||
$labels['youhavedeclined'] = 'You have declined this invitation';
|
||||
$labels['notanattendee'] = 'You\'re not listed as an attendee of this event';
|
||||
$labels['eventcancelled'] = 'The event has been cancelled';
|
||||
$labels['saveincalendar'] = 'save in';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Summary';
|
||||
$labels['tabrecurrence'] = 'Recurrence';
|
||||
$labels['tabattendees'] = 'Participants';
|
||||
$labels['tabattachments'] = 'Attachments';
|
||||
$labels['tabsharing'] = 'Sharing';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Do you really want to delete this event?';
|
||||
$labels['deletecalendarconfirm'] = 'Do you really want to delete this calendar with all its events?';
|
||||
$labels['savingdata'] = 'Saving data...';
|
||||
$labels['errorsaving'] = 'Failed to save changes.';
|
||||
$labels['operationfailed'] = 'The requested operation failed.';
|
||||
$labels['invalideventdates'] = 'Invalid dates entered! Please check your input.';
|
||||
$labels['invalidcalendarproperties'] = 'Invalid calendar properties! Please set a valid name.';
|
||||
$labels['searchnoresults'] = 'No events found in the selected calendars.';
|
||||
$labels['successremoval'] = 'The event has been deleted successfully.';
|
||||
$labels['successrestore'] = 'The event has been restored successfully.';
|
||||
$labels['errornotifying'] = 'Failed to send notifications to event participants';
|
||||
$labels['errorimportingevent'] = 'Failed to import the event';
|
||||
$labels['newerversionexists'] = 'A newer version of this event already exists! Aborted.';
|
||||
$labels['nowritecalendarfound'] = 'No calendar found to save the event';
|
||||
$labels['importedsuccessfully'] = 'The event was successfully added to \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Successfully updated the participant\'s status';
|
||||
$labels['itipsendsuccess'] = 'Invitation sent to participants.';
|
||||
$labels['itipresponseerror'] = 'Failed to send the response to this event invitation';
|
||||
$labels['itipinvalidrequest'] = 'This invitation is no longer valid';
|
||||
$labels['sentresponseto'] = 'Successfully sent invitation response to $mailto';
|
||||
$labels['localchangeswarning'] = 'You are about to make changes that will only be reflected on your calendar and not be sent to the organizer of the event.';
|
||||
$labels['importsuccess'] = 'Successfully imported $nr events';
|
||||
$labels['importnone'] = 'No events found to be imported';
|
||||
$labels['importerror'] = 'An error occured while importing';
|
||||
$labels['aclnorights'] = 'You do not have administrator rights on this calendar.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Repeat';
|
||||
$labels['frequency'] = 'Repeat';
|
||||
$labels['never'] = 'never';
|
||||
$labels['daily'] = 'daily';
|
||||
$labels['weekly'] = 'weekly';
|
||||
$labels['monthly'] = 'monthly';
|
||||
$labels['yearly'] = 'annually';
|
||||
$labels['every'] = 'Every';
|
||||
$labels['days'] = 'day(s)';
|
||||
$labels['weeks'] = 'week(s)';
|
||||
$labels['months'] = 'month(s)';
|
||||
$labels['years'] = 'year(s) in:';
|
||||
$labels['bydays'] = 'On';
|
||||
$labels['untildate'] = 'the';
|
||||
$labels['each'] = 'Each';
|
||||
$labels['onevery'] = 'On every';
|
||||
$labels['onsamedate'] = 'On the same date';
|
||||
$labels['forever'] = 'forever';
|
||||
$labels['recurrencend'] = 'until';
|
||||
$labels['forntimes'] = 'for $nr time(s)';
|
||||
$labels['first'] = 'first';
|
||||
$labels['second'] = 'second';
|
||||
$labels['third'] = 'third';
|
||||
$labels['fourth'] = 'fourth';
|
||||
$labels['last'] = 'last';
|
||||
$labels['dayofmonth'] = 'Day of month';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Change event';
|
||||
$labels['removeeventconfirm'] = 'Remove event';
|
||||
$labels['changerecurringeventwarning'] = 'This is a recurring event. Would you like to edit the current event only, this and all future occurences, all occurences or save it as a new event?';
|
||||
$labels['removerecurringeventwarning'] = 'This is a recurring event. Would you like to remove the current event only, this and all future occurences or all occurences of this event?';
|
||||
$labels['currentevent'] = 'Current';
|
||||
$labels['futurevents'] = 'Future';
|
||||
$labels['allevents'] = 'All';
|
||||
$labels['saveasnew'] = 'Save as new';
|
||||
|
||||
?>
|
39
localization/es_ES.inc
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 3
|
||||
* @author Lazlo Westerhof
|
||||
* @author David Iribas
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Vista por defecto';
|
||||
$labels['time_format'] = 'Formato hora';
|
||||
$labels['timeslots'] = 'Periodos de hora';
|
||||
$labels['first_day'] = 'Primer dia';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Calendario';
|
||||
$labels['day'] = 'Dia';
|
||||
$labels['week'] = 'Semana';
|
||||
$labels['month'] = 'Mes';
|
||||
$labels['new_event'] = 'Nuevo evento';
|
||||
$labels['edit_event'] = 'Editar evento';
|
||||
$labels['save'] = 'Guardar';
|
||||
$labels['remove'] = 'Borrar';
|
||||
$labels['cancel'] = 'Cancelar';
|
||||
$labels['title'] = 'Resumen';
|
||||
$labels['description'] = 'Descripcion';
|
||||
$labels['all-day'] = 'dia-completo';
|
||||
$labels['export'] = 'Exportar a ICS';
|
||||
$labels['category'] = 'Categoria';
|
||||
?>
|
230
localization/et_EE.inc
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Vaikevaade';
|
||||
$labels['time_format'] = 'Aja vorming';
|
||||
$labels['timeslots'] = 'Ajaühikuid päevas';
|
||||
$labels['first_day'] = 'Esimene päev';
|
||||
$labels['first_hour'] = 'Esimene tund';
|
||||
$labels['workinghours'] = 'Tööaeg';
|
||||
$labels['add_category'] = 'Lisa kategooria';
|
||||
$labels['remove_category'] = 'Kustuta kategooria';
|
||||
$labels['defaultcalendar'] = 'Loo uued sündmused';
|
||||
$labels['eventcoloring'] = 'Sündmuste värvid';
|
||||
$labels['coloringmode0'] = 'Vastavalt kalendrile';
|
||||
$labels['coloringmode1'] = 'Vastavalt kategooriale';
|
||||
$labels['coloringmode2'] = 'Kalender väljaspool, kategooria sisul';
|
||||
$labels['coloringmode3'] = 'Kategooria väljaspool, kalender sisul';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Kalender';
|
||||
$labels['calendars'] = 'Kalendrid';
|
||||
$labels['category'] = 'Kategooria';
|
||||
$labels['categories'] = 'Kategooriad';
|
||||
$labels['createcalendar'] = 'Uus kalender';
|
||||
$labels['editcalendar'] = 'Muuda seadeid';
|
||||
$labels['name'] = 'Nimi';
|
||||
$labels['color'] = 'Värv';
|
||||
$labels['day'] = 'Päev';
|
||||
$labels['week'] = 'Nädal';
|
||||
$labels['month'] = 'Kuu';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'Uus';
|
||||
$labels['new_event'] = 'Uus sündmus';
|
||||
$labels['edit_event'] = 'Muuda sündmust';
|
||||
$labels['edit'] = 'Redigeeri';
|
||||
$labels['save'] = 'Salvesta';
|
||||
$labels['remove'] = 'Kustuta';
|
||||
$labels['cancel'] = 'Tühista';
|
||||
$labels['select'] = 'Märgi';
|
||||
$labels['print'] = 'Trüki';
|
||||
$labels['printtitle'] = 'Trüki kalendrid';
|
||||
$labels['title'] = 'Kokkuvõte';
|
||||
$labels['description'] = 'Selgitus';
|
||||
$labels['all-day'] = 'kogu päev';
|
||||
$labels['export'] = 'Ekspordi';
|
||||
$labels['exporttitle'] = 'Ekspordi iCalendar';
|
||||
$labels['location'] = 'Askukoht';
|
||||
$labels['date'] = 'Kuupäev';
|
||||
$labels['start'] = 'Algus';
|
||||
$labels['end'] = 'Lõpp';
|
||||
$labels['selectdate'] = 'Vali kuupäev';
|
||||
$labels['freebusy'] = 'Näita mind';
|
||||
$labels['free'] = 'vabana';
|
||||
$labels['busy'] = 'hõivatuna';
|
||||
$labels['outofoffice'] = 'kontorist eemal';
|
||||
$labels['tentative'] = 'ei tea';
|
||||
$labels['priority'] = 'Prioriteet';
|
||||
$labels['sensitivity'] = 'Privaatsus';
|
||||
$labels['public'] = 'avalik';
|
||||
$labels['private'] = 'varjatud';
|
||||
$labels['confidential'] = 'konfidentsiaalne';
|
||||
$labels['alarms'] = 'Meeldetuletus';
|
||||
$labels['generated'] = 'loodud';
|
||||
$labels['printdescriptions'] = 'Väljuta kirjeldus';
|
||||
$labels['parentcalendar'] = 'Sisesta';
|
||||
$labels['searchearlierdates'] = '« Otsi varasemaid sündmusi';
|
||||
$labels['searchlaterdates'] = 'Otsi hilisemaid sündmusi »';
|
||||
$labels['andnmore'] = '$nr rohkem...';
|
||||
$labels['togglerole'] = 'Kliki rolli muutmiseks';
|
||||
$labels['createfrommail'] = 'Salvesta sündmusena';
|
||||
$labels['importevents'] = 'Impordi sündmused';
|
||||
$labels['importrange'] = 'Sündmused alates';
|
||||
$labels['onemonthback'] = '1 kuu tagasi';
|
||||
$labels['nmonthsback'] = '$nr kuud tagasi';
|
||||
$labels['showurl'] = 'Näita kalendi URLi';
|
||||
$labels['showurldescription'] = 'Kasuta seda aadressi kalendri lugemisõiguse andmiseks iCal vormingus.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Näita ajavahemikku:';
|
||||
$labels['listsections'] = 'Jaga:';
|
||||
$labels['smartsections'] = 'nutikad osad';
|
||||
$labels['until'] = 'kuni';
|
||||
$labels['today'] = 'täna';
|
||||
$labels['tomorrow'] = 'homme';
|
||||
$labels['thisweek'] = 'see nädal';
|
||||
$labels['nextweek'] = 'järgmine nädal';
|
||||
$labels['thismonth'] = 'Sel kuul';
|
||||
$labels['nextmonth'] = 'Järgmisel kuul';
|
||||
$labels['weekofyear'] = 'Nädal aastas';
|
||||
$labels['pastevents'] = 'Möödunud';
|
||||
$labels['futureevents'] = 'Tulevased';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Näita meeldetuletusi';
|
||||
$labels['defaultalarmtype'] = 'Meeldetuletuse vaiketüüp';
|
||||
$labels['defaultalarmoffset'] = 'Meeldetuletuse vaikeaeg';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Ósavõtja';
|
||||
$labels['role'] = 'Roll';
|
||||
$labels['availability'] = 'Saadavus';
|
||||
$labels['confirmstate'] = 'Staatus';
|
||||
$labels['addattendee'] = 'Lisa osaleja';
|
||||
$labels['roleorganizer'] = 'Korraldaja';
|
||||
$labels['rolerequired'] = 'Vajalik';
|
||||
$labels['roleoptional'] = 'Teised';
|
||||
$labels['roleresource'] = 'Ressurss';
|
||||
$labels['availfree'] = 'Vaba';
|
||||
$labels['availbusy'] = 'Hõivatud';
|
||||
$labels['availunknown'] = 'Teadmata';
|
||||
$labels['availtentative'] = 'Tinglik';
|
||||
$labels['availoutofoffice'] = 'Kontorist eemal';
|
||||
$labels['scheduletime'] = 'Otsi saadavust';
|
||||
$labels['sendinvitations'] = 'Saada kutsed';
|
||||
$labels['sendnotifications'] = 'Anna osavõtjaile muutustest teada';
|
||||
$labels['sendcancellation'] = 'Anna osavõtjaile tühistamisest teada';
|
||||
$labels['onlyworkinghours'] = 'Leia vaba aeg minu tööajast';
|
||||
$labels['reqallattendees'] = 'Vajalikud/teised osavõtjad';
|
||||
$labels['prevslot'] = 'Eelnev aeg';
|
||||
$labels['nextslot'] = 'Järgnev aeg';
|
||||
$labels['noslotfound'] = 'Ei õnnestu leida vaba aega';
|
||||
$labels['invitationsubject'] = 'Olete kutsutud "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with all the event details which you can import to your calendar application.";
|
||||
$labels['invitationattendlinks'] = "In case your email client doesn't support iTip requests you can use the following link to either accept or decline this invitation:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" has been updated';
|
||||
$labels['eventupdatesubjectempty'] = 'An event that concerns you has been updated';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with the updated event details which you can import to your calendar application.";
|
||||
$labels['eventcancelsubject'] = '"$title" has been canceled';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nThe event has been cancelled by \$organizer.\n\nPlease find attached an iCalendar file with the updated event details.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Invitation to';
|
||||
$labels['itipupdate'] = 'Update of';
|
||||
$labels['itipcancellation'] = 'Cancelled:';
|
||||
$labels['itipreply'] = 'Reply to';
|
||||
$labels['itipaccepted'] = 'Accept';
|
||||
$labels['itiptentative'] = 'Maybe';
|
||||
$labels['itipdeclined'] = 'Decline';
|
||||
$labels['itipsubjectaccepted'] = '"$title" has been accepted by $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" has been tentatively accepted by $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" has been declined by $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender has accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender has tentatively accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender has declined the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Do you want to decline your invitation to this event?';
|
||||
$labels['importtocalendar'] = 'Salvesta minu kalendrisse';
|
||||
$labels['removefromcalendar'] = 'Kustuta kalendrist';
|
||||
$labels['updateattendeestatus'] = 'Värskenda osavõtja staatust';
|
||||
$labels['acceptinvitation'] = 'Kas kutse vastu võtta?';
|
||||
$labels['youhaveaccepted'] = 'Oled kutse vastu võtnud';
|
||||
$labels['youhavetentative'] = 'Oled kutse tingimisi vastu võtnud';
|
||||
$labels['youhavedeclined'] = 'Oled kutsest keeldunud';
|
||||
$labels['notanattendee'] = 'Sa ei ole osavõtjate nimekirjas';
|
||||
$labels['eventcancelled'] = 'Sündmus on tühistatud';
|
||||
$labels['saveincalendar'] = 'salvesta';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Kokkuvõte';
|
||||
$labels['tabrecurrence'] = 'Kordumine';
|
||||
$labels['tabattendees'] = 'Osavõtjad';
|
||||
$labels['tabattachments'] = 'Manused';
|
||||
$labels['tabsharing'] = 'Jagamine';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Kas tõsti kustutada see sündmus?';
|
||||
$labels['deletecalendarconfirm'] = 'Kas tõesti kustutada see kalender koos kõigi sündmustega?';
|
||||
$labels['savingdata'] = 'Andmete salvestamine...';
|
||||
$labels['errorsaving'] = 'Andmete salvestamine ebaõnnestus.';
|
||||
$labels['operationfailed'] = 'Operatsioon nurjus.';
|
||||
$labels['invalideventdates'] = 'Kuupäev on vigane! Kontrollige vormingut.';
|
||||
$labels['invalidcalendarproperties'] = 'Vigane kalendri atribuut! Valige sobiv atribuut.';
|
||||
$labels['searchnoresults'] = 'Sellest kalendrist ei leitud ühtki sündmust.';
|
||||
$labels['successremoval'] = 'Sündmus on edukalt kustutatud.';
|
||||
$labels['successrestore'] = 'Sündmus on edukalt taastatud.';
|
||||
$labels['errornotifying'] = 'Teate saatmine osavõtjaile ebaõnnestus.';
|
||||
$labels['errorimportingevent'] = 'Sündmuse import ebaõnnestus.';
|
||||
$labels['newerversionexists'] = 'Uuem versioon sündmusest on juba olemas! Täitmine peatatud.';
|
||||
$labels['nowritecalendarfound'] = 'Kirjutamiseks sobivat kalendrit ei leitud.';
|
||||
$labels['importedsuccessfully'] = 'Sündmus on edukalt lisatud kalendrisse \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Osavõtja staatus on uuendatud';
|
||||
$labels['itipsendsuccess'] = 'Kutse on saadetud osavõtjaile.';
|
||||
$labels['itipresponseerror'] = 'Vastuse saatmine kutsele ebaõnnestus.';
|
||||
$labels['itipinvalidrequest'] = 'See kutse pole enam kehtiv.';
|
||||
$labels['sentresponseto'] = 'Vastus kutsele on edukalt saadetud aadressile $mailto';
|
||||
$labels['localchangeswarning'] = 'Muutuseid on näha ainult teie isiklikus kalendris.';
|
||||
$labels['importsuccess'] = 'Edukalt imporditud $nr sündmust';
|
||||
$labels['importnone'] = 'Ühtki imporditavat sündmust ei leitud';
|
||||
$labels['importerror'] = 'Importimise käigus tekkis viga';
|
||||
$labels['aclnorights'] = 'Ei ole selle kalendri administreerimisõigusi.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Korda';
|
||||
$labels['frequency'] = 'Sagedus';
|
||||
$labels['never'] = 'mitte kunagi';
|
||||
$labels['daily'] = 'iga päev';
|
||||
$labels['weekly'] = 'nädalati';
|
||||
$labels['monthly'] = 'iga kuu';
|
||||
$labels['yearly'] = 'iga aasta';
|
||||
$labels['every'] = 'Iga';
|
||||
$labels['days'] = 'päevad';
|
||||
$labels['weeks'] = 'nädalad';
|
||||
$labels['months'] = 'kuud';
|
||||
$labels['years'] = 'aastad:';
|
||||
$labels['bydays'] = 'On';
|
||||
$labels['untildate'] = 'the';
|
||||
$labels['each'] = 'Iga';
|
||||
$labels['onevery'] = 'Igal';
|
||||
$labels['onsamedate'] = 'samal kuupäeval';
|
||||
$labels['forever'] = 'alati';
|
||||
$labels['recurrencend'] = 'kuni';
|
||||
$labels['forntimes'] = ' $nr korda';
|
||||
$labels['first'] = 'esimesel';
|
||||
$labels['second'] = 'teisel';
|
||||
$labels['third'] = 'kolmandal';
|
||||
$labels['fourth'] = 'neljandal';
|
||||
$labels['last'] = 'viimasel';
|
||||
$labels['dayofmonth'] = 'Kuupäev';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Muuda sündmust';
|
||||
$labels['removeeventconfirm'] = 'Kustuta sündmus';
|
||||
$labels['changerecurringeventwarning'] = 'See on korduv sündmus. Kas muuta seda sündmust, seda ja kõiki järgnevaid, või salvestada uue sündmusena?';
|
||||
$labels['removerecurringeventwarning'] = 'See on korduv sündmus. Kas kustudada see sündmus, see ja kõik järgnevad sündmused?';
|
||||
$labels['currentevent'] = 'Praegune';
|
||||
$labels['futurevents'] = 'Tulevikusündmused';
|
||||
$labels['allevents'] = 'Kõik sündmused';
|
||||
$labels['saveasnew'] = 'Salvesta uuena';
|
||||
|
||||
?>
|
230
localization/fr_FR.inc
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Vue par défaut';
|
||||
$labels['time_format'] = 'Format de l\'heure';
|
||||
$labels['timeslots'] = 'Nombre d\'intervalle par heure';
|
||||
$labels['first_day'] = 'Premier jour de la semaine';
|
||||
$labels['first_hour'] = 'Première heure à afficher';
|
||||
$labels['workinghours'] = 'Heures de travail';
|
||||
$labels['add_category'] = 'Ajouter une catégorie';
|
||||
$labels['remove_category'] = 'Supprimer une catégorie';
|
||||
$labels['defaultcalendar'] = 'Ajouter un nouvel évènement';
|
||||
$labels['eventcoloring'] = 'Couleurs des évènements';
|
||||
$labels['coloringmode0'] = 'Selon l\'agenda';
|
||||
$labels['coloringmode1'] = 'Selon la catégorie';
|
||||
$labels['coloringmode2'] = 'Calendrier en contour, catégorie en contenu';
|
||||
$labels['coloringmode3'] = 'Catégorie en contour, calendrier en contenu';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Agenda';
|
||||
$labels['calendars'] = 'Agendas';
|
||||
$labels['category'] = 'Catégorie';
|
||||
$labels['categories'] = 'Catégories';
|
||||
$labels['createcalendar'] = 'Créer un nouvel agenda';
|
||||
$labels['editcalendar'] = 'Modifier les propriétés de l\'agenda';
|
||||
$labels['name'] = 'Nom';
|
||||
$labels['color'] = 'Couleur';
|
||||
$labels['day'] = 'Jour';
|
||||
$labels['week'] = 'Semaine';
|
||||
$labels['month'] = 'Mois';
|
||||
$labels['agenda'] = 'Ordre du jour';
|
||||
$labels['new'] = 'Nouveau';
|
||||
$labels['new_event'] = 'Nouvel évènement';
|
||||
$labels['edit_event'] = 'Modifier l\'évènement';
|
||||
$labels['edit'] = 'Modifier';
|
||||
$labels['save'] = 'Enregistrer';
|
||||
$labels['remove'] = 'Supprimer';
|
||||
$labels['cancel'] = 'Annuler';
|
||||
$labels['select'] = 'Sélectionner';
|
||||
$labels['print'] = 'Imprimer';
|
||||
$labels['printtitle'] = 'Imprimer les agendas';
|
||||
$labels['title'] = 'Résumé';
|
||||
$labels['description'] = 'Description';
|
||||
$labels['all-day'] = 'Toute la journée';
|
||||
$labels['export'] = 'Exporter';
|
||||
$labels['exporttitle'] = 'Exporter vers iCalendar';
|
||||
$labels['location'] = 'Lieu';
|
||||
$labels['date'] = 'Date';
|
||||
$labels['start'] = 'Début';
|
||||
$labels['end'] = 'Fin';
|
||||
$labels['selectdate'] = 'Sélectionner une date';
|
||||
$labels['freebusy'] = 'Montrez moi comme';
|
||||
$labels['free'] = 'Libre';
|
||||
$labels['busy'] = 'Occupé';
|
||||
$labels['outofoffice'] = 'Absent';
|
||||
$labels['tentative'] = 'Provisoire';
|
||||
$labels['priority'] = 'Priorité';
|
||||
$labels['sensitivity'] = 'Diffusion';
|
||||
$labels['public'] = 'publique';
|
||||
$labels['private'] = 'privée';
|
||||
$labels['confidential'] = 'Confidentiel';
|
||||
$labels['alarms'] = 'Rappel';
|
||||
$labels['generated'] = 'généré à';
|
||||
$labels['printdescriptions'] = 'Imprimer les descriptions';
|
||||
$labels['parentcalendar'] = 'Ajouter à l\'intérieur';
|
||||
$labels['searchearlierdates'] = '« Chercher des évènements plus ancien';
|
||||
$labels['searchlaterdates'] = 'Chercher des évènement plus récent »';
|
||||
$labels['andnmore'] = '$nr de plus...';
|
||||
$labels['togglerole'] = 'Cliquez pour changer de rôle';
|
||||
$labels['createfrommail'] = 'Enregistrer comme un évènement';
|
||||
$labels['importevents'] = 'Importer des évènements';
|
||||
$labels['importrange'] = 'Évènements depuis';
|
||||
$labels['onemonthback'] = '1 mois précédent';
|
||||
$labels['nmonthsback'] = '$nr mois précédents';
|
||||
$labels['showurl'] = 'Afficher l\'URL de l\'agenda';
|
||||
$labels['showurldescription'] = 'Utilisez l\'adresse suivante pour accéder(lecture seule) à votre agenda depuis une autre application. Vous pouvez copier/coller celle-ci dans n\'importe quel agenda électronique gérant le format iCal.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Intervalle à afficher :';
|
||||
$labels['listsections'] = 'Diviser en :';
|
||||
$labels['smartsections'] = 'Section intelligente';
|
||||
$labels['until'] = 'jusqu\'à';
|
||||
$labels['today'] = 'Aujourd\'hui';
|
||||
$labels['tomorrow'] = 'Demain';
|
||||
$labels['thisweek'] = 'Cette semaine';
|
||||
$labels['nextweek'] = 'Semaine prochaine';
|
||||
$labels['thismonth'] = 'Ce mois';
|
||||
$labels['nextmonth'] = 'Mois prochain';
|
||||
$labels['weekofyear'] = 'Semaine';
|
||||
$labels['pastevents'] = 'Passé';
|
||||
$labels['futureevents'] = 'Futur';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Afficher les alarmes';
|
||||
$labels['defaultalarmtype'] = 'Paramètre de rappel par défaut';
|
||||
$labels['defaultalarmoffset'] = 'Durée de rappel par défaut';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Participant';
|
||||
$labels['role'] = 'Rôle';
|
||||
$labels['availability'] = 'Dispo.';
|
||||
$labels['confirmstate'] = 'Statut';
|
||||
$labels['addattendee'] = 'Ajouter participant';
|
||||
$labels['roleorganizer'] = 'Organisateur';
|
||||
$labels['rolerequired'] = 'Requis';
|
||||
$labels['roleoptional'] = 'Optionel';
|
||||
$labels['roleresource'] = 'Ressource';
|
||||
$labels['availfree'] = 'Disponible';
|
||||
$labels['availbusy'] = 'Occupé';
|
||||
$labels['availunknown'] = 'Inconnu';
|
||||
$labels['availtentative'] = 'Provisoire';
|
||||
$labels['availoutofoffice'] = 'Absent';
|
||||
$labels['scheduletime'] = 'Trouver les disponibilités';
|
||||
$labels['sendinvitations'] = 'Envoyer les invitations';
|
||||
$labels['sendnotifications'] = 'Informer les participants des modifications';
|
||||
$labels['sendcancellation'] = 'Informer les participants de l\'annulation';
|
||||
$labels['onlyworkinghours'] = 'Trouver des disponibilités en fonction de mes heures de travail';
|
||||
$labels['reqallattendees'] = 'Demandé/tous';
|
||||
$labels['prevslot'] = 'Créneau précédent';
|
||||
$labels['nextslot'] = 'Créneau suivant';
|
||||
$labels['noslotfound'] = 'Impossible de trouver un créneau disponible';
|
||||
$labels['invitationsubject'] = 'Vous avez invité à "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nVous trouverez ci-joint un fichier iCalendar avec tous les détails de l'évènement que vous pourrez importer dans votre agenda électronique.";
|
||||
$labels['invitationattendlinks'] = "Dans le cas où votre application de messagerie ne gère pas les demandes \"iTip\". Vous pouvez utiliser ce lien pour accepter ou refuser l'invitation :\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" a été modifié';
|
||||
$labels['eventupdatesubjectempty'] = 'Un évènement vous concernant a été modifié';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nVous trouverez ci-joint un fichier iCalendar avec tous les modifications de l'évènement que vous pourrez importer dans votre agenda électronique.";
|
||||
$labels['eventcancelsubject'] = '"$title" a été annulé';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nL'évènement a été annulé par \$organizer.\n\nVous trouverez en pièce jointe un fichier iCalendar avec les modifications de l'évènement que vous pourrez importer dans votre agenda électronique.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Invitation à';
|
||||
$labels['itipupdate'] = 'Mise à jour de';
|
||||
$labels['itipcancellation'] = 'Annulation:';
|
||||
$labels['itipreply'] = 'Répondre à';
|
||||
$labels['itipaccepted'] = 'Accepter';
|
||||
$labels['itiptentative'] = 'Peut-être';
|
||||
$labels['itipdeclined'] = 'Refuser';
|
||||
$labels['itipsubjectaccepted'] = '"$title" a été accepté par $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" a été accepté provisoirement par $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" a été refusé par $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender a accepté l'invitation à l'évènement suivant :\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender a accepté provisoirement l'invitation à l'évènement suivant :\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender a refusé l'invitation à l'évènement suivant :\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Voulez-vous refuser l\'invitation à cet évènement?';
|
||||
$labels['importtocalendar'] = 'Enregistrer mon agenda';
|
||||
$labels['removefromcalendar'] = 'Supprimer de mon agenda';
|
||||
$labels['updateattendeestatus'] = 'Modifier le statut des participants';
|
||||
$labels['acceptinvitation'] = 'Acceptez-vous cette invitation?';
|
||||
$labels['youhaveaccepted'] = 'Vous avez accepté cette invitation';
|
||||
$labels['youhavetentative'] = 'Vous avez accepté provisoirement cette invitation';
|
||||
$labels['youhavedeclined'] = 'Vous avez refusé cette invitation';
|
||||
$labels['notanattendee'] = 'Vous n\'êtes pas dans la liste des participants à cet évènement';
|
||||
$labels['eventcancelled'] = 'L\'évènement a été annulé';
|
||||
$labels['saveincalendar'] = 'Enregistrer sous';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Résumé';
|
||||
$labels['tabrecurrence'] = 'Récurrence';
|
||||
$labels['tabattendees'] = 'Participants';
|
||||
$labels['tabattachments'] = 'Pièces jointes';
|
||||
$labels['tabsharing'] = 'Partage';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Voulez-vous vraiment supprimer cet évènement?';
|
||||
$labels['deletecalendarconfirm'] = 'Voulez-vous vraiment supprimer cet agenda et tous ses évènements?';
|
||||
$labels['savingdata'] = 'Enregistrer...';
|
||||
$labels['errorsaving'] = 'Échec lors de l\'enregistrement des changements';
|
||||
$labels['operationfailed'] = 'L\'opération demandée a échoué';
|
||||
$labels['invalideventdates'] = 'Dates invalides! Veuillez vérifier votre saisie.';
|
||||
$labels['invalidcalendarproperties'] = 'Propriétés d\'agenda invalides! Veuillez saisir un nom valide.';
|
||||
$labels['searchnoresults'] = 'Pas d\'évènement trouvé dans les agendas sélectionnés.';
|
||||
$labels['successremoval'] = 'L\'évènement a été supprimé.';
|
||||
$labels['successrestore'] = 'L\'évènement a été restauré.';
|
||||
$labels['errornotifying'] = 'Échec de l\'envoi de notification aux participants ';
|
||||
$labels['errorimportingevent'] = 'Échec de l\'import de l\'évènement';
|
||||
$labels['newerversionexists'] = 'Une nouvelle version de cet évènement existe! Abandon.';
|
||||
$labels['nowritecalendarfound'] = 'Pas d\'agenda trouvé pour enregistrer l\'évènement';
|
||||
$labels['importedsuccessfully'] = 'L\'évènement a été ajouté à l\'agenda \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Le statut des participants a été modifié';
|
||||
$labels['itipsendsuccess'] = 'Invitation envoyé aux participants.';
|
||||
$labels['itipresponseerror'] = 'Échec de l\'envoi d\'une réponse à cette invitation.';
|
||||
$labels['itipinvalidrequest'] = 'C\'est invitation n\'est plus valide.';
|
||||
$labels['sentresponseto'] = 'La réponse à l\'invitation a été envoyé à $mailto';
|
||||
$labels['localchangeswarning'] = 'Vous êtes sur le point de faire des changements uniquement visible sur votre agenda personnel.';
|
||||
$labels['importsuccess'] = '$nr évènements importés.';
|
||||
$labels['importnone'] = 'Pas d\'évènements à importer';
|
||||
$labels['importerror'] = 'Une erreur est arrivée lors de l\'import';
|
||||
$labels['aclnorights'] = 'Vous n\'avez pas les droits d\'administration sur cet agenda.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Répéter';
|
||||
$labels['frequency'] = 'Répéter';
|
||||
$labels['never'] = 'Jamais';
|
||||
$labels['daily'] = 'Quotidienne';
|
||||
$labels['weekly'] = 'Hebdomadaire';
|
||||
$labels['monthly'] = 'Mensuelle';
|
||||
$labels['yearly'] = 'Annuelle';
|
||||
$labels['every'] = 'Tous les';
|
||||
$labels['days'] = 'jour(s)';
|
||||
$labels['weeks'] = 'semaine(s)';
|
||||
$labels['months'] = 'mois';
|
||||
$labels['years'] = 'année(s) en :';
|
||||
$labels['bydays'] = 'Le';
|
||||
$labels['untildate'] = 'le';
|
||||
$labels['each'] = 'Chaque';
|
||||
$labels['onevery'] = 'Tous les';
|
||||
$labels['onsamedate'] = 'à la même date';
|
||||
$labels['forever'] = 'Pour toujours';
|
||||
$labels['recurrencend'] = 'Jusqu\'à';
|
||||
$labels['forntimes'] = '$nr fois';
|
||||
$labels['first'] = 'premier';
|
||||
$labels['second'] = 'deuxième';
|
||||
$labels['third'] = 'troisième';
|
||||
$labels['fourth'] = 'quatrième';
|
||||
$labels['last'] = 'dernier';
|
||||
$labels['dayofmonth'] = 'Jour du mois';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Modifier l\'évènement';
|
||||
$labels['removeeventconfirm'] = 'Supprimer l\'évènement';
|
||||
$labels['changerecurringeventwarning'] = 'Ceci est un évènement récurant. Voulez vous éditer seulement cette occurrence, celle-ci et toutes les suivantes, toutes les occurrences ou l\'enregistrer comme un nouvel évènement? ';
|
||||
$labels['removerecurringeventwarning'] = 'Ceci est un évènement récurant. Voulez-vous supprimer seulement cette occurrence, celle-ci et toutes les suivantes ou toutes les occurrences de cet évènement?';
|
||||
$labels['currentevent'] = 'Cette occurrence';
|
||||
$labels['futurevents'] = 'Cette occurrence et toutes les suivantes';
|
||||
$labels['allevents'] = 'Toutes les occurrences';
|
||||
$labels['saveasnew'] = 'Enregistrer comme un nouvel évènement';
|
||||
|
||||
?>
|
38
localization/hu_HU.inc
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Alap nézet';
|
||||
$labels['time_format'] = 'Idõ formátum';
|
||||
$labels['timeslots'] = 'Idõrés óránként';
|
||||
$labels['first_day'] = 'A hét elsõ napja';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Naptár';
|
||||
$labels['day'] = 'Nap';
|
||||
$labels['week'] = 'Hét';
|
||||
$labels['month'] = 'Hónap';
|
||||
$labels['new_event'] = 'Új bejegyzés';
|
||||
$labels['edit_event'] = 'Bejegyzés szerkesztése';
|
||||
$labels['save'] = 'Mentés';
|
||||
$labels['remove'] = 'Törlés';
|
||||
$labels['cancel'] = 'Mégse';
|
||||
$labels['title'] = 'Tárgy';
|
||||
$labels['description'] = 'Leírás';
|
||||
$labels['all-day'] = 'Egész nap';
|
||||
$labels['export'] = 'Exportálás ICS formátumba';
|
||||
$labels['category'] = 'Kategória';
|
||||
?>
|
38
localization/it_IT.inc
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Visualizzazine di default';
|
||||
$labels['time_format'] = 'Formato ora';
|
||||
$labels['timeslots'] = 'Timeslots per ora';
|
||||
$labels['first_day'] = 'Inizio settimana';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Calendario';
|
||||
$labels['day'] = 'Giorno';
|
||||
$labels['week'] = 'Settimana';
|
||||
$labels['month'] = 'Mese';
|
||||
$labels['new_event'] = 'Nuovo evento';
|
||||
$labels['edit_event'] = 'Modifica evento';
|
||||
$labels['save'] = 'Salva';
|
||||
$labels['remove'] = 'Elimina';
|
||||
$labels['cancel'] = 'Annulla';
|
||||
$labels['title'] = 'Oggetto';
|
||||
$labels['description'] = 'Descrizione';
|
||||
$labels['all-day'] = 'Giorno intero';
|
||||
$labels['export'] = 'Esporta in ICS';
|
||||
$labels['category'] = 'Categoria';
|
||||
?>
|
230
localization/ja_JP.inc
Normal file
|
@ -0,0 +1,230 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Default view';
|
||||
$labels['time_format'] = 'Time format';
|
||||
$labels['timeslots'] = 'Timeslots per hour';
|
||||
$labels['first_day'] = 'First weekday';
|
||||
$labels['first_hour'] = 'First hour to show';
|
||||
$labels['workinghours'] = 'Working hours';
|
||||
$labels['add_category'] = 'Add category';
|
||||
$labels['remove_category'] = 'Remove category';
|
||||
$labels['defaultcalendar'] = 'Create new events in';
|
||||
$labels['eventcoloring'] = 'Event coloring';
|
||||
$labels['coloringmode0'] = 'According to calendar';
|
||||
$labels['coloringmode1'] = 'According to category';
|
||||
$labels['coloringmode2'] = 'Calendar for outline, category for content';
|
||||
$labels['coloringmode3'] = 'Category for outline, calendar for content';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Calendar';
|
||||
$labels['calendars'] = 'Calendars';
|
||||
$labels['category'] = 'Category';
|
||||
$labels['categories'] = 'Categories';
|
||||
$labels['createcalendar'] = 'Create new calendar';
|
||||
$labels['editcalendar'] = 'Edit calendar properties';
|
||||
$labels['name'] = 'Name';
|
||||
$labels['color'] = 'Color';
|
||||
$labels['day'] = 'Day';
|
||||
$labels['week'] = 'Week';
|
||||
$labels['month'] = 'Month';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new'] = 'New';
|
||||
$labels['new_event'] = 'New event';
|
||||
$labels['edit_event'] = 'Edit event';
|
||||
$labels['edit'] = 'Edit';
|
||||
$labels['save'] = 'Save';
|
||||
$labels['remove'] = 'Remove';
|
||||
$labels['cancel'] = 'Cancel';
|
||||
$labels['select'] = 'Select';
|
||||
$labels['print'] = 'Print';
|
||||
$labels['printtitle'] = 'Print calendars';
|
||||
$labels['title'] = 'Summary';
|
||||
$labels['description'] = 'Description';
|
||||
$labels['all-day'] = 'all-day';
|
||||
$labels['export'] = 'Export';
|
||||
$labels['exporttitle'] = 'Export to iCalendar';
|
||||
$labels['location'] = 'Location';
|
||||
$labels['date'] = 'Date';
|
||||
$labels['start'] = 'Start';
|
||||
$labels['end'] = 'End';
|
||||
$labels['selectdate'] = 'Choose date';
|
||||
$labels['freebusy'] = 'Show me as';
|
||||
$labels['free'] = 'Free';
|
||||
$labels['busy'] = 'Busy';
|
||||
$labels['outofoffice'] = 'Out of Office';
|
||||
$labels['tentative'] = 'Tentative';
|
||||
$labels['priority'] = 'Priority';
|
||||
$labels['sensitivity'] = 'Privacy';
|
||||
$labels['public'] = 'public';
|
||||
$labels['private'] = 'private';
|
||||
$labels['confidential'] = 'confidential';
|
||||
$labels['alarms'] = 'Reminder';
|
||||
$labels['generated'] = 'generated at';
|
||||
$labels['printdescriptions'] = 'Print descriptions';
|
||||
$labels['parentcalendar'] = 'Insert inside';
|
||||
$labels['searchearlierdates'] = '« Search for earlier events';
|
||||
$labels['searchlaterdates'] = 'Search for later events »';
|
||||
$labels['andnmore'] = '$nr more...';
|
||||
$labels['togglerole'] = 'Click to toggle role';
|
||||
$labels['createfrommail'] = 'Save as event';
|
||||
$labels['importevents'] = 'Import events';
|
||||
$labels['importrange'] = 'Events from';
|
||||
$labels['onemonthback'] = '1 month back';
|
||||
$labels['nmonthsback'] = '$nr months back';
|
||||
$labels['showurl'] = 'Show calendar URL';
|
||||
$labels['showurldescription'] = 'Use the following address to access (read only) your calendar from other applications. You can copy and paste this into any calendar software that supports the iCal format.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Range to display:';
|
||||
$labels['listsections'] = 'Divide into:';
|
||||
$labels['smartsections'] = 'Smart sections';
|
||||
$labels['until'] = 'until';
|
||||
$labels['today'] = 'Today';
|
||||
$labels['tomorrow'] = 'Tomorrow';
|
||||
$labels['thisweek'] = 'This week';
|
||||
$labels['nextweek'] = 'Next week';
|
||||
$labels['thismonth'] = 'This month';
|
||||
$labels['nextmonth'] = 'Next month';
|
||||
$labels['weekofyear'] = 'Week';
|
||||
$labels['pastevents'] = 'Past';
|
||||
$labels['futureevents'] = 'Future';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Show alarms';
|
||||
$labels['defaultalarmtype'] = 'Default reminder setting';
|
||||
$labels['defaultalarmoffset'] = 'Default reminder time';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Participant';
|
||||
$labels['role'] = 'Role';
|
||||
$labels['availability'] = 'Avail.';
|
||||
$labels['confirmstate'] = 'Status';
|
||||
$labels['addattendee'] = 'Add participant';
|
||||
$labels['roleorganizer'] = 'Organizer';
|
||||
$labels['rolerequired'] = 'Required';
|
||||
$labels['roleoptional'] = 'Optional';
|
||||
$labels['roleresource'] = 'Resource';
|
||||
$labels['availfree'] = 'Free';
|
||||
$labels['availbusy'] = 'Busy';
|
||||
$labels['availunknown'] = 'Unknown';
|
||||
$labels['availtentative'] = 'Tentative';
|
||||
$labels['availoutofoffice'] = 'Out of Office';
|
||||
$labels['scheduletime'] = 'Find availability';
|
||||
$labels['sendinvitations'] = 'Send invitations';
|
||||
$labels['sendnotifications'] = 'Notify participants about modifications';
|
||||
$labels['sendcancellation'] = 'Notify participants about event cancellation';
|
||||
$labels['onlyworkinghours'] = 'Find availability within my working hours';
|
||||
$labels['reqallattendees'] = 'Required/all participants';
|
||||
$labels['prevslot'] = 'Previous Slot';
|
||||
$labels['nextslot'] = 'Next Slot';
|
||||
$labels['noslotfound'] = 'Unable to find a free time slot';
|
||||
$labels['invitationsubject'] = 'You\'ve been invited to "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with all the event details which you can import to your calendar application.";
|
||||
$labels['invitationattendlinks'] = "In case your email client doesn't support iTip requests you can use the following link to either accept or decline this invitation:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" has been updated';
|
||||
$labels['eventupdatesubjectempty'] = 'An event that concerns you has been updated';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nPlease find attached an iCalendar file with the updated event details which you can import to your calendar application.";
|
||||
$labels['eventcancelsubject'] = '"$title" has been canceled';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees\n\nThe event has been cancelled by \$organizer.\n\nPlease find attached an iCalendar file with the updated event details.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Invitation to';
|
||||
$labels['itipupdate'] = 'Update of';
|
||||
$labels['itipcancellation'] = 'Cancelled:';
|
||||
$labels['itipreply'] = 'Reply to';
|
||||
$labels['itipaccepted'] = 'Accept';
|
||||
$labels['itiptentative'] = 'Maybe';
|
||||
$labels['itipdeclined'] = 'Decline';
|
||||
$labels['itipsubjectaccepted'] = '"$title" has been accepted by $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" has been tentatively accepted by $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" has been declined by $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender has accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender has tentatively accepted the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender has declined the invitation to the following event:\n\n*\$title*\n\nWhen: \$date\n\nInvitees: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Do you want to decline your invitation to this event?';
|
||||
$labels['importtocalendar'] = 'Save to my calendar';
|
||||
$labels['removefromcalendar'] = 'Remove from my calendar';
|
||||
$labels['updateattendeestatus'] = 'Update the participant\'s status';
|
||||
$labels['acceptinvitation'] = 'Do you accept this invitation?';
|
||||
$labels['youhaveaccepted'] = 'You have accepted this invitation';
|
||||
$labels['youhavetentative'] = 'You have tentatively accepted this invitation';
|
||||
$labels['youhavedeclined'] = 'You have declined this invitation';
|
||||
$labels['notanattendee'] = 'You\'re not listed as an attendee of this event';
|
||||
$labels['eventcancelled'] = 'The event has been cancelled';
|
||||
$labels['saveincalendar'] = 'save in';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Summary';
|
||||
$labels['tabrecurrence'] = 'Recurrence';
|
||||
$labels['tabattendees'] = 'Participants';
|
||||
$labels['tabattachments'] = 'Attachments';
|
||||
$labels['tabsharing'] = 'Sharing';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Do you really want to delete this event?';
|
||||
$labels['deletecalendarconfirm'] = 'Do you really want to delete this calendar with all its events?';
|
||||
$labels['savingdata'] = 'Saving data...';
|
||||
$labels['errorsaving'] = 'Failed to save changes.';
|
||||
$labels['operationfailed'] = 'The requested operation failed.';
|
||||
$labels['invalideventdates'] = 'Invalid dates entered! Please check your input.';
|
||||
$labels['invalidcalendarproperties'] = 'Invalid calendar properties! Please set a valid name.';
|
||||
$labels['searchnoresults'] = 'No events found in the selected calendars.';
|
||||
$labels['successremoval'] = 'The event has been deleted successfully.';
|
||||
$labels['successrestore'] = 'The event has been restored successfully.';
|
||||
$labels['errornotifying'] = 'Failed to send notifications to event participants';
|
||||
$labels['errorimportingevent'] = 'Failed to import the event';
|
||||
$labels['newerversionexists'] = 'A newer version of this event already exists! Aborted.';
|
||||
$labels['nowritecalendarfound'] = 'No calendar found to save the event';
|
||||
$labels['importedsuccessfully'] = 'The event was successfully added to \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Successfully updated the participant\'s status';
|
||||
$labels['itipsendsuccess'] = 'Invitation sent to participants.';
|
||||
$labels['itipresponseerror'] = 'Failed to send the response to this event invitation';
|
||||
$labels['itipinvalidrequest'] = 'This invitation is no longer valid';
|
||||
$labels['sentresponseto'] = 'Successfully sent invitation response to $mailto';
|
||||
$labels['localchangeswarning'] = 'You are about to make changes that will only be reflected on your personal calendar';
|
||||
$labels['importsuccess'] = 'Successfully imported $nr events';
|
||||
$labels['importnone'] = 'No events found to be imported';
|
||||
$labels['importerror'] = 'An error occured while importing';
|
||||
$labels['aclnorights'] = 'You do not have administrator rights on this calendar.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Repeat';
|
||||
$labels['frequency'] = 'Repeat';
|
||||
$labels['never'] = 'never';
|
||||
$labels['daily'] = 'daily';
|
||||
$labels['weekly'] = 'weekly';
|
||||
$labels['monthly'] = 'monthly';
|
||||
$labels['yearly'] = 'annually';
|
||||
$labels['every'] = 'Every';
|
||||
$labels['days'] = 'day(s)';
|
||||
$labels['weeks'] = 'week(s)';
|
||||
$labels['months'] = 'month(s)';
|
||||
$labels['years'] = 'year(s) in:';
|
||||
$labels['bydays'] = 'On';
|
||||
$labels['untildate'] = 'the';
|
||||
$labels['each'] = 'Each';
|
||||
$labels['onevery'] = 'On every';
|
||||
$labels['onsamedate'] = 'On the same date';
|
||||
$labels['forever'] = 'forever';
|
||||
$labels['recurrencend'] = 'until';
|
||||
$labels['forntimes'] = 'for $nr time(s)';
|
||||
$labels['first'] = 'first';
|
||||
$labels['second'] = 'second';
|
||||
$labels['third'] = 'third';
|
||||
$labels['fourth'] = 'fourth';
|
||||
$labels['last'] = 'last';
|
||||
$labels['dayofmonth'] = 'Day of month';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Change event';
|
||||
$labels['removeeventconfirm'] = 'Remove event';
|
||||
$labels['changerecurringeventwarning'] = 'This is a recurring event. Would you like to edit the current event only, this and all future occurences, all occurences or save it as a new event?';
|
||||
$labels['removerecurringeventwarning'] = 'This is a recurring event. Would you like to remove the current event only, this and all future occurences or all occurences of this event?';
|
||||
$labels['currentevent'] = 'Current';
|
||||
$labels['futurevents'] = 'Future';
|
||||
$labels['allevents'] = 'All';
|
||||
$labels['saveasnew'] = 'Save as new';
|
||||
|
||||
?>
|
39
localization/nl_NL.inc
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Standaard agenda';
|
||||
$labels['time_format'] = 'Tijdsformaat';
|
||||
$labels['timeslots'] = 'Timeslots per uur';
|
||||
$labels['first_day'] = 'Eerste weekdag';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Agenda';
|
||||
$labels['day'] = 'Dag';
|
||||
$labels['week'] = 'Week';
|
||||
$labels['month'] = 'Maand';
|
||||
$labels['new_event'] = 'Nieuw evenement';
|
||||
$labels['edit_event'] = 'Wijzig evenement';
|
||||
$labels['save'] = 'Bewaar';
|
||||
$labels['remove'] = 'Verwijder';
|
||||
$labels['cancel'] = 'Terug';
|
||||
$labels['title'] = 'Samenvatting';
|
||||
$labels['description'] = 'Beschrijving';
|
||||
$labels['all-day'] = 'hele dag';
|
||||
$labels['export'] = 'Exporteer naar ICS';
|
||||
$labels['category'] = 'Categorie';
|
||||
$labels['location'] = 'Locatie';
|
||||
?>
|
224
localization/pl_PL.inc
Normal file
|
@ -0,0 +1,224 @@
|
|||
<?php
|
||||
|
||||
$labels = array();
|
||||
|
||||
// preferences
|
||||
$labels['default_view'] = 'Domyślny widok';
|
||||
$labels['time_format'] = 'Format czasu';
|
||||
$labels['timeslots'] = 'Okienka na godzinę';
|
||||
$labels['first_day'] = 'Pierwszy dzień tygodnia';
|
||||
$labels['first_hour'] = 'Pierwsza godzina do wyświetlenia';
|
||||
$labels['workinghours'] = 'Godziny pracy';
|
||||
$labels['add_category'] = 'Dodaj kategorię';
|
||||
$labels['remove_category'] = 'Usuń kategorię';
|
||||
$labels['defaultcalendar'] = 'Utwórz nowe zdarzenia w';
|
||||
$labels['eventcoloring'] = 'Kolorowanie zdarzeń';
|
||||
$labels['coloringmode0'] = 'zależnie od kalendarza';
|
||||
$labels['coloringmode1'] = 'zależnie od kategorii';
|
||||
$labels['coloringmode2'] = 'Kalendarz - obramowanie, kategoria - tło';
|
||||
$labels['coloringmode3'] = 'Kategoria - obramowanie, kalendarz - tło';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Kalendarz';
|
||||
$labels['calendars'] = 'Kalendarze';
|
||||
$labels['category'] = 'Kategoria';
|
||||
$labels['categories'] = 'Kategorie';
|
||||
$labels['createcalendar'] = 'Utwórz nowy kalendarz';
|
||||
$labels['editcalendar'] = 'Edytuj właściwości kalendarza';
|
||||
$labels['name'] = 'Nazwa';
|
||||
$labels['color'] = 'Kolor';
|
||||
$labels['day'] = 'Dzień';
|
||||
$labels['week'] = 'Tydzień';
|
||||
$labels['month'] = 'Miesiąc';
|
||||
$labels['agenda'] = 'Agenda';
|
||||
$labels['new_event'] = 'Nowe zdarzenie';
|
||||
$labels['edit_event'] = 'Edytuj zdarzenie';
|
||||
$labels['edit'] = 'Edytuj';
|
||||
$labels['save'] = 'Zapisz';
|
||||
$labels['remove'] = 'Usuń';
|
||||
$labels['cancel'] = 'Anuluj';
|
||||
$labels['select'] = 'Wybierz';
|
||||
$labels['print'] = 'Drukuj kalendarze';
|
||||
$labels['title'] = 'Podsumowanie';
|
||||
$labels['description'] = 'Opis';
|
||||
$labels['all-day'] = 'cały dzień';
|
||||
$labels['export'] = 'Eksport do iCalendarza';
|
||||
$labels['location'] = 'Położenie';
|
||||
$labels['date'] = 'Data';
|
||||
$labels['start'] = 'Początek';
|
||||
$labels['end'] = 'Koniec';
|
||||
$labels['selectdate'] = 'Wybierz datę';
|
||||
$labels['freebusy'] = 'Pokazuj mnie jako';
|
||||
$labels['free'] = 'Wolny';
|
||||
$labels['busy'] = 'Zajęty';
|
||||
$labels['outofoffice'] = 'Poza buirem';
|
||||
$labels['tentative'] = 'Niepewny';
|
||||
$labels['priority'] = 'Priorytet';
|
||||
$labels['sensitivity'] = 'Dostępność';
|
||||
$labels['public'] = 'publiczny';
|
||||
$labels['private'] = 'prywatny';
|
||||
$labels['confidential'] = 'zastrzeżony';
|
||||
$labels['alarms'] = 'Przypomnienie';
|
||||
$labels['generated'] = 'wygenerowano';
|
||||
$labels['printdescriptions'] = 'Drukuj opisy';
|
||||
$labels['parentcalendar'] = 'Nadrzędny kalendarz';
|
||||
$labels['searchearlierdates'] = '« Wyszukaj wcześniejsze zdarzenia';
|
||||
$labels['searchlaterdates'] = 'Wyszukaj późniejsze zdarzenia »';
|
||||
$labels['andnmore'] = '$nr więcej...';
|
||||
$labels['showmore'] = 'Pokaż więcej...';
|
||||
$labels['togglerole'] = 'Kliknij aby zmienić rolę';
|
||||
$labels['createfrommail'] = 'Zapisz jako zdarzenie';
|
||||
$labels['importevents'] = 'Import zdarzeń';
|
||||
$labels['importrange'] = 'Zdarzenia z';
|
||||
$labels['onemonthback'] = '1 miesiąc wstecz';
|
||||
$labels['nmonthsback'] = '$nr miesiące wstecz';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Zakres do wyświetlenia:';
|
||||
$labels['listsections'] = 'Podziel na:';
|
||||
$labels['smartsections'] = 'Inteligentne sekcje';
|
||||
$labels['until'] = 'do';
|
||||
$labels['today'] = 'Dzisiaj';
|
||||
$labels['tomorrow'] = 'Jutro';
|
||||
$labels['thisweek'] = 'Ten tydzień';
|
||||
$labels['nextweek'] = 'Następny tydzień';
|
||||
$labels['thismonth'] = 'Ten miesiąc';
|
||||
$labels['nextmonth'] = 'Następny miesiąc';
|
||||
$labels['weekofyear'] = 'Tydzień';
|
||||
$labels['pastevents'] = 'Przeszłość';
|
||||
$labels['futureevents'] = 'Przyszłość';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Wyświetlaj alarmy';
|
||||
$labels['defaultalarmtype'] = 'Domyślne ustawienia przypomnienia';
|
||||
$labels['defaultalarmoffset'] = 'Domyślny czas przypomnienia';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Uczestnik';
|
||||
$labels['role'] = 'Rola';
|
||||
$labels['availability'] = 'Dostępn.';
|
||||
$labels['confirmstate'] = 'Status';
|
||||
$labels['addattendee'] = 'Dodaj uczestnika';
|
||||
$labels['roleorganizer'] = 'Organizator';
|
||||
$labels['rolerequired'] = 'Wymagany';
|
||||
$labels['roleoptional'] = 'Opcjonalny';
|
||||
$labels['roleresource'] = 'Żródło';
|
||||
$labels['availfree'] = 'Wolny';
|
||||
$labels['availbusy'] = 'Zajęty';
|
||||
$labels['availunknown'] = 'Nieznany';
|
||||
$labels['availtentative'] = 'Niepewny';
|
||||
$labels['availoutofoffice'] = 'Poza buirem';
|
||||
$labels['scheduletime'] = 'Sprawdź dostępność';
|
||||
$labels['sendinvitations'] = 'Wyślij zaproszenia';
|
||||
$labels['sendnotifications'] = 'Informuj uczestników o zmianach';
|
||||
$labels['sendcancellation'] = 'Informuj uczestników o odwołaniu zdarzenia';
|
||||
$labels['onlyworkinghours'] = 'Sprawdź dostępność podczas moich godzin pracy';
|
||||
$labels['reqallattendees'] = 'Wymagani/wszyscy uczestnicy';
|
||||
$labels['prevslot'] = 'Poprzednie okienko';
|
||||
$labels['nextslot'] = 'Następne okienko';
|
||||
$labels['noslotfound'] = 'Nie można znaleźć wolnego okienka';
|
||||
$labels['invitationsubject'] = 'Zostałeś zaproszony na "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nKiedy: \$date\n\nZaproszeni: \$attendees\n\nW załączeniu plik w formacie iCalendar zawierający szczegóły zdarzenia, który można zaimportować do Pana/Pani kalendarza.";
|
||||
$labels['invitationattendlinks'] = "W przypadku gdy Pana/Pani program pocztowy nie obsługuje żądań iTip można użyć następującego łącza w celu akceptacji lub odrzucenia tego zdarzenia:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" zostało zaktualizowane';
|
||||
$labels['eventupdatesubjectempty'] = 'Zdarzenie, które ciebie dotyczy zostało zaktualizowane';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nKiedy: \$date\n\nUczestnicy: \$attendees\n\n.W załączeniu plik w formacie iCalendar zawierający zaktualizowane szczegóły zdarzenia, który można zaimportować do Pana/Pani kalendarza.";
|
||||
$labels['eventcancelsubject'] = '"$title" zostało anulowane';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nKiedy: \$date\n\nUczestnicy: \$attendees\n\nZdarzenie zostało anulowane przez \$organizer.\n\n.W załączeniu plik w formacie iCalendar zawierający zaktualizowane szczegóły zdarzenia.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Zaproszenie dla';
|
||||
$labels['itipupdate'] = 'Aktualizacja do';
|
||||
$labels['itipcancellation'] = 'Anulowano:';
|
||||
$labels['itipreply'] = 'Odpowiedź do';
|
||||
$labels['itipaccepted'] = 'Akceptuj';
|
||||
$labels['itiptentative'] = 'Może';
|
||||
$labels['itipdeclined'] = 'Odrzuć';
|
||||
$labels['itipsubjectaccepted'] = '"$title" zostało zaakceptowane przez $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" zostało warunkowo zaakceptowane $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" zostało odrzucone przez $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender zaakceptował zaproszenie na następującego zdarzenie:\n\n*\$title*\n\nKiedy: \$date\n\nUczestnicy: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender warunkowo zaakceptował zaproszenie na następujące zdarzenie:\n\n*\$title*\n\nKiedy: \$date\n\nUczestnicy: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender odrzucił zaproszenie na następujące zdarzenie:\n\n*\$title*\n\nKiedy: \$date\n\nUczestnicy: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Czy chcesz odrzucić zaproszenie na to zdarzenie?';
|
||||
$labels['importtocalendar'] = 'Zapisz w moim kalendarzu';
|
||||
$labels['removefromcalendar'] = 'Usuń z mojego kalendarza';
|
||||
$labels['updateattendeestatus'] = 'Aktualizuj status uczestników';
|
||||
$labels['acceptinvitation'] = 'Czy akceptujesz to zaproszenie?';
|
||||
$labels['youhaveaccepted'] = 'Zaakceptowałeś to zaproszenie';
|
||||
$labels['youhavetentative'] = 'Zaakceptowałeś warunkowo to zaproszenie';
|
||||
$labels['youhavedeclined'] = 'Odrzuciłeś to zaproszenie';
|
||||
$labels['notanattendee'] = 'Nie znajdujesz się na liście uczestników tego zdarzenia';
|
||||
$labels['eventcancelled'] = 'Zdarzenie zostało anulowane';
|
||||
$labels['saveincalendar'] = 'zapisz w';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Podsumowanie';
|
||||
$labels['tabrecurrence'] = 'Powtarzalność';
|
||||
$labels['tabattendees'] = 'Uczestnicy';
|
||||
$labels['tabattachments'] = 'Załączniki';
|
||||
$labels['tabsharing'] = 'Udostępnianie';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Czy na pewno chcesz usunąć to zdarzenie?';
|
||||
$labels['deletecalendarconfirm'] = 'Czy na pewno chcesz usunąć ten kalendarz wraz z wszystkimi zdarzeniami?';
|
||||
$labels['savingdata'] = 'Zapisywanie danych...';
|
||||
$labels['errorsaving'] = 'Nie udało się zapisanie zmian.';
|
||||
$labels['operationfailed'] = 'Żądana operacja nie powiodła się.';
|
||||
$labels['invalideventdates'] = 'Wprowadzono błędne daty! Sprawdź dane w formularzu.';
|
||||
$labels['invalidcalendarproperties'] = 'Błędne właściwości kalendarza! Proszę podać poprawną datę.';
|
||||
$labels['searchnoresults'] = 'Nie znaleziono zdarzeń w wybranym kalendarzu.';
|
||||
$labels['successremoval'] = 'Zdarzenie zostało usunięte pomyślnie.';
|
||||
$labels['successrestore'] = 'Zdarzenie zostało odtworzone pomyślnie.';
|
||||
$labels['errornotifying'] = 'Nie udało się wysłać powiadomień do uczestników';
|
||||
$labels['errorimportingevent'] = 'Nie powódł się import zdarzenia';
|
||||
$labels['newerversionexists'] = 'Nowsza wersja tego zdarzenia już istnieje! Przerwano.';
|
||||
$labels['nowritecalendarfound'] = 'Nie znaleziono kalendarza do zapisu zdarzenia';
|
||||
$labels['importedsuccessfully'] = 'Zdarzenie zostało pomyślnie zapisane w \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Pomyślnie zaktualizowano status uczestnika';
|
||||
$labels['itipresponseerror'] = 'Nie udało się wysłać odpowiedzi na to zaproszenie';
|
||||
$labels['itipinvalidrequest'] = 'To zaproszenie nie jest już aktualne';
|
||||
$labels['sentresponseto'] = 'Pomyślnie wysłano odpowiedź na zaproszenie do $mailto';
|
||||
$labels['localchangeswarning'] = 'Próbujesz dokonać zmian, które będą widoczne tylko w twoim prywatnym kalendarzu';
|
||||
$labels['importsuccess'] = 'Pomyślnie zaimportowano $nr zdarzeń';
|
||||
$labels['importnone'] = 'Nie znaleziono zdarzeń do importu';
|
||||
$labels['importerror'] = 'Wystąpił błąd podczas operacji importu.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Powtórz';
|
||||
$labels['frequency'] = 'Częstotliwość';
|
||||
$labels['never'] = 'nigdy';
|
||||
$labels['daily'] = 'codziennie';
|
||||
$labels['weekly'] = 'co tydzień';
|
||||
$labels['monthly'] = 'co miesiąc';
|
||||
$labels['yearly'] = 'co rok';
|
||||
$labels['every'] = 'Każdego';
|
||||
$labels['days'] = 'dni(a)';
|
||||
$labels['weeks'] = 'tygodni(a)';
|
||||
$labels['months'] = 'miesięcy';
|
||||
$labels['years'] = 'lat w:';
|
||||
$labels['bydays'] = 'W';
|
||||
$labels['untildate'] = 'Do';
|
||||
$labels['each'] = 'Każdy';
|
||||
$labels['onevery'] = 'W każdy';
|
||||
$labels['onsamedate'] = 'W tej samej dacie';
|
||||
$labels['forever'] = 'zawsze';
|
||||
$labels['recurrencend'] = 'aż do';
|
||||
$labels['forntimes'] = '$nr raz(y)';
|
||||
$labels['first'] = 'pierwszy';
|
||||
$labels['second'] = 'drugi';
|
||||
$labels['third'] = 'trzeci';
|
||||
$labels['fourth'] = 'czwarty';
|
||||
$labels['last'] = 'ostatni';
|
||||
$labels['dayofmonth'] = 'Dzień miesiąca';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Zmień zdarzenie';
|
||||
$labels['removeeventconfirm'] = 'Usuń zdarzenie';
|
||||
$labels['changerecurringeventwarning'] = 'To jest zdarzenie powtarzające się. Czy chesz zmienić tylko bieżące wystąpienie, to i wszystkie przyszłe wystąpienia, czy wszystkie wystąpienia i zapisać je jako nowe zdarzenie?';
|
||||
$labels['removerecurringeventwarning'] = 'To jest zdarzenie powtarzające się. Czy chesz usunąć tylko bieżące wystąpienie, to i wszystkie przyszłe wystąpienia, czy wszystkie wystąpienia tego zdarzenie?';
|
||||
$labels['currentevent'] = 'Bieżące';
|
||||
$labels['futurevents'] = 'Przyszłe';
|
||||
$labels['allevents'] = 'Wszystkie';
|
||||
$labels['saveasnew'] = 'Zapisz jako nowy';
|
||||
|
||||
?>
|
38
localization/pt_BR.inc
Normal file
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['default_view'] = 'Visualização padrão';
|
||||
$labels['time_format'] = 'Formato da hora';
|
||||
$labels['timeslots'] = 'Caixas de tempo por hora';
|
||||
$labels['first_day'] = 'Primeiro dia da semana';
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Calendário';
|
||||
$labels['day'] = 'Dia';
|
||||
$labels['week'] = 'Semana';
|
||||
$labels['month'] = 'Mês';
|
||||
$labels['new_event'] = 'Novo evento';
|
||||
$labels['edit_event'] = 'Editar evento';
|
||||
$labels['save'] = 'Gravar';
|
||||
$labels['remove'] = 'Remover';
|
||||
$labels['cancel'] = 'Cancelar';
|
||||
$labels['title'] = 'Sumário';
|
||||
$labels['description'] = 'Descrição';
|
||||
$labels['all-day'] = 'dia-a-dia';
|
||||
$labels['export'] = 'Exportar para ICS';
|
||||
$labels['category'] = 'Categoria';
|
||||
?>
|
242
localization/ru_RU.inc
Normal file
|
@ -0,0 +1,242 @@
|
|||
<?php
|
||||
/**
|
||||
* RoundCube Calendar
|
||||
*
|
||||
* Plugin to add a calendar to RoundCube.
|
||||
*
|
||||
* @version 0.2 BETA 2
|
||||
* @author Lazlo Westerhof
|
||||
* @url http://rc-calendar.lazlo.me
|
||||
* @licence GNU GPL
|
||||
* @copyright (c) 2010 Lazlo Westerhof - Netherlands
|
||||
*
|
||||
**/
|
||||
|
||||
$labels = array();
|
||||
|
||||
// config
|
||||
$labels['time_format'] = 'Формат времени';
|
||||
$labels['timeslots'] = 'Промежутков в час';
|
||||
$labels['first_day'] = 'Первый день недели';
|
||||
$labels['default_view'] = 'Вид по умолчанию';
|
||||
$labels['workinghours'] = 'Рабочие часы';
|
||||
$labels['add_category'] = 'Добавить категорию';
|
||||
$labels['remove_category'] = 'Удалить категорию';
|
||||
$labels['defaultcalendar'] = 'Создать новое событие в';
|
||||
$labels['eventcoloring'] = 'Цвет события';
|
||||
$labels['coloringmode0'] = 'Согласно цвета календаря';
|
||||
$labels['coloringmode1'] = 'Согласно цвета категории';
|
||||
$labels['coloringmode2'] = 'Календарь для внешних, категория для внутренних цветов';
|
||||
$labels['coloringmode3'] = 'Категория для внешних, календарь для внутренних цветов';
|
||||
|
||||
|
||||
// calendar
|
||||
$labels['calendar'] = 'Календарь';
|
||||
$labels['day'] = 'День';
|
||||
$labels['week'] = 'Неделя';
|
||||
$labels['month'] = 'Месяц';
|
||||
$labels['new_event'] = 'Новое событие';
|
||||
$labels['edit_event'] = 'Изменить событие';
|
||||
$labels['save'] = 'Сохранить';
|
||||
$labels['remove'] = 'Удалить';
|
||||
$labels['cancel'] = 'Завершить';
|
||||
$labels['calendars'] = 'Календари';
|
||||
$labels['category'] = 'Категория';
|
||||
$labels['categories'] = 'Категории';
|
||||
$labels['createcalendar'] = 'Создать новый календарь';
|
||||
$labels['editcalendar'] = 'Редактировать свойства календаря';
|
||||
$labels['name'] = 'Имя';
|
||||
$labels['color'] = 'Цвет';
|
||||
$labels['agenda'] = 'Список';
|
||||
$labels['new'] = 'Новый';
|
||||
$labels['edit'] = 'Редактировать';
|
||||
$labels['select'] = 'Выбрать';
|
||||
$labels['print'] = 'Распечатать';
|
||||
$labels['printtitle'] = 'Распечатать календарь';
|
||||
$labels['title'] = 'Название мероприятия';
|
||||
$labels['description'] = 'Описание';
|
||||
$labels['all-day'] = 'целый день';
|
||||
$labels['export'] = 'Экспорт';
|
||||
$labels['exporttitle'] = 'Экспорт в iCalendar';
|
||||
$labels['location'] = 'Место';
|
||||
$labels['date'] = 'Дата';
|
||||
$labels['start'] = 'Начало';
|
||||
$labels['end'] = 'Конец';
|
||||
$labels['selectdate'] = 'Выберите дату';
|
||||
$labels['freebusy'] = 'Показать как';
|
||||
$labels['free'] = 'Свободен';
|
||||
$labels['busy'] = 'Занят';
|
||||
$labels['outofoffice'] = 'Вне офиса';
|
||||
$labels['tentative'] = 'Предварительно';
|
||||
$labels['priority'] = 'Приоритет';
|
||||
$labels['sensitivity'] = 'Секретность';
|
||||
$labels['public'] = 'Общедоступная';
|
||||
$labels['private'] = 'Личная';
|
||||
$labels['confidential'] = 'Конфиденциальная';
|
||||
$labels['alarms'] = 'Напоминание';
|
||||
$labels['generated'] = 'generated at';
|
||||
$labels['printdescriptions'] = 'Распечатать описание';
|
||||
$labels['parentcalendar'] = 'Вставить внутри';
|
||||
$labels['searchearlierdates'] = 'В« Искать для ранних событий';
|
||||
$labels['searchlaterdates'] = 'Искать для поздних событий В»';
|
||||
$labels['andnmore'] = '$nr больше...';
|
||||
$labels['showmore'] = 'Показать больше...';
|
||||
$labels['togglerole'] = 'Кликните для переключения роли';
|
||||
$labels['createfrommail'] = 'Сохранить как событие';
|
||||
$labels['importevents'] = 'Импортировать события';
|
||||
$labels['importrange'] = 'События с';
|
||||
$labels['onemonthback'] = '1 месяц назад';
|
||||
$labels['nmonthsback'] = '$nr месяцев назад';
|
||||
$labels['showurl'] = 'Показать URL календаря';
|
||||
$labels['showurldescription'] = 'Используйте следующий адрес для доступа к Вашему календарю из других приложений. Вы можете скопировать и вставить это в любое приложение которое поддерживает формат iCal.';
|
||||
|
||||
// agenda view
|
||||
$labels['listrange'] = 'Диапазон:';
|
||||
$labels['listsections'] = 'Разделитесь на:';
|
||||
$labels['smartsections'] = 'Умные секции';
|
||||
$labels['until'] = 'до';
|
||||
$labels['today'] = 'Сегодня';
|
||||
$labels['tomorrow'] = 'Завтра';
|
||||
$labels['thisweek'] = 'Текущая неделя';
|
||||
$labels['nextweek'] = 'Следующая неделя';
|
||||
$labels['thismonth'] = 'Этот месяц';
|
||||
$labels['nextmonth'] = 'Следующий месяц';
|
||||
$labels['weekofyear'] = 'Неделя';
|
||||
$labels['pastevents'] = 'Прошлое';
|
||||
$labels['futureevents'] = 'Будующее';
|
||||
|
||||
// alarm/reminder settings
|
||||
$labels['showalarms'] = 'Показать уведомление';
|
||||
$labels['defaultalarmtype'] = 'Настройки напоминания по умолчанию';
|
||||
$labels['defaultalarmoffset'] = 'Время напоминания по умолчанию';
|
||||
|
||||
// attendees
|
||||
$labels['attendee'] = 'Участник';
|
||||
$labels['role'] = 'Роль';
|
||||
$labels['availability'] = 'Доступность';
|
||||
$labels['confirmstate'] = 'Статус';
|
||||
$labels['addattendee'] = 'Добавить участника';
|
||||
$labels['roleorganizer'] = 'Организатор';
|
||||
$labels['rolerequired'] = 'Обязательный';
|
||||
$labels['roleoptional'] = 'Опциональный';
|
||||
$labels['rolechair'] = 'Наблюдатель';
|
||||
$labels['availfree'] = 'Свободен';
|
||||
$labels['availbusy'] = 'Занят';
|
||||
$labels['availunknown'] = 'Неизвестно';
|
||||
$labels['availtentative'] = 'Предварительно';
|
||||
$labels['availoutofoffice'] = 'Вне офиса';
|
||||
$labels['scheduletime'] = 'Найти доступность';
|
||||
$labels['sendinvitations'] = 'Отправить приглашение';
|
||||
$labels['sendnotifications'] = 'Уведомить участников об изменениях';
|
||||
$labels['sendcancellation'] = 'Уведомить участников об отмене события';
|
||||
$labels['onlyworkinghours'] = 'Найти возможность в мои рабочие часы';
|
||||
$labels['reqallattendees'] = 'Необходимые/все участники';
|
||||
$labels['prevslot'] = 'Предыдущее время';
|
||||
$labels['nextslot'] = 'Следующее время';
|
||||
$labels['noslotfound'] = 'Невозможно найти свободное время';
|
||||
$labels['invitationsubject'] = 'Вы приглашены на "$title"';
|
||||
$labels['invitationmailbody'] = "*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees\n\nПожалуйста найдите вложения в iCalendar файл со всеми деталями события которое Вы можете импортировать в вашу программу календаря.";
|
||||
$labels['invitationattendlinks'] = "В случае, если Ваш почтовый клиент не поддерживает запросы iTip, Вы можете использовать ссылку, чтобы принять или отклонить это приглашение:\n\$url";
|
||||
$labels['eventupdatesubject'] = '"$title" было обновлено';
|
||||
$labels['eventupdatesubjectempty'] = 'Событие, которое касается Вас было обновлено';
|
||||
$labels['eventupdatemailbody'] = "*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees\n\nПожалуйста найдите вложения в iCalendar файл со всеми деталями события которое Вы можете импортировать в вашу программу календаря.";
|
||||
$labels['eventcancelsubject'] = '"$title" было отменено';
|
||||
$labels['eventcancelmailbody'] = "*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees\n\nЭто событие отменено \$organizer.\n\nПожалуйста посмотрите вложение в iCalendar файл которое обновит детали события.";
|
||||
|
||||
// invitation handling
|
||||
$labels['itipinvitation'] = 'Приглашение на';
|
||||
$labels['itipupdate'] = 'Обновление';
|
||||
$labels['itipcancellation'] = 'Отмененный:';
|
||||
$labels['itipreply'] = 'Ответить';
|
||||
$labels['itipaccepted'] = 'Принять';
|
||||
$labels['itiptentative'] = 'Может быть';
|
||||
$labels['itipdeclined'] = 'Отклонить';
|
||||
$labels['itipsubjectaccepted'] = '"$title" принято $name';
|
||||
$labels['itipsubjecttentative'] = '"$title" предварительно принято $name';
|
||||
$labels['itipsubjectdeclined'] = '"$title" отклонено $name';
|
||||
$labels['itipmailbodyaccepted'] = "\$sender принял приглашение на следующее событие:\n\n*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees";
|
||||
$labels['itipmailbodytentative'] = "\$sender предварительно принял приглашение на следующее событие:\n\n*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees";
|
||||
$labels['itipmailbodydeclined'] = "\$sender отклонил приглашение на следующее событие:\n\n*\$title*\n\nКогда: \$date\n\nПриглашенные: \$attendees";
|
||||
$labels['itipdeclineevent'] = 'Вы хотите отклонить приглашение на это событие?';
|
||||
$labels['importtocalendar'] = 'Сохранить в мой календарь';
|
||||
$labels['removefromcalendar'] = 'Удалить из моего календаря';
|
||||
$labels['updateattendeestatus'] = 'Обновить статус участника';
|
||||
$labels['acceptinvitation'] = 'Вы принимаете это приглашение?';
|
||||
$labels['youhaveaccepted'] = 'Вы приняли это приглашение';
|
||||
$labels['youhavetentative'] = 'Вы предварительно приняли это приглашение';
|
||||
$labels['youhavedeclined'] = 'Вы отклонили это приглашение';
|
||||
$labels['notanattendee'] = 'Вы не в списке этого события';
|
||||
$labels['eventcancelled'] = 'Это событие отменено';
|
||||
$labels['saveincalendar'] = 'сохранить в';
|
||||
|
||||
// event dialog tabs
|
||||
$labels['tabsummary'] = 'Сводка';
|
||||
$labels['tabrecurrence'] = 'Повторение';
|
||||
$labels['tabattendees'] = 'Участники';
|
||||
$labels['tabattachments'] = 'Вложения';
|
||||
$labels['tabsharing'] = 'Совместное использование';
|
||||
|
||||
// messages
|
||||
$labels['deleteventconfirm'] = 'Вы действительно хотите удалить это событие?';
|
||||
$labels['deletecalendarconfirm'] = 'Вы действительно хотите удалить этот календарь со всеми его событиями?';
|
||||
$labels['savingdata'] = 'Сохранение данных...';
|
||||
$labels['errorsaving'] = 'Ошибка сохранения изменений.';
|
||||
$labels['operationfailed'] = 'Ошибка запрошенной операции.';
|
||||
$labels['invalideventdates'] = 'Неверная дата! Пожалуйста проверьте данные.';
|
||||
$labels['invalidcalendarproperties'] = 'Неверные свойства календаря! Пожалуйста введите допустимые данные.';
|
||||
$labels['searchnoresults'] = 'Событие не найдено в выбранном календаре.';
|
||||
$labels['successremoval'] = 'Это событие успешно удалено.';
|
||||
$labels['successrestore'] = 'Это событие успешно восстановлено.';
|
||||
$labels['errornotifying'] = 'Ошибка в отправке уведомления участникам событий';
|
||||
$labels['errorimportingevent'] = 'Ошибка при импорте события';
|
||||
$labels['newerversionexists'] = 'Новая версия этого события уже существует! Отменено.';
|
||||
$labels['nowritecalendarfound'] = 'Не найден календарь для записи этого события';
|
||||
$labels['importedsuccessfully'] = 'Это событие успешно добавлено в \'$calendar\'';
|
||||
$labels['attendeupdateesuccess'] = 'Успешно обновлен статус участников';
|
||||
$labels['itipresponseerror'] = 'Невозможно послать ответ на это приглашение';
|
||||
$labels['itipinvalidrequest'] = 'Это приглашение больше не действительно';
|
||||
$labels['sentresponseto'] = 'Успешно отправлен ответ на приглашение на $mailto';
|
||||
$labels['localchangeswarning'] = 'Вы собираетесь внести изменения, которые будут только отражены на Вашем личном календаре';
|
||||
$labels['importsuccess'] = 'Успешно импортированы $nr событий';
|
||||
$labels['importnone'] = 'Не найдено событий для импорта';
|
||||
$labels['importerror'] = 'Ошибка при импорте';
|
||||
$labels['aclnorights'] = 'Вы не имеете прав администратора для этого календаря.';
|
||||
|
||||
// recurrence form
|
||||
$labels['repeat'] = 'Повторить';
|
||||
$labels['frequency'] = 'Повторить';
|
||||
$labels['never'] = 'никогда';
|
||||
$labels['daily'] = 'ежедневно';
|
||||
$labels['weekly'] = 'еженедельно';
|
||||
$labels['monthly'] = 'ежемесячно';
|
||||
$labels['yearly'] = 'ежегодно';
|
||||
$labels['every'] = 'Каждый';
|
||||
$labels['days'] = 'дней';
|
||||
$labels['weeks'] = 'недели';
|
||||
$labels['months'] = 'месяцы';
|
||||
$labels['years'] = 'годы в:';
|
||||
$labels['bydays'] = 'На';
|
||||
$labels['untildate'] = 'до числа';
|
||||
$labels['each'] = 'Каждый';
|
||||
$labels['onevery'] = 'На каждом';
|
||||
$labels['onsamedate'] = 'В ту же самую дату';
|
||||
$labels['forever'] = 'всегда';
|
||||
$labels['recurrencend'] = 'продолжительность';
|
||||
$labels['forntimes'] = '$nr дней';
|
||||
$labels['first'] = 'первое';
|
||||
$labels['second'] = 'второе';
|
||||
$labels['third'] = 'третье';
|
||||
$labels['fourth'] = 'четвертое';
|
||||
$labels['last'] = 'последнее';
|
||||
$labels['dayofmonth'] = 'День месяца';
|
||||
|
||||
$labels['changeeventconfirm'] = 'Изменить событие';
|
||||
$labels['removeeventconfirm'] = 'Удалить событие';
|
||||
$labels['changerecurringeventwarning'] = 'Это - повторяющееся событие. Хотели бы Вы редактировать только текущее событие, это и все будущие повторения, все события или сохранять его как новое событие?';
|
||||
$labels['removerecurringeventwarning'] = 'Это - повторяющееся событие. Хотели бы Вы удалить только текущее событие, это и все будущие события или все эти события?';
|
||||
$labels['currentevent'] = 'Текущее';
|
||||
$labels['futurevents'] = 'Будущие';
|
||||
$labels['allevents'] = 'Все';
|
||||
$labels['saveasnew'] = 'Сохранить как новое';
|
||||
|
||||
?>
|
168
print.js
Normal file
|
@ -0,0 +1,168 @@
|
|||
/**
|
||||
* Print view for the Calendar plugin
|
||||
*
|
||||
* @version @package_version@
|
||||
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||
*
|
||||
* Copyright (C) 2011, Kolab Systems AG <contact@kolabsys.com>
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
|
||||
/* calendar plugin printing code */
|
||||
window.rcmail && rcmail.addEventListener('init', function(evt) {
|
||||
|
||||
// quote html entities
|
||||
var Q = function(str)
|
||||
{
|
||||
return String(str).replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
||||
};
|
||||
|
||||
var rc_loading;
|
||||
var showdesc = true;
|
||||
var settings = $.extend(rcmail.env.calendar_settings, rcmail.env.libcal_settings);
|
||||
|
||||
// create list of event sources AKA calendars
|
||||
var src, event_sources = [];
|
||||
var add_url = (rcmail.env.search ? '&q='+escape(rcmail.env.search) : '');
|
||||
for (var id in rcmail.env.calendars) {
|
||||
source = $.extend({
|
||||
url: "./?_task=calendar&_action=load_events&source=" + escape(id) + add_url,
|
||||
className: 'fc-event-cal-'+id,
|
||||
id: id
|
||||
}, rcmail.env.calendars[id]);
|
||||
|
||||
event_sources.push(source);
|
||||
}
|
||||
|
||||
var viewdate = new Date();
|
||||
if (rcmail.env.date)
|
||||
viewdate.setTime(rcmail.env.date * 1000);
|
||||
|
||||
// initalize the fullCalendar plugin
|
||||
var fc = $('#calendar').fullCalendar({
|
||||
header: {
|
||||
left: '',
|
||||
center: 'title',
|
||||
right: 'agendaDay,agendaWeek,month,table'
|
||||
},
|
||||
aspectRatio: 0.85,
|
||||
ignoreTimezone: true, // will treat the given date strings as in local (browser's) timezone
|
||||
date: viewdate.getDate(),
|
||||
month: viewdate.getMonth(),
|
||||
year: viewdate.getFullYear(),
|
||||
defaultView: rcmail.env.view,
|
||||
eventSources: event_sources,
|
||||
monthNames : settings['months'],
|
||||
monthNamesShort : settings['months_short'],
|
||||
dayNames : settings['days'],
|
||||
dayNamesShort : settings['days_short'],
|
||||
firstDay : settings['first_day'],
|
||||
firstHour : settings['first_hour'],
|
||||
slotMinutes : 60/settings['timeslots'],
|
||||
timeFormat: {
|
||||
'': settings['time_format'],
|
||||
agenda: settings['time_format'] + '{ - ' + settings['time_format'] + '}',
|
||||
list: settings['time_format'] + '{ - ' + settings['time_format'] + '}',
|
||||
table: settings['time_format'] + '{ - ' + settings['time_format'] + '}'
|
||||
},
|
||||
axisFormat : settings['time_format'],
|
||||
columnFormat: {
|
||||
month: 'ddd', // Mon
|
||||
week: 'ddd ' + settings['date_short'], // Mon 9/7
|
||||
day: 'dddd ' + settings['date_short'], // Monday 9/7
|
||||
list: settings['date_agenda'],
|
||||
table: settings['date_agenda']
|
||||
},
|
||||
titleFormat: {
|
||||
month: 'MMMM yyyy',
|
||||
week: settings['dates_long'],
|
||||
day: 'dddd ' + settings['date_long'],
|
||||
list: settings['dates_long'],
|
||||
table: settings['dates_long']
|
||||
},
|
||||
listSections: rcmail.env.listSections !== undefined ? rcmail.env.listSections : settings['agenda_sections'],
|
||||
listRange: rcmail.env.listRange || settings['agenda_range'],
|
||||
tableCols: ['handle', 'date', 'time', 'title', 'location'],
|
||||
allDayText: rcmail.gettext('all-day', 'calendar'),
|
||||
buttonText: {
|
||||
day: rcmail.gettext('day', 'calendar'),
|
||||
week: rcmail.gettext('week', 'calendar'),
|
||||
month: rcmail.gettext('month', 'calendar'),
|
||||
table: rcmail.gettext('agenda', 'calendar')
|
||||
},
|
||||
listTexts: {
|
||||
until: rcmail.gettext('until', 'calendar'),
|
||||
past: rcmail.gettext('pastevents', 'calendar'),
|
||||
today: rcmail.gettext('today', 'calendar'),
|
||||
tomorrow: rcmail.gettext('tomorrow', 'calendar'),
|
||||
thisWeek: rcmail.gettext('thisweek', 'calendar'),
|
||||
nextWeek: rcmail.gettext('nextweek', 'calendar'),
|
||||
thisMonth: rcmail.gettext('thismonth', 'calendar'),
|
||||
nextMonth: rcmail.gettext('nextmonth', 'calendar'),
|
||||
future: rcmail.gettext('futureevents', 'calendar'),
|
||||
week: rcmail.gettext('weekofyear', 'calendar')
|
||||
},
|
||||
loading: function(isLoading) {
|
||||
rc_loading = rcmail.set_busy(isLoading, 'loading', rc_loading);
|
||||
},
|
||||
// event rendering
|
||||
eventRender: function(event, element, view) {
|
||||
if (view.name != 'month') {
|
||||
var cont = element.find('div.fc-event-title');
|
||||
if (event.location) {
|
||||
cont.after('<div class="fc-event-location">@ ' + Q(event.location) + '</div>');
|
||||
cont = cont.next();
|
||||
}
|
||||
if (event.description && showdesc) {
|
||||
cont.after('<div class="fc-event-description">' + Q(event.description) + '</div>');
|
||||
}
|
||||
/* TODO: create icons black on white
|
||||
if (event.recurrence)
|
||||
element.find('div.fc-event-time').append('<i class="fc-icon-recurring"></i>');
|
||||
if (event.alarms)
|
||||
element.find('div.fc-event-time').append('<i class="fc-icon-alarms"></i>');
|
||||
*/
|
||||
}
|
||||
if (view.name == 'table' && event.description && showdesc) {
|
||||
var cols = element.children().css('border', 0).length;
|
||||
element.after('<tr class="fc-event-row-secondary fc-event"><td colspan="'+cols+'" class="fc-event-description">' + Q(event.description) + '</td></tr>');
|
||||
}
|
||||
},
|
||||
viewDisplay: function(view) {
|
||||
// remove hard-coded hight and make contents visible
|
||||
window.setTimeout(function(){
|
||||
if (view.name == 'table') {
|
||||
$('div.fc-list-content').css('overflow', 'visible').height('auto');
|
||||
}
|
||||
else {
|
||||
$('div.fc-agenda-divider')
|
||||
.next().css('overflow', 'visible').height('auto')
|
||||
.children('div').css('overflow', 'visible').height('auto');
|
||||
}
|
||||
// adjust fixed height if vertical day slots
|
||||
var h = $('table.fc-agenda-slots:visible').height() + $('table.fc-agenda-allday:visible').height() + 4;
|
||||
if (h) $('table.fc-agenda-days td.fc-widget-content').children('div').height(h);
|
||||
}, 20);
|
||||
}
|
||||
});
|
||||
|
||||
// activate settings form
|
||||
$('#propdescription').change(function(){
|
||||
showdesc = this.checked;
|
||||
fc.fullCalendar('render');
|
||||
});
|
||||
|
||||
});
|
5
skins/classic/README
Normal file
|
@ -0,0 +1,5 @@
|
|||
Icons by Fugue Icons <http://p.yusukekamiyamane.com/>
|
||||
|
||||
Copyright (C) 2010 Yusuke Kamiyamane. All rights reserved.
|
||||
The icons are licensed under a Creative Commons Attribution
|
||||
3.0 license. <http://creativecommons.org/licenses/by/3.0/>
|
1269
skins/classic/calendar.css
Normal file
724
skins/classic/fullcalendar.css
Normal file
|
@ -0,0 +1,724 @@
|
|||
/*
|
||||
* FullCalendar v1.5.4-rcube-0.9.0 Stylesheet
|
||||
*
|
||||
* Copyright (c) 2011 Adam Shaw
|
||||
* Copyright (c) 2011, Kolab Systems AG
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Wed Nov 7 16:28:11 2012 +0100
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
.fc {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
html .fc,
|
||||
.fc table {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.fc td,
|
||||
.fc th {
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Header
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-header td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-header-left {
|
||||
width: 25%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc-header-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-header-right {
|
||||
width: 25%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-header-title {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fc-header-title h2 {
|
||||
margin-top: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc .fc-header-space {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.fc-header .fc-button {
|
||||
margin-bottom: 1em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* buttons edges butting together */
|
||||
|
||||
.fc-header .fc-button {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.fc-header .fc-corner-right {
|
||||
margin-right: 1px; /* back to normal */
|
||||
}
|
||||
|
||||
.fc-header .ui-corner-right {
|
||||
margin-right: 0; /* back to normal */
|
||||
}
|
||||
|
||||
/* button layering (for border precedence) */
|
||||
|
||||
.fc-header .fc-state-hover,
|
||||
.fc-header .ui-state-hover {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.fc-header .fc-state-down {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.fc-header .fc-state-active,
|
||||
.fc-header .ui-state-active {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Content
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-content {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.fc-view {
|
||||
width: 100%; /* needed for view switching (when view is absolute) */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Cell Styles
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-widget-header, /* <th>, usually */
|
||||
.fc-widget-content { /* <td>, usually */
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */
|
||||
background: #ffc;
|
||||
}
|
||||
|
||||
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
|
||||
background: #9cf;
|
||||
opacity: .2;
|
||||
filter: alpha(opacity=20); /* for IE */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Buttons
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fc-state-default { /* non-theme */
|
||||
border-style: solid;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.fc-button-inner {
|
||||
position: relative;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-state-default .fc-button-inner { /* non-theme */
|
||||
border-style: solid;
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-button-content {
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 1.9em;
|
||||
line-height: 1.9em;
|
||||
padding: 0 .6em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* icon (for jquery ui) */
|
||||
|
||||
.fc-button-content .fc-icon-wrap {
|
||||
position: relative;
|
||||
float: left;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.fc-button-content .ui-icon {
|
||||
position: relative;
|
||||
float: left;
|
||||
margin-top: -50%;
|
||||
*margin-top: 0;
|
||||
*top: -50%;
|
||||
}
|
||||
|
||||
/* gloss effect */
|
||||
|
||||
.fc-state-default .fc-button-effect {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.fc-state-default .fc-button-effect span {
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
left: 0;
|
||||
width: 500px;
|
||||
height: 100px;
|
||||
border-width: 100px 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #fff;
|
||||
background: #444;
|
||||
opacity: .09;
|
||||
filter: alpha(opacity=9);
|
||||
}
|
||||
|
||||
/* button states (determines colors) */
|
||||
|
||||
.fc-state-default,
|
||||
.fc-state-default .fc-button-inner {
|
||||
border-style: solid;
|
||||
border-color: #ccc #bbb #aaa;
|
||||
background: #F3F3F3;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.fc-state-hover,
|
||||
.fc-state-hover .fc-button-inner {
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
.fc-state-down,
|
||||
.fc-state-down .fc-button-inner {
|
||||
border-color: #555;
|
||||
background: #777;
|
||||
}
|
||||
|
||||
.fc-state-active,
|
||||
.fc-state-active .fc-button-inner {
|
||||
border-color: #555;
|
||||
background: #777;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fc-state-disabled,
|
||||
.fc-state-disabled .fc-button-inner {
|
||||
color: #999;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.fc-state-disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.fc-state-disabled .fc-button-effect {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Global Event Styles
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event {
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
font-size: .85em;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
a.fc-event,
|
||||
.fc-event-draggable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.fc-event {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-event {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-event-skin {
|
||||
border-color: #36c; /* default BORDER color */
|
||||
background-color: #36c; /* default BACKGROUND color */
|
||||
color: #fff; /* default TEXT color */
|
||||
}
|
||||
|
||||
.fc-event-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-event-time,
|
||||
.fc-event-title {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.fc .ui-resizable-handle { /*** TODO: don't use ui-resizable anymore, change class ***/
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
overflow: hidden; /* hacky spaces (IE6/7) */
|
||||
font-size: 300%; /* */
|
||||
line-height: 50%; /* */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Horizontal Events
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event-hori {
|
||||
border-width: 1px 0;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
/* resizable */
|
||||
|
||||
.fc-event-hori .ui-resizable-e {
|
||||
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||
right: -3px !important;
|
||||
width: 7px !important;
|
||||
height: 100% !important;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.fc-event-hori .ui-resizable-w {
|
||||
top: 0 !important;
|
||||
left: -3px !important;
|
||||
width: 7px !important;
|
||||
height: 100% !important;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.fc-event-hori .ui-resizable-handle {
|
||||
_padding-bottom: 14px; /* IE6 had 0 height */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fake Rounded Corners (for buttons and events)
|
||||
------------------------------------------------------------*/
|
||||
|
||||
.fc-corner-left {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-left .fc-button-inner,
|
||||
.fc-corner-left .fc-event-inner {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-right {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-right .fc-button-inner,
|
||||
.fc-corner-right .fc-event-inner {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-top {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-top .fc-event-inner {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom .fc-event-inner {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fake Rounded Corners SPECIFICALLY FOR EVENTS
|
||||
-----------------------------------------------------------------*/
|
||||
|
||||
.fc-corner-left .fc-event-inner {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-right .fc-event-inner {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-top .fc-event-inner {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom .fc-event-inner {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Reusable Separate-border Table
|
||||
------------------------------------------------------------*/
|
||||
|
||||
table.fc-border-separate {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.fc-border-separate th,
|
||||
.fc-border-separate td {
|
||||
border-width: 1px 0 0 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate th.fc-last,
|
||||
.fc-border-separate td.fc-last {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate tr.fc-last th,
|
||||
.fc-border-separate tr.fc-last td {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate tbody tr.fc-first td,
|
||||
.fc-border-separate tbody tr.fc-first th {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Month View, Basic Week View, Basic Day View
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-grid th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-grid .fc-day-number {
|
||||
float: right;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.fc-grid .fc-other-month .fc-day-number {
|
||||
opacity: 0.3;
|
||||
filter: alpha(opacity=30); /* for IE */
|
||||
/* opacity with small font can sometimes look too faded
|
||||
might want to set the 'color' property instead
|
||||
making day-numbers bold also fixes the problem */
|
||||
}
|
||||
|
||||
.fc-grid .fc-day-content {
|
||||
clear: both;
|
||||
padding: 2px 2px 1px; /* distance between events and day edges */
|
||||
}
|
||||
|
||||
/* event styles */
|
||||
|
||||
.fc-grid .fc-event-time {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* right-to-left */
|
||||
|
||||
.fc-rtl .fc-grid .fc-day-number {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-grid .fc-event-time {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.fc-more-link {
|
||||
font-size: 0.85em;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
/* Agenda Week View, Agenda Day View
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-agenda table {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.fc-agenda-days th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-agenda .fc-agenda-axis {
|
||||
width: 50px;
|
||||
padding: 0 4px;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.fc-agenda .fc-day-content {
|
||||
padding: 2px 2px 1px;
|
||||
}
|
||||
|
||||
/* make axis border take precedence */
|
||||
|
||||
.fc-agenda-days .fc-agenda-axis {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-agenda-days .fc-col0 {
|
||||
border-left-width: 0;
|
||||
}
|
||||
|
||||
/* all-day area */
|
||||
|
||||
.fc-agenda-allday th {
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-agenda-allday .fc-day-content {
|
||||
min-height: 34px; /* TODO: doesnt work well in quirksmode */
|
||||
_height: 34px;
|
||||
}
|
||||
|
||||
/* divider (between all-day and slots) */
|
||||
|
||||
.fc-agenda-divider-inner {
|
||||
height: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-widget-header .fc-agenda-divider-inner {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
/* slot rows */
|
||||
|
||||
.fc-agenda-slots th {
|
||||
border-width: 1px 1px 0;
|
||||
}
|
||||
|
||||
.fc-agenda-slots td {
|
||||
border-width: 1px 0 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.fc-agenda-slots td div {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-slot0 th,
|
||||
.fc-agenda-slots tr.fc-slot0 td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-minor th,
|
||||
.fc-agenda-slots tr.fc-minor td {
|
||||
border-top-style: dotted;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-minor th.ui-widget-header {
|
||||
*border-top-style: solid; /* doesn't work with background in IE6/7 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Vertical Events
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event-vert {
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-head,
|
||||
.fc-event-vert .fc-event-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-time {
|
||||
white-space: nowrap;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
opacity: .3;
|
||||
filter: alpha(opacity=30);
|
||||
}
|
||||
|
||||
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
|
||||
.fc-select-helper .fc-event-bg {
|
||||
display: none\9; /* for IE6/7/8. nested opacity filters while dragging don't work */
|
||||
}
|
||||
|
||||
/* resizable */
|
||||
|
||||
.fc-event-vert .ui-resizable-s {
|
||||
bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||
width: 100% !important;
|
||||
height: 8px !important;
|
||||
overflow: hidden !important;
|
||||
line-height: 8px !important;
|
||||
font-size: 11px !important;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.fc-agenda .ui-resizable-resizing { /* TODO: better selector */
|
||||
_overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-timeline {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-top: 2px solid #3ec400;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* List view (by bruederli@kolabsys.com)
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-view-list,
|
||||
.fc-view-table {
|
||||
border: 1px solid #ccc;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-list-header,
|
||||
.fc-view-table td.fc-list-header {
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-first td.fc-list-header {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.fc-list-section {
|
||||
padding: 4px 2px;
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-last {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.fc-list-section .fc-event {
|
||||
position: relative;
|
||||
margin: 1px 2px 3px 2px;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td {
|
||||
padding: 2px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td.fc-event-handle {
|
||||
padding: 3px 8px 3px 3px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-skin {
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-inner {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-handle {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.fc-event-handle .fc-event-inner {
|
||||
border-color: inherit;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-date {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-list-day col.fc-event-date {
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-time {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.fc-view-table td.fc-event-date,
|
||||
.fc-view-table td.fc-event-time {
|
||||
white-space: nowrap;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
88
skins/classic/iehacks.css
Normal file
|
@ -0,0 +1,88 @@
|
|||
/* CSS hacks for IE 6/7 */
|
||||
|
||||
#main {
|
||||
width: expression(Math.max(300, parseInt(document.documentElement.clientWidth)-10)+'px');
|
||||
height: expression(Math.max(300, parseInt(document.documentElement.clientHeight)-100)+'px');
|
||||
}
|
||||
|
||||
#calendarsidebar,
|
||||
#calendarsidebartoggle {
|
||||
height: expression((parseInt(this.parentNode.offsetHeight)-37)+'px');
|
||||
}
|
||||
|
||||
#calendar {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-parseInt(document.getElementById('calendarsidebartoggle').offsetWidth)-parseInt(document.getElementById('calendarsidebartoggle').offsetLeft)-4)+'px');
|
||||
height: expression(parseInt(this.parentNode.offsetHeight)+'px');
|
||||
}
|
||||
|
||||
#calendars {
|
||||
height: expression((parseInt(this.parentNode.offsetHeight)-220)+'px');
|
||||
}
|
||||
|
||||
#agendaoptions {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-12)+'px');
|
||||
}
|
||||
|
||||
#calendartoolbar a.buttonPas {
|
||||
filter: alpha(opacity=35);
|
||||
}
|
||||
|
||||
html #calendartoolbar a.button,
|
||||
html #calendartoolbar a.buttonPas {
|
||||
background-image: url(images/toolbar.gif);
|
||||
}
|
||||
|
||||
#datepicker a.ui-priority-secondary {
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
#calendarslist li span.handle {
|
||||
background-image: url(images/calendars.gif);
|
||||
}
|
||||
|
||||
#datepicker .ui-widget-header {
|
||||
width: 102%;
|
||||
}
|
||||
|
||||
#eventshow.sensitivity-private {
|
||||
background-image: url(images/badge_private.gif);
|
||||
}
|
||||
|
||||
#eventshow.sensitivity-confidential {
|
||||
background-image: url(images/badge_confidential.gif);
|
||||
}
|
||||
|
||||
.fc-day-content {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.fc-header-title h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.fc-event-temp .fc-event-bg {
|
||||
display: none; /* nested opacity filters while dragging don't work */
|
||||
}
|
||||
|
||||
#schedule-event-time {
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
#eventfreebusy .schedule-buttons,
|
||||
#edit-attendees-form #edit-attendee-schedule {
|
||||
right: 0.6em;
|
||||
}
|
||||
|
||||
#schedule-freebusy-times td.all-busy,
|
||||
#schedule-freebusy-times td.all-tentative,
|
||||
#schedule-freebusy-times td.all-out-of-office {
|
||||
background-image: url('images/freebusy-colors.gif');
|
||||
}
|
||||
|
||||
#schedule-freebusy-times tr.times td.allday {
|
||||
width: expression(Math.max(60, parseInt(this.offsetWidth))+'px');
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-titlebar {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-26)+'px');
|
||||
}
|
BIN
skins/classic/images/attendee-status.gif
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
skins/classic/images/badge_confidential.gif
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
skins/classic/images/badge_confidential.png
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
skins/classic/images/badge_private.gif
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
skins/classic/images/badge_private.png
Normal file
After Width: | Height: | Size: 3.3 KiB |
BIN
skins/classic/images/calendar-blue.png
Normal file
After Width: | Height: | Size: 896 B |
BIN
skins/classic/images/calendar.gif
Normal file
After Width: | Height: | Size: 546 B |
BIN
skins/classic/images/calendar.png
Normal file
After Width: | Height: | Size: 888 B |
BIN
skins/classic/images/calendars.gif
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
skins/classic/images/calendars.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
skins/classic/images/eventicons.gif
Normal file
After Width: | Height: | Size: 107 B |
BIN
skins/classic/images/export.png
Normal file
After Width: | Height: | Size: 746 B |
BIN
skins/classic/images/freebusy-colors.gif
Normal file
After Width: | Height: | Size: 408 B |
BIN
skins/classic/images/freebusy-colors.png
Normal file
After Width: | Height: | Size: 631 B |
BIN
skins/classic/images/invitation.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
skins/classic/images/listheader.gif
Normal file
After Width: | Height: | Size: 322 B |
BIN
skins/classic/images/loading_blue.gif
Normal file
After Width: | Height: | Size: 847 B |
BIN
skins/classic/images/minicolors-all.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
skins/classic/images/minicolors-handles.gif
Normal file
After Width: | Height: | Size: 421 B |
BIN
skins/classic/images/preview.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
skins/classic/images/print.png
Normal file
After Width: | Height: | Size: 869 B |
BIN
skins/classic/images/spacer.gif
Normal file
After Width: | Height: | Size: 807 B |
BIN
skins/classic/images/toggle.gif
Normal file
After Width: | Height: | Size: 110 B |
BIN
skins/classic/images/toolbar.gif
Normal file
After Width: | Height: | Size: 6 KiB |
BIN
skins/classic/images/toolbar.png
Normal file
After Width: | Height: | Size: 14 KiB |
106
skins/classic/jquery.miniColors.css
Normal file
|
@ -0,0 +1,106 @@
|
|||
.miniColors-trigger {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
background: url('images/minicolors-all.png') -170px 0 no-repeat;
|
||||
vertical-align: middle;
|
||||
margin: 0 .25em;
|
||||
display: inline-block;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.miniColors-selector {
|
||||
position: absolute;
|
||||
width: 175px;
|
||||
height: 150px;
|
||||
background: #FFF;
|
||||
border: solid 1px #BBB;
|
||||
-moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
-webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, .25);
|
||||
-moz-border-radius: 5px;
|
||||
-webkit-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
padding: 5px;
|
||||
z-index: 999999;
|
||||
}
|
||||
|
||||
.miniColors-selector.black {
|
||||
background: #000;
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.miniColors-colors {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 5px;
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
background: url('images/minicolors-all.png') top left no-repeat;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.miniColors-hues {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
left: 160px;
|
||||
width: 20px;
|
||||
height: 150px;
|
||||
background: url('images/minicolors-all.png') -150px 0 no-repeat;
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.miniColors-colorPicker {
|
||||
position: absolute;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
background: url('images/minicolors-all.png') -170px -28px no-repeat;
|
||||
}
|
||||
|
||||
.miniColors-huePicker {
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
width: 26px;
|
||||
height: 3px;
|
||||
background: url('images/minicolors-all.png') -170px -24px no-repeat;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.miniColors-presets {
|
||||
position: absolute;
|
||||
left: 185px;
|
||||
top: 5px;
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.miniColors-colorPreset {
|
||||
float: left;
|
||||
width: 18px;
|
||||
height: 15px;
|
||||
margin: 2px;
|
||||
border: 1px solid #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.miniColors-colorPreset-active {
|
||||
border: 2px dotted #666;
|
||||
margin: 1px;
|
||||
}
|
||||
|
||||
/* Hacks for IE6/7 */
|
||||
|
||||
* html .miniColors-colors {
|
||||
background-image: none;
|
||||
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='plugins/calendar/skins/classic/images/minicolors-all.png', sizingMethod='crop');
|
||||
}
|
||||
|
||||
* html .miniColors-colorPicker {
|
||||
background: url('images/minicolors-handles.gif') 0 -28px no-repeat;
|
||||
}
|
||||
|
||||
* html .miniColors-huePicker {
|
||||
background: url('images/minicolors-handles.gif') 0 -24px no-repeat;
|
||||
}
|
||||
|
||||
* html .miniColors-trigger {
|
||||
background: url('images/minicolors-handles.gif') 0 0 no-repeat;
|
||||
}
|
209
skins/classic/print.css
Normal file
|
@ -0,0 +1,209 @@
|
|||
/*** Printing styles for Calendar plugin ***/
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
color: #000;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
body, td, th, div, p, h3, select, input, textarea {
|
||||
font-family: "Lucida Grande", Verdana, Arial, Helvetica, sans-serif;
|
||||
font-size: 8pt;
|
||||
}
|
||||
|
||||
#calendar {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: auto;
|
||||
margin: 5em auto 0 auto;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
#calendar .fc-header-right {
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
#printconfig {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
z-index: 10000;
|
||||
padding: 0.5em;
|
||||
background: #ebebeb;
|
||||
border-bottom: 1px solid #999;
|
||||
box-shadow: 0 3px 4px #ccc;
|
||||
-moz-box-shadow: 0 3px 4px #ccc;
|
||||
-webkit-box-shadow: 0 3px 4px #ccc;
|
||||
}
|
||||
|
||||
#printconfig .prop {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
||||
#message {
|
||||
position: absolute;
|
||||
top: 5.5em;
|
||||
left: 1em;
|
||||
}
|
||||
|
||||
#message div.loading {
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
#calendarlist {
|
||||
list-style-type: square;
|
||||
margin: 2em 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
#calendarlist li {
|
||||
float: left;
|
||||
padding-left: 0;
|
||||
padding-right: 3em;
|
||||
margin-left: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#calendarlist input,
|
||||
#calendarlist .handle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.calwidth {
|
||||
width: 700px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.rightalign {
|
||||
float: right;
|
||||
padding-top: 0.3em;
|
||||
}
|
||||
|
||||
@media print {
|
||||
.noprint,
|
||||
.fc-header-right span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#calendar {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* fullcalendar style overrides */
|
||||
|
||||
.fc-view {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.fc-event-skin,
|
||||
.fc-event-inner .fc-event-skin {
|
||||
color: black;
|
||||
background-color: #fff !important;
|
||||
}
|
||||
|
||||
.fc-event-title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.fc-event-hori .fc-event-title {
|
||||
font-weight: normal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-event-hori .fc-event-time {
|
||||
white-space: nowrap;
|
||||
font-weight: normal !important;
|
||||
font-size: 10px;
|
||||
padding-right: 0.6em;
|
||||
}
|
||||
|
||||
.fc-grid .fc-event-time {
|
||||
font-weight: normal !important;
|
||||
padding-right: 0.3em;
|
||||
}
|
||||
|
||||
.fc-event-cateories {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.fc-event-location {
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.fc-agenda-slots td div {
|
||||
height: 1.4em;
|
||||
}
|
||||
|
||||
.fc-widget-header,
|
||||
.fc-mon, .fc-tue, .fc-wed, .fc-thu, .fc-fri {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.fc-widget-header, .fc-widget-content {
|
||||
border-color: #ccc;
|
||||
}
|
||||
|
||||
.fc-icon-alarms,
|
||||
.fc-icon-recurring {
|
||||
display: inline-block;
|
||||
width: 11px;
|
||||
height: 11px;
|
||||
background: url('images/eventicons.gif') 0 0 no-repeat;
|
||||
margin-left: 3px;
|
||||
line-height: 10px;
|
||||
}
|
||||
|
||||
.fc-icon-alarms {
|
||||
background-position: 0 -13px;
|
||||
}
|
||||
|
||||
.fc-view-list, .fc-view-table {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.fc-view-list div.fc-list-header,
|
||||
.fc-view-table td.fc-list-header {
|
||||
padding: 0.3em;
|
||||
background: #fff;
|
||||
font-weight: bold;
|
||||
font-size: 1.2em;
|
||||
color: #333;
|
||||
border-color: #333;
|
||||
border-style: solid;
|
||||
border-width: 1px 0;
|
||||
filter: none;
|
||||
}
|
||||
|
||||
.fc-list-section .fc-event {
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td,
|
||||
.fc-view-table tr.fc-event td.fc-event-handle {
|
||||
border-color: #999;
|
||||
padding-top: 0.5em;
|
||||
padding-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-last td {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event .fc-event-description {
|
||||
padding-left: 2em;
|
||||
padding-top: 0em;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-description {
|
||||
font-size: 90%;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
|
||||
.fc-view-table col.fc-event-location {
|
||||
width: 20%;
|
||||
}
|
25
skins/classic/print.iehacks.css
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* CSS hacks for IE 6/7 */
|
||||
|
||||
#calendar {
|
||||
top: 5em;
|
||||
}
|
||||
|
||||
.calwidth {
|
||||
width: 172mm;
|
||||
}
|
||||
|
||||
.fc-header-title h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
#calendarlist li {
|
||||
float: none;
|
||||
padding: 0;
|
||||
margin-left: 1em;
|
||||
}
|
||||
|
||||
@media print {
|
||||
#calendar {
|
||||
top: 0;
|
||||
}
|
||||
}
|
26
skins/classic/templates/attachment.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="extwin">
|
||||
|
||||
<roundcube:include file="/includes/header.html" />
|
||||
|
||||
<div id="partheader">
|
||||
<roundcube:object name="plugin.attachmentcontrols" cellpadding="2" cellspacing="0" />
|
||||
|
||||
<div style="position:absolute; top:2px; right:0; width:12em; text-align:right">
|
||||
[<a href="#close" class="closelink" onclick="self.close()"><roundcube:label name="close" /></a>]
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div id="attachmentcontainer">
|
||||
<roundcube:object name="plugin.attachmentframe" id="attachmentframe" width="100%" height="100%" />
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
201
skins/classic/templates/calendar.html
Normal file
|
@ -0,0 +1,201 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
<script type="text/javascript" src="/functions.js"></script>
|
||||
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="./plugins/calendar/skins/classic/iehacks.css" /><![endif]-->
|
||||
</head>
|
||||
<body class="calendarmain">
|
||||
|
||||
<roundcube:include file="/includes/taskbar.html" />
|
||||
<roundcube:include file="/includes/header.html" />
|
||||
|
||||
<div id="main">
|
||||
<div id="calendarsidebar">
|
||||
<div id="datepicker"></div>
|
||||
<div id="calendars" style="visibility:hidden">
|
||||
<div class="boxtitle"><roundcube:label name="calendar.calendars" /></div>
|
||||
<div class="boxlistcontent">
|
||||
<roundcube:object name="plugin.calendar_list" id="calendarslist" />
|
||||
</div>
|
||||
<div class="boxfooter">
|
||||
<roundcube:button command="calendar-create" type="link" title="calendar.createcalendar" class="buttonPas addgroup" classAct="button addgroup" content=" " />
|
||||
<roundcube:button name="calendaroptionslink" id="calendaroptionslink" type="link" title="moreactions" class="button groupactions" onclick="rcmail_ui.show_popup('calendaroptions');return false" content=" " />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="calendarsidebartoggle"></div>
|
||||
<div id="calendar">
|
||||
<roundcube:object name="plugin.angenda_options" class="boxfooter" id="agendaoptions" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="calendaroptionsmenu" class="popupmenu">
|
||||
<ul>
|
||||
<li><roundcube:button command="calendar-edit" label="calendar.edit" classAct="active" /></li>
|
||||
<li><roundcube:button command="calendar-remove" label="calendar.remove" classAct="active" /></li>
|
||||
<li><roundcube:button command="events-import" label="calendar.importevents" classAct="active" /></li>
|
||||
<li><roundcube:button command="calendar-showurl" label="calendar.showurl" classAct="active" /></li>
|
||||
<roundcube:if condition="env:calendar_driver == 'kolab'" />
|
||||
<li class="separator_above"><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
|
||||
<roundcube:endif />
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="eventshow" class="uidialog">
|
||||
<h1 id="event-title">Event Title</h1>
|
||||
<div class="event-section" id="event-location">Location</div>
|
||||
<div class="event-section" id="event-date">From-To</div>
|
||||
<div class="event-section" id="event-description">
|
||||
<h5 class="label"><roundcube:label name="calendar.description" /></h5>
|
||||
<div class="event-text"></div>
|
||||
</div>
|
||||
<div class="event-section" id="event-url">
|
||||
<h5 class="label"><roundcube:label name="calendar.url" /></h5>
|
||||
<div class="event-text"></div>
|
||||
</div>
|
||||
<div class="event-section" id="event-repeat">
|
||||
<h5 class="label"><roundcube:label name="calendar.repeat" /></h5>
|
||||
<div class="event-text"></div>
|
||||
</div>
|
||||
<div class="event-section" id="event-alarm">
|
||||
<h5 class="label"><roundcube:label name="calendar.alarms" /></h5>
|
||||
<div class="event-text"></div>
|
||||
</div>
|
||||
<div class="event-section" id="event-attendees">
|
||||
<h5 class="label"><roundcube:label name="calendar.tabattendees" /></h5>
|
||||
<div class="event-text"></div>
|
||||
</div>
|
||||
<div class="event-line" id="event-calendar">
|
||||
<label><roundcube:label name="calendar.calendar" /></label>
|
||||
<span class="event-text">Default</span>
|
||||
</div>
|
||||
<div class="event-line" id="event-category">
|
||||
<label><roundcube:label name="calendar.category" /></label>
|
||||
<span class="event-text"></span>
|
||||
</div>
|
||||
<div class="event-line" id="event-free-busy">
|
||||
<label><roundcube:label name="calendar.freebusy" /></label>
|
||||
<span class="event-text"></span>
|
||||
</div>
|
||||
<div class="event-line" id="event-priority">
|
||||
<label><roundcube:label name="calendar.priority" /></label>
|
||||
<span class="event-text"></span>
|
||||
</div>
|
||||
<div class="event-line" id="event-sensitivity">
|
||||
<label><roundcube:label name="calendar.sensitivity" /></label>
|
||||
<span class="event-text"></span>
|
||||
</div>
|
||||
<div class="event-section" id="event-attachments">
|
||||
<label><roundcube:label name="attachments" /></label>
|
||||
<div class="event-text attachments-list"></div>
|
||||
</div>
|
||||
|
||||
<roundcube:object name="plugin.event_rsvp_buttons" id="event-rsvp" style="display:none" />
|
||||
</div>
|
||||
|
||||
<roundcube:include file="/templates/eventedit.html" />
|
||||
|
||||
<div id="eventfreebusy" class="uidialog">
|
||||
<roundcube:object name="plugin.attendees_freebusy_table" id="attendees-freebusy-table" cellspacing="0" cellpadding="0" border="0" />
|
||||
|
||||
<div class="schedule-options">
|
||||
|
||||
<div class="schedule-buttons">
|
||||
<button id="shedule-freebusy-prev" title="<roundcube:label name='previouspage' />">◄</button><button id="shedule-freebusy-next" title="<roundcube:label name='nextpage' />">►</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="float:left; width:28em">
|
||||
<div class="form-section">
|
||||
<label for="schedule-startdate"><roundcube:label name="calendar.start" /></label>
|
||||
<input type="text" name="startdate" size="11" id="schedule-startdate" disabled="true" />
|
||||
<input type="text" name="starttime" size="6" id="schedule-starttime" disabled="true" />
|
||||
</div>
|
||||
<div class="form-section">
|
||||
<label for="schedule-enddate"><roundcube:label name="calendar.end" /></label>
|
||||
<input type="text" name="enddate" size="11" id="schedule-enddate" disabled="true" />
|
||||
<input type="text" name="endtime" size="6" id="schedule-endtime" disabled="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div style="float:left">
|
||||
<div class="schedule-find-buttons">
|
||||
<button id="shedule-find-prev">◄ <roundcube:label name="calendar.prevslot" /></button>
|
||||
<button id="shedule-find-next"><roundcube:label name="calendar.nextslot" /> ►</button>
|
||||
</div>
|
||||
<div class="schedule-options">
|
||||
<label><input type="checkbox" id="schedule-freebusy-workinghours" value="1" /><roundcube:label name="calendar.onlyworkinghours" /></label>
|
||||
</div>
|
||||
</div>
|
||||
<br style="clear:both;" />
|
||||
|
||||
<roundcube:include file="/templates/freebusylegend.html" />
|
||||
<div class="attendees-list">
|
||||
<span class="attendee organizer"><roundcube:label name="calendar.roleorganizer" /></span>
|
||||
<span class="attendee req-participant"><roundcube:label name="calendar.rolerequired" /></span>
|
||||
<span class="attendee opt-participant"><roundcube:label name="calendar.roleoptional" /></span>
|
||||
<span class="attendee chair"><roundcube:label name="calendar.rolechair" /></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="calendarform" class="uidialog">
|
||||
<roundcube:label name="loading" />
|
||||
</div>
|
||||
|
||||
<div id="eventsimport" class="uidialog">
|
||||
<roundcube:object name="plugin.events_import_form" id="events-import-form" uploadFieldSize="30" />
|
||||
</div>
|
||||
|
||||
<div id="calendarurlbox" class="uidialog">
|
||||
<p><roundcube:label name="calendar.showurldescription" /></p>
|
||||
<textarea id="calfeedurl" rows="2" readonly="readonly"></textarea>
|
||||
</div>
|
||||
|
||||
<div id="calendartoolbar">
|
||||
<roundcube:button command="addevent" type="link" class="buttonPas addevent" classAct="button addevent" classSel="button addeventSel" title="calendar.new_event" content=" " />
|
||||
<roundcube:button command="print" type="link" class="buttonPas print" classAct="button print" classSel="button printSel" title="calendar.print" content=" " />
|
||||
<roundcube:button command="export" type="link" class="buttonPas export" classAct="button export" classSel="button exportSel" title="calendar.export" content=" " />
|
||||
<roundcube:container name="toolbar" id="calendartoolbar" />
|
||||
</div>
|
||||
|
||||
<div id="quicksearchbar">
|
||||
<roundcube:button name="searchmenulink" id="searchmenulink" image="/images/icons/glass.png" />
|
||||
<roundcube:object name="plugin.searchform" id="quicksearchbox" />
|
||||
<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" />
|
||||
</div>
|
||||
|
||||
<roundcube:object name="plugin.calendar_css" />
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// use skin functions to handle popup-menus
|
||||
rcube_init_mail_ui();
|
||||
rcmail_ui.popups.calendaroptions = { id:'calendaroptionsmenu', above:1, obj:$('#calendaroptionsmenu') };
|
||||
|
||||
$(document).ready(function(e){
|
||||
// initialize sidebar toggle
|
||||
$('#calendarsidebartoggle').click(function() {
|
||||
var width = $(this).data('sidebarwidth');
|
||||
var offset = $(this).data('offset');
|
||||
var $sidebar = $('#calendarsidebar'), time = 250;
|
||||
|
||||
if ($sidebar.is(':visible')) {
|
||||
$sidebar.animate({ left:'-'+(width+10)+'px' }, time, function(){ $('#calendarsidebar').hide(); });
|
||||
$(this).animate({ left:'8px'}, time, function(){ $('#calendarsidebartoggle').addClass('sidebarclosed') });
|
||||
$('#calendar').animate({ left:'20px'}, time, function(){ $(this).fullCalendar('render'); });
|
||||
}
|
||||
else {
|
||||
$sidebar.show().animate({ left:'10px' }, time);
|
||||
$(this).animate({ left:offset+'px'}, time, function(){ $('#calendarsidebartoggle').removeClass('sidebarclosed'); });
|
||||
$('#calendar').animate({ left:(width+16)+'px'}, time, function(){ $(this).fullCalendar('render'); });
|
||||
}
|
||||
})
|
||||
.data('offset', $('#calendarsidebartoggle').position().left)
|
||||
.data('sidebarwidth', $('#calendarsidebar').width() + $('#calendarsidebar').position().left);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
108
skins/classic/templates/eventedit.html
Normal file
|
@ -0,0 +1,108 @@
|
|||
<div id="eventedit" class="uidialog">
|
||||
<form id="eventtabs" action="#" method="post" enctype="multipart/form-data">
|
||||
<ul>
|
||||
<li><a href="#event-tab-1"><roundcube:label name="calendar.tabsummary" /></a></li>
|
||||
<li id="edit-tab-recurrence"><a href="#event-tab-2"><roundcube:label name="calendar.tabrecurrence" /></a></li>
|
||||
<li id="edit-tab-attendees"><a href="#event-tab-3"><roundcube:label name="calendar.tabattendees" /></a></li>
|
||||
<li id="edit-tab-attachments"><a href="#event-tab-4"><roundcube:label name="calendar.tabattachments" /></a></li>
|
||||
</ul>
|
||||
<!-- basic info -->
|
||||
<div id="event-tab-1">
|
||||
<div class="event-section">
|
||||
<label for="edit-title"><roundcube:label name="calendar.title" /></label>
|
||||
<br />
|
||||
<input type="text" class="text" name="title" id="edit-title" size="40" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-location"><roundcube:label name="calendar.location" /></label>
|
||||
<br />
|
||||
<input type="text" class="text" name="location" id="edit-location" size="40" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-description"><roundcube:label name="calendar.description" /></label>
|
||||
<br />
|
||||
<textarea name="description" id="edit-description" class="text" rows="5" cols="40"></textarea>
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-url"><roundcube:label name="calendar.url" /></label>
|
||||
<br />
|
||||
<input type="text" class="text" name="vurl" id="edit-url" size="40" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label style="float:right;padding-right:0.5em"><input type="checkbox" name="allday" id="edit-allday" value="1" /><roundcube:label name="calendar.all-day" /></label>
|
||||
<label for="edit-startdate"><roundcube:label name="calendar.start" /></label>
|
||||
<input type="text" name="startdate" size="11" id="edit-startdate" />
|
||||
<input type="text" name="starttime" size="6" id="edit-starttime" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-enddate"><roundcube:label name="calendar.end" /></label>
|
||||
<input type="text" name="enddate" size="11" id="edit-enddate" />
|
||||
<input type="text" name="endtime" size="6" id="edit-endtime" />
|
||||
</div>
|
||||
<div class="event-section" id="edit-alarms">
|
||||
<label for="edit-alarm"><roundcube:label name="calendar.alarms" /></label>
|
||||
<roundcube:object name="plugin.alarm_select" />
|
||||
</div>
|
||||
<div class="event-section" id="calendar-select">
|
||||
<label for="edit-calendar"><roundcube:label name="calendar.calendar" /></label>
|
||||
<roundcube:object name="plugin.calendar_select" id="edit-calendar" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-categories"><roundcube:label name="calendar.category" /></label>
|
||||
<roundcube:object name="plugin.category_select" id="edit-categories" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-free-busy"><roundcube:label name="calendar.freebusy" /></label>
|
||||
<roundcube:object name="plugin.freebusy_select" id="edit-free-busy" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-priority"><roundcube:label name="calendar.priority" /></label>
|
||||
<roundcube:object name="plugin.priority_select" id="edit-priority" />
|
||||
</div>
|
||||
<div class="event-section">
|
||||
<label for="edit-sensitivity"><roundcube:label name="calendar.sensitivity" /></label>
|
||||
<roundcube:object name="plugin.sensitivity_select" id="edit-sensitivity" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- recurrence settings -->
|
||||
<div id="event-tab-2">
|
||||
<div class="event-section border-after">
|
||||
<roundcube:object name="plugin.recurrence_form" part="frequency" />
|
||||
</div>
|
||||
<div class="recurrence-form border-after" id="recurrence-form-daily">
|
||||
<roundcube:object name="plugin.recurrence_form" part="daily" class="event-section" />
|
||||
</div>
|
||||
<div class="recurrence-form border-after" id="recurrence-form-weekly">
|
||||
<roundcube:object name="plugin.recurrence_form" part="weekly" class="event-section" />
|
||||
</div>
|
||||
<div class="recurrence-form border-after" id="recurrence-form-monthly">
|
||||
<roundcube:object name="plugin.recurrence_form" part="monthly" class="event-section" />
|
||||
</div>
|
||||
<div class="recurrence-form border-after" id="recurrence-form-yearly">
|
||||
<roundcube:object name="plugin.recurrence_form" part="yearly" class="event-section" />
|
||||
</div>
|
||||
<div class="recurrence-form" id="recurrence-form-until">
|
||||
<roundcube:object name="plugin.recurrence_form" part="until" class="event-section" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- attendees list -->
|
||||
<div id="event-tab-3">
|
||||
<roundcube:object name="plugin.attendees_list" id="edit-attendees-table" cellspacing="0" cellpadding="0" border="0" />
|
||||
<roundcube:object name="plugin.attendees_form" id="edit-attendees-form" />
|
||||
<roundcube:include file="/templates/freebusylegend.html" />
|
||||
</div>
|
||||
<!-- attachments list (with upload form) -->
|
||||
<div id="event-tab-4">
|
||||
<div id="edit-attachments" class="attachments-list">
|
||||
<roundcube:object name="plugin.attachments_list" id="attachmentlist" deleteIcon="/images/icons/delete.png" cancelIcon="/images/icons/delete.png" loadingIcon="/images/display/loading_blue.gif" />
|
||||
</div>
|
||||
<div id="edit-attachments-form">
|
||||
<roundcube:object name="plugin.attachments_form" id="calendar-attachment-form" attachmentFieldSize="30" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<roundcube:object name="plugin.edit_attendees_notify" id="edit-attendees-notify" class="event-dialog-message" style="display:none" />
|
||||
<roundcube:object name="plugin.edit_recurring_warning" class="event-dialog-message edit-recurring-warning" style="display:none" />
|
||||
<div id="edit-localchanges-warning" class="event-dialog-message" style="display:none"><roundcube:label name="calendar.localchangeswarning" /></div>
|
||||
</div>
|
7
skins/classic/templates/freebusylegend.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div id="edit-attendees-legend" class="availability">
|
||||
<span class="legend"><img class="availabilityicon free" src="./program/resources/blank.gif" /> <roundcube:label name="calendar.availfree" /></span>
|
||||
<span class="legend"><img class="availabilityicon busy" src="./program/resources/blank.gif" /> <roundcube:label name="calendar.availbusy" /></span>
|
||||
<span class="legend"><img class="availabilityicon tentative" src="./program/resources/blank.gif" /> <roundcube:label name="calendar.availtentative" /></span>
|
||||
<span class="legend"><img class="availabilityicon out-of-office" src="./program/resources/blank.gif" /> <roundcube:label name="calendar.availoutofoffice" /></span>
|
||||
<span class="legend"><img class="availabilityicon unknown" src="./program/resources/blank.gif" /> <roundcube:label name="calendar.availunknown" /></span>
|
||||
</div>
|
21
skins/classic/templates/itipattend.html
Normal file
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
</head>
|
||||
<body class="calendaritipattend">
|
||||
|
||||
<roundcube:object name="logo" src="/images/roundcube_logo.png" id="logo" border="0" style="margin:0 11px" />
|
||||
|
||||
<roundcube:object name="message" id="message" />
|
||||
|
||||
<div class="centerbox">
|
||||
<roundcube:object name="plugin.event_inviteform" />
|
||||
<roundcube:object name="plugin.event_invitebox" class="calendar-invitebox" />
|
||||
<roundcube:object name="plugin.event_rsvp_buttons" type="submit" iname="rsvp" id="event-rsvp" />
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
13
skins/classic/templates/kolabacl.html
Normal file
|
@ -0,0 +1,13 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
<roundcube:include file="/includes/links.html" />
|
||||
<script type="text/javascript" src="/functions.js"></script>
|
||||
</head>
|
||||
<body class="iframe" style="background:#fff; margin:0">
|
||||
|
||||
<roundcube:object name="folderacl" />
|
||||
|
||||
</body>
|
||||
</html>
|
7
skins/classic/templates/kolabform.html
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div id="calendar-kolabform">
|
||||
<roundcube:object name="calendarform" />
|
||||
</div>
|
||||
<script type="text/javascript">rcube_init_tabs('calendar-kolabform');</script>
|
||||
<style type="text/css">
|
||||
#calendarpropform { min-width:680px }
|
||||
</style>
|
28
skins/classic/templates/print.html
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title><roundcube:object name="pagetitle" /></title>
|
||||
</head>
|
||||
<body class="calendarprint">
|
||||
|
||||
<div id="printconfig" class="noprint">
|
||||
<div class="calwidth">
|
||||
<a href="#close" onclick="window.close()" class="rightalign"><roundcube:label name="close" /></a>
|
||||
<span class="prop"><input type="button" id="printme" value="<roundcube:label name='print' />" onclick="window.print()"></span>
|
||||
<span class="prop"><label><input type="checkbox" id="propdescription" checked="checked" /> <roundcube:label name="calendar.printdescriptions" /></label></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<roundcube:object name="message" id="message" class="noprint" />
|
||||
|
||||
<div id="calendar" class="calwidth"></div>
|
||||
|
||||
<div class="calwidth">
|
||||
<roundcube:object name="plugin.calendar_list" activeonly="true" id="calendarlist" />
|
||||
</div>
|
||||
|
||||
<roundcube:object name="plugin.calendar_css" printmode="true" />
|
||||
|
||||
<!--[if lte IE 7]><link rel="stylesheet" type="text/css" href="./plugins/calendar/skins/classic/print.iehacks.css" /><![endif]-->
|
||||
</body>
|
||||
</html>
|
11
skins/larry/README
Normal file
|
@ -0,0 +1,11 @@
|
|||
Screendesign by FLINT / Büro für Gestaltung, Bern, Switzerland
|
||||
http://bueroflint.com
|
||||
|
||||
|
||||
LICENSE
|
||||
-------
|
||||
The contents of this folder are subject to the Creative Commons
|
||||
Attribution-ShareAlike License. It is allowed to copy, distribute,
|
||||
transmit and to adapt the work by keeping credits to the original
|
||||
autors in the README file.
|
||||
See http://creativecommons.org/licenses/by-sa/3.0/ for details.
|
1441
skins/larry/calendar.css
Normal file
724
skins/larry/fullcalendar.css
Normal file
|
@ -0,0 +1,724 @@
|
|||
/*
|
||||
* FullCalendar v1.5.4-rcube-0.9.0 Stylesheet
|
||||
*
|
||||
* Copyright (c) 2011 Adam Shaw
|
||||
* Copyright (c) 2011, Kolab Systems AG
|
||||
* Dual licensed under the MIT and GPL licenses, located in
|
||||
* MIT-LICENSE.txt and GPL-LICENSE.txt respectively.
|
||||
*
|
||||
* Date: Wed Nov 7 16:28:11 2012 +0100
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
.fc {
|
||||
direction: ltr;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
}
|
||||
|
||||
html .fc,
|
||||
.fc table {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.fc td,
|
||||
.fc th {
|
||||
padding: 0;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Header
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-header td {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc-header-left {
|
||||
width: 25%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.fc-header-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-header-right {
|
||||
width: 25%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-header-title {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.fc-header-title h2 {
|
||||
margin-top: 0;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.fc .fc-header-space {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.fc-header .fc-button {
|
||||
margin-bottom: 1em;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
/* buttons edges butting together */
|
||||
|
||||
.fc-header .fc-button {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.fc-header .fc-corner-right {
|
||||
margin-right: 1px; /* back to normal */
|
||||
}
|
||||
|
||||
.fc-header .ui-corner-right {
|
||||
margin-right: 0; /* back to normal */
|
||||
}
|
||||
|
||||
/* button layering (for border precedence) */
|
||||
|
||||
.fc-header .fc-state-hover,
|
||||
.fc-header .ui-state-hover {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.fc-header .fc-state-down {
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.fc-header .fc-state-active,
|
||||
.fc-header .ui-state-active {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Content
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-content {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.fc-view {
|
||||
width: 100%; /* needed for view switching (when view is absolute) */
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Cell Styles
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-widget-header, /* <th>, usually */
|
||||
.fc-widget-content { /* <td>, usually */
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.fc-state-highlight { /* <td> today cell */ /* TODO: add .fc-today to <th> */
|
||||
background: #ffc;
|
||||
}
|
||||
|
||||
.fc-cell-overlay { /* semi-transparent rectangle while dragging */
|
||||
background: #9cf;
|
||||
opacity: .2;
|
||||
filter: alpha(opacity=20); /* for IE */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Buttons
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-button {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.fc-state-default { /* non-theme */
|
||||
border-style: solid;
|
||||
border-width: 1px 0;
|
||||
}
|
||||
|
||||
.fc-button-inner {
|
||||
position: relative;
|
||||
float: left;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-state-default .fc-button-inner { /* non-theme */
|
||||
border-style: solid;
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-button-content {
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 1.9em;
|
||||
line-height: 1.9em;
|
||||
padding: 0 .6em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* icon (for jquery ui) */
|
||||
|
||||
.fc-button-content .fc-icon-wrap {
|
||||
position: relative;
|
||||
float: left;
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.fc-button-content .ui-icon {
|
||||
position: relative;
|
||||
float: left;
|
||||
margin-top: -50%;
|
||||
*margin-top: 0;
|
||||
*top: -50%;
|
||||
}
|
||||
|
||||
/* gloss effect */
|
||||
|
||||
.fc-state-default .fc-button-effect {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.fc-state-default .fc-button-effect span {
|
||||
position: absolute;
|
||||
top: -100px;
|
||||
left: 0;
|
||||
width: 500px;
|
||||
height: 100px;
|
||||
border-width: 100px 0 0 1px;
|
||||
border-style: solid;
|
||||
border-color: #fff;
|
||||
background: #444;
|
||||
opacity: .09;
|
||||
filter: alpha(opacity=9);
|
||||
}
|
||||
|
||||
/* button states (determines colors) */
|
||||
|
||||
.fc-state-default,
|
||||
.fc-state-default .fc-button-inner {
|
||||
border-style: solid;
|
||||
border-color: #ccc #bbb #aaa;
|
||||
background: #F3F3F3;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.fc-state-hover,
|
||||
.fc-state-hover .fc-button-inner {
|
||||
border-color: #999;
|
||||
}
|
||||
|
||||
.fc-state-down,
|
||||
.fc-state-down .fc-button-inner {
|
||||
border-color: #555;
|
||||
background: #777;
|
||||
}
|
||||
|
||||
.fc-state-active,
|
||||
.fc-state-active .fc-button-inner {
|
||||
border-color: #555;
|
||||
background: #777;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.fc-state-disabled,
|
||||
.fc-state-disabled .fc-button-inner {
|
||||
color: #999;
|
||||
border-color: #ddd;
|
||||
}
|
||||
|
||||
.fc-state-disabled {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.fc-state-disabled .fc-button-effect {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Global Event Styles
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event {
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
font-size: .85em;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
a.fc-event,
|
||||
.fc-event-draggable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a.fc-event {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-event {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.fc-event-skin {
|
||||
border-color: #36c; /* default BORDER color */
|
||||
background-color: #36c; /* default BACKGROUND color */
|
||||
color: #fff; /* default TEXT color */
|
||||
}
|
||||
|
||||
.fc-event-inner {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-style: solid;
|
||||
border-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-event-time,
|
||||
.fc-event-title {
|
||||
padding: 0 1px;
|
||||
}
|
||||
|
||||
.fc .ui-resizable-handle { /*** TODO: don't use ui-resizable anymore, change class ***/
|
||||
display: block;
|
||||
position: absolute;
|
||||
z-index: 99999;
|
||||
overflow: hidden; /* hacky spaces (IE6/7) */
|
||||
font-size: 300%; /* */
|
||||
line-height: 50%; /* */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Horizontal Events
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event-hori {
|
||||
border-width: 1px 0;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
/* resizable */
|
||||
|
||||
.fc-event-hori .ui-resizable-e {
|
||||
top: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||
right: -3px !important;
|
||||
width: 7px !important;
|
||||
height: 100% !important;
|
||||
cursor: e-resize;
|
||||
}
|
||||
|
||||
.fc-event-hori .ui-resizable-w {
|
||||
top: 0 !important;
|
||||
left: -3px !important;
|
||||
width: 7px !important;
|
||||
height: 100% !important;
|
||||
cursor: w-resize;
|
||||
}
|
||||
|
||||
.fc-event-hori .ui-resizable-handle {
|
||||
_padding-bottom: 14px; /* IE6 had 0 height */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fake Rounded Corners (for buttons and events)
|
||||
------------------------------------------------------------*/
|
||||
|
||||
.fc-corner-left {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-left .fc-button-inner,
|
||||
.fc-corner-left .fc-event-inner {
|
||||
margin-left: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-right {
|
||||
margin-right: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-right .fc-button-inner,
|
||||
.fc-corner-right .fc-event-inner {
|
||||
margin-right: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-top {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-top .fc-event-inner {
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom {
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom .fc-event-inner {
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Fake Rounded Corners SPECIFICALLY FOR EVENTS
|
||||
-----------------------------------------------------------------*/
|
||||
|
||||
.fc-corner-left .fc-event-inner {
|
||||
border-left-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-right .fc-event-inner {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-top .fc-event-inner {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.fc-corner-bottom .fc-event-inner {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Reusable Separate-border Table
|
||||
------------------------------------------------------------*/
|
||||
|
||||
table.fc-border-separate {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.fc-border-separate th,
|
||||
.fc-border-separate td {
|
||||
border-width: 1px 0 0 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate th.fc-last,
|
||||
.fc-border-separate td.fc-last {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate tr.fc-last th,
|
||||
.fc-border-separate tr.fc-last td {
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.fc-border-separate tbody tr.fc-first td,
|
||||
.fc-border-separate tbody tr.fc-first th {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Month View, Basic Week View, Basic Day View
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-grid th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-grid .fc-day-number {
|
||||
float: right;
|
||||
padding: 0 2px;
|
||||
}
|
||||
|
||||
.fc-grid .fc-other-month .fc-day-number {
|
||||
opacity: 0.3;
|
||||
filter: alpha(opacity=30); /* for IE */
|
||||
/* opacity with small font can sometimes look too faded
|
||||
might want to set the 'color' property instead
|
||||
making day-numbers bold also fixes the problem */
|
||||
}
|
||||
|
||||
.fc-grid .fc-day-content {
|
||||
clear: both;
|
||||
padding: 2px 2px 1px; /* distance between events and day edges */
|
||||
}
|
||||
|
||||
/* event styles */
|
||||
|
||||
.fc-grid .fc-event-time {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* right-to-left */
|
||||
|
||||
.fc-rtl .fc-grid .fc-day-number {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.fc-rtl .fc-grid .fc-event-time {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.fc-more-link {
|
||||
font-size: 0.85em;
|
||||
white-space: nowrap;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
padding: 1px;
|
||||
}
|
||||
|
||||
/* Agenda Week View, Agenda Day View
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-agenda table {
|
||||
border-collapse: separate;
|
||||
}
|
||||
|
||||
.fc-agenda-days th {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.fc-agenda .fc-agenda-axis {
|
||||
width: 50px;
|
||||
padding: 0 4px;
|
||||
vertical-align: middle;
|
||||
text-align: right;
|
||||
white-space: nowrap;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.fc-agenda .fc-day-content {
|
||||
padding: 2px 2px 1px;
|
||||
}
|
||||
|
||||
/* make axis border take precedence */
|
||||
|
||||
.fc-agenda-days .fc-agenda-axis {
|
||||
border-right-width: 1px;
|
||||
}
|
||||
|
||||
.fc-agenda-days .fc-col0 {
|
||||
border-left-width: 0;
|
||||
}
|
||||
|
||||
/* all-day area */
|
||||
|
||||
.fc-agenda-allday th {
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-agenda-allday .fc-day-content {
|
||||
min-height: 34px; /* TODO: doesnt work well in quirksmode */
|
||||
_height: 34px;
|
||||
}
|
||||
|
||||
/* divider (between all-day and slots) */
|
||||
|
||||
.fc-agenda-divider-inner {
|
||||
height: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-widget-header .fc-agenda-divider-inner {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
/* slot rows */
|
||||
|
||||
.fc-agenda-slots th {
|
||||
border-width: 1px 1px 0;
|
||||
}
|
||||
|
||||
.fc-agenda-slots td {
|
||||
border-width: 1px 0 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
.fc-agenda-slots td div {
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-slot0 th,
|
||||
.fc-agenda-slots tr.fc-slot0 td {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-minor th,
|
||||
.fc-agenda-slots tr.fc-minor td {
|
||||
border-top-style: dotted;
|
||||
}
|
||||
|
||||
.fc-agenda-slots tr.fc-minor th.ui-widget-header {
|
||||
*border-top-style: solid; /* doesn't work with background in IE6/7 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Vertical Events
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-event-vert {
|
||||
border-width: 0 1px;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-head,
|
||||
.fc-event-vert .fc-event-content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-time {
|
||||
white-space: nowrap;
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.fc-event-vert .fc-event-bg { /* makes the event lighter w/ a semi-transparent overlay */
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fff;
|
||||
opacity: .3;
|
||||
filter: alpha(opacity=30);
|
||||
}
|
||||
|
||||
.fc .ui-draggable-dragging .fc-event-bg, /* TODO: something nicer like .fc-opacity */
|
||||
.fc-select-helper .fc-event-bg {
|
||||
display: none\9; /* for IE6/7/8. nested opacity filters while dragging don't work */
|
||||
}
|
||||
|
||||
/* resizable */
|
||||
|
||||
.fc-event-vert .ui-resizable-s {
|
||||
bottom: 0 !important; /* importants override pre jquery ui 1.7 styles */
|
||||
width: 100% !important;
|
||||
height: 8px !important;
|
||||
overflow: hidden !important;
|
||||
line-height: 8px !important;
|
||||
font-size: 11px !important;
|
||||
font-family: monospace;
|
||||
text-align: center;
|
||||
cursor: s-resize;
|
||||
}
|
||||
|
||||
.fc-agenda .ui-resizable-resizing { /* TODO: better selector */
|
||||
_overflow: hidden;
|
||||
}
|
||||
|
||||
.fc-timeline {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-top: 2px solid #3ec400;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* List view (by bruederli@kolabsys.com)
|
||||
------------------------------------------------------------------------*/
|
||||
|
||||
.fc-view-list,
|
||||
.fc-view-table {
|
||||
border: 1px solid #ccc;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-list-header,
|
||||
.fc-view-table td.fc-list-header {
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
padding: 3px 5px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-first td.fc-list-header {
|
||||
border-top-width: 0;
|
||||
}
|
||||
|
||||
.fc-list-section {
|
||||
padding: 4px 2px;
|
||||
border-width: 0;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
|
||||
.fc-view-list .fc-last {
|
||||
border-bottom-width: 0;
|
||||
}
|
||||
|
||||
.fc-list-section .fc-event {
|
||||
position: relative;
|
||||
margin: 1px 2px 3px 2px;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td {
|
||||
padding: 2px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.fc-view-table tr.fc-event td.fc-event-handle {
|
||||
padding: 3px 8px 3px 3px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-skin {
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-event-handle .fc-event-inner {
|
||||
display: block;
|
||||
width: 8px;
|
||||
height: 10px;
|
||||
border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
}
|
||||
|
||||
.fc-view-table table {
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-handle {
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
.fc-event-handle .fc-event-inner {
|
||||
border-color: inherit;
|
||||
background-color: inherit;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-date {
|
||||
width: 7em;
|
||||
}
|
||||
|
||||
.fc-view-table .fc-list-day col.fc-event-date {
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.fc-view-table col.fc-event-time {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.fc-view-table td.fc-event-date,
|
||||
.fc-view-table td.fc-event-time {
|
||||
white-space: nowrap;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
77
skins/larry/iehacks.css
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* CSS hacks for IE 7 */
|
||||
|
||||
#calendarsidebar,
|
||||
#calendarsidebartoggle {
|
||||
height: expression((parseInt(this.parentNode.offsetHeight)-37)+'px');
|
||||
}
|
||||
|
||||
#calendar {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-parseInt(document.getElementById('calendarsidebartoggle').offsetWidth)-parseInt(document.getElementById('calendarsidebartoggle').offsetLeft)-4)+'px');
|
||||
height: expression((parseInt(this.parentNode.offsetHeight)-30)+'px');
|
||||
}
|
||||
|
||||
#calendars {
|
||||
height: expression((parseInt(this.parentNode.offsetHeight)-240)+'px');
|
||||
}
|
||||
|
||||
#agendaoptions {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-12)+'px');
|
||||
}
|
||||
|
||||
#calendartoolbar a.buttonPas {
|
||||
filter: alpha(opacity=35);
|
||||
}
|
||||
|
||||
#datepicker a.ui-priority-secondary {
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
.calendarmain .fc-day-content {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.calendarmain .fc-view-table col.fc-event-date {
|
||||
width: 8em;
|
||||
}
|
||||
|
||||
.calendarmain .fc-view-table col.fc-event-time {
|
||||
width: 9em;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-title h2 {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-left {
|
||||
width: 248px;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-center {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.calendarmain .fc-header-right {
|
||||
width: 144px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.calendarmain .fc-event-temp .fc-event-bg {
|
||||
display: none; /* nested opacity filters while dragging don't work */
|
||||
}
|
||||
|
||||
#schedule-event-time {
|
||||
filter: alpha(opacity=40);
|
||||
}
|
||||
|
||||
#eventfreebusy .schedule-buttons,
|
||||
#edit-attendees-form #edit-attendee-schedule {
|
||||
right: 0.6em;
|
||||
}
|
||||
|
||||
#schedule-freebusy-times tr.times td.allday {
|
||||
width: expression(Math.max(60, parseInt(this.offsetWidth))+'px');
|
||||
}
|
||||
|
||||
.ui-dialog .ui-dialog-titlebar {
|
||||
width: expression((parseInt(this.parentNode.offsetWidth)-26)+'px');
|
||||
}
|