Initial commit.
This commit is contained in:
commit
128a49ddde
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
build
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
calcmosaic.jar
|
69
HISTORY
Normal file
69
HISTORY
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
The story of CalcMosaic:
|
||||||
|
|
||||||
|
===================================================================
|
||||||
|
Villeroy's work inspired me the idea to pass the color value to
|
||||||
|
the BASIC macros in order to run faster.
|
||||||
|
|
||||||
|
http://forum.openoffice.org/en/forum/viewtopic.php?f=49&t=55857
|
||||||
|
|
||||||
|
But in the end I still cannot understand Villeroy's code. He
|
||||||
|
uses styles which I believe is faster. But it runs in a different
|
||||||
|
way than my Calc Mosaic. I cannot adapt his method. Also, I really
|
||||||
|
can not understand how the data work for his horse. He is so smart.
|
||||||
|
|
||||||
|
Here is my own version. It is 8 times faster than the previous
|
||||||
|
version. Now I learned how to inject and run OpenOffice BASIC macros
|
||||||
|
with Java UNO. I also learned that each Java UNO command triggers a
|
||||||
|
display refresh, which is costly. OpenOffice BASIC macros does not
|
||||||
|
trigger refresh, which is why it is faster.
|
||||||
|
|
||||||
|
Thanks for the people in the OpenOffice track of ApacheCon EU
|
||||||
|
2012, that I have a chance to review my code, rewrite it and
|
||||||
|
demostrate it.
|
||||||
|
|
||||||
|
imacat ^_*'
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2012-10-08
|
||||||
|
|
||||||
|
===================================================================
|
||||||
|
The origin of this is a video "Stop-Motion Excel" posted on
|
||||||
|
YouTube on 2012-08-09.
|
||||||
|
|
||||||
|
http://www.youtube.com/watch?v=Fq9EV2fYF2E
|
||||||
|
|
||||||
|
This video quickly caught the media discusussion. Not only
|
||||||
|
because it is cool, but also that viewers found the author is not
|
||||||
|
using Excel, but OpenOffice Calc. This draw a discussion in the
|
||||||
|
OpenOffice development list, too. After watching the video, I feel I
|
||||||
|
can do it programmatically.
|
||||||
|
|
||||||
|
http://www.youtube.com/watch?v=AlA7HFwxDSU
|
||||||
|
|
||||||
|
(The original Apple iPod Ad)
|
||||||
|
|
||||||
|
http://www.youtube.com/watch?v=NlHUz99l-eo
|
||||||
|
|
||||||
|
And then I presented it in the lightning talk in COSCUP 2012
|
||||||
|
Taiwan a week after, on 2012-08-18.
|
||||||
|
|
||||||
|
http://www.youtube.com/watch?v=tEhz0zNmTFQ
|
||||||
|
|
||||||
|
The files used in the presentation is here for download. ^_*'
|
||||||
|
|
||||||
|
http://people.apache.org/~imacat/stop-motion-calc.zip
|
||||||
|
|
||||||
|
There is a hidden black button at A1 of the first sheet. Click
|
||||||
|
on the button to start the animation.
|
||||||
|
|
||||||
|
It seems that the talk without talk and the fresh-typed
|
||||||
|
presentation is too cool that many people did not notice what I
|
||||||
|
presented. :p But it helps to fill up the room when I presented an
|
||||||
|
introduction to Apache OpenOffice 3.4 the next day.
|
||||||
|
|
||||||
|
Welcome to download and try Calc Mosaic.
|
||||||
|
|
||||||
|
Hope you like it! Your comment is welcome! ^_*'
|
||||||
|
|
||||||
|
imacat ^_*'
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2012-08-24
|
611
LICENSE
Normal file
611
LICENSE
Normal file
@ -0,0 +1,611 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
APACHE HTTP SERVER SUBCOMPONENTS:
|
||||||
|
|
||||||
|
The Apache HTTP Server includes a number of subcomponents with
|
||||||
|
separate copyright notices and license terms. Your use of the source
|
||||||
|
code for the these subcomponents is subject to the terms and
|
||||||
|
conditions of the following licenses.
|
||||||
|
|
||||||
|
For the mod_mime_magic component:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mod_mime_magic: MIME type lookup via file magic numbers
|
||||||
|
* Copyright (c) 1996-1997 Cisco Systems, Inc.
|
||||||
|
*
|
||||||
|
* This software was submitted by Cisco Systems to the Apache Group in July
|
||||||
|
* 1997. Future revisions and derivatives of this source code must
|
||||||
|
* acknowledge Cisco Systems as the original contributor of this module.
|
||||||
|
* All other licensing and usage conditions are those of the Apache Group.
|
||||||
|
*
|
||||||
|
* Some of this code is derived from the free version of the file command
|
||||||
|
* originally posted to comp.sources.unix. Copyright info for that program
|
||||||
|
* is included below as required.
|
||||||
|
* ---------------------------------------------------------------------------
|
||||||
|
* - Copyright (c) Ian F. Darwin, 1987. Written by Ian F. Darwin.
|
||||||
|
*
|
||||||
|
* This software is not subject to any license of the American Telephone and
|
||||||
|
* Telegraph Company or of the Regents of the University of California.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose on any
|
||||||
|
* computer system, and to alter it and redistribute it freely, subject to
|
||||||
|
* the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The author is not responsible for the consequences of use of this
|
||||||
|
* software, no matter how awful, even if they arise from flaws in it.
|
||||||
|
*
|
||||||
|
* 2. The origin of this software must not be misrepresented, either by
|
||||||
|
* explicit claim or by omission. Since few users ever read sources, credits
|
||||||
|
* must appear in the documentation.
|
||||||
|
*
|
||||||
|
* 3. Altered versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software. Since few users ever read
|
||||||
|
* sources, credits must appear in the documentation.
|
||||||
|
*
|
||||||
|
* 4. This notice may not be removed or altered.
|
||||||
|
* -------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
For the modules\mappers\mod_imagemap.c component:
|
||||||
|
|
||||||
|
"macmartinized" polygon code copyright 1992 by Eric Haines, erich@eye.com
|
||||||
|
|
||||||
|
For the server\util_md5.c component:
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* NCSA HTTPd Server
|
||||||
|
* Software Development Group
|
||||||
|
* National Center for Supercomputing Applications
|
||||||
|
* University of Illinois at Urbana-Champaign
|
||||||
|
* 605 E. Springfield, Champaign, IL 61820
|
||||||
|
* httpd@ncsa.uiuc.edu
|
||||||
|
*
|
||||||
|
* Copyright (C) 1995, Board of Trustees of the University of Illinois
|
||||||
|
*
|
||||||
|
************************************************************************
|
||||||
|
*
|
||||||
|
* md5.c: NCSA HTTPd code which uses the md5c.c RSA Code
|
||||||
|
*
|
||||||
|
* Original Code Copyright (C) 1994, Jeff Hostetler, Spyglass, Inc.
|
||||||
|
* Portions of Content-MD5 code Copyright (C) 1993, 1994 by Carnegie Mellon
|
||||||
|
* University (see Copyright below).
|
||||||
|
* Portions of Content-MD5 code Copyright (C) 1991 Bell Communications
|
||||||
|
* Research, Inc. (Bellcore) (see Copyright below).
|
||||||
|
* Portions extracted from mpack, John G. Myers - jgm+@cmu.edu
|
||||||
|
* Content-MD5 Code contributed by Martin Hamilton (martin@net.lut.ac.uk)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/* these portions extracted from mpack, John G. Myers - jgm+@cmu.edu */
|
||||||
|
/* (C) Copyright 1993,1994 by Carnegie Mellon University
|
||||||
|
* All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this software
|
||||||
|
* and its documentation for any purpose is hereby granted without
|
||||||
|
* fee, provided that the above copyright notice appear in all copies
|
||||||
|
* and that both that copyright notice and this permission notice
|
||||||
|
* appear in supporting documentation, and that the name of Carnegie
|
||||||
|
* Mellon University not be used in advertising or publicity
|
||||||
|
* pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. Carnegie Mellon University makes no
|
||||||
|
* representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||||
|
* THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
* AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
|
||||||
|
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||||
|
* SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1991 Bell Communications Research, Inc. (Bellcore)
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this material
|
||||||
|
* for any purpose and without fee is hereby granted, provided
|
||||||
|
* that the above copyright notice and this permission notice
|
||||||
|
* appear in all copies, and that the name of Bellcore not be
|
||||||
|
* used in advertising or publicity pertaining to this
|
||||||
|
* material without the specific, prior written permission
|
||||||
|
* of an authorized representative of Bellcore. BELLCORE
|
||||||
|
* MAKES NO REPRESENTATIONS ABOUT THE ACCURACY OR SUITABILITY
|
||||||
|
* OF THIS MATERIAL FOR ANY PURPOSE. IT IS PROVIDED "AS IS",
|
||||||
|
* WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the srclib\apr\include\apr_md5.h component:
|
||||||
|
/*
|
||||||
|
* This is work is derived from material Copyright RSA Data Security, Inc.
|
||||||
|
*
|
||||||
|
* The RSA copyright statement and Licence for that original material is
|
||||||
|
* included below. This is followed by the Apache copyright statement and
|
||||||
|
* licence for the modifications made to that material.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted provided that it
|
||||||
|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
License is also granted to make and use derivative works provided
|
||||||
|
that such works are identified as "derived from the RSA Data
|
||||||
|
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||||
|
mentioning or referencing the derived work.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the srclib\apr\passwd\apr_md5.c component:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is work is derived from material Copyright RSA Data Security, Inc.
|
||||||
|
*
|
||||||
|
* The RSA copyright statement and Licence for that original material is
|
||||||
|
* included below. This is followed by the Apache copyright statement and
|
||||||
|
* licence for the modifications made to that material.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
rights reserved.
|
||||||
|
|
||||||
|
License to copy and use this software is granted provided that it
|
||||||
|
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||||
|
Algorithm" in all material mentioning or referencing this software
|
||||||
|
or this function.
|
||||||
|
|
||||||
|
License is also granted to make and use derivative works provided
|
||||||
|
that such works are identified as "derived from the RSA Data
|
||||||
|
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||||
|
mentioning or referencing the derived work.
|
||||||
|
|
||||||
|
RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
the merchantability of this software or the suitability of this
|
||||||
|
software for any particular purpose. It is provided "as is"
|
||||||
|
without express or implied warranty of any kind.
|
||||||
|
|
||||||
|
These notices must be retained in any copies of any part of this
|
||||||
|
documentation and/or software.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* The apr_md5_encode() routine uses much code obtained from the FreeBSD 3.0
|
||||||
|
* MD5 crypt() function, which is licenced as follows:
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
||||||
|
* <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
|
||||||
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
||||||
|
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the srclib\apr-util\crypto\apr_md4.c component:
|
||||||
|
|
||||||
|
* This is derived from material copyright RSA Data Security, Inc.
|
||||||
|
* Their notice is reproduced below in its entirety.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
* rights reserved.
|
||||||
|
*
|
||||||
|
* License to copy and use this software is granted provided that it
|
||||||
|
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
|
||||||
|
* Algorithm" in all material mentioning or referencing this software
|
||||||
|
* or this function.
|
||||||
|
*
|
||||||
|
* License is also granted to make and use derivative works provided
|
||||||
|
* that such works are identified as "derived from the RSA Data
|
||||||
|
* Security, Inc. MD4 Message-Digest Algorithm" in all material
|
||||||
|
* mentioning or referencing the derived work.
|
||||||
|
*
|
||||||
|
* RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
* the merchantability of this software or the suitability of this
|
||||||
|
* software for any particular purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty of any kind.
|
||||||
|
*
|
||||||
|
* These notices must be retained in any copies of any part of this
|
||||||
|
* documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the srclib\apr-util\include\apr_md4.h component:
|
||||||
|
|
||||||
|
*
|
||||||
|
* This is derived from material copyright RSA Data Security, Inc.
|
||||||
|
* Their notice is reproduced below in its entirety.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||||
|
* rights reserved.
|
||||||
|
*
|
||||||
|
* License to copy and use this software is granted provided that it
|
||||||
|
* is identified as the "RSA Data Security, Inc. MD4 Message-Digest
|
||||||
|
* Algorithm" in all material mentioning or referencing this software
|
||||||
|
* or this function.
|
||||||
|
*
|
||||||
|
* License is also granted to make and use derivative works provided
|
||||||
|
* that such works are identified as "derived from the RSA Data
|
||||||
|
* Security, Inc. MD4 Message-Digest Algorithm" in all material
|
||||||
|
* mentioning or referencing the derived work.
|
||||||
|
*
|
||||||
|
* RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
* the merchantability of this software or the suitability of this
|
||||||
|
* software for any particular purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty of any kind.
|
||||||
|
*
|
||||||
|
* These notices must be retained in any copies of any part of this
|
||||||
|
* documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
For the srclib\apr-util\test\testmd4.c component:
|
||||||
|
|
||||||
|
*
|
||||||
|
* This is derived from material copyright RSA Data Security, Inc.
|
||||||
|
* Their notice is reproduced below in its entirety.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
|
||||||
|
* rights reserved.
|
||||||
|
*
|
||||||
|
* RSA Data Security, Inc. makes no representations concerning either
|
||||||
|
* the merchantability of this software or the suitability of this
|
||||||
|
* software for any particular purpose. It is provided "as is"
|
||||||
|
* without express or implied warranty of any kind.
|
||||||
|
*
|
||||||
|
* These notices must be retained in any copies of any part of this
|
||||||
|
* documentation and/or software.
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the srclib\apr-util\xml\expat\conftools\install-sh component:
|
||||||
|
|
||||||
|
#
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||||
|
#
|
||||||
|
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
# documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
# the above copyright notice appear in all copies and that both that
|
||||||
|
# copyright notice and this permission notice appear in supporting
|
||||||
|
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||||
|
# publicity pertaining to distribution of the software without specific,
|
||||||
|
# written prior permission. M.I.T. makes no representations about the
|
||||||
|
# suitability of this software for any purpose. It is provided "as is"
|
||||||
|
# without express or implied warranty.
|
||||||
|
#
|
||||||
|
|
||||||
|
For the srclib\pcre\install-sh component:
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
# documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
# the above copyright notice appear in all copies and that both that
|
||||||
|
# copyright notice and this permission notice appear in supporting
|
||||||
|
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||||
|
# publicity pertaining to distribution of the software without specific,
|
||||||
|
# written prior permission. M.I.T. makes no representations about the
|
||||||
|
# suitability of this software for any purpose. It is provided "as is"
|
||||||
|
# without express or implied warranty.
|
||||||
|
|
||||||
|
For the pcre component:
|
||||||
|
|
||||||
|
PCRE LICENCE
|
||||||
|
------------
|
||||||
|
|
||||||
|
PCRE is a library of functions to support regular expressions whose syntax
|
||||||
|
and semantics are as close as possible to those of the Perl 5 language.
|
||||||
|
|
||||||
|
Release 5 of PCRE is distributed under the terms of the "BSD" licence, as
|
||||||
|
specified below. The documentation for PCRE, supplied in the "doc"
|
||||||
|
directory, is distributed under the same terms as the software itself.
|
||||||
|
|
||||||
|
Written by: Philip Hazel <ph10@cam.ac.uk>
|
||||||
|
|
||||||
|
University of Cambridge Computing Service,
|
||||||
|
Cambridge, England. Phone: +44 1223 334714.
|
||||||
|
|
||||||
|
Copyright (c) 1997-2004 University of Cambridge
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the University of Cambridge nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived from
|
||||||
|
this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
End PCRE LICENCE
|
||||||
|
|
||||||
|
|
||||||
|
For the test\zb.c component:
|
||||||
|
|
||||||
|
/* ZeusBench V1.01
|
||||||
|
===============
|
||||||
|
|
||||||
|
This program is Copyright (C) Zeus Technology Limited 1996.
|
||||||
|
|
||||||
|
This program may be used and copied freely providing this copyright notice
|
||||||
|
is not removed.
|
||||||
|
|
||||||
|
This software is provided "as is" and any express or implied waranties,
|
||||||
|
including but not limited to, the implied warranties of merchantability and
|
||||||
|
fitness for a particular purpose are disclaimed. In no event shall
|
||||||
|
Zeus Technology Ltd. be liable for any direct, indirect, incidental, special,
|
||||||
|
exemplary, or consequential damaged (including, but not limited to,
|
||||||
|
procurement of substitute good or services; loss of use, data, or profits;
|
||||||
|
or business interruption) however caused and on theory of liability. Whether
|
||||||
|
in contract, strict liability or tort (including negligence or otherwise)
|
||||||
|
arising in any way out of the use of this software, even if advised of the
|
||||||
|
possibility of such damage.
|
||||||
|
|
||||||
|
Written by Adam Twiss (adam@zeus.co.uk). March 1996
|
||||||
|
|
||||||
|
Thanks to the following people for their input:
|
||||||
|
Mike Belshe (mbelshe@netscape.com)
|
||||||
|
Michael Campanella (campanella@stevms.enet.dec.com)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
For the expat xml parser component:
|
||||||
|
|
||||||
|
Copyright (c) 1998, 1999, 2000 Thai Open Source Software Center Ltd
|
||||||
|
and Clark Cooper
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included
|
||||||
|
in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
====================================================================
|
70
NEWS
Normal file
70
NEWS
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
NEWS in calcmosaic
|
||||||
|
|
||||||
|
2.1.0
|
||||||
|
* Better user interface processing: Added an icon, shortcut keys,
|
||||||
|
button focus, enter key, the number of chosen files, etc.
|
||||||
|
* Added information and WinJava64.reg for the problem running on
|
||||||
|
MS Windows 64-bit with 64-bit Java JRE. See:
|
||||||
|
https://issues.apache.org/ooo/show_bug.cgi?id=121258
|
||||||
|
|
||||||
|
2.0.0
|
||||||
|
* You can run calcmosaic.jar from the file manager. An
|
||||||
|
option dialog was added to obtain the options with GUI.
|
||||||
|
* You can now run in the 0.x mode that paint the mosaic sheet cell
|
||||||
|
by cell, for presentation, by using the -slow switch.
|
||||||
|
* Better localized in Traditional Chinese.
|
||||||
|
* Errors are better handled. Error messages are shown in either
|
||||||
|
STDERR or message box automatically. Errors reading from
|
||||||
|
non-image files are handled.
|
||||||
|
* The end-of-run message will not block for the user input when
|
||||||
|
running from console.
|
||||||
|
* An API to return mosaic color data is added.
|
||||||
|
* Many minor fixes.
|
||||||
|
|
||||||
|
1.0.3
|
||||||
|
* Fixed build.xml includeantruntime warning.
|
||||||
|
* Changed case of thisComponent to ThisComponent.
|
||||||
|
|
||||||
|
1.0.2
|
||||||
|
* Fixed Javadoc problems.
|
||||||
|
|
||||||
|
1.0.1
|
||||||
|
* Removed unused algorithms to calculate the mosaic cell color.
|
||||||
|
|
||||||
|
1.0.0
|
||||||
|
* Rewritten to be faster (about 8 times faster). Most of
|
||||||
|
program is now OpenOffice BASIC. The Java program actually
|
||||||
|
injects OpenOffice BASIC macros into the document and run it.
|
||||||
|
Unlike Java UNO, OpenOffice BASIC does not refresh the display
|
||||||
|
for each UNO command. The execution is now a LOT faster.
|
||||||
|
* Added the play script and the start buttons, to help playing
|
||||||
|
the spreadsheet stop-motion.
|
||||||
|
|
||||||
|
0.2.1
|
||||||
|
* Added a maximum check for the number of images used. This
|
||||||
|
users from errors after hours of work of conversion.
|
||||||
|
* Added HISTORY for the story behind Calc Mosaic.
|
||||||
|
* Added explanation for the FFMPEG command to use for grabbing
|
||||||
|
snapshots.
|
||||||
|
|
||||||
|
0.2.0
|
||||||
|
* Added the ability to convert multiple images.
|
||||||
|
* Added the ability to calculate the mosaic cell size
|
||||||
|
automatically.
|
||||||
|
* Added command line options and help.
|
||||||
|
* Changed the option mosaic cell size to maximum number of
|
||||||
|
rows to use, to make it easier (and more meaningful) to
|
||||||
|
the users.
|
||||||
|
* Changed the algorithm to calculate the color of the mosaic
|
||||||
|
cell, to have sharper result on the edges.
|
||||||
|
|
||||||
|
0.1.2
|
||||||
|
* 0.1.1 mistakenly packaged 0.1.0 along with 0.1.1, and this is
|
||||||
|
fixed.
|
||||||
|
|
||||||
|
0.1.1
|
||||||
|
* License changed from GPLv3 to Apache License v2.
|
||||||
|
|
||||||
|
0.1.0
|
||||||
|
* Initial release
|
||||||
|
|
66
README
Normal file
66
README
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
Calc Mosaic README
|
||||||
|
|
||||||
|
|
||||||
|
INTRODUCTION
|
||||||
|
|
||||||
|
Calc Mosaic is a program to create mosaic art from images with
|
||||||
|
OpenOffice Calc. This can be used to create cool stop motion movies.
|
||||||
|
|
||||||
|
See HISTORY for the story behind Calc Mosaic.
|
||||||
|
|
||||||
|
|
||||||
|
COMPILATION
|
||||||
|
|
||||||
|
You need JDK, Apache ANT and OpenOffice SDK in order to compile
|
||||||
|
this program.
|
||||||
|
|
||||||
|
You need juh.jar, jurt.jar, ridl.jar and unoil.jar in order to
|
||||||
|
compile the source. They can be found in OpenOffice SDK.
|
||||||
|
|
||||||
|
${OpenOffice Installation}/ure/share/java/juh.jar
|
||||||
|
${OpenOffice Installation}/ure/share/java/jurt.jar
|
||||||
|
${OpenOffice Installation}/ure/share/java/ridl.jar
|
||||||
|
${OpenOffice Installation}/basis3.4/program/classes/unoil.jar
|
||||||
|
|
||||||
|
Just copy them into the lib/ directory and they will work. Also
|
||||||
|
You may want to review the property value of ooo.dir.sdk-classes in
|
||||||
|
build.xml.
|
||||||
|
|
||||||
|
To compile, simply type "ant compile". Type "ant jar" will
|
||||||
|
create the jar file. Type "ant help" for more information.
|
||||||
|
|
||||||
|
Alternatively, there is a pre-compiled jar file here within
|
||||||
|
the distribution.
|
||||||
|
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
|
||||||
|
Type "java -jar calcmosaic.jar -help" to display a simple help.
|
||||||
|
|
||||||
|
The snapshots of a video can be grabbed using ffmpeg:
|
||||||
|
|
||||||
|
ffmpeg -i video.mp4 -r <framerate> -sameq -y -f image2 img%04d.jpg
|
||||||
|
|
||||||
|
Note that a spreadsheet document can only contain at most 256
|
||||||
|
spreadsheets.
|
||||||
|
|
||||||
|
Save file first for the macro to work.
|
||||||
|
|
||||||
|
Hit the start button at A1 of the first and last sheet to play
|
||||||
|
the sheets.
|
||||||
|
|
||||||
|
You can set the break time (in milliseconds) between sheets at
|
||||||
|
B1 of the first sheet (default 100 ms).
|
||||||
|
|
||||||
|
You can set the background music at C1 of the first sheet. This
|
||||||
|
only works on Linux and you must install mplayer. Relative file path
|
||||||
|
is relative to the document file. Play once before your live show to
|
||||||
|
avoid the I/O delay with cache.
|
||||||
|
|
||||||
|
If you found problem running on Windows X64, see Windows-x64.txt.
|
||||||
|
|
||||||
|
Hope you like it! ^_*'
|
||||||
|
|
||||||
|
imacat ^_*'
|
||||||
|
imacat@mail.imacat.idv.tw
|
||||||
|
2012-08-24
|
BIN
WinJava64.reg
Normal file
BIN
WinJava64.reg
Normal file
Binary file not shown.
42
Windows-x64.txt
Normal file
42
Windows-x64.txt
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
Information running on Windows x64
|
||||||
|
|
||||||
|
If you are running on MS Windows x64, you might not be able to
|
||||||
|
run calcmosaic.jar just by double-clicking it. If you go to the
|
||||||
|
command line and run:
|
||||||
|
|
||||||
|
java -jar calcmosaic.jar
|
||||||
|
|
||||||
|
You may see the following error message
|
||||||
|
|
||||||
|
Exception in thread "main" java.lang.UnsatisfiedLinkError:
|
||||||
|
C:\Users\<login>\AppData\Local\Temp\unowinreg1072712583236131558.dll:
|
||||||
|
Can't load IA 32-bit .dll on a AMD 64-bit platform
|
||||||
|
|
||||||
|
(If you do not experience such problem, that is fine.)
|
||||||
|
|
||||||
|
The reason behind this is that, the unowinreg.dll shipped with
|
||||||
|
OpenOffice SDK to find and run OpenOffice has only a 32-bit version,
|
||||||
|
which cannot be run with your 64-bit Java VM. Currently 64-bit
|
||||||
|
unowinreg.dll is not available yet. This has already been reported:
|
||||||
|
|
||||||
|
https://issues.apache.org/ooo/show_bug.cgi?id=121258
|
||||||
|
|
||||||
|
You may try one of the following workarounds:
|
||||||
|
|
||||||
|
1. Install 32-bit Java JRE on top of your 64-bit Java JRE.
|
||||||
|
|
||||||
|
2. If you already have 32-bit Java JRE and 64-bit Java JRE installed
|
||||||
|
together, with 64-bit Java JRE on top of 32-bit Java JRE, you
|
||||||
|
may run from the command line with full path:
|
||||||
|
|
||||||
|
"C:\Program Files (x86)\Java\jre7\bin\java.exe" -jar calcmosaic.jar
|
||||||
|
|
||||||
|
Alternatively, you may install WinJava64.reg that come with
|
||||||
|
this package. This will change the file association so that
|
||||||
|
.jar files will be run with 32-bit Java JRE in the future.
|
||||||
|
|
||||||
|
Thanks to 李振 goodser456@hotmail.com for helping me notice
|
||||||
|
this problem.
|
||||||
|
|
||||||
|
imacat <imacat@mail.imacat.idv.tw>
|
||||||
|
2012/10/29
|
140
build.xml
Normal file
140
build.xml
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
Copyright (c) 2012 imacat.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
<!-- build.xml: The Ant build file for the Calc Mosaic creator -->
|
||||||
|
<!-- by imacat <imacat@mail.imacat.idv.tw>, 2012-08-12 -->
|
||||||
|
<project name="calcmosaic" default="help" basedir=".">
|
||||||
|
<!-- property: Build variables -->
|
||||||
|
<loadfile property="project.version" srcfile="${basedir}/VERSION">
|
||||||
|
<filterchain>
|
||||||
|
<striplinebreaks />
|
||||||
|
</filterchain>
|
||||||
|
</loadfile>
|
||||||
|
<property name="src.dir" value="${basedir}/src" />
|
||||||
|
<property name="lib.dir" value="lib" />
|
||||||
|
<property name="build.dir" value="build" />
|
||||||
|
<property name="classes.dir" value="${build.dir}/classes" />
|
||||||
|
<property name="jar.dir" value="${basedir}" />
|
||||||
|
<property name="jar.path" value="${jar.dir}/${ant.project.name}.jar" />
|
||||||
|
<property name="docs.dir" value="${basedir}/docs" />
|
||||||
|
<property name="dist.build.dir" value="${build.dir}/dist" />
|
||||||
|
<property name="dist.dir" value="${basedir}" />
|
||||||
|
<property name="ooo.dir.sdk-classes" value="/opt/openoffice.org3/basis-link/sdk/classes" />
|
||||||
|
<condition property="main-class" value="tw.idv.imacat.calcmosaic.CalcMosaic">
|
||||||
|
<not>
|
||||||
|
<isset property="main-class" />
|
||||||
|
</not>
|
||||||
|
</condition>
|
||||||
|
|
||||||
|
<!-- -set-ooo-classpath: Set the OpenOffice class path -->
|
||||||
|
<target name="-set-ooo-classpath">
|
||||||
|
<path id="classpath">
|
||||||
|
<fileset dir="${lib.dir}" includes="**/*.jar" />
|
||||||
|
</path>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- help: Display the help information -->
|
||||||
|
<target name="help">
|
||||||
|
<echo level="info" message="Available targets:" />
|
||||||
|
<echo level="info" message=" compile: Compile the source" />
|
||||||
|
<echo level="info" message=" jar: Create the jar archive as ${jar.path}" />
|
||||||
|
<echo level="info" message=" run: Run the program" />
|
||||||
|
<echo level="info" message=" docs: Generate the documents in ${docs.dir}" />
|
||||||
|
<echo level="info" message=" dist: Create the pacakge distribution as ${ant.project.name}-${project.version}.zip" />
|
||||||
|
<echo level="info" message=" clean: Clean-up the build files" />
|
||||||
|
<echo level="info" message=" help: Display this help" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- compile: Compile the source -->
|
||||||
|
<target name="compile" depends="-set-ooo-classpath">
|
||||||
|
<mkdir dir="${classes.dir}" />
|
||||||
|
<translate todir="${classes.dir}"
|
||||||
|
bundle="${src.dir}/tw/idv/imacat/calcmosaic/res/L10n"
|
||||||
|
starttoken="#" endtoken="#">
|
||||||
|
<fileset dir="${src.dir}">
|
||||||
|
<include name="**/*.properties" />
|
||||||
|
</fileset>
|
||||||
|
</translate>
|
||||||
|
<javac srcdir="${src.dir}" destdir="${classes.dir}" encoding="utf-8"
|
||||||
|
classpathref="classpath" debug="true" includeantruntime="false">
|
||||||
|
<compilerarg value="-Xlint:unchecked" />
|
||||||
|
</javac>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- jar: Create the jar archive -->
|
||||||
|
<target name="jar" depends="compile">
|
||||||
|
<mkdir dir="${jar.dir}" />
|
||||||
|
<echo level="info" message="ooo.dir.sdk-classes=${ooo.dir.sdk-classes}" />
|
||||||
|
<jar destfile="${jar.path}" basedir="${classes.dir}">
|
||||||
|
<fileset dir="${basedir}" includes="images/*" />
|
||||||
|
<zipfileset src="${lib.dir}/juh.jar" />
|
||||||
|
<zipfileset src="${lib.dir}/jurt.jar" />
|
||||||
|
<zipfileset src="${lib.dir}/ridl.jar" />
|
||||||
|
<zipfileset src="${lib.dir}/unoil.jar" />
|
||||||
|
<fileset dir="${ooo.dir.sdk-classes}" includes="**/*.class **/*.dll" />
|
||||||
|
<manifest>
|
||||||
|
<attribute name="Main-Class"
|
||||||
|
value="com.sun.star.lib.loader.Loader" />
|
||||||
|
<section name="com/sun/star/lib/loader/Loader.class">
|
||||||
|
<attribute name="Application-Class" value="${main-class}" />
|
||||||
|
</section>
|
||||||
|
</manifest>
|
||||||
|
</jar>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- run: Run the program -->
|
||||||
|
<target name="run" depends="jar">
|
||||||
|
<java jar="${jar.path}" fork="true" failonerror="true" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- docs: Generate the API document -->
|
||||||
|
<target name="docs" depends="-set-ooo-classpath">
|
||||||
|
<mkdir dir="${docs.dir}" />
|
||||||
|
<javadoc sourcepath="${src.dir}" destdir="${docs.dir}" encoding="utf-8"
|
||||||
|
classpathref="classpath" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- -distdir: Create the distribution directory -->
|
||||||
|
<target name="-distdir" depends="jar,docs">
|
||||||
|
<copy todir="${dist.build.dir}/${ant.project.name}-${project.version}"
|
||||||
|
preservelastmodified="true">
|
||||||
|
<fileset dir="${basedir}"
|
||||||
|
excludes="${build.dir}/ ${lib.dir}/ ${ant.project.name}-*.zip" />
|
||||||
|
</copy>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- dist: Create the pacakge distribution -->
|
||||||
|
<target name="dist" depends="-distdir">
|
||||||
|
<zip destfile="${dist.dir}/${ant.project.name}-${project.version}.zip"
|
||||||
|
basedir="${dist.build.dir}" />
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- clean: Clean-up the build files -->
|
||||||
|
<target name="clean">
|
||||||
|
<delete dir="${build.dir}" />
|
||||||
|
<delete dir="${docs.dir}" />
|
||||||
|
<delete file="${jar.path}" />
|
||||||
|
<delete verbose="true">
|
||||||
|
<fileset file="${dist.dir}/${ant.project.name}-*.zip*" />
|
||||||
|
</delete>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
<!-- lib-clean: Clean-up the build files -->
|
||||||
|
<target name="lib-clean" depends="clean" />
|
||||||
|
|
||||||
|
<!-- distclean: A duplicate to the clean target, for convienence -->
|
||||||
|
<target name="distclean" depends="clean" />
|
||||||
|
</project>
|
BIN
images/calcmosaic.png
Normal file
BIN
images/calcmosaic.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 306 B |
BIN
lib/juh.jar
Normal file
BIN
lib/juh.jar
Normal file
Binary file not shown.
BIN
lib/jurt.jar
Normal file
BIN
lib/jurt.jar
Normal file
Binary file not shown.
BIN
lib/ridl.jar
Normal file
BIN
lib/ridl.jar
Normal file
Binary file not shown.
BIN
lib/unoil.jar
Normal file
BIN
lib/unoil.jar
Normal file
Binary file not shown.
877
src/tw/idv/imacat/calcmosaic/CalcMosaic.java
Normal file
877
src/tw/idv/imacat/calcmosaic/CalcMosaic.java
Normal file
@ -0,0 +1,877 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CalcMosaic
|
||||||
|
*
|
||||||
|
* Created on 2012-08-12
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Image;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A program to create mosaic art from images with Calc.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 2.1.0
|
||||||
|
*/
|
||||||
|
public class CalcMosaic {
|
||||||
|
|
||||||
|
/** The title of the application. */
|
||||||
|
public static final String APP_NAME = "Calc Moasic";
|
||||||
|
|
||||||
|
/** The title of the application. */
|
||||||
|
private static final String ICON = "images/calcmosaic.png";
|
||||||
|
|
||||||
|
/** The version number. */
|
||||||
|
private static final String VERSION = "2.1.0";
|
||||||
|
|
||||||
|
/** The name of the jar file. */
|
||||||
|
private static final String JAR_NAME = "calcmosaic.jar";
|
||||||
|
|
||||||
|
/** The module name of the BASIC playing macros. */
|
||||||
|
private static final String playModule = "_0Play";
|
||||||
|
|
||||||
|
/** The module name of the BASIC macros. */
|
||||||
|
private static final String basicModule = "_1CalcMosaic";
|
||||||
|
|
||||||
|
/** The BASIC macros to play the mosaic art. */
|
||||||
|
private static final String playMacros =
|
||||||
|
"' Copyright (c) 2012 imacat.\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' Licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
||||||
|
+ "' you may not use this file except in compliance with the License.\n"
|
||||||
|
+ "' You may obtain a copy of the License at\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' http://www.apache.org/licenses/LICENSE-2.0\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' Unless required by applicable law or agreed to in writing, software\n"
|
||||||
|
+ "' distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
||||||
|
+ "' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
|
||||||
|
+ "' See the License for the specific language governing permissions and\n"
|
||||||
|
+ "' limitations under the License.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' _0Play: The BASIC macros to play the spreadsheets\n"
|
||||||
|
+ "' Created with " + APP_NAME + " version " + VERSION + "\n"
|
||||||
|
+ "' By imacat <imacat@mail.imacat.idv.tw>, 2012/10/5\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Option Explicit\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' The default background music, related to the document file\n"
|
||||||
|
+ "Const sDefaultMusic = \"\"\n"
|
||||||
|
+ "' The default break time between sheets (ms)\n"
|
||||||
|
+ "Const nDefaultBreak = 100\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subPlaySheets: Plays the spreadsheets.\n"
|
||||||
|
+ "' 1. Save file first for the macro to work.\n"
|
||||||
|
+ "' 2. Hit the start button at A1 of the first\n"
|
||||||
|
+ "' and last sheet to play the sheets.\n"
|
||||||
|
+ "' 3. You can set the break time (in\n"
|
||||||
|
+ "' milliseconds) between sheets at B1 of\n"
|
||||||
|
+ "' the first sheet (default 100 ms).\n"
|
||||||
|
+ "' 4. You can set the background music at C1\n"
|
||||||
|
+ "' of the first sheet. This only works on\n"
|
||||||
|
+ "' Linux and you must install mplayer.\n"
|
||||||
|
+ "' Relative file path is relative to the\n"
|
||||||
|
+ "' document file. Play once before your\n"
|
||||||
|
+ "' live show to avoid the I/O delay with cache.\n"
|
||||||
|
+ "Sub subPlaySheets\n"
|
||||||
|
+ "\tDim oController As Object, oSheets As Object\n"
|
||||||
|
+ "\tDim nBreak As Integer, nI As Integer\n"
|
||||||
|
+ "\tDim nCount As Integer, oSheet As Object\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toController = ThisComponent.getCurrentController\n"
|
||||||
|
+ "\toSheets = ThisComponent.getSheets\n"
|
||||||
|
+ "\tnBreak = oSheets.getByIndex (0).getCellByPosition (1, 0).getValue\n"
|
||||||
|
+ "\tIf nBreak = 0 Then\n"
|
||||||
|
+ "\t\tnBreak = nDefaultBreak\n"
|
||||||
|
+ "\tEnd If\n"
|
||||||
|
+ "\tnCount = oSheets.getCount\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\tsubPlayMusic\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\tFor nI = 0 To nCount - 1\n"
|
||||||
|
+ "\t\toSheet = oSheets.getByIndex (nI)\n"
|
||||||
|
+ "\t\toController.setActiveSheet (oSheet)\n"
|
||||||
|
+ "\t\tWait nBreak\n"
|
||||||
|
+ "\tNext nI\n"
|
||||||
|
+ "End Sub\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subPlayMusic: Plays the background music.\n"
|
||||||
|
+ "Sub subPlayMusic\n"
|
||||||
|
+ "\tDim oSheet As Object, sMusic As String\n"
|
||||||
|
+ "\tDim sFile As String, nPos As Integer\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\t' This only works on Linux and you must install mplayer.\n"
|
||||||
|
+ "\tIf Not FileExists (\"/usr/bin/mplayer\") Then\n"
|
||||||
|
+ "\t\tExit Sub\n"
|
||||||
|
+ "\tEnd if\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toSheet = ThisComponent.getSheets.getByIndex (0)\n"
|
||||||
|
+ "\tsMusic = oSheet.getCellByPosition (2, 0).getString\n"
|
||||||
|
+ "\tIf sMusic = \"\" Then\n"
|
||||||
|
+ "\t\tsMusic = sDefaultMusic\n"
|
||||||
|
+ "\tEnd If\n"
|
||||||
|
+ "\tIf sMusic = \"\" Then\n"
|
||||||
|
+ "\t\tExit Sub\n"
|
||||||
|
+ "\tEnd If\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\t' Relative file path is relative to the document file.\n"
|
||||||
|
+ "\tIf Left (sMusic, 1) <> \"/\" Then\n"
|
||||||
|
+ "\t\tsFile = ConvertFromURL (ThisComponent.getLocation)\n"
|
||||||
|
+ "\t\tIf sFile = \"\" Then\n"
|
||||||
|
+ "\t\t\tExit Sub\n"
|
||||||
|
+ "\t\tEnd If\n"
|
||||||
|
+ "\t\tnPos = Len (sFile)\n"
|
||||||
|
+ "\t\tDo While Mid (sFile, nPos, 1) <> \"/\"\n"
|
||||||
|
+ "\t\t\tnPos = nPos - 1\n"
|
||||||
|
+ "\t\tLoop\n"
|
||||||
|
+ "\t\tsMusic = Left (sFile, nPos) & sMusic\n"
|
||||||
|
+ "\tEnd If\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\tShell \"mplayer\", 6, \"\"\"\" & sMusic & \"\"\"\", False\n"
|
||||||
|
+ "End Sub\n";
|
||||||
|
|
||||||
|
/** The BASIC macros to convert color numbers to mosaic art. */
|
||||||
|
private static final String basicMacros =
|
||||||
|
"' Copyright (c) 2012 imacat\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' Licensed under the Apache License, Version 2.0 (the \"License\");\n"
|
||||||
|
+ "' you may not use this file except in compliance with the License.\n"
|
||||||
|
+ "' You may obtain a copy of the License at\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' http://www.apache.org/licenses/LICENSE-2.0\n"
|
||||||
|
+ "' \n"
|
||||||
|
+ "' Unless required by applicable law or agreed to in writing, software\n"
|
||||||
|
+ "' distributed under the License is distributed on an \"AS IS\" BASIS,\n"
|
||||||
|
+ "' WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n"
|
||||||
|
+ "' See the License for the specific language governing permissions and\n"
|
||||||
|
+ "' limitations under the License.\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' _1CalcMosaic: The BASIC macros of Calc Mosaic\n"
|
||||||
|
+ "' Created with " + APP_NAME + " version " + VERSION + "\n"
|
||||||
|
+ "' By imacat <imacat@mail.imacat.idv.tw>, 2012/10/5\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "Option Explicit\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subCreateMosaic: Creates the spreadsheets of mosaic art\n"
|
||||||
|
+ "Sub subCreateMosaic (mData () As Object)\n"
|
||||||
|
+ "\tDim mNames (UBound (mData (0))) As String\n"
|
||||||
|
+ "\tDim mColors (UBound (mData (1))) As Object\n"
|
||||||
|
+ "\tDim oSheet As Object, nI As Integer\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\t' Adds the spreadsheets and allocates memory first, to prevent\n"
|
||||||
|
+ "\t' memory corruption when the the number of sheets goes large.\n"
|
||||||
|
+ "\tmNames = mData (0)\n"
|
||||||
|
+ "\tmColors = mData (1)\n"
|
||||||
|
+ "\tsubInitializeSheets (mNames)\n"
|
||||||
|
+ "\tFor nI = 0 To UBound (mNames)\n"
|
||||||
|
+ "\t\tsubCreateMosaicSheet (mNames (nI), mColors (nI))\n"
|
||||||
|
+ "\tNext nI\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\tsubAddMacroTriggers\n"
|
||||||
|
+ "End Sub\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subCreateMosaicSheet: Creates a spreadsheet of mosaic art with\n"
|
||||||
|
+ "' the color values\n"
|
||||||
|
+ "Sub subCreateMosaicSheet (sSheet As String, mColors () As Object)\n"
|
||||||
|
+ "\tDim oSheet As Object, oRange As Object, oCell As Object\n"
|
||||||
|
+ "\tDim nRow As Integer, nColumn As Integer, nWidth As Integer\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toSheet = ThisComponent.getSheets.getByName (sSheet)\n"
|
||||||
|
+ "\toRange = oSheet.getCellRangeByPosition ( _\n"
|
||||||
|
+ "\t\t0, 0, UBound (mColors (0)), UBound (mColors))\n"
|
||||||
|
+ "\tFor nRow = 0 To UBound (mColors)\n"
|
||||||
|
+ "\t\tFor nColumn = 0 To UBound (mColors (0))\n"
|
||||||
|
+ "\t\t\toCell = oRange.getCellByPosition (nColumn, nRow)\n"
|
||||||
|
+ "\t\t\toCell.setPropertyValue (\"CellBackColor\", _\n"
|
||||||
|
+ "\t\t\t\tCLng (mColors (nRow)(nColumn)))\n"
|
||||||
|
+ "\t\tNext nColumn\n"
|
||||||
|
+ "\tNext nRow\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\t' Shortly displays the sheet. Removing these can save the\n"
|
||||||
|
+ "\t' display refreshing time and run slightly faster, with\n"
|
||||||
|
+ "\t' the cost of not seeing the progress and looking like hang.\n"
|
||||||
|
+ "\tnWidth = oRange.getRows.getPropertyValue (\"Height\")\n"
|
||||||
|
+ "\toRange.getColumns.setPropertyValue (\"Width\", nWidth)\n"
|
||||||
|
+ "\tThisComponent.getCurrentController.setActiveSheet (oSheet)\n"
|
||||||
|
+ "\tWait 1\n"
|
||||||
|
+ "End Sub\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subInitializeSheets: Initialize the spreadsheets\n"
|
||||||
|
+ "Sub subInitializeSheets (mNames () As Object)\n"
|
||||||
|
+ "\tDim oSheets As Object, nI As Integer, mExisting () As String\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toSheets = ThisComponent.getSheets\n"
|
||||||
|
+ "\tIf oSheets.hasByName (mNames (0)) Then\n"
|
||||||
|
+ "\t\tIf oSheets.getCount = 1 Then\n"
|
||||||
|
+ "\t\t\toSheets.insertNewByName (mNames (0) & 1, 0)\n"
|
||||||
|
+ "\t\tEnd If\n"
|
||||||
|
+ "\t\toSheets.removeByName (mNames (0))\n"
|
||||||
|
+ "\tEnd If\n"
|
||||||
|
+ "\tmExisting = oSheets.getElementNames\n"
|
||||||
|
+ "\toSheets.insertNewByName (mNames (0), 0)\n"
|
||||||
|
+ "\tFor nI = 0 To UBound (mExisting)\n"
|
||||||
|
+ "\t\toSheets.removeByName (mExisting (nI))\n"
|
||||||
|
+ "\tNext nI\n"
|
||||||
|
+ "\tFor nI = 1 To UBound (mNames)\n"
|
||||||
|
+ "\t\toSheets.insertNewByName (mNames (nI), nI)\n"
|
||||||
|
+ "\tNext nI\n"
|
||||||
|
+ "End Sub\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' fnGetEmptyStringArray: Returns an empty array of String.\n"
|
||||||
|
+ "Function fnGetEmptyStringArray (nUBound As Integer)\n"
|
||||||
|
+ "\tDim mArray (nUBound) As String\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\tfnGetEmptyStringArray = mArray\n"
|
||||||
|
+ "End Function\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subAddMacroTriggers: Adds the macro trigggers to show the sheets\n"
|
||||||
|
+ "Sub subAddMacroTriggers\n"
|
||||||
|
+ "\tDim oSheets As Object, oSheet As Object\n"
|
||||||
|
+ "\tDim oCell As Object, nColor As Long\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toSheets = ThisComponent.getSheets\n"
|
||||||
|
+ "\tsubAddStartButton (oSheets.getByIndex (0))\n"
|
||||||
|
+ "\t' Adds a start button at the end. Last time (2012/8/18 on\n"
|
||||||
|
+ "\t' COSCUP 2012 lightning talk) I tested playing and ended at\n"
|
||||||
|
+ "\t' the last sheet. When talk started I did not notice it and\n"
|
||||||
|
+ "\t' spent quite some time finding the button. Audience got\n"
|
||||||
|
+ "\t' anxious and even lost attention when the show begins.\n"
|
||||||
|
+ "\tsubAddStartButton (oSheets.getByIndex (oSheets.getCount - 1))\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toSheet = ThisComponent.getSheets.getByIndex (0)\n"
|
||||||
|
+ "\tThisComponent.getCurrentController.setActiveSheet (oSheet)\n"
|
||||||
|
+ "\toCell = oSheet.getCellByPosition (1, 0)\n"
|
||||||
|
+ "\tnColor = oCell.getPropertyValue (\"CellBackColor\")\n"
|
||||||
|
+ "\toCell.setPropertyValue (\"CharColor\", nColor)\n"
|
||||||
|
+ "\toCell = oSheet.getCellByPosition (2, 0)\n"
|
||||||
|
+ "\tnColor = oCell.getPropertyValue (\"CellBackColor\")\n"
|
||||||
|
+ "\toCell.setPropertyValue (\"CharColor\", nColor)\n"
|
||||||
|
+ "End Sub\n"
|
||||||
|
+ "\n"
|
||||||
|
+ "' subAddStartButton: Adds a start button to show the sheets\n"
|
||||||
|
+ "Sub subAddStartButton (oSheet As Object)\n"
|
||||||
|
+ "\tDim oPage As Object, oShape As Object, oButton As Object\n"
|
||||||
|
+ "\tDim nSize As Integer, nColor As Long\n"
|
||||||
|
+ "\tDim aPos As New com.sun.star.awt.Point\n"
|
||||||
|
+ "\tDim aSize As New com.sun.star.awt.Size\n"
|
||||||
|
+ "\tDim oForm As Object, nIndex As Integer\n"
|
||||||
|
+ "\tDim aEvent As New com.sun.star.script.ScriptEventDescriptor\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toPage = oSheet.getDrawPage\n"
|
||||||
|
+ "\tnSize = oSheet.getRows.getPropertyValue (\"Height\")\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toShape = ThisComponent.createInstance ( _\n"
|
||||||
|
+ "\t\t\"com.sun.star.drawing.ControlShape\")\n"
|
||||||
|
+ "\taPos.X = 0\n"
|
||||||
|
+ "\taPos.Y = 0\n"
|
||||||
|
+ "\toShape.setPosition (aPos)\n"
|
||||||
|
+ "\taSize.Width = nSize\n"
|
||||||
|
+ "\taSize.Height = nSize\n"
|
||||||
|
+ "\toShape.setSize (aSize)\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toButton = ThisComponent.createInstance ( _\n"
|
||||||
|
+ "\t\t\"com.sun.star.form.component.CommandButton\")\n"
|
||||||
|
+ "\tnColor = oSheet.getCellByPosition (0, 0).getPropertyValue ( _\n"
|
||||||
|
+ "\t\t\"CellBackColor\")\n"
|
||||||
|
+ "\toButton.setPropertyValue (\"BackgroundColor\", nColor)\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\toShape.setControl (oButton)\n"
|
||||||
|
+ "\toPage.add (oShape)\n"
|
||||||
|
+ "\t\n"
|
||||||
|
+ "\taEvent.ListenerType = \"XActionListener\"\n"
|
||||||
|
+ "\taEvent.EventMethod = \"actionPerformed\"\n"
|
||||||
|
+ "\taEvent.ScriptType = \"Script\"\n"
|
||||||
|
+ "\taEvent.ScriptCode = \"vnd.sun.star.script:\" _\n"
|
||||||
|
+ "\t\t& \"Standard." + playModule + ".subPlaySheets\" _\n"
|
||||||
|
+ "\t\t& \"?language=Basic&location=document\"\n"
|
||||||
|
+ "\toForm = oButton.getParent\n"
|
||||||
|
+ "\tnIndex = oForm.getCount - 1\n"
|
||||||
|
+ "\toForm.registerScriptEvent (nIndex, aEvent)\n"
|
||||||
|
+ "End Sub\n";
|
||||||
|
|
||||||
|
/** The localization resources. */
|
||||||
|
private ResourceBundle l10n = null;
|
||||||
|
|
||||||
|
/** The window icon. */
|
||||||
|
protected static Image icon = null;
|
||||||
|
|
||||||
|
/** The image files. */
|
||||||
|
private File files[] = new File[0];;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of rows to use, default to 0 (estimate it
|
||||||
|
* automatically).
|
||||||
|
*/
|
||||||
|
private int numRows = 0;
|
||||||
|
|
||||||
|
/** Whether we should run in slow motion (for presentation). */
|
||||||
|
private boolean isSlow = false;
|
||||||
|
|
||||||
|
/** Should we uses GUI. */
|
||||||
|
private boolean isGui = false;
|
||||||
|
|
||||||
|
/** The spreadsheet document to work with. */
|
||||||
|
private SpreadsheetDocument document = null;
|
||||||
|
|
||||||
|
/** The available dimension of mosaic cells. */
|
||||||
|
private Dimension availCells = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of CalcMosaic.
|
||||||
|
*
|
||||||
|
* @param args the command line arguments
|
||||||
|
* @throws IllegalArgumentException if the arguments are
|
||||||
|
* illegal
|
||||||
|
*/
|
||||||
|
private CalcMosaic(String args[])
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
// Obtains the localization resources
|
||||||
|
this.l10n = ResourceBundle.getBundle(
|
||||||
|
this.getClass().getPackage().getName() + ".res.L10n");
|
||||||
|
this.parseArguments(args);
|
||||||
|
if (this.isGui) {
|
||||||
|
icon = Toolkit.getDefaultToolkit().getImage(ICON);
|
||||||
|
OptionDialog dialog = new OptionDialog(
|
||||||
|
this.files, this.numRows, this.isSlow);
|
||||||
|
Options options = dialog.getOptions();
|
||||||
|
// Cancelled
|
||||||
|
if (options == null) {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
this.files = options.files;
|
||||||
|
this.numRows = options.numRows;
|
||||||
|
this.isSlow = options.isSlow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of CalcMosaic, with the parameters.
|
||||||
|
*
|
||||||
|
* @param files The image files
|
||||||
|
* @param numRows The number of rows to use, default to 0 (estimate it
|
||||||
|
* automatically)
|
||||||
|
* @param isSlow Should we create in slow motion (for presentation)
|
||||||
|
*/
|
||||||
|
public CalcMosaic(File files[], int numRows, boolean isSlow) {
|
||||||
|
// Obtains the localization resources
|
||||||
|
this.l10n = ResourceBundle.getBundle(
|
||||||
|
this.getClass().getPackage().getName() + ".res.L10n");
|
||||||
|
this.files = files;
|
||||||
|
this.numRows = numRows;
|
||||||
|
this.isSlow = isSlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs CalcMosaic from the command line.
|
||||||
|
*
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String args[]) {
|
||||||
|
CalcMosaic mosaic = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
mosaic = new CalcMosaic(args);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
System.err.println(APP_NAME + ": " + e.getMessage());
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
mosaic.create();
|
||||||
|
} catch (com.sun.star.comp.helper.BootstrapException e) {
|
||||||
|
mosaic.showErrorMessage(e.getMessage());
|
||||||
|
System.exit(2);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
mosaic.showErrorMessage(e.getMessage());
|
||||||
|
System.exit(2);
|
||||||
|
} catch (NotAnImageException e) {
|
||||||
|
mosaic.showErrorMessage(e.getMessage());
|
||||||
|
System.exit(2);
|
||||||
|
}
|
||||||
|
mosaic.showMessage(mosaic._("finished"));
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the mosaic color matrix from an image file.
|
||||||
|
*
|
||||||
|
* @param image the image
|
||||||
|
* @param cellSize the size of the mosaic cell
|
||||||
|
* @return the values of the mosaic color matrix, with Alpha
|
||||||
|
* channel removed
|
||||||
|
*/
|
||||||
|
public static int[][] addMacroTriggers(
|
||||||
|
BufferedImage image, int cellSize) {
|
||||||
|
int colors[][] = new int
|
||||||
|
[(image.getHeight() - 1) / cellSize + 1]
|
||||||
|
[(image.getWidth() - 1) / cellSize + 1];
|
||||||
|
|
||||||
|
// Gets the color of each cell
|
||||||
|
for (int y0 = 0; y0 < image.getHeight(); y0 += cellSize) {
|
||||||
|
int y1 = y0 + cellSize - 1;
|
||||||
|
if (y1 >= image.getHeight()) {
|
||||||
|
y1 = image.getHeight() - 1;
|
||||||
|
}
|
||||||
|
for (int x0 = 0; x0 < image.getWidth(); x0 += cellSize) {
|
||||||
|
int x1 = x0 + cellSize - 1;
|
||||||
|
if (x1 >= image.getWidth()) {
|
||||||
|
x1 = image.getWidth() - 1;
|
||||||
|
}
|
||||||
|
Color color = getMosaicColor(image, x0, y0, x1, y1);
|
||||||
|
colors[y0 / cellSize][x0 / cellSize]
|
||||||
|
= color.getRGB() & 0x00FFFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the mosaic color of a block in the image.
|
||||||
|
*
|
||||||
|
* @param image the image
|
||||||
|
* @param x0 the x-coordinate of the upper-left corner of the
|
||||||
|
* block in the image
|
||||||
|
* @param y0 the y-coordinate of the upper-left corner of the
|
||||||
|
* block in the image
|
||||||
|
* @param x1 the x-coordinate of the lower-right corner of the
|
||||||
|
* block in the image
|
||||||
|
* @param y1 the y-coordinate of the lower-right corner of the
|
||||||
|
* block in the image
|
||||||
|
* @return the mosaic color of the block in the image
|
||||||
|
*/
|
||||||
|
public static Color getMosaicColor(BufferedImage image,
|
||||||
|
int x0, int y0, int x1, int y1) {
|
||||||
|
/*
|
||||||
|
* Using linear distance weakening: When calculating the
|
||||||
|
* average color of this block, the weights of the colors at
|
||||||
|
* all the pixels are different: Colors of pixels closer to
|
||||||
|
* the center of the block have a larger weight that those
|
||||||
|
* colors of pixels far away from center. The weight
|
||||||
|
* decreases from the center in a linear speed. The resulting
|
||||||
|
* weights may look like a circled cone. This creates a
|
||||||
|
* mosaic effect that is more sharp, especially with images of
|
||||||
|
* only a few colors. Our eye focus stay mostly at the center
|
||||||
|
* of the block. The colors of the center area outweights the
|
||||||
|
* skirts area.
|
||||||
|
*/
|
||||||
|
|
||||||
|
double totalWeight = 0;
|
||||||
|
double alpha = 0, red = 0, green = 0, blue = 0;
|
||||||
|
double centerX = (double) (x0 + x1) / 2;
|
||||||
|
double centerY = (double) (y0 + y1) / 2;
|
||||||
|
double radius = 1 + Math.sqrt(
|
||||||
|
(x0 - centerX) * (x0 - centerX)
|
||||||
|
+ (y0 - centerY) * (y0 - centerY));
|
||||||
|
|
||||||
|
for (int x = x0; x <= x1; x++) {
|
||||||
|
for (int y = y0; y <= y1; y++) {
|
||||||
|
Color color = new Color(image.getRGB(x, y));
|
||||||
|
double distance = Math.sqrt(
|
||||||
|
(x - centerX) * (x - centerX)
|
||||||
|
+ (y - centerY) * (y - centerY));
|
||||||
|
double weight = (radius - distance) / radius;
|
||||||
|
|
||||||
|
alpha += color.getAlpha() * weight;
|
||||||
|
red += color.getRed() * weight;
|
||||||
|
green += color.getGreen() * weight;
|
||||||
|
blue += color.getBlue() * weight;
|
||||||
|
totalWeight += weight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alpha /= totalWeight;
|
||||||
|
red /= totalWeight;
|
||||||
|
green /= totalWeight;
|
||||||
|
blue /= totalWeight;
|
||||||
|
|
||||||
|
return new Color((int) red, (int) green, (int) blue,
|
||||||
|
(int) alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the command line arguments.
|
||||||
|
*
|
||||||
|
* @param args the command line arguments
|
||||||
|
* @throws IllegalArgumentException if the arguments are
|
||||||
|
* illegal
|
||||||
|
*/
|
||||||
|
private void parseArguments(String args[])
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
List<String> filesList = new ArrayList<String>();
|
||||||
|
|
||||||
|
for (int i = 0; i < args.length; i++) {
|
||||||
|
if (args[i].equals("-r") || args[i].equals("-rows")) {
|
||||||
|
i++;
|
||||||
|
if (i >= args.length) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
_("err_rows_miss"));
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
this.numRows = Integer.parseInt(args[i]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
args[i - 1] + " \"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
if (this.numRows <= 0) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
args[i - 1] + " \"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
} else if (args[i].startsWith("-r=")) {
|
||||||
|
try {
|
||||||
|
this.numRows = Integer.parseInt(args[i].substring(3));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
"\"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
if (this.numRows <= 0) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
"\"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
} else if (args[i].startsWith("-rows=")) {
|
||||||
|
try {
|
||||||
|
this.numRows = Integer.parseInt(args[i].substring(6));
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
"\"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
if (this.numRows <= 0) {
|
||||||
|
throw new NumberFormatException(
|
||||||
|
"\"" + args[i] + "\": "
|
||||||
|
+ _("err_rows_not_pint"));
|
||||||
|
}
|
||||||
|
} else if (args[i].equals("-s") || args[i].equals("-slow")) {
|
||||||
|
this.isSlow = true;
|
||||||
|
} else if (args[i].equals("-noslow")) {
|
||||||
|
this.isSlow = false;
|
||||||
|
} else if (args[i].equals("-h") || args[i].equals("-help")) {
|
||||||
|
System.out.println(String.format(_("help"), JAR_NAME));
|
||||||
|
System.exit(0);
|
||||||
|
} else if (args[i].equals("-v") || args[i].equals("-version")) {
|
||||||
|
System.out.println(String.format(_("version"),
|
||||||
|
APP_NAME, VERSION, _("author")));
|
||||||
|
System.exit(0);
|
||||||
|
} else if (args[i].startsWith("-")) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
args[i] + ": " + _("err_arg_unknown"));
|
||||||
|
} else {
|
||||||
|
filesList.add(args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks the files.
|
||||||
|
// This is processed last, after all the options, so that
|
||||||
|
// -help and -version takes effect before this.
|
||||||
|
this.files = new File[filesList.size()];
|
||||||
|
for (int i = 0; i < this.files.length; i++) {
|
||||||
|
File file = new File(filesList.get(i));
|
||||||
|
|
||||||
|
if (!file.exists()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
args[i] + ": " + _("err_file_not_exist"));
|
||||||
|
}
|
||||||
|
if (!file.isFile()) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
args[i] + ": " + _("err_file_not_a_file"));
|
||||||
|
}
|
||||||
|
this.files[i] = file;
|
||||||
|
}
|
||||||
|
// Checks the limits of the number of images/spreadsheets.
|
||||||
|
if (this.files.length > 256) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
_("err_file_too_many"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use GUI if no files are supplied.
|
||||||
|
if (this.files.length == 0) {
|
||||||
|
this.isGui = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates mosaic art of images with Calc.
|
||||||
|
*
|
||||||
|
* @throws com.sun.star.comp.helper.BootstrapException if fails to
|
||||||
|
* create the initial component context
|
||||||
|
* @throws java.io.IOException if an error occurs during reading
|
||||||
|
* the image
|
||||||
|
* @throws NotAnImageException if the file read is not an image
|
||||||
|
*/
|
||||||
|
private void create()
|
||||||
|
throws com.sun.star.comp.helper.BootstrapException,
|
||||||
|
java.io.IOException,
|
||||||
|
NotAnImageException {
|
||||||
|
if (this.isSlow) {
|
||||||
|
this.createSlowly();
|
||||||
|
} else {
|
||||||
|
this.createNormal();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates mosaic art of images with Calc with the normal speed.
|
||||||
|
*
|
||||||
|
* @throws com.sun.star.comp.helper.BootstrapException if fails to
|
||||||
|
* create the initial component context
|
||||||
|
* @throws java.io.IOException if an error occurs during reading
|
||||||
|
* the image
|
||||||
|
* @throws NotAnImageException if the file read is not an image
|
||||||
|
*/
|
||||||
|
private void createNormal()
|
||||||
|
throws com.sun.star.comp.helper.BootstrapException,
|
||||||
|
java.io.IOException,
|
||||||
|
NotAnImageException {
|
||||||
|
OpenOffice office = null;
|
||||||
|
Object param[] = new Object[1];
|
||||||
|
Object data[][] = new Object[2][this.files.length];
|
||||||
|
|
||||||
|
try {
|
||||||
|
office = new OpenOffice();
|
||||||
|
} catch (com.sun.star.comp.helper.BootstrapException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
this.document = office.startNewSpreadsheetDocument();
|
||||||
|
this.document.addBasicModule(playModule, playMacros);
|
||||||
|
this.document.addBasicModule(basicModule, basicMacros);
|
||||||
|
for (int i = 0; i < this.files.length; i++) {
|
||||||
|
data[0][i] = this.files[i].getName();
|
||||||
|
try {
|
||||||
|
data[1][i] = this.addMacroTriggers(this.files[i]);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (NotAnImageException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param[0] = data;
|
||||||
|
this.document.runBasicMacro(
|
||||||
|
basicModule, "subCreateMosaic", param);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates mosaic art of images with Calc in slow motion.
|
||||||
|
*
|
||||||
|
* @throws com.sun.star.comp.helper.BootstrapException if fails to
|
||||||
|
* create the initial component context
|
||||||
|
* @throws java.io.IOException if an error occurs during reading
|
||||||
|
* the image
|
||||||
|
* @throws NotAnImageException if the file read is not an image
|
||||||
|
*/
|
||||||
|
private void createSlowly()
|
||||||
|
throws com.sun.star.comp.helper.BootstrapException,
|
||||||
|
java.io.IOException,
|
||||||
|
NotAnImageException {
|
||||||
|
OpenOffice office = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
office = new OpenOffice();
|
||||||
|
} catch (com.sun.star.comp.helper.BootstrapException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
this.document = office.startNewSpreadsheetDocument();
|
||||||
|
this.document.addBasicModule(playModule, playMacros);
|
||||||
|
for (int i = 0; i < this.files.length; i++) {
|
||||||
|
String name = this.files[i].getName();
|
||||||
|
int colors[][] = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
colors = this.addMacroTriggers(this.files[i]);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw e;
|
||||||
|
} catch (NotAnImageException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
this.document.createMosaicSheet(name, i, colors);
|
||||||
|
}
|
||||||
|
this.document.addMacroTriggers();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the mosaic color matrix from an image file.
|
||||||
|
*
|
||||||
|
* @param file the source image file
|
||||||
|
* @return the values of the mosaic color matrix, with Alpha
|
||||||
|
* channel removed
|
||||||
|
* @throws java.io.IOException if an error occurs during reading
|
||||||
|
* the image
|
||||||
|
* @throws NotAnImageException if the file read is not an image
|
||||||
|
*/
|
||||||
|
private int[][] addMacroTriggers(File file)
|
||||||
|
throws java.io.IOException,
|
||||||
|
NotAnImageException {
|
||||||
|
BufferedImage image = null;
|
||||||
|
int cellSize = -1;
|
||||||
|
|
||||||
|
try {
|
||||||
|
image = ImageIO.read(file);
|
||||||
|
} catch (java.io.IOException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
if (image == null) {
|
||||||
|
throw new NotAnImageException(
|
||||||
|
file.getName() + ": " + _("err_file_not_an_image"));
|
||||||
|
}
|
||||||
|
|
||||||
|
cellSize = this.getCellSize(image);
|
||||||
|
return addMacroTriggers(image, cellSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the mosaic cell size.
|
||||||
|
*
|
||||||
|
* @param image the source image
|
||||||
|
* @return the calculated mosaic cell size
|
||||||
|
*/
|
||||||
|
private int getCellSize(BufferedImage image) {
|
||||||
|
if (this.numRows != 0) {
|
||||||
|
return (image.getHeight() - 1) / this.numRows + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the size that fits the whole image.
|
||||||
|
int width = 0, height = 0;
|
||||||
|
|
||||||
|
this.estimateAvailableCells();
|
||||||
|
width = (image.getWidth() - 1) / this.availCells.width + 1;
|
||||||
|
height = (image.getHeight() - 1) / this.availCells.height + 1;
|
||||||
|
return width > height? width: height;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimates the number of rows to use automatically
|
||||||
|
*
|
||||||
|
* @param image the source image
|
||||||
|
* @return the number of rows to use
|
||||||
|
*/
|
||||||
|
private int estimateNumRows(BufferedImage image) {
|
||||||
|
// Calculate the size that fits the whole image.
|
||||||
|
int width = -1, height = -1, cellSize = -1;
|
||||||
|
|
||||||
|
this.estimateAvailableCells();
|
||||||
|
width = (image.getWidth() - 1) / this.availCells.width + 1;
|
||||||
|
height = (image.getHeight() - 1) / this.availCells.height + 1;
|
||||||
|
cellSize = width > height? width: height;
|
||||||
|
return Math.round((float) image.getHeight() / cellSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Estimates the available dimension of the mosaic cells.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void estimateAvailableCells() {
|
||||||
|
if (this.availCells == null) {
|
||||||
|
Dimension window = this.document.getWindowSize();
|
||||||
|
int rowHeight = this.document.getRowHeight();
|
||||||
|
|
||||||
|
// Only use the row height, because the height is always
|
||||||
|
// shorter than the width in newly-created sheets.
|
||||||
|
this.availCells = new Dimension(
|
||||||
|
window.width * 25 / rowHeight,
|
||||||
|
window.height * 25 / rowHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a error message.
|
||||||
|
*
|
||||||
|
* @param message the error message to be shown
|
||||||
|
*/
|
||||||
|
private void showErrorMessage(String message) {
|
||||||
|
if (this.isGui) {
|
||||||
|
JFrame frame = new JFrame(APP_NAME);
|
||||||
|
Dimension screenSize
|
||||||
|
= Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
Dimension frameSize = frame.getSize();
|
||||||
|
|
||||||
|
frame.setIconImage(icon);
|
||||||
|
frame.setLocation(
|
||||||
|
(screenSize.width - frameSize.width) / 2,
|
||||||
|
(screenSize.height - frameSize.height) / 2
|
||||||
|
);
|
||||||
|
frame.setVisible(true);
|
||||||
|
JOptionPane.showMessageDialog(frame, message,
|
||||||
|
String.format(_("dialog_err_title"),
|
||||||
|
CalcMosaic.APP_NAME),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
frame.setVisible(false);
|
||||||
|
} else {
|
||||||
|
System.err.println(APP_NAME + ": " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a message.
|
||||||
|
*
|
||||||
|
* @param message the message to be shown
|
||||||
|
*/
|
||||||
|
private void showMessage(String message) {
|
||||||
|
if (this.isGui) {
|
||||||
|
JFrame frame = new JFrame(APP_NAME);
|
||||||
|
Dimension screenSize
|
||||||
|
= Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
Dimension frameSize = frame.getSize();
|
||||||
|
|
||||||
|
frame.setIconImage(icon);
|
||||||
|
frame.setLocation(
|
||||||
|
(screenSize.width - frameSize.width) / 2,
|
||||||
|
(screenSize.height - frameSize.height) / 2
|
||||||
|
);
|
||||||
|
frame.setVisible(true);
|
||||||
|
JOptionPane.showMessageDialog(frame, message, APP_NAME,
|
||||||
|
JOptionPane.INFORMATION_MESSAGE);
|
||||||
|
frame.setVisible(false);
|
||||||
|
} else {
|
||||||
|
System.out.println(APP_NAME + ": " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for the given key from this resource bundle
|
||||||
|
* or one of its parents. If the key is missing, returns
|
||||||
|
* the key itself.
|
||||||
|
*
|
||||||
|
* @param key the key for the desired string
|
||||||
|
* @return the string for the given key
|
||||||
|
*/
|
||||||
|
private String _(String key) {
|
||||||
|
try {
|
||||||
|
return new String(
|
||||||
|
l10n.getString(key).getBytes("ISO-8859-1"), "UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e) {
|
||||||
|
return l10n.getString(key);
|
||||||
|
} catch (java.util.MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
src/tw/idv/imacat/calcmosaic/NotAnImageException.java
Normal file
89
src/tw/idv/imacat/calcmosaic/NotAnImageException.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NotAnImageException
|
||||||
|
*
|
||||||
|
* Created on 2012-10-27, rewritten from CalcMosaic
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception thrown when the file read is not an image.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 0.0.1
|
||||||
|
*/
|
||||||
|
public class NotAnImageException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a <code>NotAnImageException</code> exception with
|
||||||
|
* <code>null</code> as its error detail message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public NotAnImageException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a <code>NotAnImageException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param message The detail message (which is saved for later
|
||||||
|
* retrieval by the Throwable.getMessage() method)
|
||||||
|
*/
|
||||||
|
public NotAnImageException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an <code>NotAnImageException</code> with the
|
||||||
|
* specified detail message and cause.
|
||||||
|
* <p>
|
||||||
|
* Note that the detail message associated with <code>cause</code>
|
||||||
|
* is <em>not</em> automatically incorporated into this
|
||||||
|
* exception's detail message.
|
||||||
|
*
|
||||||
|
* @param message The detail message (which is saved for later
|
||||||
|
* retrieval by the Throwable.getMessage() method)
|
||||||
|
* @param cause The cause (which is saved for later retrieval
|
||||||
|
* by the Throwable.getCause() method). (A null
|
||||||
|
* value is permitted, and indicates that the
|
||||||
|
* cause is nonexistent or unknown.)
|
||||||
|
*/
|
||||||
|
public NotAnImageException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an <code>NotAnImageException</code> with the
|
||||||
|
* specified cause and a detail message of <code>(cause==null
|
||||||
|
* ? null : cause.toString())</code> (which typically contains
|
||||||
|
* the class and detail message of <code>cause</code>). This
|
||||||
|
* constructor is useful for IO exceptions that are little more
|
||||||
|
* than wrappers for other throwables.
|
||||||
|
*
|
||||||
|
* @param cause The cause (which is saved for later retrieval
|
||||||
|
* by the Throwable.getCause() method). (A null
|
||||||
|
* value is permitted, and indicates that the
|
||||||
|
* cause is nonexistent or unknown.)
|
||||||
|
*/
|
||||||
|
public NotAnImageException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
189
src/tw/idv/imacat/calcmosaic/OpenOffice.java
Normal file
189
src/tw/idv/imacat/calcmosaic/OpenOffice.java
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OpenOffice
|
||||||
|
*
|
||||||
|
* Created on 2012-08-16, rewritten from CalcMosaic
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import com.sun.star.beans.PropertyValue;
|
||||||
|
import com.sun.star.beans.XPropertySet;
|
||||||
|
import com.sun.star.comp.helper.Bootstrap;
|
||||||
|
import com.sun.star.bridge.XUnoUrlResolver;
|
||||||
|
import com.sun.star.frame.XComponentLoader;
|
||||||
|
import com.sun.star.frame.XDesktop;
|
||||||
|
import com.sun.star.lang.XComponent;
|
||||||
|
import com.sun.star.lang.XMultiComponentFactory;
|
||||||
|
import com.sun.star.uno.UnoRuntime;
|
||||||
|
import com.sun.star.uno.XComponentContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OpenOffice instance.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 2.0.0
|
||||||
|
*/
|
||||||
|
public class OpenOffice {
|
||||||
|
|
||||||
|
/** The localization resources. */
|
||||||
|
private ResourceBundle l10n = null;
|
||||||
|
|
||||||
|
/** The desktop service. */
|
||||||
|
private XDesktop desktop = null;
|
||||||
|
|
||||||
|
/** The bootstrap context. */
|
||||||
|
private XComponentContext bootstrapContext = null;
|
||||||
|
|
||||||
|
/** The registry service manager. */
|
||||||
|
private XMultiComponentFactory serviceManager = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of Office.
|
||||||
|
*
|
||||||
|
* @throws com.sun.star.comp.helper.BootstrapException if fails to
|
||||||
|
* create the initial component context
|
||||||
|
*/
|
||||||
|
public OpenOffice()
|
||||||
|
throws com.sun.star.comp.helper.BootstrapException {
|
||||||
|
// Obtains the localization resources
|
||||||
|
this.l10n = ResourceBundle.getBundle(
|
||||||
|
this.getClass().getPackage().getName() + ".res.L10n");
|
||||||
|
try {
|
||||||
|
this.connect();
|
||||||
|
} catch (com.sun.star.comp.helper.BootstrapException e) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Connects to the OpenOffice program.
|
||||||
|
*
|
||||||
|
* @throws com.sun.star.comp.helper.BootstrapException if fails to
|
||||||
|
* create the initial component context
|
||||||
|
*/
|
||||||
|
private void connect()
|
||||||
|
throws com.sun.star.comp.helper.BootstrapException {
|
||||||
|
XMultiComponentFactory localServiceManager = null;
|
||||||
|
Object unoUrlResolver = null;
|
||||||
|
XUnoUrlResolver xUnoUrlResolver = null;
|
||||||
|
Object service = null;
|
||||||
|
|
||||||
|
if (this.isConnected()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains the local context
|
||||||
|
try {
|
||||||
|
this.bootstrapContext = Bootstrap.bootstrap();
|
||||||
|
} catch (java.lang.Exception e) {
|
||||||
|
throw new com.sun.star.comp.helper.BootstrapException(e);
|
||||||
|
}
|
||||||
|
if (this.bootstrapContext == null) {
|
||||||
|
throw new com.sun.star.comp.helper.BootstrapException(
|
||||||
|
this._("err_ooo_no_lcc"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains the local service manager
|
||||||
|
this.serviceManager = this.bootstrapContext.getServiceManager();
|
||||||
|
|
||||||
|
// Obtain the desktop service
|
||||||
|
try {
|
||||||
|
service = this.serviceManager.createInstanceWithContext(
|
||||||
|
"com.sun.star.frame.Desktop", this.bootstrapContext);
|
||||||
|
} catch (com.sun.star.uno.Exception e) {
|
||||||
|
throw new java.lang.UnsupportedOperationException(e);
|
||||||
|
}
|
||||||
|
this.desktop = (XDesktop) UnoRuntime.queryInterface(
|
||||||
|
XDesktop.class, service);
|
||||||
|
|
||||||
|
// Obtains the service manager
|
||||||
|
this.serviceManager = this.bootstrapContext.getServiceManager();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the connection is on and alive.
|
||||||
|
*
|
||||||
|
* @return true if the connection is alive, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean isConnected() {
|
||||||
|
if (this.serviceManager == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, this.serviceManager);
|
||||||
|
} catch (com.sun.star.lang.DisposedException e) {
|
||||||
|
this.serviceManager = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new spreadsheet document.
|
||||||
|
*
|
||||||
|
* @return the new spreadsheet document
|
||||||
|
*/
|
||||||
|
public SpreadsheetDocument startNewSpreadsheetDocument() {
|
||||||
|
XComponentLoader xComponentLoader = (XComponentLoader)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XComponentLoader.class, this.desktop);
|
||||||
|
PropertyValue props[] = new PropertyValue[0];
|
||||||
|
final String url = "private:factory/scalc";
|
||||||
|
XComponent xComponent = null;
|
||||||
|
|
||||||
|
// Load a new document
|
||||||
|
try {
|
||||||
|
xComponent = xComponentLoader.loadComponentFromURL(url,
|
||||||
|
"_default", 0, props);
|
||||||
|
} catch (com.sun.star.io.IOException e) {
|
||||||
|
throw new java.lang.RuntimeException(
|
||||||
|
String.format(_("err_open"), url), e);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.RuntimeException(
|
||||||
|
String.format(_("err_open"), url), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SpreadsheetDocument(xComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for the given key from this resource bundle
|
||||||
|
* or one of its parents. If the key is missing, returns
|
||||||
|
* the key itself.
|
||||||
|
*
|
||||||
|
* @param key the key for the desired string
|
||||||
|
* @return the string for the given key
|
||||||
|
*/
|
||||||
|
private String _(String key) {
|
||||||
|
try {
|
||||||
|
return new String(
|
||||||
|
this.l10n.getString(key).getBytes("ISO-8859-1"),
|
||||||
|
"UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e) {
|
||||||
|
return this.l10n.getString(key);
|
||||||
|
} catch (java.util.MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
272
src/tw/idv/imacat/calcmosaic/OptionDialog.java
Normal file
272
src/tw/idv/imacat/calcmosaic/OptionDialog.java
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OptionDialog
|
||||||
|
*
|
||||||
|
* Created on 2012-10-29
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import java.awt.Dialog.ModalityType;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.KeyEvent;
|
||||||
|
import java.awt.GridLayout;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JSpinner;
|
||||||
|
import javax.swing.SpinnerNumberModel;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An dialog to obtain the options.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 2.1.0
|
||||||
|
*/
|
||||||
|
public class OptionDialog {
|
||||||
|
|
||||||
|
/** The localization resources. */
|
||||||
|
private ResourceBundle l10n = null;
|
||||||
|
|
||||||
|
/** The option set. */
|
||||||
|
private Options options = null;
|
||||||
|
|
||||||
|
/** The dialog. */
|
||||||
|
private JDialog dialog = new JDialog(
|
||||||
|
null, ModalityType.TOOLKIT_MODAL);
|
||||||
|
|
||||||
|
/** The image files. */
|
||||||
|
public File files[] = new File[0];;
|
||||||
|
|
||||||
|
/** The number of rows to use. */
|
||||||
|
public int numRows = 0;
|
||||||
|
|
||||||
|
/** Whether we should run in slow motion (for presentation). */
|
||||||
|
public boolean isSlow = false;
|
||||||
|
|
||||||
|
/** The current directory. */
|
||||||
|
private File currentDirectory = null;
|
||||||
|
|
||||||
|
/** The file chooser button. */
|
||||||
|
private JButton filesButton = new JButton();
|
||||||
|
|
||||||
|
/** The spinner of the number of rows. */
|
||||||
|
private JSpinner numRowsSpinner = new JSpinner();
|
||||||
|
|
||||||
|
/** The check box of whether we should run in slow motion. */
|
||||||
|
private JCheckBox isSlowCheckBox = new JCheckBox();
|
||||||
|
|
||||||
|
/** The OK button. */
|
||||||
|
private JButton okButton = new JButton();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new option dialog.
|
||||||
|
*
|
||||||
|
* @param files the image files
|
||||||
|
* @param numRows the number of rows to use
|
||||||
|
* @param isSlow whether we should run in slow motion (for
|
||||||
|
* presentation)
|
||||||
|
*/
|
||||||
|
public OptionDialog(File files[], int numRows, boolean isSlow) {
|
||||||
|
// Obtains the localization resources
|
||||||
|
this.l10n = ResourceBundle.getBundle(
|
||||||
|
this.getClass().getPackage().getName() + ".res.L10n");
|
||||||
|
this.files = files;
|
||||||
|
this.numRows = numRows;
|
||||||
|
this.isSlow = isSlow;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Asks the user and returns the options.
|
||||||
|
*
|
||||||
|
* @return the options set by the user
|
||||||
|
*/
|
||||||
|
public Options getOptions() {
|
||||||
|
JPanel optionPanel = new JPanel();
|
||||||
|
JLabel label = null;
|
||||||
|
JButton cancelButton = new JButton(_("dialog_btn_cancel"));
|
||||||
|
SpinnerNumberModel spinnerModel = new SpinnerNumberModel(
|
||||||
|
this.numRows, 0, 32767, 1);
|
||||||
|
Dimension screenSize
|
||||||
|
= Toolkit.getDefaultToolkit().getScreenSize();
|
||||||
|
Dimension frameSize = null;
|
||||||
|
|
||||||
|
// Makes "enter" acts as "space" that activates the buttons
|
||||||
|
UIManager.put("Button.defaultButtonFollowsFocus", true);
|
||||||
|
|
||||||
|
this.dialog.setIconImage(CalcMosaic.icon);
|
||||||
|
this.dialog.setTitle(String.format(_("dialog_opts_title"),
|
||||||
|
CalcMosaic.APP_NAME));
|
||||||
|
this.dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
||||||
|
optionPanel.setLayout(new GridLayout(4, 2, 10, 5));
|
||||||
|
|
||||||
|
// Reserves the space for a 3-digit number
|
||||||
|
this.filesButton.setText(
|
||||||
|
String.format(_("dialog_btn_files"), 256));
|
||||||
|
this.filesButton.setMnemonic(KeyEvent.VK_F);
|
||||||
|
this.filesButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
chooseFiles();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
label = new JLabel(_("dialog_label_files"));
|
||||||
|
label.setLabelFor(this.filesButton);
|
||||||
|
optionPanel.add(label);
|
||||||
|
optionPanel.add(this.filesButton);
|
||||||
|
|
||||||
|
this.numRowsSpinner.setModel(spinnerModel);
|
||||||
|
label = new JLabel(_("dialog_label_numrows"));
|
||||||
|
label.setLabelFor(this.numRowsSpinner);
|
||||||
|
optionPanel.add(label);
|
||||||
|
optionPanel.add(this.numRowsSpinner);
|
||||||
|
|
||||||
|
this.isSlowCheckBox.setText(_("dialog_checkbox_isslow"));
|
||||||
|
this.isSlowCheckBox.setSelected(this.isSlow);
|
||||||
|
label = new JLabel(_("dialog_label_isslow"));
|
||||||
|
label.setLabelFor(this.isSlowCheckBox);
|
||||||
|
optionPanel.add(label);
|
||||||
|
optionPanel.add(this.isSlowCheckBox);
|
||||||
|
|
||||||
|
this.okButton.setText(_("dialog_btn_ok"));
|
||||||
|
this.okButton.setMnemonic(KeyEvent.VK_O);
|
||||||
|
this.okButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
options = new Options(files,
|
||||||
|
(Integer) numRowsSpinner.getValue(),
|
||||||
|
isSlowCheckBox.isSelected());
|
||||||
|
dialog.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (this.files.length == 0) {
|
||||||
|
this.okButton.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
this.okButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
optionPanel.add(this.okButton);
|
||||||
|
cancelButton = new JButton(_("dialog_btn_cancel"));
|
||||||
|
cancelButton.setMnemonic(KeyEvent.VK_C);
|
||||||
|
cancelButton.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
options = null;
|
||||||
|
dialog.dispose();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
optionPanel.add(cancelButton);
|
||||||
|
|
||||||
|
this.options = null;
|
||||||
|
this.dialog.add(optionPanel);
|
||||||
|
this.dialog.pack();
|
||||||
|
frameSize = this.dialog.getSize();
|
||||||
|
this.dialog.setLocation(
|
||||||
|
(screenSize.width - frameSize.width) / 2,
|
||||||
|
(screenSize.height - frameSize.height) / 2
|
||||||
|
);
|
||||||
|
this.filesButton.setText(
|
||||||
|
String.format(_("dialog_btn_files"), this.files.length));
|
||||||
|
this.dialog.setVisible(true);
|
||||||
|
|
||||||
|
return this.options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chooses the image files.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void chooseFiles() {
|
||||||
|
File chosen[] = new File[0];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
JFileChooser chooser = new JFileChooser(
|
||||||
|
this.currentDirectory);
|
||||||
|
FileNameExtensionFilter filter = new FileNameExtensionFilter(
|
||||||
|
_("dialog_file_chooser_image_type"), "jpg", "png", "gif");
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
|
chooser.setDialogTitle(_("dialog_file_chooser_title"));
|
||||||
|
chooser.setFileFilter(filter);
|
||||||
|
chooser.setMultiSelectionEnabled(true);
|
||||||
|
result = chooser.showOpenDialog(this.dialog);
|
||||||
|
this.currentDirectory = chooser.getCurrentDirectory();
|
||||||
|
|
||||||
|
if (result == JFileChooser.CANCEL_OPTION) {
|
||||||
|
return;
|
||||||
|
|
||||||
|
} else if (result == JFileChooser.ERROR_OPTION) {
|
||||||
|
JOptionPane.showMessageDialog(this.dialog,
|
||||||
|
_("err_file_chooser_failed"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
chosen = chooser.getSelectedFiles();
|
||||||
|
if (chosen.length > 256) {
|
||||||
|
JOptionPane.showMessageDialog(this.dialog,
|
||||||
|
_("err_file_too_many"),
|
||||||
|
String.format(_("dialog_err_title"),
|
||||||
|
CalcMosaic.APP_NAME),
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.files = chosen;
|
||||||
|
this.filesButton.setText(
|
||||||
|
String.format(_("dialog_btn_files"), this.files.length));
|
||||||
|
if (this.files.length == 0) {
|
||||||
|
this.okButton.setEnabled(false);
|
||||||
|
} else {
|
||||||
|
this.okButton.setEnabled(true);
|
||||||
|
this.okButton.grabFocus();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for the given key from this resource bundle
|
||||||
|
* or one of its parents. If the key is missing, returns
|
||||||
|
* the key itself.
|
||||||
|
*
|
||||||
|
* @param key the key for the desired string
|
||||||
|
* @return the string for the given key
|
||||||
|
*/
|
||||||
|
private String _(String key) {
|
||||||
|
try {
|
||||||
|
return new String(
|
||||||
|
this.l10n.getString(key).getBytes("ISO-8859-1"),
|
||||||
|
"UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e) {
|
||||||
|
return this.l10n.getString(key);
|
||||||
|
} catch (java.util.MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
58
src/tw/idv/imacat/calcmosaic/Options.java
Normal file
58
src/tw/idv/imacat/calcmosaic/Options.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Options
|
||||||
|
*
|
||||||
|
* Created on 2012-10-29
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The options of Calc Mosaic.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 0.0.1
|
||||||
|
*/
|
||||||
|
public class Options {
|
||||||
|
|
||||||
|
/** The image files. */
|
||||||
|
public File files[] = new File[0];;
|
||||||
|
|
||||||
|
/** The number of rows to use. */
|
||||||
|
public int numRows = 0;
|
||||||
|
|
||||||
|
/** Whether we should run in slow motion (for presentation). */
|
||||||
|
public boolean isSlow = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new set of options.
|
||||||
|
*
|
||||||
|
* @param files the image files
|
||||||
|
* @param numRows the number of rows to use
|
||||||
|
* @param isSlow whether we should run in slow motion (for
|
||||||
|
* presentation)
|
||||||
|
*/
|
||||||
|
public Options(File files[], int numRows, boolean isSlow) {
|
||||||
|
this.files = files;
|
||||||
|
this.numRows = numRows;
|
||||||
|
this.isSlow = isSlow;
|
||||||
|
}
|
||||||
|
}
|
655
src/tw/idv/imacat/calcmosaic/SpreadsheetDocument.java
Normal file
655
src/tw/idv/imacat/calcmosaic/SpreadsheetDocument.java
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
/* Copyright (c) 2012 imacat
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SpreadsheetDocument
|
||||||
|
*
|
||||||
|
* Created on 2012-08-16, rewritten from CalcMosaic
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 imacat
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
|
||||||
|
import com.sun.star.awt.Size;
|
||||||
|
import com.sun.star.awt.XView;
|
||||||
|
import com.sun.star.awt.XWindow;
|
||||||
|
import com.sun.star.beans.XPropertySet;
|
||||||
|
import com.sun.star.container.XIndexAccess;
|
||||||
|
import com.sun.star.container.XNameContainer;
|
||||||
|
import com.sun.star.frame.XController;
|
||||||
|
import com.sun.star.frame.XFrame;
|
||||||
|
import com.sun.star.frame.XModel;
|
||||||
|
import com.sun.star.lang.XComponent;
|
||||||
|
import com.sun.star.script.XLibraryContainer;
|
||||||
|
import com.sun.star.script.provider.XScript;
|
||||||
|
import com.sun.star.script.provider.XScriptProvider;
|
||||||
|
import com.sun.star.script.provider.XScriptProviderSupplier;
|
||||||
|
import com.sun.star.sheet.XSpreadsheetDocument;
|
||||||
|
import com.sun.star.table.XColumnRowRange;
|
||||||
|
import com.sun.star.table.XTableRows;
|
||||||
|
import com.sun.star.uno.UnoRuntime;
|
||||||
|
|
||||||
|
// Used in slow-motion mode.
|
||||||
|
import com.sun.star.awt.Point;
|
||||||
|
import com.sun.star.awt.Size;
|
||||||
|
import com.sun.star.awt.XControlModel;
|
||||||
|
import com.sun.star.container.XIndexContainer;
|
||||||
|
import com.sun.star.drawing.XControlShape;
|
||||||
|
import com.sun.star.drawing.XDrawPage;
|
||||||
|
import com.sun.star.drawing.XDrawPageSupplier;
|
||||||
|
import com.sun.star.drawing.XShape;
|
||||||
|
import com.sun.star.form.XFormComponent;
|
||||||
|
import com.sun.star.lang.XMultiServiceFactory;
|
||||||
|
import com.sun.star.script.ScriptEventDescriptor;
|
||||||
|
import com.sun.star.script.XEventAttacherManager;
|
||||||
|
import com.sun.star.sheet.XSpreadsheet;
|
||||||
|
import com.sun.star.sheet.XSpreadsheets;
|
||||||
|
import com.sun.star.sheet.XSpreadsheetView;
|
||||||
|
import com.sun.star.table.XCell;
|
||||||
|
import com.sun.star.table.XCellRange;
|
||||||
|
import com.sun.star.table.XColumnRowRange;
|
||||||
|
import com.sun.star.table.XTableColumns;
|
||||||
|
import com.sun.star.table.XTableRows;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A spreadsheet document.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 2.1.0
|
||||||
|
*/
|
||||||
|
public class SpreadsheetDocument {
|
||||||
|
|
||||||
|
/** The BASIC library name. */
|
||||||
|
private static final String libraryName = "Standard";
|
||||||
|
|
||||||
|
/** The localization resources. */
|
||||||
|
private ResourceBundle l10n = null;
|
||||||
|
|
||||||
|
/** The spreadsheet document. */
|
||||||
|
private XSpreadsheetDocument document = null;
|
||||||
|
|
||||||
|
/** The spreadsheet collection. */
|
||||||
|
private XSpreadsheets sheets = null;
|
||||||
|
|
||||||
|
/** The document controller. */
|
||||||
|
private XController xController = null;
|
||||||
|
|
||||||
|
/** The spreadsheet view. */
|
||||||
|
private XSpreadsheetView xSpreadsheetView = null;
|
||||||
|
|
||||||
|
/** The row height, to be cached. */
|
||||||
|
private int rowHeight = -1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of SpreadsheetDocument.
|
||||||
|
*
|
||||||
|
* @param document the document component
|
||||||
|
*/
|
||||||
|
public SpreadsheetDocument(XComponent document) {
|
||||||
|
XModel xModel = null;
|
||||||
|
|
||||||
|
// Obtains the localization resources
|
||||||
|
this.l10n = ResourceBundle.getBundle(
|
||||||
|
this.getClass().getPackage().getName() + ".res.L10n");
|
||||||
|
|
||||||
|
this.document = (XSpreadsheetDocument)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XSpreadsheetDocument.class, document);
|
||||||
|
|
||||||
|
this.sheets = this.document.getSheets();
|
||||||
|
|
||||||
|
// Obtains the document controller
|
||||||
|
xModel = (XModel) UnoRuntime.queryInterface(
|
||||||
|
XModel.class, this.document);
|
||||||
|
this.xController = xModel.getCurrentController();
|
||||||
|
this.xSpreadsheetView = (XSpreadsheetView)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XSpreadsheetView.class, this.xController);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a module of BASIC macros to the document.
|
||||||
|
*
|
||||||
|
* @param module the name of the module.
|
||||||
|
* @param macros the content of the module
|
||||||
|
*/
|
||||||
|
public void addBasicModule(String module, String macros) {
|
||||||
|
XPropertySet xProps = null;
|
||||||
|
Object libraries = null;
|
||||||
|
XLibraryContainer libraryContainer = null;
|
||||||
|
Object library = null;
|
||||||
|
XNameContainer moduleContainer = null;
|
||||||
|
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, this.document);
|
||||||
|
try {
|
||||||
|
libraries = xProps.getPropertyValue("BasicLibraries");
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
libraryContainer = (XLibraryContainer)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XLibraryContainer.class, libraries);
|
||||||
|
if (!libraryContainer.hasByName(libraryName)) {
|
||||||
|
try {
|
||||||
|
libraryContainer.createLibrary(libraryName);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.container.ElementExistException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
library = libraryContainer.getByName(libraryName);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
moduleContainer = (XNameContainer) UnoRuntime.queryInterface(
|
||||||
|
XNameContainer.class, library);
|
||||||
|
if (moduleContainer.hasByName(module)) {
|
||||||
|
try {
|
||||||
|
moduleContainer.removeByName(module);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
moduleContainer.insertByName(module, macros);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.container.ElementExistException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs a BASIC macro of the document.
|
||||||
|
*
|
||||||
|
* @param module the name of the module of the macro.
|
||||||
|
* @param macro the name of the macro.
|
||||||
|
* @param param the parameters for the macro
|
||||||
|
*/
|
||||||
|
public void runBasicMacro(String module, String macro, Object param[]) {
|
||||||
|
String scriptUri = String.format(
|
||||||
|
"vnd.sun.star.script:%s.%s.%s?language=Basic&location=document",
|
||||||
|
libraryName, module, macro);
|
||||||
|
XScriptProviderSupplier xSupplier = (XScriptProviderSupplier)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XScriptProviderSupplier.class, document);
|
||||||
|
XScriptProvider xProvider = xSupplier.getScriptProvider();
|
||||||
|
XScript xScript = null;
|
||||||
|
short outParamIndex[][] = new short[0][0];
|
||||||
|
Object outParam[][] = new Object[0][0];
|
||||||
|
|
||||||
|
try {
|
||||||
|
xScript = xProvider.getScript(scriptUri);
|
||||||
|
} catch (com.sun.star.script.provider.ScriptFrameworkErrorException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
xScript.invoke(param, outParamIndex, outParam);
|
||||||
|
} catch (com.sun.star.script.provider.ScriptFrameworkErrorException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.reflection.InvocationTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.DisposedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the window.
|
||||||
|
*
|
||||||
|
* @return the size of the window
|
||||||
|
*/
|
||||||
|
public Dimension getWindowSize() {
|
||||||
|
XFrame frame = this.xController.getFrame();
|
||||||
|
XWindow window = frame.getComponentWindow();
|
||||||
|
XView xView = (XView) UnoRuntime.queryInterface(
|
||||||
|
XView.class, window);
|
||||||
|
Size size = xView.getSize();
|
||||||
|
return new Dimension(size.Width - 55, size.Height - 72);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the height of the rows. We do not need
|
||||||
|
* the width, since the height is always shorter in new
|
||||||
|
* spreadsheets.
|
||||||
|
*
|
||||||
|
* @return the height of the rows.
|
||||||
|
*/
|
||||||
|
public int getRowHeight() {
|
||||||
|
if (this.rowHeight != -1) {
|
||||||
|
return this.rowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
XIndexAccess sheetIndexAccess = (XIndexAccess)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XIndexAccess.class, this.sheets);
|
||||||
|
Object sheet = null;
|
||||||
|
XColumnRowRange xColumnRowRange = null;
|
||||||
|
XTableRows rows = null;
|
||||||
|
XPropertySet xProps = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
sheet = sheetIndexAccess.getByIndex(0);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains the height of the rows.
|
||||||
|
xColumnRowRange = (XColumnRowRange) UnoRuntime.queryInterface(
|
||||||
|
XColumnRowRange.class, sheet);
|
||||||
|
rows = xColumnRowRange.getRows();
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, rows);
|
||||||
|
try {
|
||||||
|
this.rowHeight = (Integer)
|
||||||
|
xProps.getPropertyValue("Height");
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.rowHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a mosaic spreadsheet.
|
||||||
|
*
|
||||||
|
* @param name the spreadsheet name
|
||||||
|
* @param index the spreadsheet index
|
||||||
|
* @param colors the color values matrix
|
||||||
|
*/
|
||||||
|
public void createMosaicSheet(String name, int index,
|
||||||
|
int colors[][]) {
|
||||||
|
XSpreadsheet sheet = this.initializeMosaicSheet(name, index);
|
||||||
|
|
||||||
|
this.xSpreadsheetView.setActiveSheet(sheet);
|
||||||
|
this.setColumnWidth(sheet, colors.length, colors[0].length);
|
||||||
|
|
||||||
|
// Paints the colors.
|
||||||
|
for (int row = 0; row < colors.length; row++) {
|
||||||
|
for (int column = 0; column < colors[row].length; column++) {
|
||||||
|
XCell cell = null;
|
||||||
|
XPropertySet xProps = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
cell = sheet.getCellByPosition(column, row);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, cell);
|
||||||
|
try {
|
||||||
|
xProps.setPropertyValue(
|
||||||
|
"CellBackColor", colors[row][column]);
|
||||||
|
xProps.setPropertyValue(
|
||||||
|
"IsCellBackgroundTransparent", false);
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.beans.PropertyVetoException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a mosaic spreadsheet.
|
||||||
|
*
|
||||||
|
* @param name the spreadsheet name
|
||||||
|
* @param index the spreadsheet index
|
||||||
|
* @return the spreadsheet
|
||||||
|
*/
|
||||||
|
private XSpreadsheet initializeMosaicSheet(
|
||||||
|
String name, int index) {
|
||||||
|
XIndexAccess sheetIndexAccess = (XIndexAccess)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XIndexAccess.class, this.sheets);
|
||||||
|
Object sheet = null;
|
||||||
|
XSpreadsheet xSheet = null;
|
||||||
|
|
||||||
|
// Adds our spreadsheet.
|
||||||
|
if (this.sheets.hasByName(name)) {
|
||||||
|
if (sheetIndexAccess.getCount() == 1) {
|
||||||
|
this.sheets.insertNewByName(name + 1, (short) 0);
|
||||||
|
try {
|
||||||
|
this.sheets.removeByName(name);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
this.sheets.insertNewByName(name, (short) index);
|
||||||
|
try {
|
||||||
|
this.sheets.removeByName(name + 1);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
this.sheets.removeByName(name);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
this.sheets.insertNewByName(name, (short) index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.sheets.insertNewByName(name, (short) index);
|
||||||
|
}
|
||||||
|
// Cleans-up
|
||||||
|
if (index == 0) {
|
||||||
|
String names[] = this.sheets.getElementNames();
|
||||||
|
for (int i = 0; i < names.length; i++) {
|
||||||
|
if (!names[i].equals(name)) {
|
||||||
|
try {
|
||||||
|
this.sheets.removeByName(names[i]);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obtains the speadsheet.
|
||||||
|
try {
|
||||||
|
sheet = sheets.getByName(name);
|
||||||
|
} catch (com.sun.star.container.NoSuchElementException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
xSheet = (XSpreadsheet) UnoRuntime.queryInterface(
|
||||||
|
XSpreadsheet.class, sheet);
|
||||||
|
return xSheet;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the width of the columns.
|
||||||
|
*
|
||||||
|
* @param sheet the spreadsheet
|
||||||
|
* @param rows the number of rows in the cell range
|
||||||
|
* @param columns the number of columns in the cell range
|
||||||
|
*/
|
||||||
|
private void setColumnWidth(XSpreadsheet sheet,
|
||||||
|
int rows, int columns) {
|
||||||
|
XCellRange range = null;
|
||||||
|
XColumnRowRange xColumnRowRange = null;
|
||||||
|
XTableColumns xColumns = null;
|
||||||
|
int height = -1;
|
||||||
|
XPropertySet xProps = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
range = sheet.getCellRangeByPosition(
|
||||||
|
0, 0, columns - 1, rows - 1);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
xColumnRowRange = (XColumnRowRange) UnoRuntime.queryInterface(
|
||||||
|
XColumnRowRange.class, range);
|
||||||
|
xColumns = xColumnRowRange.getColumns();
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, xColumns);
|
||||||
|
try {
|
||||||
|
xProps.setPropertyValue("Width", this.getRowHeight());
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.beans.PropertyVetoException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the macro triggers to show the sheets.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void addMacroTriggers() {
|
||||||
|
XIndexAccess sheetIndexAccess = (XIndexAccess)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XIndexAccess.class, this.sheets);
|
||||||
|
int count = sheetIndexAccess.getCount();
|
||||||
|
Object firstSheet = null, lastSheet = null;
|
||||||
|
XSpreadsheet xFirstSheet = null, xLastSheet;
|
||||||
|
XCell breaksCell = null, musicCell = null;
|
||||||
|
XPropertySet breaksCellProps = null, musicCellProps = null;
|
||||||
|
int breaksColor = -1, musicColor = -1;
|
||||||
|
|
||||||
|
// Adds start buttons on the first and the last sheets.
|
||||||
|
try {
|
||||||
|
firstSheet = sheetIndexAccess.getByIndex(0);
|
||||||
|
lastSheet = sheetIndexAccess.getByIndex(count - 1);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
xFirstSheet = (XSpreadsheet) UnoRuntime.queryInterface(
|
||||||
|
XSpreadsheet.class, firstSheet);
|
||||||
|
xLastSheet = (XSpreadsheet) UnoRuntime.queryInterface(
|
||||||
|
XSpreadsheet.class, lastSheet);
|
||||||
|
this.addStartButton(xFirstSheet);
|
||||||
|
this.addStartButton(xLastSheet);
|
||||||
|
|
||||||
|
// Sets the text color to be the same as the background color
|
||||||
|
// at B1 and C1 of the first sheet, where are the breaks
|
||||||
|
// between sheets and the music files, so that users can
|
||||||
|
// hide these two pieces of information.
|
||||||
|
this.xSpreadsheetView.setActiveSheet(xFirstSheet);
|
||||||
|
try {
|
||||||
|
breaksCell = xFirstSheet.getCellByPosition(1, 0);
|
||||||
|
musicCell = xFirstSheet.getCellByPosition(2, 0);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
breaksCellProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, breaksCell);
|
||||||
|
musicCellProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, musicCell);
|
||||||
|
try {
|
||||||
|
breaksColor = (Integer) breaksCellProps.getPropertyValue(
|
||||||
|
"CellBackColor");
|
||||||
|
musicColor = (Integer) musicCellProps.getPropertyValue(
|
||||||
|
"CellBackColor");
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
breaksCellProps.setPropertyValue(
|
||||||
|
"CharColor", breaksColor);
|
||||||
|
musicCellProps.setPropertyValue(
|
||||||
|
"CharColor", musicColor);
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.beans.PropertyVetoException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a start button to show the sheets.
|
||||||
|
*
|
||||||
|
* @param sheet the spreadsheet to add a start button unto
|
||||||
|
*/
|
||||||
|
private void addStartButton(XSpreadsheet sheet) {
|
||||||
|
XMultiServiceFactory serviceManager = (XMultiServiceFactory)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XMultiServiceFactory.class, this.document);
|
||||||
|
Object shape = null;
|
||||||
|
XControlShape xShape = null;
|
||||||
|
Point position = new Point();
|
||||||
|
Size size = new Size();
|
||||||
|
Object button = null;
|
||||||
|
XCell cell = null;
|
||||||
|
XPropertySet xProps = null;
|
||||||
|
int color = -1;
|
||||||
|
XControlModel buttonModel = null;
|
||||||
|
XDrawPageSupplier xDrawPageSupplier = null;
|
||||||
|
XDrawPage drawPage = null;
|
||||||
|
ScriptEventDescriptor event = new ScriptEventDescriptor();
|
||||||
|
XFormComponent xFormComponent = null;
|
||||||
|
Object form = null;
|
||||||
|
XIndexContainer xContainer = null;
|
||||||
|
XEventAttacherManager xEventAttacherManager = null;
|
||||||
|
|
||||||
|
// Creates the shape for the button, as a control shape.
|
||||||
|
try {
|
||||||
|
shape = serviceManager.createInstance(
|
||||||
|
"com.sun.star.drawing.ControlShape");
|
||||||
|
} catch (com.sun.star.uno.Exception e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
xShape = (XControlShape) UnoRuntime.queryInterface(
|
||||||
|
XControlShape.class, shape);
|
||||||
|
position.X = 0;
|
||||||
|
position.Y = 0;
|
||||||
|
xShape.setPosition(position);
|
||||||
|
size.Width = this.getRowHeight();
|
||||||
|
size.Height = size.Width;
|
||||||
|
try {
|
||||||
|
xShape.setSize(size);
|
||||||
|
} catch (com.sun.star.beans.PropertyVetoException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates the button.
|
||||||
|
try {
|
||||||
|
button = serviceManager.createInstance(
|
||||||
|
"com.sun.star.form.component.CommandButton");
|
||||||
|
} catch (com.sun.star.uno.Exception e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
cell = sheet.getCellByPosition(0, 0);
|
||||||
|
} catch (com.sun.star.lang.IndexOutOfBoundsException e) {
|
||||||
|
throw new java.lang.IndexOutOfBoundsException(
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, cell);
|
||||||
|
try {
|
||||||
|
color = (Integer) xProps.getPropertyValue(
|
||||||
|
"CellBackColor");
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
xProps = (XPropertySet) UnoRuntime.queryInterface(
|
||||||
|
XPropertySet.class, button);
|
||||||
|
try {
|
||||||
|
xProps.setPropertyValue("BackgroundColor", color);
|
||||||
|
} catch (com.sun.star.beans.UnknownPropertyException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.beans.PropertyVetoException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
} catch (com.sun.star.lang.WrappedTargetException e) {
|
||||||
|
throw new java.lang.RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the button to the page.
|
||||||
|
buttonModel = (XControlModel) UnoRuntime.queryInterface(
|
||||||
|
XControlModel.class, button);
|
||||||
|
xShape.setControl(buttonModel);
|
||||||
|
xDrawPageSupplier = (XDrawPageSupplier) UnoRuntime.queryInterface(
|
||||||
|
XDrawPageSupplier.class, sheet);
|
||||||
|
drawPage = xDrawPageSupplier.getDrawPage();
|
||||||
|
drawPage.add(xShape);
|
||||||
|
|
||||||
|
// Sets the action of the button
|
||||||
|
event.ListenerType = "XActionListener";
|
||||||
|
event.EventMethod = "actionPerformed";
|
||||||
|
event.ScriptType = "Script";
|
||||||
|
event.ScriptCode = "vnd.sun.star.script:"
|
||||||
|
+ "Standard._0Play.subPlaySheets"
|
||||||
|
+ "?language=Basic&location=document";
|
||||||
|
xFormComponent = (XFormComponent) UnoRuntime.queryInterface(
|
||||||
|
XFormComponent.class, button);
|
||||||
|
form = xFormComponent.getParent();
|
||||||
|
xContainer = (XIndexContainer) UnoRuntime.queryInterface(
|
||||||
|
XIndexContainer.class, form);
|
||||||
|
xEventAttacherManager = (XEventAttacherManager)
|
||||||
|
UnoRuntime.queryInterface(
|
||||||
|
XEventAttacherManager.class, form);
|
||||||
|
try {
|
||||||
|
xEventAttacherManager.registerScriptEvent(
|
||||||
|
xContainer.getCount() - 1, event);
|
||||||
|
} catch (com.sun.star.lang.IllegalArgumentException e) {
|
||||||
|
throw new java.lang.IllegalArgumentException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a string for the given key from this resource bundle
|
||||||
|
* or one of its parents. If the key is missing, returns
|
||||||
|
* the key itself.
|
||||||
|
*
|
||||||
|
* @param key the key for the desired string
|
||||||
|
* @return the string for the given key
|
||||||
|
*/
|
||||||
|
private String _(String key) {
|
||||||
|
try {
|
||||||
|
return new String(
|
||||||
|
this.l10n.getString(key).getBytes("ISO-8859-1"),
|
||||||
|
"UTF-8");
|
||||||
|
} catch (java.io.UnsupportedEncodingException e) {
|
||||||
|
return this.l10n.getString(key);
|
||||||
|
} catch (java.util.MissingResourceException e) {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
src/tw/idv/imacat/calcmosaic/package-info.java
Normal file
8
src/tw/idv/imacat/calcmosaic/package-info.java
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/**
|
||||||
|
* A program to create mosaic art from images with Calc.
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 0.1.1
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic;
|
53
src/tw/idv/imacat/calcmosaic/res/L10n.properties
Normal file
53
src/tw/idv/imacat/calcmosaic/res/L10n.properties
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# The default resource properties
|
||||||
|
author = imacat <imacat@mail.imacat.idv.tw>
|
||||||
|
err_rows_miss = You did not specify the number of rows to use.
|
||||||
|
err_rows_not_pint = The number of rows is not a positive integer.
|
||||||
|
err_file_not_exist = File does not exist.
|
||||||
|
err_file_not_a_file = Not a file.
|
||||||
|
err_file_too_many = Too many images (256 max). A spreadsheet document can only contain at most 256 spreadsheets.
|
||||||
|
err_file_not_an_image = Not an image.
|
||||||
|
err_file_chooser_failed = Failed to select the images.
|
||||||
|
err_arg_unknown = Unrecognized switch.
|
||||||
|
err_ooo_no_lcc = Failed to obtain the local component context.
|
||||||
|
err_open = Failed to open “%s”.
|
||||||
|
dialog_opts_title = %s Options
|
||||||
|
dialog_btn_files = %d file(s)
|
||||||
|
dialog_label_files = Image files:
|
||||||
|
dialog_label_numrows = Number of rows:
|
||||||
|
dialog_checkbox_isslow = Run in slow motion
|
||||||
|
dialog_label_isslow = Slow?
|
||||||
|
dialog_btn_ok = OK
|
||||||
|
dialog_btn_cancel = Cancel
|
||||||
|
dialog_file_chooser_title = Select Image Files
|
||||||
|
dialog_file_chooser_image_type = Image files (JPG, PNG, GIF)
|
||||||
|
dialog_err_title = %s Error
|
||||||
|
help = \
|
||||||
|
Usage: java -jar %s [options] image1 [image2...]\n\
|
||||||
|
Create mosaic art from images with Calc.\n\
|
||||||
|
\n \
|
||||||
|
-r,-rows num The number of rows to use (default to\n \
|
||||||
|
estimate it automatically).\n \
|
||||||
|
-s,-slow Run in slow motion (for presentation).\n \
|
||||||
|
-noslow Run in the normal speed (default).\n \
|
||||||
|
-h,-help Display this help.\n \
|
||||||
|
-v,-version Display version number.\n \
|
||||||
|
image1, image2... The image files.\n\
|
||||||
|
\n\
|
||||||
|
The snapshots of a video can be grabbed using ffmpeg:\n\
|
||||||
|
ffmpeg -i video.mp4 -r <framerate> -sameq -y -f image2 img%%04d.jpg\n\
|
||||||
|
Note that a spreadsheet document can only contain at most 256 spreadsheets.
|
||||||
|
version = %s v%s by %s
|
||||||
|
finished = \
|
||||||
|
Done. Notice:\n\
|
||||||
|
1. Save file first for the macro to work.\n\
|
||||||
|
2. Hit the start button at A1 of the first\n \
|
||||||
|
and last sheet to play the sheets.\n\
|
||||||
|
3. You can set the break time (in\n \
|
||||||
|
milliseconds) between sheets at B1 of\n \
|
||||||
|
the first sheet (default 100 ms).\n\
|
||||||
|
4. You can set the background music at C1\n \
|
||||||
|
of the first sheet. This only works on\n \
|
||||||
|
Linux and you must install mplayer.\n \
|
||||||
|
Relative file path is relative to the\n \
|
||||||
|
document file. Play once before your\n \
|
||||||
|
live show to avoid the I/O delay with cache.
|
50
src/tw/idv/imacat/calcmosaic/res/L10n_zh_TW.properties
Normal file
50
src/tw/idv/imacat/calcmosaic/res/L10n_zh_TW.properties
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# The Chinese-Taiwan resource properties
|
||||||
|
author = 依瑪貓 <imacat@mail.imacat.idv.tw>
|
||||||
|
err_rows_miss = 沒有設定要使用幾個橫列。
|
||||||
|
err_rows_not_pint = 橫列數不是正整數。
|
||||||
|
err_file_not_exist = 查無此檔。
|
||||||
|
err_file_not_a_file = 不是檔案。
|
||||||
|
err_file_too_many = 圖檔太多(最多 256 個圖)。試算表文件最多只能有 256 張試算表。
|
||||||
|
err_file_not_an_image = 不是圖檔。
|
||||||
|
err_file_chooser_failed = 選擇圖檔失敗。
|
||||||
|
err_arg_unknown = 參數不明。
|
||||||
|
err_ooo_no_lcc = 無法取得local component context。
|
||||||
|
err_open = 無法開啟「%s」。
|
||||||
|
dialog_opts_title = %s 選項
|
||||||
|
dialog_btn_files = %d 個圖檔(F)
|
||||||
|
dialog_label_files = 圖檔:
|
||||||
|
dialog_label_numrows = 橫列數:
|
||||||
|
dialog_checkbox_isslow = 以慢動作執行。
|
||||||
|
dialog_label_isslow = 慢動作?
|
||||||
|
dialog_btn_ok = 確定(O)
|
||||||
|
dialog_btn_cancel = 取消(C)
|
||||||
|
dialog_file_chooser_title = 請選擇圖檔
|
||||||
|
dialog_file_chooser_image_type = 圖檔(JPG、PNG、GIF)
|
||||||
|
dialog_err_title = %s 錯誤
|
||||||
|
help = \
|
||||||
|
用法: java -jar %s [選項] 圖檔1 [圖檔2...]\n\
|
||||||
|
用 Calc 製作馬賽克拼貼圖。\n\
|
||||||
|
\n \
|
||||||
|
-r,-rows 列數 要用的橫列數(預設自動估算)。\n \
|
||||||
|
-s,-slow 以慢動作執行(簡報用)。\n \
|
||||||
|
-noslow 以正常速度執行(預設)。\n \
|
||||||
|
-h,-help 顯示這個說明。\n \
|
||||||
|
-v,-version 顯示版號。\n \
|
||||||
|
圖檔1, 圖檔2... 圖檔。\n\
|
||||||
|
\n\
|
||||||
|
可以用 ffmpeg 來抓影片截圖:\n\
|
||||||
|
ffmpeg -i 影片檔.mp4 -r <影格率> -sameq -y -f image2 img%%04d.jpg\n\
|
||||||
|
註:一個試算表檔,最多只能有 256 張試算表。
|
||||||
|
version = %s %s 版,作者 %s
|
||||||
|
finished = \
|
||||||
|
執行結束。請注意:\n\
|
||||||
|
1. 要先存檔,才能執行巨集。\n\
|
||||||
|
2. 第一張和最後一張試算表的 A1 有隱藏按鈕,按\n \
|
||||||
|
下去會播放試算表。\n\
|
||||||
|
3. 在第一張試算表的 B1 ,可以設定每張試算表播\n \
|
||||||
|
放的間隔時間(單位毫秒)。預設 100 毫秒。\n\
|
||||||
|
4. 在第一張試算表的 C1 ,可以設定背景音樂檔。\n \
|
||||||
|
背景音樂只支援 Linux ,需安裝 mplayer 。\n \
|
||||||
|
相對路徑相對於試算表檔案本身。為避免音樂延\n \
|
||||||
|
遲,實際表演前,請先執行過一遍,以快取硬碟\n \
|
||||||
|
資料。
|
12
src/tw/idv/imacat/calcmosaic/res/package-info.java
Normal file
12
src/tw/idv/imacat/calcmosaic/res/package-info.java
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* The localization resource bundles for the mosaic art creator.
|
||||||
|
* The creation of a seperate package space is to prevent name
|
||||||
|
* clashing with the localization resource bundles of the client
|
||||||
|
* applications. <em>Do not use anything in this package unless you
|
||||||
|
* know what you are doing.</em>
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:imacat@mail.imacat.idv.tw">imacat</a>
|
||||||
|
* @version 0.01
|
||||||
|
*/
|
||||||
|
|
||||||
|
package tw.idv.imacat.calcmosaic.res;
|
Loading…
Reference in New Issue
Block a user