commit 8362bf63dea22bbf6736609b0f49c152f975eb63 Author: tpearson Date: Wed Jan 20 01:29:50 2010 +0000 Added old abandoned KDE3 version of koffice git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..f47405b82 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +See in the each subdirectory for the authors of each KOffice application/filter. diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..2e6a0b73d --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 000000000..788ed3e53 --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,486 @@ +NOTE! The LGPL below is copyrighted by the Free Software Foundation, but +the instance of code that it refers to (parts of koffice) are copyrighted +by the authors who actually wrote it. + +--------------------------------------------------------------------------- + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Suite 330 + Boston, MA 02110-1301, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Doxyfile.temp b/Doxyfile.temp new file mode 100644 index 000000000..6f60392b7 --- /dev/null +++ b/Doxyfile.temp @@ -0,0 +1,199 @@ +# Doxyfile 0.1 + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = KOffice +PROJECT_NUMBER = "SVN trunk" +OUTPUT_DIRECTORY = "../apidocs" +OUTPUT_LANGUAGE = English +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ALWAYS_DETAILED_SEC = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +INTERNAL_DOCS = NO +STRIP_CODE_COMMENTS = YES +CASE_SENSE_NAMES = YES +SHORT_NAMES = NO +HIDE_SCOPE_NAMES = NO +VERBATIM_HEADERS = YES +SHOW_INCLUDE_FILES = YES +JAVADOC_AUTOBRIEF = NO +INHERIT_DOCS = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +ALIASES = +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +OPTIMIZE_OUTPUT_FOR_C = NO +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = NO +WARN_FORMAT = +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = example \ + filters \ + interfaces \ + karbon \ + kchart \ + kdgantt \ + kexi \ + kformula \ + kivio \ + koshell \ + kplato \ + kpresenter \ + krita \ + kspread kugar kword lib +FILE_PATTERNS = *.h +RECURSIVE = YES +#EXCLUDE = \ +#arts/tests kdeprint/tests khtml/java/tests kio/kfile/tests kioslave/http/kcookiejar/tests kwallet/backend/tests \ +#kdecore/tests kdeui/tests kinit/tests kio/tests kparts/tests libkmid/tests +# */tests doesn't seem to work :( + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = *.ui.h *.moc.* Makefile.* ChangeLog CHANGES CHANGES.* README \ + README.* *.png AUTHORS DESIGN DESIGN.* *.desktop \ + DESKTOP* COMMENTS HOWTO magic NOTES TODO THANKS + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .kde3 +MAN_LINKS = YES +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +TEMPLATE_RELATIONS = YES +HIDE_UNDOC_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 640 +MAX_DOT_GRAPH_HEIGHT = 1024 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +CGI_NAME = +CGI_URL = +DOC_URL = +DOC_ABSPATH = +BIN_ABSPATH = +EXT_DOC_PATHS = diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..3a1a94ab1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,186 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes a while. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/kde/bin', `/usr/local/kde/lib', etc. You can specify an +installation prefix other than `/usr/local/kde' by giving `configure' +the option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +KDE Specific +============ + +If you use ./configure --prefix to install KOffice in a different +location than the rest of KDE, you need to tell KDE about it. +For this, either set $KDEDIRS so that it contains both prefixes, +or add this to /etc/kderc : +[Directories] +prefixes=/the/prefix/I/used/to/install/koffice/ + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/Mainpage.dox b/Mainpage.dox new file mode 100644 index 000000000..7b7837450 --- /dev/null +++ b/Mainpage.dox @@ -0,0 +1,12 @@ +/** +* @mainpage KOffice API Reference +* +* +* KOffice consists of a number of applications. +* Very few actually have any API dox to speak of. +* +* - KDGantt +* - Kexi +* - KSpread +* +*/ diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..046318517 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,20 @@ +## koffice/Makefile.am.in +## (C) 1997 Stephan Kulow + +AUTOMAKE_OPTIONS = foreign 1.4 +COMPILE_FIRST = lib interfaces +# COMPILE_BEFORE_kexi = kword kugar +# COMPILE_BEFORE_kplato = kdgantt kugar +# For kword/mailmerge/kspread +# COMPILE_BEFORE_kword = kspread +# COMPILE_BEFORE_ascend = kword +COMPILE_LAST = filters +DISTCLEANFILES = inst-apps + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 SUBDIRS + +include admin/deps.am + +include admin/Doxyfile.am + +SUBDIRS=$(TOPSUBDIRS) diff --git a/Makefile.am.in b/Makefile.am.in new file mode 100644 index 000000000..c39c17c79 --- /dev/null +++ b/Makefile.am.in @@ -0,0 +1,19 @@ +## koffice/Makefile.am.in +## (C) 1997 Stephan Kulow + +AUTOMAKE_OPTIONS = foreign 1.4 +COMPILE_FIRST = lib interfaces +COMPILE_BEFORE_kexi = kword kugar +COMPILE_BEFORE_kplato = kdgantt kugar +# For kword/mailmerge/kspread +COMPILE_BEFORE_kword = kspread +COMPILE_BEFORE_ascend = kword +COMPILE_LAST = filters +DISTCLEANFILES = inst-apps + +MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 SUBDIRS + +include admin/deps.am + +include admin/Doxyfile.am + diff --git a/Makefile.cvs b/Makefile.cvs new file mode 100644 index 000000000..be59a8695 --- /dev/null +++ b/Makefile.cvs @@ -0,0 +1,14 @@ +all: + @echo "This Makefile is only for the CVS repository" + @echo "This will be deleted before making the distribution" + @echo "" + @if test ! -d admin; then \ + echo "Please recheckout this module!" ;\ + echo "for cvs: use checkout once and after that update again" ;\ + echo "for cvsup: checkout kde-common from cvsup and" ;\ + echo " link kde-common/admin to ./admin" ;\ + exit 1 ;\ + fi + $(MAKE) -f admin/Makefile.common cvs + +.SILENT: diff --git a/README b/README new file mode 100644 index 000000000..e979baed2 --- /dev/null +++ b/README @@ -0,0 +1,92 @@ +KOffice is based on KDE ( http://www.kde.org ) which is needed to run KOffice. +You need kdelibs and kdebase installed if you want to compile and run +KOffice. Look in the kdelibs sourcedir for the file COMPILING for help. Also +look at the website as there are many helpfiles available. + +KOffice is a collection of office applications linked together by a common +basis. This common basis assures that all office application can work +together. You can, for instance, insert a spreadsheet in your thesis without +leaving your document. Editing the spreadsheet happens _inside_ your thesis. + +The applications currently included in KOffice are: +- KWord + Professional text editing +- KSpread + Professional number cruncher/spreadsheet +- KPresenter + Professional presentation program +- KChart + Graphing of your abstract data +- Karbon + Vector graphics tool +- Kugar + Database report creation +- Kivio + Flowcharting program +- Kexi + Integrated data management +- Krita + A pixel graphics tool +- KFormula + A mathematical formula editor +- KOffice Workspace + A combination of all of the above + +Note: these applications are not necessarily part of the previous or next +official stable version of KOffice. + +Developers: +=========== + +KOffice is created by Open Source programmers around the world. All developers +give their time/code to the community for everyone to benefit. The major reason +this is done is because those developers want to have a good office suite, and +they don't mind sharing it with you. + +If you feel you found a bug or missing feature you can always contact the +developers of KOffice (via http://www.koffice.org ) or delve into the software +yourself. + +The part that is shared between all KOffice applications can be found in the lib +directory. There classes like KoDocument can be found; these classes are +extended in the project directories. + +Read the .h files in the respective directories for more info. + + +Document format: +================ + +Nearly all KOffice applications use XML formatted files in a ZIP file. + +The main document in XML format can be read with a text editor (after having +unzip-ped it from the ZIP file.) XML itself is simply a set of tags, +where the application can define the meaning of these tags. The definition of +the document type is therefore different for each KOffice application (as you +will most likely not find a curved line in a KWord document). The Document Type +Definition can be found in every application's source directory in the +directory '(application)/dtd.' + +If you would like more information about the makeup of the actual KOffice +document structure (not the XML DTD), see the lib/store/SPEC file. + +If you want to see more/fix bugs in this file, feel free to ask or add it +yourself. + + +Contacts: +========= + +User mailing list: mailto:koffice@kde.org +Developer mailing list: mailto:koffice-devel@kde.org + +Subscribing and list information: http://www.kde.org/mailinglists +Archives: http://lists.kde.org + +If you have questions about this README file or about KOffice in general, +please mail to the KOffice mailing list: mailto:koffice@kde.org + + + +Thomas Zander +Chris Lee diff --git a/README.APPS b/README.APPS new file mode 100644 index 000000000..6e76e0b20 --- /dev/null +++ b/README.APPS @@ -0,0 +1,31 @@ +This directory contains the source code for the upcoming KOffice 1.6. +The 1.6 release is a kind of "in-between" release, and not every program +will be actively developed here. + +The maintainers of some programs have announced that they think that +the release cycle for 2.0 is too long and want a feature release in +between 1.5 and 2.0. For all the rest of the programs, bugfixes that +are committed in the 1.5 branch will be forward ported to 1.6 at the +time of the release. + +The real development will happen in trunk, and will eventually lead to +KOffice version 2.0, which will be based on Qt4 and kdelibs4. + +Here is the list of applications and libraries that will be developed +in the 1.6 cycle: + +- lib/koproperty +- lib/kross +- kchart +- kexi +- krita +- kdgantt +- kplato +- doc +- kformula +- lib/kformula + +It is up to the maintainer of those applications to merge their change +with trunk, and with 1.5 for fixed bugs. For all the rest of the +applications / subdirectories, all changes for 1.5 will be forward +ported as described above. diff --git a/README.PACKAGERS b/README.PACKAGERS new file mode 100644 index 000000000..af3849903 --- /dev/null +++ b/README.PACKAGERS @@ -0,0 +1,187 @@ +Packaging Information for KOffice. +---------------------------------- + +We recommend building several binary packages from the KOffice source. + +Splitting KOffice into packages: + * gives users a better choice of which components they have + installed; + * allows users to install just the applications without unnecessary + dependencies; + * helps to reduce packaging conflicts for users with non-standard + package selections. + + +Table Of Contents +----------------- + +1. Database drivers (MySQL, PostgreSQL) +2. Development files + 2.1. KexiDB development files + 2.2. Krita development files +3. Scripting support +4. Microsoft Access Import (optional, recommended) +5. Quick command-line tests of Kexi installation + + + +1. Database drivers +------------------- + +Kexi provides database drivers for MySQL and PostgreSQL. We suggest +putting each driver in a separate package, and that installation of +these packages be optional. Each driver package may then depend on +the corresponding 'native' libraries: libmysqlclient for MySQL; and +and libpqxx for PostgreSQL (libpqxx in turn depends on libpq). + +Thus, the MySQL driver package could contain: + lib/kde3/kexidb_mysqldriver.so + lib/kde3/kexidb_mysqldriver.la + lib/kde3/keximigrate_mysql.so + lib/kde3/keximigrate_mysql.la + share/services/kexidb_mysqldriver.desktop + share/services/keximigrate_mysql.desktop + +The PostgreSQL driver package consists of the following files: + lib/kde3/kexidb_pqxxsqldriver.so + lib/kde3/kexidb_pqxxsqldriver.la + lib/kde3/keximigrate_pqxx.so + lib/kde3/keximigrate_pqxx.la + share/services/kexidb_pqxxsqldriver.desktop + share/services/keximigrate_pqxx.desktop + +Note that you SHOULD NOT care about SQLite database driver or adding +dependencies for SQLite, because SQLite support is built into Kexi +using a fork of SQLite source code. + + +2. Development files +-------------------- + +2.1. KexiDB development files + +Location: koffice/kexi/kexiutils, koffice/kexi/kexidb, koffice/kexi/migration + +KexiDB, the database abstraction library used in Kexi, installs some +development files which are required for building external plugins, +such as the MS Access import plugin described below. + +We recommend providing KexiDB development files in a separate package. +The files are: + include/kexidb/*.h + include/kexiutils/*.h + lib/libkexidb.la + lib/libkexidb.so + lib/libkexidbparser.so + lib/libkexidbparser.la + +The installation can be tested by building the MS Access import plugin +as described in the Microsoft Access import plugin section below. + +2.2. Krita development files + +Location: koffice/krita/core, koffice/krita/sdk, +koffice/krita/kritacolor, koffice/krita/ui + +These directories contain header files that are installed and can be +used by plugin developers to extend Krita with new tools, colorspaces, +paint-ops and more. If your distribution packages development files +separately, it may be a good idea to make a package with these headers. + + +3. Scripting support +-------------------- + +Preliminary support for Ruby and Python scripting is available for +Krita and Kexi. +It can be disabled by passing the '--disable-scripting' option to +'configure'. + +The 'Kross' scripting library (koffice/lib/kross) provides access to +the Python and Ruby scripting languages by the dynamically loaded +plugins. + +Build time dependencies: + Python and Ruby development packages need to be installed in order + to build KOffice with full scripting support. In addition, the Ruby + interpreter is also required at build time. + +Run time dependencies: + Kross detects which of these libraries is installed dynamically, at + run-time. Therefore, KOffice packages need not have any run-time + dependencies on any scripting interpreter. + +The scripting language plugins can be found in: + koffice/lib/kross/python; and + koffice/lib/kross/ruby. +They install as: + lib/kde3/krosspython.{la,so}; and + lib/kde3/krossruby.{la,so} + +It is recommended to put each interpreter plugin into a separate +package, and the user decide if they would like support for each +language individually. + +For example, the Python scripting package may contain: + lib/kde3/krosspython.so + lib/kde3/krosspython.la + share/apps/kexi/scripts/exportxhtml/ExportXHTML.py + share/apps/kexi/scripts/exportxhtml/ExportXHTML.rc + share/apps/kexi/scripts/importxhtml/ImportXHTML.py + share/apps/kexi/scripts/importxhtml/ImportXHTML.rc + share/apps/kexi/scripts/projectdocumentor/ProjectDocumentor.py + share/apps/kexi/scripts/projectdocumentor/ProjectDocumentor.rc + share/apps/krita/scripts/invert.py + share/apps/krita/scripts/reshapehisto.py + +and the Ruby scripting package may contain: + lib/kde3/krossruby.so + lib/kde3/krossruby.la + share/apps/krita/scripts/ruby/invert.rb + share/apps/krita/scripts/ruby/changecs.rb + share/apps/krita/scripts/ruby/randompaint.rb + + +4. Microsoft Access Import (optional, recommended) +------------------------------------- + +A plugin to allow the import of MS Access (.mdb) files is available +for packaging separately. It is called KexiMDB. + +This package is based on a stripped-down and modified version of +mdbtools: http://mdbtools.sf.net/ +The package should be built after KOffice. It requires GLib, and the +Kexi development files as described above. + +The version of the plugin for use with KOffice 1.5 should be available +from: +ftp://ftp.kde.org/pub/kde/stable/apps/KDE3.x/database/keximdb-1.0.tar.gz + +Alternatively, it can be found in the KDE Subversion repository. It +can be built as follows: + svn export svn://anonsvn.kde.org/home/kde/branches/work/keximdb/koffice-1.5 keximdb-1.0 + cd keximdb-1.0 + make -f Makefile.cvs + ./configure --enable-debug=full + make + make install + +Configure may need to be informed of the location of the KexiDB +headers using the --with-kexidb-includes=... and the +--with-kexidb-libraries=... options. + + +5. Quick command-line tests of Kexi installation +------------------------------------------------ + +If you don't want to click through Kexi interface but still want +to make (almost) sure the application is properly packaged, please +install it and type the following from the command line: + + kexi --create-opendb --drv sqlite3 --new form testdb + +(ignore possible warning message) +This will: +- create a new empty database file "testdb", +- open it, +- create a new empty form diff --git a/acinclude.m4 b/acinclude.m4 new file mode 100644 index 000000000..660b34573 --- /dev/null +++ b/acinclude.m4 @@ -0,0 +1,12406 @@ +## -*- autoconf -*- + +dnl This file is part of the KDE libraries/packages +dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu) +dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org) + +dnl This file is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Library General Public +dnl License as published by the Free Software Foundation; either +dnl version 2 of the License, or (at your option) any later version. + +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Library General Public License for more details. + +dnl You should have received a copy of the GNU Library General Public License +dnl along with this library; see the file COPYING.LIB. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +dnl Boston, MA 02110-1301, USA. + +dnl IMPORTANT NOTE: +dnl Please do not modify this file unless you expect your modifications to be +dnl carried into every other module in the repository. +dnl +dnl Single-module modifications are best placed in configure.in for kdelibs +dnl and kdebase or configure.in.in if present. + +# KDE_PATH_X_DIRECT +dnl Internal subroutine of AC_PATH_X. +dnl Set ac_x_includes and/or ac_x_libraries. +AC_DEFUN([KDE_PATH_X_DIRECT], +[ +AC_REQUIRE([KDE_CHECK_LIB64]) + +if test "$ac_x_includes" = NO; then + # Guess where to find include files, by looking for this one X11 .h file. + test -z "$x_direct_test_include" && x_direct_test_include=X11/Intrinsic.h + + # First, try using that file with no special directory specified. +AC_TRY_CPP([#include <$x_direct_test_include>], +[# We can compile using X headers with no special include directory. +ac_x_includes=], +[# Look for the header file in a standard set of common directories. +# Check X11 before X11Rn because it is often a symlink to the current release. + for ac_dir in \ + /usr/X11/include \ + /usr/X11R6/include \ + /usr/X11R5/include \ + /usr/X11R4/include \ + \ + /usr/include/X11 \ + /usr/include/X11R6 \ + /usr/include/X11R5 \ + /usr/include/X11R4 \ + \ + /usr/local/X11/include \ + /usr/local/X11R6/include \ + /usr/local/X11R5/include \ + /usr/local/X11R4/include \ + \ + /usr/local/include/X11 \ + /usr/local/include/X11R6 \ + /usr/local/include/X11R5 \ + /usr/local/include/X11R4 \ + \ + /usr/X386/include \ + /usr/x386/include \ + /usr/XFree86/include/X11 \ + \ + /usr/include \ + /usr/local/include \ + /usr/unsupported/include \ + /usr/athena/include \ + /usr/local/x11r5/include \ + /usr/lpp/Xamples/include \ + \ + /usr/openwin/include \ + /usr/openwin/share/include \ + ; \ + do + if test -r "$ac_dir/$x_direct_test_include"; then + ac_x_includes=$ac_dir + break + fi + done]) +fi # $ac_x_includes = NO + +if test "$ac_x_libraries" = NO; then + # Check for the libraries. + + test -z "$x_direct_test_library" && x_direct_test_library=Xt + test -z "$x_direct_test_function" && x_direct_test_function=XtMalloc + + # See if we find them without any special options. + # Don't add to $LIBS permanently. + ac_save_LIBS="$LIBS" + LIBS="-l$x_direct_test_library $LIBS" +AC_TRY_LINK([#include ], [${x_direct_test_function}(1)], +[LIBS="$ac_save_LIBS" +# We can link X programs with no special library path. +ac_x_libraries=], +[LIBS="$ac_save_LIBS" +# First see if replacing the include by lib works. +# Check X11 before X11Rn because it is often a symlink to the current release. +for ac_dir in `echo "$ac_x_includes" | sed s/include/lib${kdelibsuff}/` \ + /usr/X11/lib${kdelibsuff} \ + /usr/X11R6/lib${kdelibsuff} \ + /usr/X11R5/lib${kdelibsuff} \ + /usr/X11R4/lib${kdelibsuff} \ + \ + /usr/lib${kdelibsuff}/X11 \ + /usr/lib${kdelibsuff}/X11R6 \ + /usr/lib${kdelibsuff}/X11R5 \ + /usr/lib${kdelibsuff}/X11R4 \ + \ + /usr/local/X11/lib${kdelibsuff} \ + /usr/local/X11R6/lib${kdelibsuff} \ + /usr/local/X11R5/lib${kdelibsuff} \ + /usr/local/X11R4/lib${kdelibsuff} \ + \ + /usr/local/lib${kdelibsuff}/X11 \ + /usr/local/lib${kdelibsuff}/X11R6 \ + /usr/local/lib${kdelibsuff}/X11R5 \ + /usr/local/lib${kdelibsuff}/X11R4 \ + \ + /usr/X386/lib${kdelibsuff} \ + /usr/x386/lib${kdelibsuff} \ + /usr/XFree86/lib${kdelibsuff}/X11 \ + \ + /usr/lib${kdelibsuff} \ + /usr/local/lib${kdelibsuff} \ + /usr/unsupported/lib${kdelibsuff} \ + /usr/athena/lib${kdelibsuff} \ + /usr/local/x11r5/lib${kdelibsuff} \ + /usr/lpp/Xamples/lib${kdelibsuff} \ + /lib/usr/lib${kdelibsuff}/X11 \ + \ + /usr/openwin/lib${kdelibsuff} \ + /usr/openwin/share/lib${kdelibsuff} \ + ; \ +do +dnl Don't even attempt the hair of trying to link an X program! + for ac_extension in a so sl; do + if test -r $ac_dir/lib${x_direct_test_library}.$ac_extension; then + ac_x_libraries=$ac_dir + break 2 + fi + done +done]) +fi # $ac_x_libraries = NO +]) + + +dnl ------------------------------------------------------------------------ +dnl Find a file (or one of more files in a list of dirs) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_FIND_FILE], +[ +$3=NO +for i in $2; +do + for j in $1; + do + echo "configure: __oline__: $i/$j" >&AC_FD_CC + if test -r "$i/$j"; then + echo "taking that" >&AC_FD_CC + $3=$i + break 2 + fi + done +done +]) + +dnl KDE_FIND_PATH(program-name, variable-name, list-of-dirs, +dnl if-not-found, test-parameter, prepend-path) +dnl +dnl Look for program-name in list-of-dirs+$PATH. +dnl If prepend-path is set, look in $PATH+list-of-dirs instead. +dnl If found, $variable-name is set. If not, if-not-found is evaluated. +dnl test-parameter: if set, the program is executed with this arg, +dnl and only a successful exit code is required. +AC_DEFUN([KDE_FIND_PATH], +[ + AC_MSG_CHECKING([for $1]) + if test -n "$$2"; then + kde_cv_path="$$2"; + else + kde_cache=`echo $1 | sed 'y%./+-%__p_%'` + + AC_CACHE_VAL(kde_cv_path_$kde_cache, + [ + kde_cv_path="NONE" + kde_save_IFS=$IFS + IFS=':' + dirs="" + for dir in $PATH; do + dirs="$dirs $dir" + done + if test -z "$6"; then dnl Append dirs in PATH (default) + dirs="$3 $dirs" + else dnl Prepend dirs in PATH (if 6th arg is set) + dirs="$dirs $3" + fi + IFS=$kde_save_IFS + + for dir in $dirs; do + if test -x "$dir/$1"; then + if test -n "$5" + then + evalstr="$dir/$1 $5 2>&1 " + if eval $evalstr; then + kde_cv_path="$dir/$1" + break + fi + else + kde_cv_path="$dir/$1" + break + fi + fi + done + + eval "kde_cv_path_$kde_cache=$kde_cv_path" + + ]) + + eval "kde_cv_path=\"`echo '$kde_cv_path_'$kde_cache`\"" + + fi + + if test -z "$kde_cv_path" || test "$kde_cv_path" = NONE; then + AC_MSG_RESULT(not found) + $4 + else + AC_MSG_RESULT($kde_cv_path) + $2=$kde_cv_path + + fi +]) + +AC_DEFUN([KDE_MOC_ERROR_MESSAGE], +[ + AC_MSG_ERROR([No Qt meta object compiler (moc) found! +Please check whether you installed Qt correctly. +You need to have a running moc binary. +configure tried to run $ac_cv_path_moc and the test didn't +succeed. If configure shouldn't have tried this one, set +the environment variable MOC to the right one before running +configure. +]) +]) + +AC_DEFUN([KDE_UIC_ERROR_MESSAGE], +[ + AC_MSG_WARN([No Qt ui compiler (uic) found! +Please check whether you installed Qt correctly. +You need to have a running uic binary. +configure tried to run $ac_cv_path_uic and the test didn't +succeed. If configure shouldn't have tried this one, set +the environment variable UIC to the right one before running +configure. +]) +]) + + +AC_DEFUN([KDE_CHECK_UIC_FLAG], +[ + AC_MSG_CHECKING([whether uic supports -$1 ]) + kde_cache=`echo $1 | sed 'y% .=/+-%____p_%'` + AC_CACHE_VAL(kde_cv_prog_uic_$kde_cache, + [ + cat >conftest.ui < +EOT + ac_uic_testrun="$UIC_PATH -$1 $2 conftest.ui >/dev/null" + if AC_TRY_EVAL(ac_uic_testrun); then + eval "kde_cv_prog_uic_$kde_cache=yes" + else + eval "kde_cv_prog_uic_$kde_cache=no" + fi + rm -f conftest* + ]) + + if eval "test \"`echo '$kde_cv_prog_uic_'$kde_cache`\" = yes"; then + AC_MSG_RESULT([yes]) + : + $3 + else + AC_MSG_RESULT([no]) + : + $4 + fi +]) + + +dnl ------------------------------------------------------------------------ +dnl Find the meta object compiler and the ui compiler in the PATH, +dnl in $QTDIR/bin, and some more usual places +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_PATH_QT_MOC_UIC], +[ + AC_REQUIRE([KDE_CHECK_PERL]) + qt_bindirs="" + for dir in $kde_qt_dirs; do + qt_bindirs="$qt_bindirs $dir/bin $dir/src/moc" + done + qt_bindirs="$qt_bindirs /usr/bin /usr/X11R6/bin /usr/local/qt/bin" + if test ! "$ac_qt_bindir" = "NO"; then + qt_bindirs="$ac_qt_bindir $qt_bindirs" + fi + + KDE_FIND_PATH(moc, MOC, [$qt_bindirs], [KDE_MOC_ERROR_MESSAGE]) + if test -z "$UIC_NOT_NEEDED"; then + KDE_FIND_PATH(uic, UIC_PATH, [$qt_bindirs], [UIC_PATH=""]) + if test -z "$UIC_PATH" ; then + KDE_UIC_ERROR_MESSAGE + exit 1 + else + UIC=$UIC_PATH + + if test $kde_qtver = 3; then + KDE_CHECK_UIC_FLAG(L,[/nonexistent],ac_uic_supports_libpath=yes,ac_uic_supports_libpath=no) + KDE_CHECK_UIC_FLAG(nounload,,ac_uic_supports_nounload=yes,ac_uic_supports_nounload=no) + + if test x$ac_uic_supports_libpath = xyes; then + UIC="$UIC -L \$(kde_widgetdir)" + fi + if test x$ac_uic_supports_nounload = xyes; then + UIC="$UIC -nounload" + fi + fi + fi + else + UIC="echo uic not available: " + fi + + AC_SUBST(MOC) + AC_SUBST(UIC) + + UIC_TR="i18n" + if test $kde_qtver = 3; then + UIC_TR="tr2i18n" + fi + + AC_SUBST(UIC_TR) +]) + +AC_DEFUN([KDE_1_CHECK_PATHS], +[ + KDE_1_CHECK_PATH_HEADERS + + KDE_TEST_RPATH= + + if test -n "$USE_RPATH"; then + + if test -n "$kde_libraries"; then + KDE_TEST_RPATH="-R $kde_libraries" + fi + + if test -n "$qt_libraries"; then + KDE_TEST_RPATH="$KDE_TEST_RPATH -R $qt_libraries" + fi + + if test -n "$x_libraries"; then + KDE_TEST_RPATH="$KDE_TEST_RPATH -R $x_libraries" + fi + + KDE_TEST_RPATH="$KDE_TEST_RPATH $KDE_EXTRA_RPATH" + fi + +AC_MSG_CHECKING([for KDE libraries installed]) +ac_link='$LIBTOOL_SHELL --silent --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext $LIBS -lkdecore $LIBQT $KDE_TEST_RPATH 1>&5' + +if AC_TRY_EVAL(ac_link) && test -s conftest; then + AC_MSG_RESULT(yes) +else + AC_MSG_ERROR([your system fails at linking a small KDE application! +Check, if your compiler is installed correctly and if you have used the +same compiler to compile Qt and kdelibs as you did use now. +For more details about this problem, look at the end of config.log.]) +fi + +if eval `KDEDIR= ./conftest 2>&5`; then + kde_result=done +else + kde_result=problems +fi + +KDEDIR= ./conftest 2> /dev/null >&5 # make an echo for config.log +kde_have_all_paths=yes + +KDE_SET_PATHS($kde_result) + +]) + +AC_DEFUN([KDE_SET_PATHS], +[ + kde_cv_all_paths="kde_have_all_paths=\"yes\" \ + kde_htmldir=\"$kde_htmldir\" \ + kde_appsdir=\"$kde_appsdir\" \ + kde_icondir=\"$kde_icondir\" \ + kde_sounddir=\"$kde_sounddir\" \ + kde_datadir=\"$kde_datadir\" \ + kde_locale=\"$kde_locale\" \ + kde_cgidir=\"$kde_cgidir\" \ + kde_confdir=\"$kde_confdir\" \ + kde_kcfgdir=\"$kde_kcfgdir\" \ + kde_mimedir=\"$kde_mimedir\" \ + kde_toolbardir=\"$kde_toolbardir\" \ + kde_wallpaperdir=\"$kde_wallpaperdir\" \ + kde_templatesdir=\"$kde_templatesdir\" \ + kde_bindir=\"$kde_bindir\" \ + kde_servicesdir=\"$kde_servicesdir\" \ + kde_servicetypesdir=\"$kde_servicetypesdir\" \ + kde_moduledir=\"$kde_moduledir\" \ + kde_styledir=\"$kde_styledir\" \ + kde_widgetdir=\"$kde_widgetdir\" \ + xdg_appsdir=\"$xdg_appsdir\" \ + xdg_menudir=\"$xdg_menudir\" \ + xdg_directorydir=\"$xdg_directorydir\" \ + kde_result=$1" +]) + +AC_DEFUN([KDE_SET_DEFAULT_PATHS], +[ +if test "$1" = "default"; then + + if test -z "$kde_htmldir"; then + kde_htmldir='\${datadir}/doc/HTML' + fi + if test -z "$kde_appsdir"; then + kde_appsdir='\${datadir}/applnk' + fi + if test -z "$kde_icondir"; then + kde_icondir='\${datadir}/icons' + fi + if test -z "$kde_sounddir"; then + kde_sounddir='\${datadir}/sounds' + fi + if test -z "$kde_datadir"; then + kde_datadir='\${datadir}/apps' + fi + if test -z "$kde_locale"; then + kde_locale='\${datadir}/locale' + fi + if test -z "$kde_cgidir"; then + kde_cgidir='\${exec_prefix}/cgi-bin' + fi + if test -z "$kde_confdir"; then + kde_confdir='\${datadir}/config' + fi + if test -z "$kde_kcfgdir"; then + kde_kcfgdir='\${datadir}/config.kcfg' + fi + if test -z "$kde_mimedir"; then + kde_mimedir='\${datadir}/mimelnk' + fi + if test -z "$kde_toolbardir"; then + kde_toolbardir='\${datadir}/toolbar' + fi + if test -z "$kde_wallpaperdir"; then + kde_wallpaperdir='\${datadir}/wallpapers' + fi + if test -z "$kde_templatesdir"; then + kde_templatesdir='\${datadir}/templates' + fi + if test -z "$kde_bindir"; then + kde_bindir='\${exec_prefix}/bin' + fi + if test -z "$kde_servicesdir"; then + kde_servicesdir='\${datadir}/services' + fi + if test -z "$kde_servicetypesdir"; then + kde_servicetypesdir='\${datadir}/servicetypes' + fi + if test -z "$kde_moduledir"; then + if test "$kde_qtver" = "2"; then + kde_moduledir='\${libdir}/kde2' + else + kde_moduledir='\${libdir}/kde3' + fi + fi + if test -z "$kde_styledir"; then + kde_styledir='\${libdir}/kde3/plugins/styles' + fi + if test -z "$kde_widgetdir"; then + kde_widgetdir='\${libdir}/kde3/plugins/designer' + fi + if test -z "$xdg_appsdir"; then + xdg_appsdir='\${datadir}/applications/kde' + fi + if test -z "$xdg_menudir"; then + xdg_menudir='\${sysconfdir}/xdg/menus' + fi + if test -z "$xdg_directorydir"; then + xdg_directorydir='\${datadir}/desktop-directories' + fi + + KDE_SET_PATHS(defaults) + +else + + if test $kde_qtver = 1; then + AC_MSG_RESULT([compiling]) + KDE_1_CHECK_PATHS + else + AC_MSG_ERROR([path checking not yet supported for KDE 2]) + fi + +fi +]) + +AC_DEFUN([KDE_CHECK_PATHS_FOR_COMPLETENESS], +[ if test -z "$kde_htmldir" || test -z "$kde_appsdir" || + test -z "$kde_icondir" || test -z "$kde_sounddir" || + test -z "$kde_datadir" || test -z "$kde_locale" || + test -z "$kde_cgidir" || test -z "$kde_confdir" || + test -z "$kde_kcfgdir" || + test -z "$kde_mimedir" || test -z "$kde_toolbardir" || + test -z "$kde_wallpaperdir" || test -z "$kde_templatesdir" || + test -z "$kde_bindir" || test -z "$kde_servicesdir" || + test -z "$kde_servicetypesdir" || test -z "$kde_moduledir" || + test -z "$kde_styledir" || test -z "kde_widgetdir" || + test -z "$xdg_appsdir" || test -z "$xdg_menudir" || test -z "$xdg_directorydir" || + test "x$kde_have_all_paths" != "xyes"; then + kde_have_all_paths=no + fi +]) + +AC_DEFUN([KDE_MISSING_PROG_ERROR], +[ + AC_MSG_ERROR([The important program $1 was not found! +Please check whether you installed KDE correctly. +]) +]) + +AC_DEFUN([KDE_MISSING_ARTS_ERROR], +[ + AC_MSG_ERROR([The important program $1 was not found! +Please check whether you installed aRts correctly or use +--without-arts to compile without aRts support (this will remove functionality). +]) +]) + +AC_DEFUN([KDE_SET_DEFAULT_BINDIRS], +[ + kde_default_bindirs="/usr/bin /usr/local/bin /opt/local/bin /usr/X11R6/bin /opt/kde/bin /opt/kde3/bin /usr/kde/bin /usr/local/kde/bin" + test -n "$KDEDIR" && kde_default_bindirs="$KDEDIR/bin $kde_default_bindirs" + if test -n "$KDEDIRS"; then + kde_save_IFS=$IFS + IFS=: + for dir in $KDEDIRS; do + kde_default_bindirs="$dir/bin $kde_default_bindirs " + done + IFS=$kde_save_IFS + fi +]) + +AC_DEFUN([KDE_SUBST_PROGRAMS], +[ + AC_ARG_WITH(arts, + AC_HELP_STRING([--without-arts],[build without aRts [default=no]]), + [build_arts=$withval], + [build_arts=yes] + ) + AM_CONDITIONAL(include_ARTS, test "$build_arts" '!=' "no") + if test "$build_arts" = "no"; then + AC_DEFINE(WITHOUT_ARTS, 1, [Defined if compiling without arts]) + fi + + KDE_SET_DEFAULT_BINDIRS + kde_default_bindirs="$exec_prefix/bin $prefix/bin $kde_libs_prefix/bin $kde_default_bindirs" + KDE_FIND_PATH(dcopidl, DCOPIDL, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl)]) + KDE_FIND_PATH(dcopidl2cpp, DCOPIDL2CPP, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidl2cpp)]) + if test "$build_arts" '!=' "no"; then + KDE_FIND_PATH(mcopidl, MCOPIDL, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(mcopidl)]) + KDE_FIND_PATH(artsc-config, ARTSCCONFIG, [$kde_default_bindirs], [KDE_MISSING_ARTS_ERROR(artsc-config)]) + fi + KDE_FIND_PATH(meinproc, MEINPROC, [$kde_default_bindirs]) + + kde32ornewer=1 + kde33ornewer=1 + if test -n "$kde_qtver" && test "$kde_qtver" -lt 3; then + kde32ornewer= + kde33ornewer= + else + if test "$kde_qtver" = "3"; then + if test "$kde_qtsubver" -le 1; then + kde32ornewer= + fi + if test "$kde_qtsubver" -le 2; then + kde33ornewer= + fi + if test "$KDECONFIG" != "compiled"; then + if test `$KDECONFIG --version | grep KDE | sed 's/KDE: \(...\).*/\1/'` = 3.2; then + kde33ornewer= + fi + fi + fi + fi + + if test -n "$kde32ornewer"; then + KDE_FIND_PATH(kconfig_compiler, KCONFIG_COMPILER, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kconfig_compiler)]) + KDE_FIND_PATH(dcopidlng, DCOPIDLNG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(dcopidlng)]) + fi + if test -n "$kde33ornewer"; then + KDE_FIND_PATH(makekdewidgets, MAKEKDEWIDGETS, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(makekdewidgets)]) + AC_SUBST(MAKEKDEWIDGETS) + fi + KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin], [XMLLINT=""]) + + if test -n "$MEINPROC" -a "$MEINPROC" != "compiled"; then + kde_sharedirs="/usr/share/kde /usr/local/share /usr/share /opt/kde3/share /opt/kde/share $prefix/share" + test -n "$KDEDIR" && kde_sharedirs="$KDEDIR/share $kde_sharedirs" + AC_FIND_FILE(apps/ksgmltools2/customization/kde-chunk.xsl, $kde_sharedirs, KDE_XSL_STYLESHEET) + if test "$KDE_XSL_STYLESHEET" = "NO"; then + KDE_XSL_STYLESHEET="" + else + KDE_XSL_STYLESHEET="$KDE_XSL_STYLESHEET/apps/ksgmltools2/customization/kde-chunk.xsl" + fi + fi + + DCOP_DEPENDENCIES='$(DCOPIDL)' + if test -n "$kde32ornewer"; then + KCFG_DEPENDENCIES='$(KCONFIG_COMPILER)' + DCOP_DEPENDENCIES='$(DCOPIDL) $(DCOPIDLNG)' + AC_SUBST(KCONFIG_COMPILER) + AC_SUBST(KCFG_DEPENDENCIES) + AC_SUBST(DCOPIDLNG) + fi + AC_SUBST(DCOPIDL) + AC_SUBST(DCOPIDL2CPP) + AC_SUBST(DCOP_DEPENDENCIES) + AC_SUBST(MCOPIDL) + AC_SUBST(ARTSCCONFIG) + AC_SUBST(MEINPROC) + AC_SUBST(KDE_XSL_STYLESHEET) + AC_SUBST(XMLLINT) +])dnl + +AC_DEFUN([AC_CREATE_KFSSTND], +[ +AC_REQUIRE([AC_CHECK_RPATH]) + +AC_MSG_CHECKING([for KDE paths]) +kde_result="" +kde_cached_paths=yes +AC_CACHE_VAL(kde_cv_all_paths, +[ + KDE_SET_DEFAULT_PATHS($1) + kde_cached_paths=no +]) +eval "$kde_cv_all_paths" +KDE_CHECK_PATHS_FOR_COMPLETENESS +if test "$kde_have_all_paths" = "no" && test "$kde_cached_paths" = "yes"; then + # wrong values were cached, may be, we can set better ones + kde_result= + kde_htmldir= kde_appsdir= kde_icondir= kde_sounddir= + kde_datadir= kde_locale= kde_cgidir= kde_confdir= kde_kcfgdir= + kde_mimedir= kde_toolbardir= kde_wallpaperdir= kde_templatesdir= + kde_bindir= kde_servicesdir= kde_servicetypesdir= kde_moduledir= + kde_have_all_paths= + kde_styledir= + kde_widgetdir= + xdg_appsdir = xdg_menudir= xdg_directorydir= + KDE_SET_DEFAULT_PATHS($1) + eval "$kde_cv_all_paths" + KDE_CHECK_PATHS_FOR_COMPLETENESS + kde_result="$kde_result (cache overridden)" +fi +if test "$kde_have_all_paths" = "no"; then + AC_MSG_ERROR([configure could not run a little KDE program to test the environment. +Since it had compiled and linked before, it must be a strange problem on your system. +Look at config.log for details. If you are not able to fix this, look at +http://www.kde.org/faq/installation.html or any www.kde.org mirror. +(If you're using an egcs version on Linux, you may update binutils!) +]) +else + rm -f conftest* + AC_MSG_RESULT($kde_result) +fi + +bindir=$kde_bindir + +KDE_SUBST_PROGRAMS + +]) + +AC_DEFUN([AC_SUBST_KFSSTND], +[ +AC_SUBST(kde_htmldir) +AC_SUBST(kde_appsdir) +AC_SUBST(kde_icondir) +AC_SUBST(kde_sounddir) +AC_SUBST(kde_datadir) +AC_SUBST(kde_locale) +AC_SUBST(kde_confdir) +AC_SUBST(kde_kcfgdir) +AC_SUBST(kde_mimedir) +AC_SUBST(kde_wallpaperdir) +AC_SUBST(kde_bindir) +dnl X Desktop Group standards +AC_SUBST(xdg_appsdir) +AC_SUBST(xdg_menudir) +AC_SUBST(xdg_directorydir) +dnl for KDE 2 +AC_SUBST(kde_templatesdir) +AC_SUBST(kde_servicesdir) +AC_SUBST(kde_servicetypesdir) +AC_SUBST(kde_moduledir) +AC_SUBST(kdeinitdir, '$(kde_moduledir)') +AC_SUBST(kde_styledir) +AC_SUBST(kde_widgetdir) +if test "$kde_qtver" = 1; then + kde_minidir="$kde_icondir/mini" +else +# for KDE 1 - this breaks KDE2 apps using minidir, but +# that's the plan ;-/ + kde_minidir="/dev/null" +fi +dnl AC_SUBST(kde_minidir) +dnl AC_SUBST(kde_cgidir) +dnl AC_SUBST(kde_toolbardir) +]) + +AC_DEFUN([KDE_MISC_TESTS], +[ + dnl Checks for libraries. + AC_CHECK_LIB(util, main, [LIBUTIL="-lutil"]) dnl for *BSD + AC_SUBST(LIBUTIL) + AC_CHECK_LIB(compat, main, [LIBCOMPAT="-lcompat"]) dnl for *BSD + AC_SUBST(LIBCOMPAT) + kde_have_crypt= + AC_CHECK_LIB(crypt, crypt, [LIBCRYPT="-lcrypt"; kde_have_crypt=yes], + AC_CHECK_LIB(c, crypt, [kde_have_crypt=yes], [ + AC_MSG_WARN([you have no crypt in either libcrypt or libc. +You should install libcrypt from another source or configure with PAM +support]) + kde_have_crypt=no + ])) + AC_SUBST(LIBCRYPT) + if test $kde_have_crypt = yes; then + AC_DEFINE_UNQUOTED(HAVE_CRYPT, 1, [Defines if your system has the crypt function]) + fi + AC_CHECK_SOCKLEN_T + AC_CHECK_LIB(dnet, dnet_ntoa, [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet"]) + if test $ac_cv_lib_dnet_dnet_ntoa = no; then + AC_CHECK_LIB(dnet_stub, dnet_ntoa, + [X_EXTRA_LIBS="$X_EXTRA_LIBS -ldnet_stub"]) + fi + AC_CHECK_FUNC(inet_ntoa) + if test $ac_cv_func_inet_ntoa = no; then + AC_CHECK_LIB(nsl, inet_ntoa, X_EXTRA_LIBS="$X_EXTRA_LIBS -lnsl") + fi + AC_CHECK_FUNC(connect) + if test $ac_cv_func_connect = no; then + AC_CHECK_LIB(socket, connect, X_EXTRA_LIBS="-lsocket $X_EXTRA_LIBS", , + $X_EXTRA_LIBS) + fi + + AC_CHECK_FUNC(remove) + if test $ac_cv_func_remove = no; then + AC_CHECK_LIB(posix, remove, X_EXTRA_LIBS="$X_EXTRA_LIBS -lposix") + fi + + # BSDI BSD/OS 2.1 needs -lipc for XOpenDisplay. + AC_CHECK_FUNC(shmat, , + AC_CHECK_LIB(ipc, shmat, X_EXTRA_LIBS="$X_EXTRA_LIBS -lipc")) + + # more headers that need to be explicitly included on darwin + AC_CHECK_HEADERS(sys/types.h stdint.h) + + # sys/bitypes.h is needed for uint32_t and friends on Tru64 + AC_CHECK_HEADERS(sys/bitypes.h) + + # darwin requires a poll emulation library + AC_CHECK_LIB(poll, poll, LIB_POLL="-lpoll") + + # for some image handling on Mac OS X + AC_CHECK_HEADERS(Carbon/Carbon.h) + + # CoreAudio framework + AC_CHECK_HEADER(CoreAudio/CoreAudio.h, [ + AC_DEFINE(HAVE_COREAUDIO, 1, [Define if you have the CoreAudio API]) + FRAMEWORK_COREAUDIO="-Wl,-framework,CoreAudio" + ]) + + AC_CHECK_RES_INIT + AC_SUBST(LIB_POLL) + AC_SUBST(FRAMEWORK_COREAUDIO) + LIBSOCKET="$X_EXTRA_LIBS" + AC_SUBST(LIBSOCKET) + AC_SUBST(X_EXTRA_LIBS) + AC_CHECK_LIB(ucb, killpg, [LIBUCB="-lucb"]) dnl for Solaris2.4 + AC_SUBST(LIBUCB) + + case $host in dnl this *is* LynxOS specific + *-*-lynxos* ) + AC_MSG_CHECKING([LynxOS header file wrappers]) + [CFLAGS="$CFLAGS -D__NO_INCLUDE_WARN__"] + AC_MSG_RESULT(disabled) + AC_CHECK_LIB(bsd, gethostbyname, [LIBSOCKET="-lbsd"]) dnl for LynxOS + ;; + esac + + KDE_CHECK_TYPES + KDE_CHECK_LIBDL + KDE_CHECK_STRLCPY + KDE_CHECK_PIE_SUPPORT + +# darwin needs this to initialize the environment +AC_CHECK_HEADERS(crt_externs.h) +AC_CHECK_FUNC(_NSGetEnviron, [AC_DEFINE(HAVE_NSGETENVIRON, 1, [Define if your system needs _NSGetEnviron to set up the environment])]) + +AH_VERBATIM(_DARWIN_ENVIRON, +[ +#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) +# include +# include +# define environ (*_NSGetEnviron()) +#endif +]) + +AH_VERBATIM(_AIX_STRINGS_H_BZERO, +[ +/* + * AIX defines FD_SET in terms of bzero, but fails to include + * that defines bzero. + */ + +#if defined(_AIX) +#include +#endif +]) + +AC_CHECK_FUNCS([vsnprintf snprintf]) + +AH_VERBATIM(_TRU64,[ +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +#if !defined(HAVE_VSNPRINTF) || defined(hpux) +#if __STDC__ +#include +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" +#endif +int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); +#ifdef __cplusplus +extern "C" +#endif +int snprintf(char *str, size_t n, char const *fmt, ...); +#endif +]) + +]) + +dnl ------------------------------------------------------------------------ +dnl Find the header files and libraries for X-Windows. Extended the +dnl macro AC_PATH_X +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([K_PATH_X], +[ +AC_REQUIRE([KDE_MISC_TESTS])dnl +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_ARG_ENABLE( + embedded, + AC_HELP_STRING([--enable-embedded],[link to Qt-embedded, don't use X]), + kde_use_qt_emb=$enableval, + kde_use_qt_emb=no +) + +AC_ARG_ENABLE( + qtopia, + AC_HELP_STRING([--enable-qtopia],[link to Qt-embedded, link to the Qtopia Environment]), + kde_use_qt_emb_palm=$enableval, + kde_use_qt_emb_palm=no +) + +AC_ARG_ENABLE( + mac, + AC_HELP_STRING([--enable-mac],[link to Qt/Mac (don't use X)]), + kde_use_qt_mac=$enableval, + kde_use_qt_mac=no +) + +# used to disable x11-specific stuff on special platforms +AM_CONDITIONAL(include_x11, test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no") + +if test "$kde_use_qt_emb" = "no" && test "$kde_use_qt_mac" = "no"; then + +AC_MSG_CHECKING(for X) + +AC_CACHE_VAL(kde_cv_have_x, +[# One or both of the vars are not set, and there is no cached value. +if test "{$x_includes+set}" = set || test "$x_includes" = NONE; then + kde_x_includes=NO +else + kde_x_includes=$x_includes +fi +if test "{$x_libraries+set}" = set || test "$x_libraries" = NONE; then + kde_x_libraries=NO +else + kde_x_libraries=$x_libraries +fi + +# below we use the standard autoconf calls +ac_x_libraries=$kde_x_libraries +ac_x_includes=$kde_x_includes + +KDE_PATH_X_DIRECT +dnl AC_PATH_X_XMKMF picks /usr/lib as the path for the X libraries. +dnl Unfortunately, if compiling with the N32 ABI, this is not the correct +dnl location. The correct location is /usr/lib32 or an undefined value +dnl (the linker is smart enough to pick the correct default library). +dnl Things work just fine if you use just AC_PATH_X_DIRECT. +dnl Solaris has a similar problem. AC_PATH_X_XMKMF forces x_includes to +dnl /usr/openwin/include, which doesn't work. /usr/include does work, so +dnl x_includes should be left alone. +case "$host" in +mips-sgi-irix6*) + ;; +*-*-solaris*) + ;; +*) + _AC_PATH_X_XMKMF + if test -z "$ac_x_includes"; then + ac_x_includes="." + fi + if test -z "$ac_x_libraries"; then + ac_x_libraries="/usr/lib${kdelibsuff}" + fi +esac +#from now on we use our own again + +# when the user already gave --x-includes, we ignore +# what the standard autoconf macros told us. +if test "$kde_x_includes" = NO; then + kde_x_includes=$ac_x_includes +fi + +# for --x-libraries too +if test "$kde_x_libraries" = NO; then + kde_x_libraries=$ac_x_libraries +fi + +if test "$kde_x_includes" = NO; then + AC_MSG_ERROR([Can't find X includes. Please check your installation and add the correct paths!]) +fi + +if test "$kde_x_libraries" = NO; then + AC_MSG_ERROR([Can't find X libraries. Please check your installation and add the correct paths!]) +fi + +# Record where we found X for the cache. +kde_cv_have_x="have_x=yes \ + kde_x_includes=$kde_x_includes kde_x_libraries=$kde_x_libraries" +])dnl + +eval "$kde_cv_have_x" + +if test "$have_x" != yes; then + AC_MSG_RESULT($have_x) + no_x=yes +else + AC_MSG_RESULT([libraries $kde_x_libraries, headers $kde_x_includes]) +fi + +if test -z "$kde_x_includes" || test "x$kde_x_includes" = xNONE; then + X_INCLUDES="" + x_includes="."; dnl better than nothing :- + else + x_includes=$kde_x_includes + X_INCLUDES="-I$x_includes" +fi + +if test -z "$kde_x_libraries" || test "x$kde_x_libraries" = xNONE || test "$kde_x_libraries" = "/usr/lib"; then + X_LDFLAGS="" + x_libraries="/usr/lib"; dnl better than nothing :- + else + x_libraries=$kde_x_libraries + X_LDFLAGS="-L$x_libraries" +fi +all_includes="$X_INCLUDES" +all_libraries="$X_LDFLAGS $LDFLAGS_AS_NEEDED $LDFLAGS_NEW_DTAGS" + +# Check for libraries that X11R6 Xt/Xaw programs need. +ac_save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $X_LDFLAGS" +# SM needs ICE to (dynamically) link under SunOS 4.x (so we have to +# check for ICE first), but we must link in the order -lSM -lICE or +# we get undefined symbols. So assume we have SM if we have ICE. +# These have to be linked with before -lX11, unlike the other +# libraries we check for below, so use a different variable. +# --interran@uluru.Stanford.EDU, kb@cs.umb.edu. +AC_CHECK_LIB(ICE, IceConnectionNumber, + [LIBSM="-lSM -lICE"], , $X_EXTRA_LIBS) +LDFLAGS="$ac_save_LDFLAGS" + +LIB_X11='-lX11 $(LIBSOCKET)' + +AC_MSG_CHECKING(for libXext) +AC_CACHE_VAL(kde_cv_have_libXext, +[ +kde_ldflags_safe="$LDFLAGS" +kde_libs_safe="$LIBS" + +LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS" +LIBS="-lXext -lX11 $LIBSOCKET" + +AC_TRY_LINK([ +#include +#ifdef STDC_HEADERS +# include +#endif +], +[ +printf("hello Xext\n"); +], +kde_cv_have_libXext=yes, +kde_cv_have_libXext=no +) + +LDFLAGS=$kde_ldflags_safe +LIBS=$kde_libs_safe +]) + +AC_MSG_RESULT($kde_cv_have_libXext) + +if test "$kde_cv_have_libXext" = "no"; then + AC_MSG_ERROR([We need a working libXext to proceed. Since configure +can't find it itself, we stop here assuming that make wouldn't find +them either.]) +fi + +LIB_XEXT="-lXext" +QTE_NORTTI="" + +elif test "$kde_use_qt_emb" = "yes"; then + dnl We're using QT Embedded + CPPFLAGS=-DQWS + CXXFLAGS="$CXXFLAGS -fno-rtti" + QTE_NORTTI="-fno-rtti -DQWS" + X_PRE_LIBS="" + LIB_X11="" + LIB_XEXT="" + LIB_XRENDER="" + LIBSM="" + X_INCLUDES="" + X_LDFLAGS="" + x_includes="" + x_libraries="" +elif test "$kde_use_qt_mac" = "yes"; then + dnl We're using QT/Mac (I use QT_MAC so that qglobal.h doesn't *have* to + dnl be included to get the information) --Sam + CXXFLAGS="$CXXFLAGS -DQT_MAC -no-cpp-precomp" + CFLAGS="$CFLAGS -DQT_MAC -no-cpp-precomp" + X_PRE_LIBS="" + LIB_X11="" + LIB_XEXT="" + LIB_XRENDER="" + LIBSM="" + X_INCLUDES="" + X_LDFLAGS="" + x_includes="" + x_libraries="" +fi +AC_SUBST(X_PRE_LIBS) +AC_SUBST(LIB_X11) +AC_SUBST(LIB_XRENDER) +AC_SUBST(LIBSM) +AC_SUBST(X_INCLUDES) +AC_SUBST(X_LDFLAGS) +AC_SUBST(x_includes) +AC_SUBST(x_libraries) +AC_SUBST(QTE_NORTTI) +AC_SUBST(LIB_XEXT) + +]) + +AC_DEFUN([KDE_PRINT_QT_PROGRAM], +[ +AC_REQUIRE([KDE_USE_QT]) +cat > conftest.$ac_ext < +#include +EOF +if test "$kde_qtver" = "2"; then +cat >> conftest.$ac_ext < +#include +#include +EOF + +if test $kde_qtsubver -gt 0; then +cat >> conftest.$ac_ext <> conftest.$ac_ext < +#include +#include +EOF +fi + +echo "#if ! ($kde_qt_verstring)" >> conftest.$ac_ext +cat >> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <> conftest.$ac_ext <&AC_FD_CC + cat conftest.$ac_ext >&AC_FD_CC +fi + +rm -f conftest* +CXXFLAGS="$ac_cxxflags_safe" +LDFLAGS="$ac_ldflags_safe" +LIBS="$ac_libs_safe" + +LD_LIBRARY_PATH="$ac_LD_LIBRARY_PATH_safe" +export LD_LIBRARY_PATH +LIBRARY_PATH="$ac_LIBRARY_PATH" +export LIBRARY_PATH +AC_LANG_RESTORE +]) + +if test "$kde_cv_qt_direct" = "yes"; then + AC_MSG_RESULT(yes) + $1 +else + AC_MSG_RESULT(no) + $2 +fi +]) + +dnl ------------------------------------------------------------------------ +dnl Try to find the Qt headers and libraries. +dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed) +dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_PATH_QT_1_3], +[ +AC_REQUIRE([K_PATH_X]) +AC_REQUIRE([KDE_USE_QT]) +AC_REQUIRE([KDE_CHECK_LIB64]) + +dnl ------------------------------------------------------------------------ +dnl Add configure flag to enable linking to MT version of Qt library. +dnl ------------------------------------------------------------------------ + +AC_ARG_ENABLE( + mt, + AC_HELP_STRING([--disable-mt],[link to non-threaded Qt (deprecated)]), + kde_use_qt_mt=$enableval, + [ + if test $kde_qtver = 3; then + kde_use_qt_mt=yes + else + kde_use_qt_mt=no + fi + ] +) + +USING_QT_MT="" + +dnl ------------------------------------------------------------------------ +dnl If we not get --disable-qt-mt then adjust some vars for the host. +dnl ------------------------------------------------------------------------ + +KDE_MT_LDFLAGS= +KDE_MT_LIBS= +if test "x$kde_use_qt_mt" = "xyes"; then + KDE_CHECK_THREADING + if test "x$kde_use_threading" = "xyes"; then + CPPFLAGS="$USE_THREADS -DQT_THREAD_SUPPORT $CPPFLAGS" + KDE_MT_LDFLAGS="$USE_THREADS" + KDE_MT_LIBS="$LIBPTHREAD" + else + kde_use_qt_mt=no + fi +fi +AC_SUBST(KDE_MT_LDFLAGS) +AC_SUBST(KDE_MT_LIBS) + +kde_qt_was_given=yes + +dnl ------------------------------------------------------------------------ +dnl If we haven't been told how to link to Qt, we work it out for ourselves. +dnl ------------------------------------------------------------------------ +if test -z "$LIBQT_GLOB"; then + if test "x$kde_use_qt_emb" = "xyes"; then + LIBQT_GLOB="libqte.*" + else + LIBQT_GLOB="libqt.*" + fi +fi + +dnl ------------------------------------------------------------ +dnl If we got --enable-embedded then adjust the Qt library name. +dnl ------------------------------------------------------------ +if test "x$kde_use_qt_emb" = "xyes"; then + qtlib="qte" +else + qtlib="qt" +fi + +kde_int_qt="-l$qtlib" + +if test -z "$LIBQPE"; then +dnl ------------------------------------------------------------ +dnl If we got --enable-palmtop then add -lqpe to the link line +dnl ------------------------------------------------------------ + if test "x$kde_use_qt_emb" = "xyes"; then + if test "x$kde_use_qt_emb_palm" = "xyes"; then + LIB_QPE="-lqpe" + else + LIB_QPE="" + fi + else + LIB_QPE="" + fi +fi + +dnl ------------------------------------------------------------------------ +dnl If we got --enable-qt-mt then adjust the Qt library name for the host. +dnl ------------------------------------------------------------------------ + +if test "x$kde_use_qt_mt" = "xyes"; then + LIBQT="-l$qtlib-mt" + kde_int_qt="-l$qtlib-mt" + LIBQT_GLOB="lib$qtlib-mt.*" + USING_QT_MT="using -mt" +else + LIBQT="-l$qtlib" +fi + +if test $kde_qtver != 1; then + + AC_REQUIRE([AC_FIND_PNG]) + AC_REQUIRE([AC_FIND_JPEG]) + LIBQT="$LIBQT $LIBPNG $LIBJPEG" +fi + +if test $kde_qtver = 3; then + AC_REQUIRE([KDE_CHECK_LIBDL]) + LIBQT="$LIBQT $LIBDL" +fi + +AC_MSG_CHECKING([for Qt]) + +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBQT="$LIBQT $X_PRE_LIBS -lXext -lX11 $LIBSM $LIBSOCKET" +fi +ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO +qt_libraries="" +qt_includes="" +AC_ARG_WITH(qt-dir, + AC_HELP_STRING([--with-qt-dir=DIR],[where the root of Qt is installed ]), + [ ac_qt_includes="$withval"/include + ac_qt_libraries="$withval"/lib${kdelibsuff} + ac_qt_bindir="$withval"/bin + ]) + +AC_ARG_WITH(qt-includes, + AC_HELP_STRING([--with-qt-includes=DIR],[where the Qt includes are. ]), + [ + ac_qt_includes="$withval" + ]) + +kde_qt_libs_given=no + +AC_ARG_WITH(qt-libraries, + AC_HELP_STRING([--with-qt-libraries=DIR],[where the Qt library is installed.]), + [ ac_qt_libraries="$withval" + kde_qt_libs_given=yes + ]) + +AC_CACHE_VAL(ac_cv_have_qt, +[#try to guess Qt locations + +qt_incdirs="" +for dir in $kde_qt_dirs; do + qt_incdirs="$qt_incdirs $dir/include $dir" +done +qt_incdirs="$QTINC $qt_incdirs /usr/local/qt/include /usr/include/qt /usr/include /usr/X11R6/include/X11/qt /usr/X11R6/include/qt /usr/X11R6/include/qt2 /usr/include/qt3 $x_includes" +if test ! "$ac_qt_includes" = "NO"; then + qt_incdirs="$ac_qt_includes $qt_incdirs" +fi + +if test "$kde_qtver" != "1"; then + kde_qt_header=qstyle.h +else + kde_qt_header=qglobal.h +fi + +AC_FIND_FILE($kde_qt_header, $qt_incdirs, qt_incdir) +ac_qt_includes="$qt_incdir" + +qt_libdirs="" +for dir in $kde_qt_dirs; do + qt_libdirs="$qt_libdirs $dir/lib${kdelibsuff} $dir" +done +qt_libdirs="$QTLIB $qt_libdirs /usr/X11R6/lib /usr/lib /usr/local/qt/lib $x_libraries" +if test ! "$ac_qt_libraries" = "NO"; then + qt_libdir=$ac_qt_libraries +else + qt_libdirs="$ac_qt_libraries $qt_libdirs" + # if the Qt was given, the chance is too big that libqt.* doesn't exist + qt_libdir=NONE + for dir in $qt_libdirs; do + try="ls -1 $dir/${LIBQT_GLOB}" + if test -n "`$try 2> /dev/null`"; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi + done +fi +for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do + if test -e "$a"; then + LIBQT="$LIBQT ${kde_int_qt}_incremental" + break + fi +done + +ac_qt_libraries="$qt_libdir" + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +ac_cxxflags_safe="$CXXFLAGS" +ac_ldflags_safe="$LDFLAGS" +ac_libs_safe="$LIBS" + +CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" +LDFLAGS="$LDFLAGS -L$qt_libdir $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" +LIBS="$LIBS $LIBQT $KDE_MT_LIBS" + +KDE_PRINT_QT_PROGRAM + +if AC_TRY_EVAL(ac_link) && test -s conftest; then + rm -f conftest* +else + echo "configure: failed program was:" >&AC_FD_CC + cat conftest.$ac_ext >&AC_FD_CC + ac_qt_libraries="NO" +fi +rm -f conftest* +CXXFLAGS="$ac_cxxflags_safe" +LDFLAGS="$ac_ldflags_safe" +LIBS="$ac_libs_safe" + +AC_LANG_RESTORE +if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then + ac_cv_have_qt="have_qt=no" + ac_qt_notfound="" + missing_qt_mt="" + if test "$ac_qt_includes" = NO; then + if test "$ac_qt_libraries" = NO; then + ac_qt_notfound="(headers and libraries)"; + else + ac_qt_notfound="(headers)"; + fi + else + if test "x$kde_use_qt_mt" = "xyes"; then + missing_qt_mt=" +Make sure that you have compiled Qt with thread support!" + ac_qt_notfound="(library $qtlib-mt)"; + else + ac_qt_notfound="(library $qtlib)"; + fi + fi + + AC_MSG_ERROR([Qt ($kde_qt_minversion) $ac_qt_notfound not found. Please check your installation! +For more details about this problem, look at the end of config.log.$missing_qt_mt]) +else + have_qt="yes" +fi +]) + +eval "$ac_cv_have_qt" + +if test "$have_qt" != yes; then + AC_MSG_RESULT([$have_qt]); +else + ac_cv_have_qt="have_qt=yes \ + ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries" + AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes $USING_QT_MT]) + + qt_libraries="$ac_qt_libraries" + qt_includes="$ac_qt_includes" +fi + +if test ! "$kde_qt_libs_given" = "yes" && test ! "$kde_qtver" = 3; then + KDE_CHECK_QT_DIRECT(qt_libraries= ,[]) +fi + +AC_SUBST(qt_libraries) +AC_SUBST(qt_includes) + +if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then + QT_INCLUDES="" +else + QT_INCLUDES="-I$qt_includes" + all_includes="$QT_INCLUDES $all_includes" +fi + +if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then + QT_LDFLAGS="" +else + QT_LDFLAGS="-L$qt_libraries" + all_libraries="$QT_LDFLAGS $all_libraries" +fi +test -z "$KDE_MT_LDFLAGS" || all_libraries="$all_libraries $KDE_MT_LDFLAGS" + +AC_SUBST(QT_INCLUDES) +AC_SUBST(QT_LDFLAGS) +AC_PATH_QT_MOC_UIC + +KDE_CHECK_QT_JPEG + +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG) -lXext $(LIB_X11) $(LIBSM)' +else +LIB_QT="$kde_int_qt $LIBJPEG_QT "'$(LIBZ) $(LIBPNG)' +fi +test -z "$KDE_MT_LIBS" || LIB_QT="$LIB_QT $KDE_MT_LIBS" +for a in $qt_libdir/lib`echo ${kde_int_qt} | sed 's,^-l,,'`_incremental.*; do + if test -e "$a"; then + LIB_QT="$LIB_QT ${kde_int_qt}_incremental" + break + fi +done + +AC_SUBST(LIB_QT) +AC_SUBST(LIB_QPE) + +AC_SUBST(kde_qtver) +]) + +AC_DEFUN([AC_PATH_QT], +[ +AC_PATH_QT_1_3 +]) + +AC_DEFUN([KDE_CHECK_UIC_PLUGINS], +[ +AC_REQUIRE([AC_PATH_QT_MOC_UIC]) + +if test x$ac_uic_supports_libpath = xyes; then + +AC_MSG_CHECKING([if UIC has KDE plugins available]) +AC_CACHE_VAL(kde_cv_uic_plugins, +[ +cat > actest.ui << EOF + +NewConnectionDialog + + + + testInput + + + + +EOF + + + +kde_cv_uic_plugins=no +kde_line="$UIC_PATH -L $kde_widgetdir" +if test x$ac_uic_supports_nounload = xyes; then + kde_line="$kde_line -nounload" +fi +kde_line="$kde_line -impl actest.h actest.ui > actest.cpp" +if AC_TRY_EVAL(kde_line); then + # if you're trying to debug this check and think it's incorrect, + # better check your installation. The check _is_ correct - your + # installation is not. + if test -f actest.cpp && grep klineedit actest.cpp > /dev/null; then + kde_cv_uic_plugins=yes + fi +fi +rm -f actest.ui actest.cpp +]) + +AC_MSG_RESULT([$kde_cv_uic_plugins]) +if test "$kde_cv_uic_plugins" != yes; then + AC_MSG_ERROR([ +you need to install kdelibs first. + +If you did install kdelibs, then the Qt version that is picked up by +this configure is not the same version you used to compile kdelibs. +The Qt Plugin installed by kdelibs is *ONLY* loadable if it is the +_same Qt version_, compiled with the _same compiler_ and the same Qt +configuration settings. +]) +fi +fi +]) + +AC_DEFUN([KDE_CHECK_FINAL], +[ + AC_ARG_ENABLE(final, + AC_HELP_STRING([--enable-final], + [build size optimized apps (experimental - needs lots of memory)]), + kde_use_final=$enableval, kde_use_final=no) + + if test "x$kde_use_final" = "xyes"; then + KDE_USE_FINAL_TRUE="" + KDE_USE_FINAL_FALSE="#" + else + KDE_USE_FINAL_TRUE="#" + KDE_USE_FINAL_FALSE="" + fi + AC_SUBST(KDE_USE_FINAL_TRUE) + AC_SUBST(KDE_USE_FINAL_FALSE) +]) + +AC_DEFUN([KDE_CHECK_CLOSURE], +[ + AC_ARG_ENABLE(closure, + AC_HELP_STRING([--enable-closure],[delay template instantiation]), + kde_use_closure=$enableval, kde_use_closure=no) + + KDE_NO_UNDEFINED="" + if test "x$kde_use_closure" = "xyes"; then + KDE_USE_CLOSURE_TRUE="" + KDE_USE_CLOSURE_FALSE="#" +# CXXFLAGS="$CXXFLAGS $REPO" + else + KDE_USE_CLOSURE_TRUE="#" + KDE_USE_CLOSURE_FALSE="" + KDE_NO_UNDEFINED="" + fi + AC_SUBST(KDE_USE_CLOSURE_TRUE) + AC_SUBST(KDE_USE_CLOSURE_FALSE) + AC_SUBST(KDE_NO_UNDEFINED) +]) + +dnl Check if the linker supports --enable-new-dtags and --as-needed +AC_DEFUN([KDE_CHECK_NEW_LDFLAGS], +[ + AC_ARG_ENABLE(new_ldflags, + AC_HELP_STRING([--enable-new-ldflags], + [enable the new linker flags]), + kde_use_new_ldflags=$enableval, + kde_use_new_ldflags=no) + + LDFLAGS_AS_NEEDED="" + LDFLAGS_NEW_DTAGS="" + if test "x$kde_use_new_ldflags" = "xyes"; then + LDFLAGS_NEW_DTAGS="" + KDE_CHECK_COMPILER_FLAG([Wl,--enable-new-dtags], + [LDFLAGS_NEW_DTAGS="-Wl,--enable-new-dtags"],) + + KDE_CHECK_COMPILER_FLAG([Wl,--as-needed], + [LDFLAGS_AS_NEEDED="-Wl,--as-needed"],) + fi + AC_SUBST(LDFLAGS_AS_NEEDED) + AC_SUBST(LDFLAGS_NEW_DTAGS) +]) + +AC_DEFUN([KDE_CHECK_NMCHECK], +[ + AC_ARG_ENABLE(nmcheck,AC_HELP_STRING([--enable-nmcheck],[enable automatic namespace cleanness check]), + kde_use_nmcheck=$enableval, kde_use_nmcheck=no) + + if test "$kde_use_nmcheck" = "yes"; then + KDE_USE_NMCHECK_TRUE="" + KDE_USE_NMCHECK_FALSE="#" + else + KDE_USE_NMCHECK_TRUE="#" + KDE_USE_NMCHECK_FALSE="" + fi + AC_SUBST(KDE_USE_NMCHECK_TRUE) + AC_SUBST(KDE_USE_NMCHECK_FALSE) +]) + +AC_DEFUN([KDE_EXPAND_MAKEVAR], [ +savex=$exec_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +tmp=$$2 +while $1=`eval echo "$tmp"`; test "x$$1" != "x$tmp"; do tmp=$$1; done +exec_prefix=$savex +]) + +dnl ------------------------------------------------------------------------ +dnl Now, the same with KDE +dnl $(KDE_LDFLAGS) will be the kdeliblocation (if needed) +dnl and $(kde_includes) will be the kdehdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_BASE_PATH_KDE], +[ +AC_REQUIRE([KDE_CHECK_STL]) +AC_REQUIRE([AC_PATH_QT])dnl +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_CHECK_RPATH +AC_MSG_CHECKING([for KDE]) + +if test "${prefix}" != NONE; then + kde_includes=${includedir} + KDE_EXPAND_MAKEVAR(ac_kde_includes, includedir) + + kde_libraries=${libdir} + KDE_EXPAND_MAKEVAR(ac_kde_libraries, libdir) + +else + ac_kde_includes= + ac_kde_libraries= + kde_libraries="" + kde_includes="" +fi + +AC_CACHE_VAL(ac_cv_have_kde, +[#try to guess kde locations + +if test "$kde_qtver" = 1; then + kde_check_header="ksock.h" + kde_check_lib="libkdecore.la" +else + kde_check_header="ksharedptr.h" + kde_check_lib="libkio.la" +fi + +if test -z "$1"; then + +kde_incdirs="$kde_libs_prefix/include /usr/lib/kde/include /usr/local/kde/include /usr/local/include /usr/kde/include /usr/include/kde /usr/include /opt/kde3/include /opt/kde/include $x_includes $qt_includes" +test -n "$KDEDIR" && kde_incdirs="$KDEDIR/include $KDEDIR/include/kde $KDEDIR $kde_incdirs" +kde_incdirs="$ac_kde_includes $kde_incdirs" +AC_FIND_FILE($kde_check_header, $kde_incdirs, kde_incdir) +ac_kde_includes="$kde_incdir" + +if test -n "$ac_kde_includes" && test ! -r "$ac_kde_includes/$kde_check_header"; then + AC_MSG_ERROR([ +in the prefix, you've chosen, are no KDE headers installed. This will fail. +So, check this please and use another prefix!]) +fi + +kde_libdirs="$kde_libs_prefix/lib${kdelibsuff} /usr/lib/kde/lib${kdelibsuff} /usr/local/kde/lib${kdelibsuff} /usr/kde/lib${kdelibsuff} /usr/lib${kdelibsuff}/kde /usr/lib${kdelibsuff}/kde3 /usr/lib${kdelibsuff} /usr/X11R6/lib${kdelibsuff} /usr/local/lib${kdelibsuff} /opt/kde3/lib${kdelibsuff} /opt/kde/lib${kdelibsuff} /usr/X11R6/kde/lib${kdelibsuff}" +test -n "$KDEDIR" && kde_libdirs="$KDEDIR/lib${kdelibsuff} $KDEDIR $kde_libdirs" +kde_libdirs="$ac_kde_libraries $libdir $kde_libdirs" +AC_FIND_FILE($kde_check_lib, $kde_libdirs, kde_libdir) +ac_kde_libraries="$kde_libdir" + +kde_widgetdir=NO +dnl this might be somewhere else +AC_FIND_FILE("kde3/plugins/designer/kdewidgets.la", $kde_libdirs, kde_widgetdir) + +if test -n "$ac_kde_libraries" && test ! -r "$ac_kde_libraries/$kde_check_lib"; then +AC_MSG_ERROR([ +in the prefix, you've chosen, are no KDE libraries installed. This will fail. +So, check this please and use another prefix!]) +fi + +if test -n "$kde_widgetdir" && test ! -r "$kde_widgetdir/kde3/plugins/designer/kdewidgets.la"; then +AC_MSG_ERROR([ +I can't find the designer plugins. These are required and should have been installed +by kdelibs]) +fi + +if test -n "$kde_widgetdir"; then + kde_widgetdir="$kde_widgetdir/kde3/plugins/designer" +fi + + +if test "$ac_kde_includes" = NO || test "$ac_kde_libraries" = NO || test "$kde_widgetdir" = NO; then + ac_cv_have_kde="have_kde=no" +else + ac_cv_have_kde="have_kde=yes \ + ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" +fi + +else dnl test -z $1, e.g. from kdelibs + + ac_cv_have_kde="have_kde=no" + +fi +])dnl + +eval "$ac_cv_have_kde" + +if test "$have_kde" != "yes"; then + if test "${prefix}" = NONE; then + ac_kde_prefix="$ac_default_prefix" + else + ac_kde_prefix="$prefix" + fi + if test "$exec_prefix" = NONE; then + ac_kde_exec_prefix="$ac_kde_prefix" + AC_MSG_RESULT([will be installed in $ac_kde_prefix]) + else + ac_kde_exec_prefix="$exec_prefix" + AC_MSG_RESULT([will be installed in $ac_kde_prefix and $ac_kde_exec_prefix]) + fi + + kde_libraries="${libdir}" + kde_includes="${includedir}" + +else + ac_cv_have_kde="have_kde=yes \ + ac_kde_includes=$ac_kde_includes ac_kde_libraries=$ac_kde_libraries" + AC_MSG_RESULT([libraries $ac_kde_libraries, headers $ac_kde_includes]) + + kde_libraries="$ac_kde_libraries" + kde_includes="$ac_kde_includes" +fi +AC_SUBST(kde_libraries) +AC_SUBST(kde_includes) + +if test "$kde_includes" = "$x_includes" || test "$kde_includes" = "$qt_includes" || test "$kde_includes" = "/usr/include"; then + KDE_INCLUDES="" +else + KDE_INCLUDES="-I$kde_includes" + all_includes="$KDE_INCLUDES $all_includes" +fi + +KDE_DEFAULT_CXXFLAGS="-DQT_CLEAN_NAMESPACE -DQT_NO_ASCII_CAST -DQT_NO_STL -DQT_NO_COMPAT -DQT_NO_TRANSLATION" + +KDE_LDFLAGS="-L$kde_libraries" +if test ! "$kde_libraries" = "$x_libraries" && test ! "$kde_libraries" = "$qt_libraries" ; then + all_libraries="$KDE_LDFLAGS $all_libraries" +fi + +AC_SUBST(KDE_LDFLAGS) +AC_SUBST(KDE_INCLUDES) + +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + +all_libraries="$all_libraries $USER_LDFLAGS" +all_includes="$all_includes $USER_INCLUDES" +AC_SUBST(all_includes) +AC_SUBST(all_libraries) + +if test -z "$1"; then +KDE_CHECK_UIC_PLUGINS +fi + +ac_kde_libraries="$kde_libdir" + +AC_SUBST(AUTODIRS) + + +]) + +AC_DEFUN([KDE_CHECK_EXTRA_LIBS], +[ +AC_MSG_CHECKING(for extra includes) +AC_ARG_WITH(extra-includes,AC_HELP_STRING([--with-extra-includes=DIR],[adds non standard include paths]), + kde_use_extra_includes="$withval", + kde_use_extra_includes=NONE +) +kde_extra_includes= +if test -n "$kde_use_extra_includes" && \ + test "$kde_use_extra_includes" != "NONE"; then + + ac_save_ifs=$IFS + IFS=':' + for dir in $kde_use_extra_includes; do + kde_extra_includes="$kde_extra_includes $dir" + USER_INCLUDES="$USER_INCLUDES -I$dir" + done + IFS=$ac_save_ifs + kde_use_extra_includes="added" +else + kde_use_extra_includes="no" +fi +AC_SUBST(USER_INCLUDES) + +AC_MSG_RESULT($kde_use_extra_includes) + +kde_extra_libs= +AC_MSG_CHECKING(for extra libs) +AC_ARG_WITH(extra-libs,AC_HELP_STRING([--with-extra-libs=DIR],[adds non standard library paths]), + kde_use_extra_libs=$withval, + kde_use_extra_libs=NONE +) +if test -n "$kde_use_extra_libs" && \ + test "$kde_use_extra_libs" != "NONE"; then + + ac_save_ifs=$IFS + IFS=':' + for dir in $kde_use_extra_libs; do + kde_extra_libs="$kde_extra_libs $dir" + KDE_EXTRA_RPATH="$KDE_EXTRA_RPATH -R $dir" + USER_LDFLAGS="$USER_LDFLAGS -L$dir" + done + IFS=$ac_save_ifs + kde_use_extra_libs="added" +else + kde_use_extra_libs="no" +fi + +AC_SUBST(USER_LDFLAGS) + +AC_MSG_RESULT($kde_use_extra_libs) + +]) + +AC_DEFUN([KDE_1_CHECK_PATH_HEADERS], +[ + AC_MSG_CHECKING([for KDE headers installed]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS +cat > conftest.$ac_ext < +#endif +#include +#include "confdefs.h" +#include + +int main() { + printf("kde_htmldir=\\"%s\\"\n", KApplication::kde_htmldir().data()); + printf("kde_appsdir=\\"%s\\"\n", KApplication::kde_appsdir().data()); + printf("kde_icondir=\\"%s\\"\n", KApplication::kde_icondir().data()); + printf("kde_sounddir=\\"%s\\"\n", KApplication::kde_sounddir().data()); + printf("kde_datadir=\\"%s\\"\n", KApplication::kde_datadir().data()); + printf("kde_locale=\\"%s\\"\n", KApplication::kde_localedir().data()); + printf("kde_cgidir=\\"%s\\"\n", KApplication::kde_cgidir().data()); + printf("kde_confdir=\\"%s\\"\n", KApplication::kde_configdir().data()); + printf("kde_mimedir=\\"%s\\"\n", KApplication::kde_mimedir().data()); + printf("kde_toolbardir=\\"%s\\"\n", KApplication::kde_toolbardir().data()); + printf("kde_wallpaperdir=\\"%s\\"\n", + KApplication::kde_wallpaperdir().data()); + printf("kde_bindir=\\"%s\\"\n", KApplication::kde_bindir().data()); + printf("kde_partsdir=\\"%s\\"\n", KApplication::kde_partsdir().data()); + printf("kde_servicesdir=\\"/tmp/dummy\\"\n"); + printf("kde_servicetypesdir=\\"/tmp/dummy\\"\n"); + printf("kde_moduledir=\\"/tmp/dummy\\"\n"); + printf("kde_styledir=\\"/tmp/dummy\\"\n"); + printf("kde_widgetdir=\\"/tmp/dummy\\"\n"); + printf("xdg_appsdir=\\"/tmp/dummy\\"\n"); + printf("xdg_menudir=\\"/tmp/dummy\\"\n"); + printf("xdg_directorydir=\\"/tmp/dummy\\"\n"); + printf("kde_kcfgdir=\\"/tmp/dummy\\"\n"); + return 0; + } +EOF + + ac_save_CPPFLAGS=$CPPFLAGS + CPPFLAGS="$all_includes $CPPFLAGS" + if AC_TRY_EVAL(ac_compile); then + AC_MSG_RESULT(yes) + else + AC_MSG_ERROR([your system is not able to compile a small KDE application! +Check, if you installed the KDE header files correctly. +For more details about this problem, look at the end of config.log.]) + fi + CPPFLAGS=$ac_save_CPPFLAGS + + AC_LANG_RESTORE +]) + +AC_DEFUN([KDE_CHECK_KDEQTADDON], +[ +AC_MSG_CHECKING(for kde-qt-addon) +AC_CACHE_VAL(kde_cv_have_kdeqtaddon, +[ + kde_ldflags_safe="$LDFLAGS" + kde_libs_safe="$LIBS" + kde_cxxflags_safe="$CXXFLAGS" + + LIBS="-lkde-qt-addon $LIBQT $LIBS" + CXXFLAGS="$CXXFLAGS -I$prefix/include -I$prefix/include/kde $all_includes" + LDFLAGS="$LDFLAGS $all_libraries $USER_LDFLAGS" + + AC_TRY_LINK([ + #include + ], + [ + QDomDocument doc; + ], + kde_cv_have_kdeqtaddon=yes, + kde_cv_have_kdeqtaddon=no + ) + + LDFLAGS=$kde_ldflags_safe + LIBS=$kde_libs_safe + CXXFLAGS=$kde_cxxflags_safe +]) + +AC_MSG_RESULT($kde_cv_have_kdeqtaddon) + +if test "$kde_cv_have_kdeqtaddon" = "no"; then + AC_MSG_ERROR([Can't find libkde-qt-addon. You need to install it first. +It is a separate package (and CVS module) named kde-qt-addon.]) +fi +]) + +AC_DEFUN([KDE_CREATE_LIBS_ALIASES], +[ + AC_REQUIRE([KDE_MISC_TESTS]) + AC_REQUIRE([KDE_CHECK_LIBDL]) + AC_REQUIRE([K_PATH_X]) + +if test $kde_qtver = 3; then + case $host in + *cygwin*) lib_kded="-lkdeinit_kded" ;; + *) lib_kded="" ;; + esac + AC_SUBST(LIB_KDED, $lib_kded) + AC_SUBST(LIB_KDECORE, "-lkdecore") + AC_SUBST(LIB_KDEUI, "-lkdeui") + AC_SUBST(LIB_KIO, "-lkio") + AC_SUBST(LIB_KJS, "-lkjs") + AC_SUBST(LIB_SMB, "-lsmb") + AC_SUBST(LIB_KAB, "-lkab") + AC_SUBST(LIB_KABC, "-lkabc") + AC_SUBST(LIB_KHTML, "-lkhtml") + AC_SUBST(LIB_KSPELL, "-lkspell") + AC_SUBST(LIB_KPARTS, "-lkparts") + AC_SUBST(LIB_KDEPRINT, "-lkdeprint") + AC_SUBST(LIB_KUTILS, "-lkutils") + AC_SUBST(LIB_KDEPIM, "-lkdepim") + AC_SUBST(LIB_KIMPROXY, "-lkimproxy") + AC_SUBST(LIB_KNEWSTUFF, "-lknewstuff") + AC_SUBST(LIB_KDNSSD, "-lkdnssd") + AC_SUBST(LIB_KUNITTEST, "-lkunittest") +# these are for backward compatibility + AC_SUBST(LIB_KSYCOCA, "-lkio") + AC_SUBST(LIB_KFILE, "-lkio") +elif test $kde_qtver = 2; then + AC_SUBST(LIB_KDECORE, "-lkdecore") + AC_SUBST(LIB_KDEUI, "-lkdeui") + AC_SUBST(LIB_KIO, "-lkio") + AC_SUBST(LIB_KSYCOCA, "-lksycoca") + AC_SUBST(LIB_SMB, "-lsmb") + AC_SUBST(LIB_KFILE, "-lkfile") + AC_SUBST(LIB_KAB, "-lkab") + AC_SUBST(LIB_KHTML, "-lkhtml") + AC_SUBST(LIB_KSPELL, "-lkspell") + AC_SUBST(LIB_KPARTS, "-lkparts") + AC_SUBST(LIB_KDEPRINT, "-lkdeprint") +else + AC_SUBST(LIB_KDECORE, "-lkdecore -lXext $(LIB_QT)") + AC_SUBST(LIB_KDEUI, "-lkdeui $(LIB_KDECORE)") + AC_SUBST(LIB_KFM, "-lkfm $(LIB_KDECORE)") + AC_SUBST(LIB_KFILE, "-lkfile $(LIB_KFM) $(LIB_KDEUI)") + AC_SUBST(LIB_KAB, "-lkab $(LIB_KIMGIO) $(LIB_KDECORE)") +fi +]) + +AC_DEFUN([AC_PATH_KDE], +[ + AC_BASE_PATH_KDE + AC_ARG_ENABLE(path-check,AC_HELP_STRING([--disable-path-check],[don't try to find out, where to install]), + [ + if test "$enableval" = "no"; + then ac_use_path_checking="default" + else ac_use_path_checking="" + fi + ], + [ + if test "$kde_qtver" = 1; + then ac_use_path_checking="" + else ac_use_path_checking="default" + fi + ] + ) + + AC_CREATE_KFSSTND($ac_use_path_checking) + + AC_SUBST_KFSSTND + KDE_CREATE_LIBS_ALIASES +]) + +dnl KDE_CHECK_FUNC_EXT(, [headers], [sample-use], [C prototype], [autoheader define], [call if found]) +AC_DEFUN([KDE_CHECK_FUNC_EXT], +[ +AC_MSG_CHECKING(for $1) +AC_CACHE_VAL(kde_cv_func_$1, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +save_CXXFLAGS="$CXXFLAGS" +kde_safe_LIBS="$LIBS" +LIBS="$LIBS $X_EXTRA_LIBS" +AC_TRY_COMPILE([ +$2 +], +[ +$3 +], +kde_cv_func_$1=yes, +kde_cv_func_$1=no) +CXXFLAGS="$save_CXXFLAGS" +LIBS="$kde_safe_LIBS" +AC_LANG_RESTORE +]) + +AC_MSG_RESULT($kde_cv_func_$1) + +AC_MSG_CHECKING([if $1 needs custom prototype]) +AC_CACHE_VAL(kde_cv_proto_$1, +[ +if test "x$kde_cv_func_$1" = xyes; then + kde_cv_proto_$1=no +else + case "$1" in + setenv|unsetenv|usleep|random|srandom|seteuid|mkstemps|mkstemp|revoke|vsnprintf|strlcpy|strlcat) + kde_cv_proto_$1="yes - in libkdefakes" + ;; + *) + kde_cv_proto_$1=unknown + ;; + esac +fi + +if test "x$kde_cv_proto_$1" = xunknown; then + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + kde_safe_libs=$LIBS + LIBS="$LIBS $X_EXTRA_LIBS" + AC_TRY_LINK([ +$2 + +extern "C" $4; +], +[ +$3 +], +[ kde_cv_func_$1=yes + kde_cv_proto_$1=yes ], + [kde_cv_proto_$1="$1 unavailable"] +) +LIBS=$kde_safe_libs +AC_LANG_RESTORE +fi +]) +AC_MSG_RESULT($kde_cv_proto_$1) + +if test "x$kde_cv_func_$1" = xyes; then + AC_DEFINE(HAVE_$5, 1, [Define if you have $1]) + $6 +fi +if test "x$kde_cv_proto_$1" = xno; then + AC_DEFINE(HAVE_$5_PROTO, 1, + [Define if you have the $1 prototype]) +fi + +AH_VERBATIM([_HAVE_$5_PROTO], +[ +#if !defined(HAVE_$5_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +$4; +#ifdef __cplusplus +} +#endif +#endif +]) +]) + +AC_DEFUN([AC_CHECK_SETENV], +[ + KDE_CHECK_FUNC_EXT(setenv, [ +#include +], + [setenv("VAR", "VALUE", 1);], + [int setenv (const char *, const char *, int)], + [SETENV]) +]) + +AC_DEFUN([AC_CHECK_UNSETENV], +[ + KDE_CHECK_FUNC_EXT(unsetenv, [ +#include +], + [unsetenv("VAR");], + [void unsetenv (const char *)], + [UNSETENV]) +]) + +AC_DEFUN([AC_CHECK_GETDOMAINNAME], +[ + KDE_CHECK_FUNC_EXT(getdomainname, [ +#include +#include +#include +], + [ +char buffer[200]; +getdomainname(buffer, 200); +], + [#include + int getdomainname (char *, size_t)], + [GETDOMAINNAME]) +]) + +AC_DEFUN([AC_CHECK_GETHOSTNAME], +[ + KDE_CHECK_FUNC_EXT(gethostname, [ +#include +#include +], + [ +char buffer[200]; +gethostname(buffer, 200); +], + [int gethostname (char *, unsigned int)], + [GETHOSTNAME]) +]) + +AC_DEFUN([AC_CHECK_USLEEP], +[ + KDE_CHECK_FUNC_EXT(usleep, [ +#include +], + [ +usleep(200); +], + [int usleep (unsigned int)], + [USLEEP]) +]) + + +AC_DEFUN([AC_CHECK_RANDOM], +[ + KDE_CHECK_FUNC_EXT(random, [ +#include +], + [ +random(); +], + [long int random(void)], + [RANDOM]) + + KDE_CHECK_FUNC_EXT(srandom, [ +#include +], + [ +srandom(27); +], + [void srandom(unsigned int)], + [SRANDOM]) + +]) + +AC_DEFUN([AC_CHECK_INITGROUPS], +[ + KDE_CHECK_FUNC_EXT(initgroups, [ +#include +#include +#include +], + [ +char buffer[200]; +initgroups(buffer, 27); +], + [int initgroups(const char *, gid_t)], + [INITGROUPS]) +]) + +AC_DEFUN([AC_CHECK_MKSTEMPS], +[ + KDE_CHECK_FUNC_EXT(mkstemps, [ +#include +#include +], + [ +mkstemps("/tmp/aaaXXXXXX", 6); +], + [int mkstemps(char *, int)], + [MKSTEMPS]) +]) + +AC_DEFUN([AC_CHECK_MKSTEMP], +[ + KDE_CHECK_FUNC_EXT(mkstemp, [ +#include +#include +], + [ +mkstemp("/tmp/aaaXXXXXX"); +], + [int mkstemp(char *)], + [MKSTEMP]) +]) + +AC_DEFUN([AC_CHECK_MKDTEMP], +[ + KDE_CHECK_FUNC_EXT(mkdtemp, [ +#include +#include +], + [ +mkdtemp("/tmp/aaaXXXXXX"); +], + [char *mkdtemp(char *)], + [MKDTEMP]) +]) + + +AC_DEFUN([AC_CHECK_RES_INIT], +[ + AC_MSG_CHECKING([if res_init needs -lresolv]) + kde_libs_safe="$LIBS" + LIBS="$LIBS $X_EXTRA_LIBS -lresolv" + AC_TRY_LINK( + [ +#include +#include +#include +#include + ], + [ + res_init(); + ], + [ + LIBRESOLV="-lresolv" + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_RES_INIT, 1, [Define if you have the res_init function]) + ], + [ AC_MSG_RESULT(no) ] + ) + LIBS=$kde_libs_safe + AC_SUBST(LIBRESOLV) + + KDE_CHECK_FUNC_EXT(res_init, + [ +#include +#include +#include +#include + ], + [res_init()], + [int res_init(void)], + [RES_INIT]) +]) + +AC_DEFUN([AC_CHECK_STRLCPY], +[ + KDE_CHECK_FUNC_EXT(strlcpy, [ +#include +], +[ char buf[20]; + strlcpy(buf, "KDE function test", sizeof(buf)); +], + [unsigned long strlcpy(char*, const char*, unsigned long)], + [STRLCPY]) +]) + +AC_DEFUN([AC_CHECK_STRLCAT], +[ + KDE_CHECK_FUNC_EXT(strlcat, [ +#include +], +[ char buf[20]; + buf[0]='\0'; + strlcat(buf, "KDE function test", sizeof(buf)); +], + [unsigned long strlcat(char*, const char*, unsigned long)], + [STRLCAT]) +]) + +AC_DEFUN([AC_CHECK_RES_QUERY], +[ + KDE_CHECK_FUNC_EXT(res_query, [ +#include +#include +#include +#include +#include +], +[ +res_query(NULL, 0, 0, NULL, 0); +], + [int res_query(const char *, int, int, unsigned char *, int)], + [RES_QUERY]) +]) + +AC_DEFUN([AC_CHECK_DN_SKIPNAME], +[ + KDE_CHECK_FUNC_EXT(dn_skipname, [ +#include +#include +#include +#include +], +[ +dn_skipname (NULL, NULL); +], + [int dn_skipname (unsigned char *, unsigned char *)], + [DN_SKIPNAME]) +]) + + +AC_DEFUN([AC_FIND_GIF], + [AC_MSG_CHECKING([for giflib]) +AC_CACHE_VAL(ac_cv_lib_gif, +[ac_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$all_libraries -lgif -lX11 $LIBSOCKET" +else +LIBS="$all_libraries -lgif" +fi +AC_TRY_LINK(dnl +[ +#ifdef __cplusplus +extern "C" { +#endif +int GifLastError(void); +#ifdef __cplusplus +} +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +], + [return GifLastError();], + eval "ac_cv_lib_gif=yes", + eval "ac_cv_lib_gif=no") +LIBS="$ac_save_LIBS" +])dnl +if eval "test \"`echo $ac_cv_lib_gif`\" = yes"; then + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_LIBGIF, 1, [Define if you have libgif]) +else + AC_MSG_ERROR(You need giflib30. Please install the kdesupport package) +fi +]) + +AC_DEFUN([KDE_FIND_JPEG_HELPER], +[ +AC_MSG_CHECKING([for libjpeg$2]) +AC_CACHE_VAL(ac_cv_lib_jpeg_$1, +[ +ac_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -ljpeg$2 -lm" +ac_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK( +[ +#ifdef __cplusplus +extern "C" { +#endif +void jpeg_CreateDecompress(); +#ifdef __cplusplus +} +#endif +], +[jpeg_CreateDecompress();], + eval "ac_cv_lib_jpeg_$1=-ljpeg$2", + eval "ac_cv_lib_jpeg_$1=no") +LIBS="$ac_save_LIBS" +CFLAGS="$ac_save_CFLAGS" +]) + +if eval "test ! \"`echo $ac_cv_lib_jpeg_$1`\" = no"; then + LIBJPEG="$ac_cv_lib_jpeg_$1" + AC_MSG_RESULT($ac_cv_lib_jpeg_$1) +else + AC_MSG_RESULT(no) + $3 +fi + +]) + +AC_DEFUN([AC_FIND_JPEG], +[ +dnl first look for libraries +KDE_FIND_JPEG_HELPER(6b, 6b, + KDE_FIND_JPEG_HELPER(normal, [], + [ + LIBJPEG= + ] + ) +) + +dnl then search the headers (can't use simply AC_TRY_xxx, as jpeglib.h +dnl requires system dependent includes loaded before it) +jpeg_incdirs="$includedir /usr/include /usr/local/include $kde_extra_includes" +AC_FIND_FILE(jpeglib.h, $jpeg_incdirs, jpeg_incdir) +test "x$jpeg_incdir" = xNO && jpeg_incdir= + +dnl if headers _and_ libraries are missing, this is no error, and we +dnl continue with a warning (the user will get no jpeg support in khtml) +dnl if only one is missing, it means a configuration error, but we still +dnl only warn +if test -n "$jpeg_incdir" && test -n "$LIBJPEG" ; then + AC_DEFINE_UNQUOTED(HAVE_LIBJPEG, 1, [Define if you have libjpeg]) +else + if test -n "$jpeg_incdir" || test -n "$LIBJPEG" ; then + AC_MSG_WARN([ +There is an installation error in jpeg support. You seem to have only one +of either the headers _or_ the libraries installed. You may need to either +provide correct --with-extra-... options, or the development package of +libjpeg6b. You can get a source package of libjpeg from http://www.ijg.org/ +Disabling JPEG support. +]) + else + AC_MSG_WARN([libjpeg not found. disable JPEG support.]) + fi + jpeg_incdir= + LIBJPEG= +fi + +AC_SUBST(LIBJPEG) +AH_VERBATIM(_AC_CHECK_JPEG, +[/* + * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system + * headers and I'm too lazy to write a configure test as long as only + * unixware is related + */ +#ifdef _UNIXWARE +#define HAVE_BOOLEAN +#endif +]) +]) + +AC_DEFUN([KDE_CHECK_QT_JPEG], +[ +if test -n "$LIBJPEG"; then +AC_MSG_CHECKING([if Qt needs $LIBJPEG]) +AC_CACHE_VAL(kde_cv_qt_jpeg, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS $LIBQT" +LIBS=`echo $LIBS | sed "s/$LIBJPEG//"` +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK( +[#include ], + [ + int argc; + char** argv; + QApplication app(argc, argv);], + eval "kde_cv_qt_jpeg=no", + eval "kde_cv_qt_jpeg=yes") +LIBS="$ac_save_LIBS" +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE +fi +]) + +if eval "test ! \"`echo $kde_cv_qt_jpeg`\" = no"; then + AC_MSG_RESULT(yes) + LIBJPEG_QT='$(LIBJPEG)' +else + AC_MSG_RESULT(no) + LIBJPEG_QT= +fi + +]) + +AC_DEFUN([AC_FIND_ZLIB], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_MSG_CHECKING([for libz]) +AC_CACHE_VAL(ac_cv_lib_z, +[ +kde_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -lz $LIBSOCKET" +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK(dnl +[ +#include +], +[ + char buf[42]; + gzFile f = (gzFile) 0; + /* this would segfault.. but we only link, don't run */ + (void) gzgets(f, buf, sizeof(buf)); + + return (zlibVersion() == ZLIB_VERSION); +], + eval "ac_cv_lib_z='-lz'", + eval "ac_cv_lib_z=no") +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if test ! "$ac_cv_lib_z" = no; then + AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz]) + LIBZ="$ac_cv_lib_z" + AC_MSG_RESULT($ac_cv_lib_z) +else + AC_MSG_ERROR(not found. + Possibly configure picks up an outdated version + installed by XFree86. Remove it from your system. + + Check your installation and look into config.log) + LIBZ="" +fi +AC_SUBST(LIBZ) +]) + +AC_DEFUN([KDE_TRY_TIFFLIB], +[ +AC_MSG_CHECKING([for libtiff $1]) + +AC_CACHE_VAL(kde_cv_libtiff_$1, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kde_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lX11 $LIBSOCKET -lm" +else +LIBS="$all_libraries $USER_LDFLAGS -l$1 $LIBJPEG $LIBZ -lm" +fi +kde_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl +[ +#include +], + [return (TIFFOpen( "", "r") == 0); ], +[ + kde_cv_libtiff_$1="-l$1 $LIBJPEG $LIBZ" +], [ + kde_cv_libtiff_$1=no +]) + +LIBS="$kde_save_LIBS" +CXXFLAGS="$kde_save_CXXFLAGS" +AC_LANG_RESTORE +]) + +if test "$kde_cv_libtiff_$1" = "no"; then + AC_MSG_RESULT(no) + LIBTIFF="" + $3 +else + LIBTIFF="$kde_cv_libtiff_$1" + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_LIBTIFF, 1, [Define if you have libtiff]) + $2 +fi + +]) + +AC_DEFUN([AC_FIND_TIFF], +[ +AC_REQUIRE([K_PATH_X]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_REQUIRE([AC_FIND_JPEG]) +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + +KDE_TRY_TIFFLIB(tiff, [], + KDE_TRY_TIFFLIB(tiff34)) + +AC_SUBST(LIBTIFF) +]) + +AC_DEFUN([KDE_FIND_LIBEXR], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_CACHE_VAL(ac_cv_libexr, +[ + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + AC_MSG_CHECKING([for OpenEXR libraries]) + + if test "$PKG_CONFIG" = "no" ; then + AC_MSG_RESULT(no) + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + if !(`$PKG_CONFIG --exists OpenEXR`) ; then + AC_MSG_RESULT(no) + EXRSTATUS=no + else + if !(`$PKG_CONFIG --atleast-version="1.1.1" OpenEXR`) ; then + AC_MSG_RESULT(no) + EXRSTATUS=old + else + kde_save_LIBS="$LIBS" + LIBS="$LIBS $all_libraries $USER_LDFLAGS `pkg-config --libs OpenEXR` $LIBZ" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + kde_save_CXXFLAGS="$CXXFLAGS" + EXR_FLAGS=`$PKG_CONFIG --cflags OpenEXR` + CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES $EXR_FLAGS" + + AC_TRY_LINK(dnl + [ + #include + ], + [ + using namespace Imf; + RgbaInputFile file ("dummy"); + return 0; + ], + eval "ac_cv_libexr='`pkg-config --libs OpenEXR`'", + eval "ac_cv_libexr=no" + ) + LIBS="$kde_save_LIBS" + CXXFLAGS="$kde_save_CXXFLAGS" + AC_LANG_RESTORE + ])dnl + if eval "test ! \"`echo $ac_cv_libexr`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_EXR, 1, [Define if you have OpenEXR]) + LIB_EXR="$ac_cv_libexr" + AC_MSG_RESULT($ac_cv_libexr) + else + AC_MSG_RESULT(no) + LIB_EXR="" + fi + fi + fi + fi + AC_SUBST(LIB_EXR) + AC_SUBST(EXR_FLAGS) +]) + + + +AC_DEFUN([AC_FIND_PNG], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_ZLIB]) +AC_MSG_CHECKING([for libpng]) +AC_CACHE_VAL(ac_cv_lib_png, +[ +kde_save_LIBS="$LIBS" +if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then +LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm -lX11 $LIBSOCKET" +else +LIBS="$LIBS $all_libraries $USER_LDFLAGS -lpng $LIBZ -lm" +fi +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl + [ + #include + ], + [ + png_structp png_ptr = png_create_read_struct( /* image ptr */ + PNG_LIBPNG_VER_STRING, 0, 0, 0 ); + return( png_ptr != 0 ); + ], + eval "ac_cv_lib_png='-lpng $LIBZ -lm'", + eval "ac_cv_lib_png=no" +) +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng]) + LIBPNG="$ac_cv_lib_png" + AC_SUBST(LIBPNG) + AC_MSG_RESULT($ac_cv_lib_png) +else + AC_MSG_RESULT(no) + LIBPNG="" + AC_SUBST(LIBPNG) +fi +]) + + +AC_DEFUN([AC_FIND_JASPER], +[ +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_REQUIRE([AC_FIND_JPEG]) +AC_MSG_CHECKING([for jasper]) +AC_CACHE_VAL(ac_cv_jasper, +[ +kde_save_LIBS="$LIBS" +LIBS="$LIBS $all_libraries $USER_LDFLAGS -ljasper $LIBJPEG -lm" +kde_save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $all_includes $USER_INCLUDES" + +AC_TRY_LINK(dnl + [ + #include + ], + [ + return( jas_init() ); + ], + eval "ac_cv_jasper='-ljasper $LIBJPEG -lm'", + eval "ac_cv_jasper=no" +) +LIBS="$kde_save_LIBS" +CFLAGS="$kde_save_CFLAGS" +])dnl +if eval "test ! \"`echo $ac_cv_jasper`\" = no"; then + AC_DEFINE_UNQUOTED(HAVE_JASPER, 1, [Define if you have jasper]) + LIB_JASPER="$ac_cv_jasper" + AC_MSG_RESULT($ac_cv_jasper) +else + AC_MSG_RESULT(no) + LIB_JASPER="" +fi +AC_SUBST(LIB_JASPER) +]) + +AC_DEFUN([AC_CHECK_BOOL], +[ + AC_DEFINE_UNQUOTED(HAVE_BOOL, 1, [You _must_ have bool]) +]) + +AC_DEFUN([AC_CHECK_GNU_EXTENSIONS], +[ +AC_MSG_CHECKING(if you need GNU extensions) +AC_CACHE_VAL(ac_cv_gnu_extensions, +[ +cat > conftest.c << EOF +#include + +#ifdef __GNU_LIBRARY__ +yes +#endif +EOF + +if (eval "$ac_cpp conftest.c") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + rm -rf conftest* + ac_cv_gnu_extensions=yes +else + ac_cv_gnu_extensions=no +fi +]) + +AC_MSG_RESULT($ac_cv_gnu_extensions) +if test "$ac_cv_gnu_extensions" = "yes"; then + AC_DEFINE_UNQUOTED(_GNU_SOURCE, 1, [Define if you need to use the GNU extensions]) +fi +]) + +AC_DEFUN([KDE_CHECK_COMPILER_FLAG], +[ +AC_MSG_CHECKING([whether $CXX supports -$1]) +kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` +AC_CACHE_VAL(kde_cv_prog_cxx_$kde_cache, +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -$1" + AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cxx_$kde_cache=yes"], []) + CXXFLAGS="$save_CXXFLAGS" + AC_LANG_RESTORE +]) +if eval "test \"`echo '$kde_cv_prog_cxx_'$kde_cache`\" = yes"; then + AC_MSG_RESULT(yes) + : + $2 +else + AC_MSG_RESULT(no) + : + $3 +fi +]) + +AC_DEFUN([KDE_CHECK_C_COMPILER_FLAG], +[ +AC_MSG_CHECKING([whether $CC supports -$1]) +kde_cache=`echo $1 | sed 'y% .=/+-,%____p__%'` +AC_CACHE_VAL(kde_cv_prog_cc_$kde_cache, +[ + AC_LANG_SAVE + AC_LANG_C + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -$1" + AC_TRY_LINK([],[ return 0; ], [eval "kde_cv_prog_cc_$kde_cache=yes"], []) + CFLAGS="$save_CFLAGS" + AC_LANG_RESTORE +]) +if eval "test \"`echo '$kde_cv_prog_cc_'$kde_cache`\" = yes"; then + AC_MSG_RESULT(yes) + : + $2 +else + AC_MSG_RESULT(no) + : + $3 +fi +]) + + +dnl AC_REMOVE_FORBIDDEN removes forbidden arguments from variables +dnl use: AC_REMOVE_FORBIDDEN(CC, [-forbid -bad-option whatever]) +dnl it's all white-space separated +AC_DEFUN([AC_REMOVE_FORBIDDEN], +[ __val=$$1 + __forbid=" $2 " + if test -n "$__val"; then + __new="" + ac_save_IFS=$IFS + IFS=" " + for i in $__val; do + case "$__forbid" in + *" $i "*) AC_MSG_WARN([found forbidden $i in $1, removing it]) ;; + *) # Careful to not add spaces, where there were none, because otherwise + # libtool gets confused, if we change e.g. CXX + if test -z "$__new" ; then __new=$i ; else __new="$__new $i" ; fi ;; + esac + done + IFS=$ac_save_IFS + $1=$__new + fi +]) + + +AC_DEFUN([KDE_CHECK_FOR_BAD_COMPILER], +[ + AC_MSG_CHECKING([whether $CC is blacklisted]) + + dnl In theory we have tu run this test against $CC and $CXX + dnl in C and in C++ mode, because its perfectly legal for + dnl the user to mix compiler versions, since C has a defined + dnl ABI. + dnl + dnl For now, we assume the user is not on crack. + + AC_TRY_COMPILE([ +#ifdef __GNUC__ +#if __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 0 +choke me +#endif +#endif +], , + kde_bad_compiler=no, + kde_bad_compiler=yes +) + + AC_MSG_RESULT($kde_bad_compiler) + +if test "$kde_bad_compiler" = "yes"; then + AC_MSG_ERROR([ + +This particular compiler version is blacklisted because it +is known to miscompile KDE. Please use a newer version, or +if that is not yet available, choose an older version. + +Please do not report a bug or bother us reporting this +configure error. We know about it, and we introduced +it by intention to avoid untraceable bugs or crashes in KDE. + +]) +fi + +]) + + +AC_DEFUN([KDE_CHECK_FOR_OPT_NOINLINE_MATCH], +[ + AC_CACHE_CHECK([whether system headers can cope with -O2 -fno-inline], + kde_cv_opt_noinline_match, + [ + kde_cv_opt_noinline_match=irrelevant + dnl if we don't use both -O2 and -fno-inline, this check is moot + if echo "$CFLAGS" | grep -e -O2 >/dev/null 2>/dev/null \ + && echo "$CFLAGS" | grep -e -fno-inline >/dev/null 2>/dev/null ; then + + ac_cflags_save="$CFLAGS" + CFLAGS="$CFLAGS -D_USE_GNU" + + AC_TRY_LINK([ + #include +], [ const char *pt, *et; + et = __extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p ( ";," ) && ((size_t)(const void *)(( ";," )+ 1) - (size_t)(const void *)( ";," ) == 1) ? ((__a0 =((__const char *) ( ";," ))[0], __a0 == '\0') ? ((void) ( pt ),((void *)0) ) : ((__a1 = ((__const char *) ( ";," ))[1], __a1== '\0') ? (__extension__ (__builtin_constant_p ( __a0 ) && ( __a0 ) == '\0' ? (char *) __rawmemchr ( pt , __a0) : strchr( pt , __a0 ))) : ((__a2 = ((__const char *) ( ";," ))[2], __a2 == '\0') ? __strpbrk_c2 ( pt , __a0, __a1) :(((__const char *) ( ";," ))[3] == '\0' ? __strpbrk_c3 ( pt ,__a0, __a1, __a2): strpbrk ( pt , ";," ))))) : strpbrk ( pt , ";," )); }) ; +], + kde_cv_opt_noinline_match=yes, + kde_cv_opt_noinline_match=no + ) + + CFLAGS="$ac_cflags_save" + fi + ]) +]) + + +dnl AC_VALIDIFY_CXXFLAGS checks for forbidden flags the user may have given +AC_DEFUN([AC_VALIDIFY_CXXFLAGS], +[dnl +if test "x$kde_use_qt_emb" != "xyes"; then + AC_REMOVE_FORBIDDEN(CXX, [-fno-rtti -rpath]) + AC_REMOVE_FORBIDDEN(CXXFLAGS, [-fno-rtti -rpath]) +else + AC_REMOVE_FORBIDDEN(CXX, [-rpath]) + AC_REMOVE_FORBIDDEN(CXXFLAGS, [-rpath]) +fi +]) + +AC_DEFUN([AC_CHECK_COMPILERS], +[ + AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug=ARG],[enables debug symbols (yes|no|full) [default=no]]), + [ + case $enableval in + yes) + kde_use_debug_code="yes" + kde_use_debug_define=no + ;; + full) + kde_use_debug_code="full" + kde_use_debug_define=no + ;; + *) + kde_use_debug_code="no" + kde_use_debug_define=yes + ;; + esac + ], + [kde_use_debug_code="no" + kde_use_debug_define=no + ]) + + dnl Just for configure --help + AC_ARG_ENABLE(dummyoption, + AC_HELP_STRING([--disable-debug], + [disables debug output and debug symbols [default=no]]), + [],[]) + + AC_ARG_ENABLE(strict, + AC_HELP_STRING([--enable-strict], + [compiles with strict compiler options (may not work!)]), + [ + if test $enableval = "no"; then + kde_use_strict_options="no" + else + kde_use_strict_options="yes" + fi + ], [kde_use_strict_options="no"]) + + AC_ARG_ENABLE(warnings,AC_HELP_STRING([--disable-warnings],[disables compilation with -Wall and similar]), + [ + if test $enableval = "no"; then + kde_use_warnings="no" + else + kde_use_warnings="yes" + fi + ], [kde_use_warnings="yes"]) + + dnl enable warnings for debug build + if test "$kde_use_debug_code" != "no"; then + kde_use_warnings=yes + fi + + AC_ARG_ENABLE(profile,AC_HELP_STRING([--enable-profile],[creates profiling infos [default=no]]), + [kde_use_profiling=$enableval], + [kde_use_profiling="no"] + ) + + dnl this prevents stupid AC_PROG_CC to add "-g" to the default CFLAGS + CFLAGS=" $CFLAGS" + + AC_PROG_CC + + AC_PROG_CPP + + if test "$GCC" = "yes"; then + if test "$kde_use_debug_code" != "no"; then + if test $kde_use_debug_code = "full"; then + CFLAGS="-g3 -fno-inline $CFLAGS" + else + CFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CFLAGS" + fi + else + CFLAGS="-O2 $CFLAGS" + fi + fi + + if test "$kde_use_debug_define" = "yes"; then + CFLAGS="-DNDEBUG $CFLAGS" + fi + + + case "$host" in + *-*-sysv4.2uw*) CFLAGS="-D_UNIXWARE $CFLAGS";; + *-*-sysv5uw7*) CFLAGS="-D_UNIXWARE7 $CFLAGS";; + esac + + if test -z "$LDFLAGS" && test "$kde_use_debug_code" = "no" && test "$GCC" = "yes"; then + LDFLAGS="" + fi + + CXXFLAGS=" $CXXFLAGS" + + AC_PROG_CXX + + KDE_CHECK_FOR_BAD_COMPILER + + if test "$GXX" = "yes" || test "$CXX" = "KCC"; then + if test "$kde_use_debug_code" != "no"; then + if test "$CXX" = "KCC"; then + CXXFLAGS="+K0 -Wall -pedantic -W -Wpointer-arith -Wwrite-strings $CXXFLAGS" + else + if test "$kde_use_debug_code" = "full"; then + CXXFLAGS="-g3 -fno-inline $CXXFLAGS" + else + CXXFLAGS="-g -O2 -fno-schedule-insns -fno-inline $CXXFLAGS" + fi + fi + KDE_CHECK_COMPILER_FLAG(fno-builtin,[CXXFLAGS="-fno-builtin $CXXFLAGS"]) + + dnl convenience compiler flags + KDE_CHECK_COMPILER_FLAG(Woverloaded-virtual, [WOVERLOADED_VIRTUAL="-Woverloaded-virtual"], [WOVERLOADED_VRITUAL=""]) + AC_SUBST(WOVERLOADED_VIRTUAL) + else + if test "$CXX" = "KCC"; then + CXXFLAGS="+K3 $CXXFLAGS" + else + CXXFLAGS="-O2 $CXXFLAGS" + fi + fi + fi + + if test "$kde_use_debug_define" = "yes"; then + CXXFLAGS="-DNDEBUG -DNO_DEBUG $CXXFLAGS" + fi + + if test "$kde_use_profiling" = "yes"; then + KDE_CHECK_COMPILER_FLAG(pg, + [ + CFLAGS="-pg $CFLAGS" + CXXFLAGS="-pg $CXXFLAGS" + ]) + fi + + if test "$kde_use_warnings" = "yes"; then + if test "$GCC" = "yes"; then + CXXFLAGS="-Wall -W -Wpointer-arith $CXXFLAGS" + case $host in + *-*-linux-gnu) + CFLAGS="-std=iso9899:1990 -W -Wall -Wchar-subscripts -Wshadow -Wpointer-arith -Wmissing-prototypes -Wwrite-strings -D_XOPEN_SOURCE=500 -D_BSD_SOURCE $CFLAGS" + CXXFLAGS="-ansi -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wchar-subscripts $CXXFLAGS" + KDE_CHECK_COMPILER_FLAG(Wmissing-format-attribute, [CXXFLAGS="$CXXFLAGS -Wformat-security -Wmissing-format-attribute"]) + KDE_CHECK_C_COMPILER_FLAG(Wmissing-format-attribute, [CFLAGS="$CFLAGS -Wformat-security -Wmissing-format-attribute"]) + ;; + esac + KDE_CHECK_COMPILER_FLAG(Wundef,[CXXFLAGS="-Wundef $CXXFLAGS"]) + KDE_CHECK_COMPILER_FLAG(Wno-long-long,[CXXFLAGS="-Wno-long-long $CXXFLAGS"]) + dnl ### FIXME: revert for KDE 4 + KDE_CHECK_COMPILER_FLAG(Wno-non-virtual-dtor,[CXXFLAGS="$CXXFLAGS -Wno-non-virtual-dtor"]) + fi + fi + + if test "$GXX" = "yes" && test "$kde_use_strict_options" = "yes"; then + CXXFLAGS="-Wcast-qual -Wshadow -Wcast-align $CXXFLAGS" + fi + + AC_ARG_ENABLE(pch, + AC_HELP_STRING([--enable-pch], + [enables precompiled header support (currently only KCC or gcc >=3.4+unsermake) [default=no]]), + [ kde_use_pch=$enableval ],[ kde_use_pch=no ]) + + HAVE_GCC_VISIBILITY=0 + AC_SUBST([HAVE_GCC_VISIBILITY]) + + if test "$GXX" = "yes"; then + gcc_no_reorder_blocks=NO + KDE_CHECK_COMPILER_FLAG(fno-reorder-blocks,[gcc_no_reorder_blocks=YES]) + if test $kde_use_debug_code != "no" && \ + test $kde_use_debug_code != "full" && \ + test "YES" = "$gcc_no_reorder_blocks" ; then + CXXFLAGS="$CXXFLAGS -fno-reorder-blocks" + CFLAGS="$CFLAGS -fno-reorder-blocks" + fi + KDE_CHECK_COMPILER_FLAG(fno-exceptions,[CXXFLAGS="$CXXFLAGS -fno-exceptions"]) + KDE_CHECK_COMPILER_FLAG(fno-check-new, [CXXFLAGS="$CXXFLAGS -fno-check-new"]) + KDE_CHECK_COMPILER_FLAG(fno-common, [CXXFLAGS="$CXXFLAGS -fno-common"]) + KDE_CHECK_COMPILER_FLAG(fexceptions, [USE_EXCEPTIONS="-fexceptions"], USE_EXCEPTIONS= ) + ENABLE_PERMISSIVE_FLAG="-fpermissive" + + if test "$kde_use_pch" = "yes"; then + AC_MSG_CHECKING(whether gcc supports precompiling c header files) + echo >conftest.h + if $CC -x c-header conftest.h >/dev/null 2>/dev/null; then + kde_gcc_supports_pch=yes + AC_MSG_RESULT(yes) + else + kde_gcc_supports_pch=no + AC_MSG_RESULT(no) + fi + if test "$kde_gcc_supports_pch" = "yes"; then + AC_MSG_CHECKING(whether gcc supports precompiling c++ header files) + if $CXX -x c++-header conftest.h >/dev/null 2>/dev/null; then + kde_gcc_supports_pch=yes + AC_MSG_RESULT(yes) + else + kde_gcc_supports_pch=no + AC_MSG_RESULT(no) + fi + fi + rm -f conftest.h conftest.h.gch + fi + + KDE_CHECK_FOR_OPT_NOINLINE_MATCH + if test "x$kde_cv_opt_noinline_match" = "xno" ; then + CFLAGS="`echo "$CFLAGS" | sed "s/ -fno-inline//"`" + fi + fi + AM_CONDITIONAL(unsermake_enable_pch, test "$kde_use_pch" = "yes" && test "$kde_gcc_supports_pch" = "yes") + if test "$CXX" = "KCC"; then + dnl unfortunately we currently cannot disable exception support in KCC + dnl because doing so is binary incompatible and Qt by default links with exceptions :-( + dnl KDE_CHECK_COMPILER_FLAG(-no_exceptions,[CXXFLAGS="$CXXFLAGS --no_exceptions"]) + dnl KDE_CHECK_COMPILER_FLAG(-exceptions, [USE_EXCEPTIONS="--exceptions"], USE_EXCEPTIONS= ) + + if test "$kde_use_pch" = "yes"; then + dnl TODO: support --pch-dir! + KDE_CHECK_COMPILER_FLAG(-pch,[CXXFLAGS="$CXXFLAGS --pch"]) + dnl the below works (but the dir must exist), but it's + dnl useless for a whole package. + dnl The are precompiled headers for each source file, so when compiling + dnl from scratch, it doesn't make a difference, and they take up + dnl around ~5Mb _per_ sourcefile. + dnl KDE_CHECK_COMPILER_FLAG(-pch_dir /tmp, + dnl [CXXFLAGS="$CXXFLAGS --pch_dir `pwd`/pcheaders"]) + fi + dnl this flag controls inlining. by default KCC inlines in optimisation mode + dnl all implementations that are defined inside the class {} declaration. + dnl because of templates-compatibility with broken gcc compilers, this + dnl can cause excessive inlining. This flag limits it to a sane level + KDE_CHECK_COMPILER_FLAG(-inline_keyword_space_time=6,[CXXFLAGS="$CXXFLAGS --inline_keyword_space_time=6"]) + KDE_CHECK_COMPILER_FLAG(-inline_auto_space_time=2,[CXXFLAGS="$CXXFLAGS --inline_auto_space_time=2"]) + KDE_CHECK_COMPILER_FLAG(-inline_implicit_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_implicit_space_time=2.0"]) + KDE_CHECK_COMPILER_FLAG(-inline_generated_space_time=2.0,[CXXFLAGS="$CXXFLAGS --inline_generated_space_time=2.0"]) + dnl Some source files are shared between multiple executables + dnl (or libraries) and some of those need template instantiations. + dnl In that case KCC needs to compile those sources with + dnl --one_instantiation_per_object. To make it easy for us we compile + dnl _all_ objects with that flag (--one_per is a shorthand). + KDE_CHECK_COMPILER_FLAG(-one_per, [CXXFLAGS="$CXXFLAGS --one_per"]) + fi + AC_SUBST(USE_EXCEPTIONS) + dnl obsolete macro - provided to keep things going + USE_RTTI= + AC_SUBST(USE_RTTI) + + case "$host" in + *-*-irix*) test "$GXX" = yes && CXXFLAGS="-D_LANGUAGE_C_PLUS_PLUS -D__LANGUAGE_C_PLUS_PLUS $CXXFLAGS" ;; + *-*-sysv4.2uw*) CXXFLAGS="-D_UNIXWARE $CXXFLAGS";; + *-*-sysv5uw7*) CXXFLAGS="-D_UNIXWARE7 $CXXFLAGS";; + *-*-solaris*) + if test "$GXX" = yes; then + libstdcpp=`$CXX -print-file-name=libstdc++.so` + if test ! -f $libstdcpp; then + AC_MSG_ERROR([You've compiled gcc without --enable-shared. This doesn't work with KDE. Please recompile gcc with --enable-shared to receive a libstdc++.so]) + fi + fi + ;; + esac + + AC_VALIDIFY_CXXFLAGS + + AC_PROG_CXXCPP + + if test "$GCC" = yes; then + NOOPT_CFLAGS=-O0 + fi + KDE_CHECK_COMPILER_FLAG(O0,[NOOPT_CXXFLAGS=-O0]) + + AC_ARG_ENABLE(coverage, + AC_HELP_STRING([--enable-coverage],[use gcc coverage testing]), [ + if test "$am_cv_CC_dependencies_compiler_type" = "gcc3"; then + ac_coverage_compiler="-fprofile-arcs -ftest-coverage" + ac_coverage_linker="-lgcc" + elif test "$am_cv_CC_dependencies_compiler_type" = "gcc"; then + ac_coverage_compiler="-fprofile-arcs -ftest-coverage" + ac_coverage_linker="" + else + AC_MSG_ERROR([coverage with your compiler is not supported]) + fi + CFLAGS="$CFLAGS $ac_coverage_compiler" + CXXFLAGS="$CXXFLAGS $ac_coverage_compiler" + LDFLAGS="$LDFLAGS $ac_coverage_linker" + ]) + + AC_SUBST(NOOPT_CXXFLAGS) + AC_SUBST(NOOPT_CFLAGS) + AC_SUBST(ENABLE_PERMISSIVE_FLAG) + + KDE_CHECK_NEW_LDFLAGS + KDE_CHECK_FINAL + KDE_CHECK_CLOSURE + KDE_CHECK_NMCHECK + + ifdef([AM_DEPENDENCIES], AC_REQUIRE([KDE_ADD_DEPENDENCIES]), []) +]) + +AC_DEFUN([KDE_CHECK_VISIBILITY_GCC_BUG], + [ + AC_CACHE_CHECK([for gcc -fvisibility-inlines-hidden bug], kde_cv_val_gcc_visibility_bug, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + safe_CXXFLAGS=$CXXFLAGS + safe_LDFLAGS=$LDFLAGS + CXXFLAGS="$CXXFLAGS -fPIC -fvisibility-inlines-hidden -O0" + LDFLAGS="$LDFLAGS -shared -fPIC" + + AC_TRY_LINK( + [ + /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19664 */ + #include + int some_function( void ) __attribute__ ((visibility("default"))); + int some_function( void ) + { + std::string s("blafasel"); + return 0; + } + ], [/* elvis is alive */], + kde_cv_val_gcc_visibility_bug=no, kde_cv_val_gcc_visibility_bug=yes) + + CXXFLAGS=$safe_CXXFLAGS + LDFLAGS=$safe_LDFLAGS + AC_LANG_RESTORE + ] + ) + + if test x$kde_cv_val_gcc_visibility_bug = xno; then + CXXFLAGS="$CXXFLAGS -fvisibility-inlines-hidden" + fi + ] +) + +AC_DEFUN([KDE_ENABLE_HIDDEN_VISIBILITY], +[ + AC_BEFORE([AC_PATH_QT_1_3], [KDE_ENABLE_HIDDEN_VISIBILITY]) + + AC_MSG_CHECKING([grepping for visibility push/pop in headers]) + + if test "x$GXX" = "xyes"; then + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_EGREP_CPP( + [GCC visibility push], + [ #include + ], + [ + AC_MSG_RESULT(yes) + kde_stdc_visibility_patched=yes ], + [ + AC_MSG_RESULT(no) + AC_MSG_WARN([Your libstdc++ doesn't appear to be patched for + visibility support. Disabling -fvisibility=hidden]) + + kde_stdc_visibility_patched=no ]) + + AC_LANG_RESTORE + + kde_have_gcc_visibility=no + KDE_CHECK_COMPILER_FLAG(fvisibility=hidden, + [ + kde_have_gcc_visibility=yes + dnl the whole toolchain is just a mess, gcc is just too buggy + dnl to handle STL with visibility enabled. Lets reconsider + dnl when gcc 4.2 is out or when things get fixed in the compiler. + dnl Contact mueller@kde.org for details. + AC_ARG_ENABLE(gcc-hidden-visibility, + AC_HELP_STRING([--enable-gcc-hidden-visibility],[toolchain hidden visibility [default=no]]), + [kde_have_gcc_visibility=$enableval], + [kde_have_gcc_visibility=no]) + + AC_CACHE_CHECK([if Qt is patched for -fvisibility], kde_cv_val_qt_gcc_visibility_patched, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + safe_CXXFLAGS=$CXXFLAGS + CXXFLAGS="$CXXFLAGS $all_includes" + + AC_TRY_COMPILE( + [ +#include +#if Q_EXPORT - 0 != 0 +/* if this compiles, then Q_EXPORT is undefined */ +/* if Q_EXPORT is nonempty, this will break compilation */ +#endif + ], [/* elvis is alive */], + kde_cv_val_qt_gcc_visibility_patched=no, kde_cv_val_qt_gcc_visibility_patched=yes) + + CXXFLAGS=$safe_CXXFLAGS + AC_LANG_RESTORE + ] + ) + + if test x$kde_have_gcc_visibility = "xyes" && test x$kde_stdc_visibility_patched = "xyes" && test x$kde_cv_val_qt_gcc_visibility_patched = "xyes"; then + CXXFLAGS="$CXXFLAGS -fvisibility=hidden" + KDE_CHECK_VISIBILITY_GCC_BUG + HAVE_GCC_VISIBILITY=1 + AC_DEFINE_UNQUOTED(__KDE_HAVE_GCC_VISIBILITY, "$HAVE_GCC_VISIBILITY", [define to 1 if -fvisibility is supported]) + fi + ]) + fi +]) + +AC_DEFUN([KDE_ADD_DEPENDENCIES], +[ + [A]M_DEPENDENCIES(CC) + [A]M_DEPENDENCIES(CXX) +]) + +dnl just a wrapper to clean up configure.in +AC_DEFUN([KDE_PROG_LIBTOOL], +[ +AC_REQUIRE([AC_CHECK_COMPILERS]) +AC_REQUIRE([AC_ENABLE_SHARED]) +AC_REQUIRE([AC_ENABLE_STATIC]) + +AC_REQUIRE([AC_LIBTOOL_DLOPEN]) +AC_REQUIRE([KDE_CHECK_LIB64]) + +AC_OBJEXT +AC_EXEEXT + +AM_PROG_LIBTOOL +AC_LIBTOOL_CXX + +LIBTOOL_SHELL="/bin/sh ./libtool" +# LIBTOOL="$LIBTOOL --silent" +KDE_PLUGIN="-avoid-version -module -no-undefined \$(KDE_NO_UNDEFINED) \$(KDE_RPATH) \$(KDE_MT_LDFLAGS)" +AC_SUBST(KDE_PLUGIN) + +# This hack ensures that libtool creates shared libs for kunittest plugins. By default check_LTLIBRARIES makes static libs. +KDE_CHECK_PLUGIN="\$(KDE_PLUGIN) -rpath \$(libdir)" +AC_SUBST(KDE_CHECK_PLUGIN) + +# we patch configure quite some so we better keep that consistent for incremental runs +AC_SUBST(AUTOCONF,'$(SHELL) $(top_srcdir)/admin/cvs.sh configure || touch configure') +]) + +AC_DEFUN([KDE_CHECK_LIB64], +[ + AC_ARG_ENABLE(libsuffix, + AC_HELP_STRING([--enable-libsuffix], + [/lib directory suffix (64,32,none,auto[=default])]), + kdelibsuff=$enableval, kdelibsuff="auto") + + if test "$kdelibsuff" = "auto"; then + +cat > conftest.c << EOF +#include +int main() { + return 0; +} +EOF + kdelibsuff=`$CC conftest.c -o conftest.out; ldd conftest.out |sed -ne '/libc.so/{ + s,.*/lib\([[^\/]]*\)/.*,\1, + p +}'` + rm -rf conftest.* + fi + + if test "$kdelibsuff" = "no" || test "$kdelibsuff" = "none"; then + kdelibsuff= + fi + if test -z "$kdelibsuff"; then + AC_MSG_RESULT([not using lib directory suffix]) + AC_DEFINE(KDELIBSUFF, [""], Suffix for lib directories) + else + if test "$libdir" = '${exec_prefix}/lib'; then + libdir="$libdir${kdelibsuff}" + AC_SUBST([libdir], ["$libdir"]) dnl ugly hack for lib64 platforms + fi + AC_DEFINE_UNQUOTED(KDELIBSUFF, ["${kdelibsuff}"], Suffix for lib directories) + AC_MSG_RESULT([using lib directory suffix $kdelibsuff]) + fi +]) + +AC_DEFUN([KDE_CHECK_TYPES], +[ AC_CHECK_SIZEOF(int, 4)dnl + AC_CHECK_SIZEOF(short)dnl + AC_CHECK_SIZEOF(long, 4)dnl + AC_CHECK_SIZEOF(char *, 4)dnl +])dnl + +dnl Not used - kept for compat only? +AC_DEFUN([KDE_DO_IT_ALL], +[ +AC_CANONICAL_SYSTEM +AC_ARG_PROGRAM +AM_INIT_AUTOMAKE($1, $2) +AM_DISABLE_LIBRARIES +AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) +AC_CHECK_COMPILERS +KDE_PROG_LIBTOOL +AM_KDE_WITH_NLS +AC_PATH_KDE +]) + +AC_DEFUN([AC_CHECK_RPATH], +[ +AC_MSG_CHECKING(for rpath) +AC_ARG_ENABLE(rpath, + AC_HELP_STRING([--disable-rpath],[do not use the rpath feature of ld]), + USE_RPATH=$enableval, USE_RPATH=yes) + +if test -z "$KDE_RPATH" && test "$USE_RPATH" = "yes"; then + + KDE_RPATH="-R \$(libdir)" + + if test "$kde_libraries" != "$libdir"; then + KDE_RPATH="$KDE_RPATH -R \$(kde_libraries)" + fi + + if test -n "$qt_libraries"; then + KDE_RPATH="$KDE_RPATH -R \$(qt_libraries)" + fi + dnl $x_libraries is set to /usr/lib in case + if test -n "$X_LDFLAGS"; then + X_RPATH="-R \$(x_libraries)" + KDE_RPATH="$KDE_RPATH $X_RPATH" + fi + if test -n "$KDE_EXTRA_RPATH"; then + KDE_RPATH="$KDE_RPATH \$(KDE_EXTRA_RPATH)" + fi +fi +AC_SUBST(KDE_EXTRA_RPATH) +AC_SUBST(KDE_RPATH) +AC_SUBST(X_RPATH) +AC_MSG_RESULT($USE_RPATH) +]) + +dnl Check for the type of the third argument of getsockname +AC_DEFUN([AC_CHECK_SOCKLEN_T], +[ + AC_MSG_CHECKING(for socklen_t) + AC_CACHE_VAL(kde_cv_socklen_t, + [ + AC_LANG_PUSH(C++) + kde_cv_socklen_t=no + AC_TRY_COMPILE([ + #include + #include + ], + [ + socklen_t len; + getpeername(0,0,&len); + ], + [ + kde_cv_socklen_t=yes + kde_cv_socklen_t_equiv=socklen_t + ]) + AC_LANG_POP(C++) + ]) + AC_MSG_RESULT($kde_cv_socklen_t) + if test $kde_cv_socklen_t = no; then + AC_MSG_CHECKING([for socklen_t equivalent for socket functions]) + AC_CACHE_VAL(kde_cv_socklen_t_equiv, + [ + kde_cv_socklen_t_equiv=int + AC_LANG_PUSH(C++) + for t in int size_t unsigned long "unsigned long"; do + AC_TRY_COMPILE([ + #include + #include + ], + [ + $t len; + getpeername(0,0,&len); + ], + [ + kde_cv_socklen_t_equiv="$t" + break + ]) + done + AC_LANG_POP(C++) + ]) + AC_MSG_RESULT($kde_cv_socklen_t_equiv) + fi + AC_DEFINE_UNQUOTED(kde_socklen_t, $kde_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined]) + AC_DEFINE_UNQUOTED(ksize_t, $kde_cv_socklen_t_equiv, + [type to use in place of socklen_t if not defined (deprecated, use kde_socklen_t)]) +]) + +dnl This is a merge of some macros out of the gettext aclocal.m4 +dnl since we don't need anything, I took the things we need +dnl the copyright for them is: +dnl > +dnl Copyright (C) 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. +dnl This Makefile.in is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. +dnl > +dnl for this file it is relicensed under LGPL + +AC_DEFUN([AM_KDE_WITH_NLS], + [ + dnl If we use NLS figure out what method + + AM_PATH_PROG_WITH_TEST_KDE(MSGFMT, msgfmt, + [test -n "`$ac_dir/$ac_word --version 2>&1 | grep 'GNU gettext'`"], msgfmt) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + + if test -z "`$GMSGFMT --version 2>&1 | grep 'GNU gettext'`"; then + AC_MSG_RESULT([found msgfmt program is not GNU msgfmt; ignore it]) + GMSGFMT=":" + fi + MSGFMT=$GMSGFMT + AC_SUBST(GMSGFMT) + AC_SUBST(MSGFMT) + + AM_PATH_PROG_WITH_TEST_KDE(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is no GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext programs is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + AC_SUBST(XGETTEXT) + + ]) + +# Search path for a program which passes the given test. +# Ulrich Drepper , 1996. + +# serial 1 +# Stephan Kulow: I appended a _KDE against name conflicts + +dnl AM_PATH_PROG_WITH_TEST_KDE(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +AC_DEFUN([AM_PATH_PROG_WITH_TEST_KDE], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test -n "[$]$1"; then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + + +# Check whether LC_MESSAGES is available in . +# Ulrich Drepper , 1995. + +# serial 1 + +AC_DEFUN([AM_LC_MESSAGES], + [if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, [Define if your locale.h file contains LC_MESSAGES]) + fi + fi]) + +dnl From Jim Meyering. +dnl FIXME: migrate into libit. + +AC_DEFUN([AM_FUNC_OBSTACK], +[AC_CACHE_CHECK([for obstacks], am_cv_func_obstack, + [AC_TRY_LINK([#include "obstack.h"], + [struct obstack *mem;obstack_free(mem,(char *) 0)], + am_cv_func_obstack=yes, + am_cv_func_obstack=no)]) + if test $am_cv_func_obstack = yes; then + AC_DEFINE(HAVE_OBSTACK) + else + LIBOBJS="$LIBOBJS obstack.o" + fi +]) + +dnl From Jim Meyering. Use this if you use the GNU error.[ch]. +dnl FIXME: Migrate into libit + +AC_DEFUN([AM_FUNC_ERROR_AT_LINE], +[AC_CACHE_CHECK([for error_at_line], am_cv_lib_error_at_line, + [AC_TRY_LINK([],[error_at_line(0, 0, "", 0, "");], + am_cv_lib_error_at_line=yes, + am_cv_lib_error_at_line=no)]) + if test $am_cv_lib_error_at_line = no; then + LIBOBJS="$LIBOBJS error.o" + fi + AC_SUBST(LIBOBJS)dnl +]) + +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995. + +# serial 1 +# Stephan Kulow: I put a KDE in it to avoid name conflicts + +AC_DEFUN([AM_KDE_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_MAKE_SET])dnl + AC_REQUIRE([AC_PROG_RANLIB])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + AC_REQUIRE([AC_TYPE_OFF_T])dnl + AC_REQUIRE([AC_TYPE_SIZE_T])dnl + AC_REQUIRE([AC_FUNC_ALLOCA])dnl + AC_REQUIRE([AC_FUNC_MMAP])dnl + AC_REQUIRE([AM_KDE_WITH_NLS])dnl + AC_CHECK_HEADERS([limits.h locale.h nl_types.h string.h values.h alloca.h]) + AC_CHECK_FUNCS([getcwd munmap putenv setlocale strchr strcasecmp \ +__argz_count __argz_stringify __argz_next]) + + AC_MSG_CHECKING(for stpcpy) + AC_CACHE_VAL(kde_cv_func_stpcpy, + [ + kde_safe_cxxflags=$CXXFLAGS + CXXFLAGS="-Werror" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([ + #include + ], + [ + char buffer[200]; + stpcpy(buffer, buffer); + ], + kde_cv_func_stpcpy=yes, + kde_cv_func_stpcpy=no) + AC_LANG_RESTORE + CXXFLAGS=$kde_safe_cxxflags + ]) + AC_MSG_RESULT($kde_cv_func_stpcpy) + if eval "test \"`echo $kde_cv_func_stpcpy`\" = yes"; then + AC_DEFINE(HAVE_STPCPY, 1, [Define if you have stpcpy]) + fi + + AM_LC_MESSAGES + + if test "x$CATOBJEXT" != "x"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for lang in ${LINGUAS=$ALL_LINGUAS}; do + case "$ALL_LINGUAS" in + *$lang*) NEW_LINGUAS="$NEW_LINGUAS $lang" ;; + esac + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + ]) + +AC_DEFUN([AC_HAVE_XPM], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$XPM_LDFLAGS" && XPM_LDFLAGS= + test -z "$XPM_INCLUDE" && XPM_INCLUDE= + + AC_ARG_WITH(xpm,AC_HELP_STRING([--without-xpm],[disable color pixmap XPM tests]), + xpm_test=$withval, xpm_test="yes") + if test "x$xpm_test" = xno; then + ac_cv_have_xpm=no + else + AC_MSG_CHECKING(for XPM) + AC_CACHE_VAL(ac_cv_have_xpm, + [ + ac_save_ldflags="$LDFLAGS" + ac_save_cflags="$CFLAGS" + if test "x$kde_use_qt_emb" != "xyes" && test "x$kde_use_qt_mac" != "xyes"; then + LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm -lX11 -lXext $LIBZ $LIBSOCKET" + else + LDFLAGS="$LDFLAGS $X_LDFLAGS $USER_LDFLAGS $LDFLAGS $XPM_LDFLAGS $all_libraries -lXpm $LIBZ $LIBSOCKET" + fi + CFLAGS="$CFLAGS $X_INCLUDES $USER_INCLUDES" + test -n "$XPM_INCLUDE" && CFLAGS="-I$XPM_INCLUDE $CFLAGS" + AC_TRY_LINK([#include ],[], + ac_cv_have_xpm="yes",ac_cv_have_xpm="no") + LDFLAGS="$ac_save_ldflags" + CFLAGS="$ac_save_cflags" + ])dnl + + if test "$ac_cv_have_xpm" = no; then + AC_MSG_RESULT(no) + XPM_LDFLAGS="" + XPMINC="" + $2 + else + AC_DEFINE(HAVE_XPM, 1, [Define if you have XPM support]) + if test "$XPM_LDFLAGS" = ""; then + XPMLIB='-lXpm $(LIB_X11)' + else + XPMLIB="-L$XPM_LDFLAGS -lXpm "'$(LIB_X11)' + fi + if test "$XPM_INCLUDE" = ""; then + XPMINC="" + else + XPMINC="-I$XPM_INCLUDE" + fi + AC_MSG_RESULT(yes) + $1 + fi + fi + AC_SUBST(XPMINC) + AC_SUBST(XPMLIB) +]) + +AC_DEFUN([AC_HAVE_DPMS], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$DPMS_LDFLAGS" && DPMS_LDFLAGS= + test -z "$DPMS_INCLUDE" && DPMS_INCLUDE= + DPMS_LIB= + + AC_ARG_WITH(dpms,AC_HELP_STRING([--without-dpms],[disable DPMS power saving]), + dpms_test=$withval, dpms_test="yes") + if test "x$dpms_test" = xno; then + ac_cv_have_dpms=no + else + AC_MSG_CHECKING(for DPMS) + dnl Note: ac_cv_have_dpms can be no, yes, or -lXdpms. + dnl 'yes' means DPMS_LIB="", '-lXdpms' means DPMS_LIB="-lXdpms". + AC_CACHE_VAL(ac_cv_have_dpms, + [ + if test "x$kde_use_qt_emb" = "xyes" || test "x$kde_use_qt_mac" = "xyes"; then + AC_MSG_RESULT(no) + ac_cv_have_dpms="no" + else + ac_save_ldflags="$LDFLAGS" + ac_save_cflags="$CFLAGS" + ac_save_libs="$LIBS" + LDFLAGS="$LDFLAGS $DPMS_LDFLAGS $all_libraries" + LIBS="-lX11 -lXext $LIBSOCKET" + CFLAGS="$CFLAGS $X_INCLUDES" + test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" + AC_TRY_LINK([ + #include + #include + #include + #include + int foo_test_dpms() + { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], + ac_cv_have_dpms="yes", [ + LIBS="-lXdpms $LIBS" + AC_TRY_LINK([ + #include + #include + #include + #include + int foo_test_dpms() + { return DPMSSetTimeouts( 0, 0, 0, 0 ); }],[], + [ + ac_cv_have_dpms="-lXdpms" + ],ac_cv_have_dpms="no") + ]) + LDFLAGS="$ac_save_ldflags" + CFLAGS="$ac_save_cflags" + LIBS="$ac_save_libs" + fi + ])dnl + + if test "$ac_cv_have_dpms" = no; then + AC_MSG_RESULT(no) + DPMS_LDFLAGS="" + DPMSINC="" + $2 + else + AC_DEFINE(HAVE_DPMS, 1, [Define if you have DPMS support]) + if test "$ac_cv_have_dpms" = "-lXdpms"; then + DPMS_LIB="-lXdpms" + fi + if test "$DPMS_LDFLAGS" = ""; then + DPMSLIB="$DPMS_LIB "'$(LIB_X11)' + else + DPMSLIB="$DPMS_LDFLAGS $DPMS_LIB "'$(LIB_X11)' + fi + if test "$DPMS_INCLUDE" = ""; then + DPMSINC="" + else + DPMSINC="-I$DPMS_INCLUDE" + fi + AC_MSG_RESULT(yes) + $1 + fi + fi + ac_save_cflags="$CFLAGS" + CFLAGS="$CFLAGS $X_INCLUDES" + test -n "$DPMS_INCLUDE" && CFLAGS="-I$DPMS_INCLUDE $CFLAGS" + AH_TEMPLATE(HAVE_DPMSCAPABLE_PROTO, + [Define if you have the DPMSCapable prototype in ]) + AC_CHECK_DECL(DPMSCapable, + AC_DEFINE(HAVE_DPMSCAPABLE_PROTO),, + [#include + #include ]) + AH_TEMPLATE(HAVE_DPMSINFO_PROTO, + [Define if you have the DPMSInfo prototype in ]) + AC_CHECK_DECL(DPMSInfo, + AC_DEFINE(HAVE_DPMSINFO_PROTO),, + [#include + #include ]) + CFLAGS="$ac_save_cflags" + AC_SUBST(DPMSINC) + AC_SUBST(DPMSLIB) +]) + +AC_DEFUN([AC_HAVE_GL], + [AC_REQUIRE_CPP()dnl + AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) + + test -z "$GL_LDFLAGS" && GL_LDFLAGS= + test -z "$GL_INCLUDE" && GL_INCLUDE= + + AC_ARG_WITH(gl,AC_HELP_STRING([--without-gl],[disable 3D GL modes]), + gl_test=$withval, gl_test="yes") + if test "x$kde_use_qt_emb" = "xyes"; then + # GL and Qt Embedded is a no-go for now. + ac_cv_have_gl=no + elif test "x$gl_test" = xno; then + ac_cv_have_gl=no + else + AC_MSG_CHECKING(for GL) + AC_CACHE_VAL(ac_cv_have_gl, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_ldflags=$LDFLAGS + ac_save_cxxflags=$CXXFLAGS + ac_save_libs=$LIBS + LDFLAGS="$LDFLAGS $GL_LDFLAGS $X_LDFLAGS $all_libraries" + LIBS="$LIBS -lGL -lGLU" + test "x$kde_use_qt_mac" != xyes && test "x$kde_use_qt_emb" != xyes && LIBS="$LIBS -lX11" + LIBS="$LIBS $LIB_XEXT -lm $LIBSOCKET" + CXXFLAGS="$CFLAGS $X_INCLUDES" + test -n "$GL_INCLUDE" && CFLAGS="-I$GL_INCLUDE $CFLAGS" + AC_TRY_LINK([#include +#include +], [], + ac_cv_have_gl="yes", ac_cv_have_gl="no") + AC_LANG_RESTORE + LDFLAGS=$ac_save_ldflags + CXXFLAGS=$ac_save_cxxflags + LIBS=$ac_save_libs + ])dnl + + if test "$ac_cv_have_gl" = "no"; then + AC_MSG_RESULT(no) + GL_LDFLAGS="" + GLINC="" + $2 + else + AC_DEFINE(HAVE_GL, 1, [Defines if you have GL (Mesa, OpenGL, ...)]) + if test "$GL_LDFLAGS" = ""; then + GLLIB='-lGLU -lGL $(LIB_X11)' + else + GLLIB="$GL_LDFLAGS -lGLU -lGL "'$(LIB_X11)' + fi + if test "$GL_INCLUDE" = ""; then + GLINC="" + else + GLINC="-I$GL_INCLUDE" + fi + AC_MSG_RESULT($ac_cv_have_gl) + $1 + fi + fi + AC_SUBST(GLINC) + AC_SUBST(GLLIB) +]) + + + dnl shadow password and PAM magic - maintained by ossi@kde.org + +AC_DEFUN([KDE_PAM], [ + AC_REQUIRE([KDE_CHECK_LIBDL]) + + want_pam= + AC_ARG_WITH(pam, + AC_HELP_STRING([--with-pam[=ARG]],[enable support for PAM: ARG=[yes|no|service name]]), + [ if test "x$withval" = "xyes"; then + want_pam=yes + pam_service=kde + elif test "x$withval" = "xno"; then + want_pam=no + else + want_pam=yes + pam_service=$withval + fi + ], [ pam_service=kde ]) + + use_pam= + PAMLIBS= + if test "x$want_pam" != xno; then + AC_CHECK_LIB(pam, pam_start, [ + AC_CHECK_HEADER(security/pam_appl.h, + [ pam_header=security/pam_appl.h ], + [ AC_CHECK_HEADER(pam/pam_appl.h, + [ pam_header=pam/pam_appl.h ], + [ + AC_MSG_WARN([PAM detected, but no headers found! +Make sure you have the necessary development packages installed.]) + ] + ) + ] + ) + ], , $LIBDL) + if test -z "$pam_header"; then + if test "x$want_pam" = xyes; then + AC_MSG_ERROR([--with-pam was specified, but cannot compile with PAM!]) + fi + else + AC_DEFINE(HAVE_PAM, 1, [Defines if you have PAM (Pluggable Authentication Modules)]) + PAMLIBS="$PAM_MISC_LIB -lpam $LIBDL" + use_pam=yes + + dnl darwin claims to be something special + if test "$pam_header" = "pam/pam_appl.h"; then + AC_DEFINE(HAVE_PAM_PAM_APPL_H, 1, [Define if your PAM headers are in pam/ instead of security/]) + fi + + dnl test whether struct pam_message is const (Linux) or not (Sun) + AC_MSG_CHECKING(for const pam_message) + AC_EGREP_HEADER([struct pam_message], $pam_header, + [ AC_EGREP_HEADER([const struct pam_message], $pam_header, + [AC_MSG_RESULT([const: Linux-type PAM])], + [AC_MSG_RESULT([nonconst: Sun-type PAM]) + AC_DEFINE(PAM_MESSAGE_NONCONST, 1, [Define if your PAM support takes non-const arguments (Solaris)])] + )], + [AC_MSG_RESULT([not found - assume const, Linux-type PAM])]) + fi + fi + + AC_SUBST(PAMLIBS) +]) + +dnl DEF_PAM_SERVICE(arg name, full name, define name) +AC_DEFUN([DEF_PAM_SERVICE], [ + AC_ARG_WITH($1-pam, + AC_HELP_STRING([--with-$1-pam=[val]],[override PAM service from --with-pam for $2]), + [ if test "x$use_pam" = xyes; then + $3_PAM_SERVICE=$withval + else + AC_MSG_ERROR([Cannot use use --with-$1-pam, as no PAM was detected. +You may want to enforce it by using --with-pam.]) + fi + ], + [ if test "x$use_pam" = xyes; then + $3_PAM_SERVICE="$pam_service" + fi + ]) + if test -n "$$3_PAM_SERVICE"; then + AC_MSG_RESULT([The PAM service used by $2 will be $$3_PAM_SERVICE]) + AC_DEFINE_UNQUOTED($3_PAM_SERVICE, "$$3_PAM_SERVICE", [The PAM service to be used by $2]) + fi + AC_SUBST($3_PAM_SERVICE) +]) + +AC_DEFUN([KDE_SHADOWPASSWD], [ + AC_REQUIRE([KDE_PAM]) + + AC_CHECK_LIB(shadow, getspent, + [ LIBSHADOW="-lshadow" + ac_use_shadow=yes + ], + [ dnl for UnixWare + AC_CHECK_LIB(gen, getspent, + [ LIBGEN="-lgen" + ac_use_shadow=yes + ], + [ AC_CHECK_FUNC(getspent, + [ ac_use_shadow=yes ], + [ ac_use_shadow=no ]) + ]) + ]) + AC_SUBST(LIBSHADOW) + AC_SUBST(LIBGEN) + + AC_MSG_CHECKING([for shadow passwords]) + + AC_ARG_WITH(shadow, + AC_HELP_STRING([--with-shadow],[If you want shadow password support]), + [ if test "x$withval" != "xno"; then + use_shadow=yes + else + use_shadow=no + fi + ], [ + use_shadow="$ac_use_shadow" + ]) + + if test "x$use_shadow" = xyes; then + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_SHADOW, 1, [Define if you use shadow passwords]) + else + AC_MSG_RESULT(no) + LIBSHADOW= + LIBGEN= + fi + + dnl finally make the relevant binaries setuid root, if we have shadow passwds. + dnl this still applies, if we could use it indirectly through pam. + if test "x$use_shadow" = xyes || + ( test "x$use_pam" = xyes && test "x$ac_use_shadow" = xyes ); then + case $host in + *-*-freebsd* | *-*-netbsd* | *-*-openbsd*) + SETUIDFLAGS="-m 4755 -o root";; + *) + SETUIDFLAGS="-m 4755";; + esac + fi + AC_SUBST(SETUIDFLAGS) + +]) + +AC_DEFUN([KDE_PASSWDLIBS], [ + AC_REQUIRE([KDE_MISC_TESTS]) dnl for LIBCRYPT + AC_REQUIRE([KDE_PAM]) + AC_REQUIRE([KDE_SHADOWPASSWD]) + + if test "x$use_pam" = "xyes"; then + PASSWDLIBS="$PAMLIBS" + else + PASSWDLIBS="$LIBCRYPT $LIBSHADOW $LIBGEN" + fi + + dnl FreeBSD uses a shadow-like setup, where /etc/passwd holds the users, but + dnl /etc/master.passwd holds the actual passwords. /etc/master.passwd requires + dnl root to read, so kcheckpass needs to be root (even when using pam, since pam + dnl may need to read /etc/master.passwd). + case $host in + *-*-freebsd*) + SETUIDFLAGS="-m 4755 -o root" + ;; + *) + ;; + esac + + AC_SUBST(PASSWDLIBS) +]) + +AC_DEFUN([KDE_CHECK_LIBDL], +[ +AC_CHECK_LIB(dl, dlopen, [ +LIBDL="-ldl" +ac_cv_have_dlfcn=yes +]) + +AC_CHECK_LIB(dld, shl_unload, [ +LIBDL="-ldld" +ac_cv_have_shload=yes +]) + +AC_SUBST(LIBDL) +]) + +AC_DEFUN([KDE_CHECK_DLOPEN], +[ +KDE_CHECK_LIBDL +AC_CHECK_HEADERS(dlfcn.h dl.h) +if test "$ac_cv_header_dlfcn_h" = "no"; then + ac_cv_have_dlfcn=no +fi + +if test "$ac_cv_header_dl_h" = "no"; then + ac_cv_have_shload=no +fi + +dnl XXX why change enable_dlopen? its already set by autoconf's AC_ARG_ENABLE +dnl (MM) +AC_ARG_ENABLE(dlopen, +AC_HELP_STRING([--disable-dlopen],[link statically [default=no]]), +enable_dlopen=$enableval, +enable_dlopen=yes) + +# override the user's opinion, if we know it better ;) +if test "$ac_cv_have_dlfcn" = "no" && test "$ac_cv_have_shload" = "no"; then + enable_dlopen=no +fi + +if test "$ac_cv_have_dlfcn" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_DLFCN, 1, [Define if you have dlfcn]) +fi + +if test "$ac_cv_have_shload" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_SHLOAD, 1, [Define if you have shload]) +fi + +if test "$enable_dlopen" = no ; then + test -n "$1" && eval $1 +else + test -n "$2" && eval $2 +fi + +]) + +AC_DEFUN([KDE_CHECK_DYNAMIC_LOADING], +[ +KDE_CHECK_DLOPEN(libtool_enable_shared=yes, libtool_enable_static=no) +KDE_PROG_LIBTOOL +AC_MSG_CHECKING([dynamic loading]) +eval "`egrep '^build_libtool_libs=' libtool`" +if test "$build_libtool_libs" = "yes" && test "$enable_dlopen" = "yes"; then + dynamic_loading=yes + AC_DEFINE_UNQUOTED(HAVE_DYNAMIC_LOADING) +else + dynamic_loading=no +fi +AC_MSG_RESULT($dynamic_loading) +if test "$dynamic_loading" = "yes"; then + $1 +else + $2 +fi +]) + +AC_DEFUN([KDE_ADD_INCLUDES], +[ +if test -z "$1"; then + test_include="Pix.h" +else + test_include="$1" +fi + +AC_MSG_CHECKING([for libg++ ($test_include)]) + +AC_CACHE_VAL(kde_cv_libgpp_includes, +[ +kde_cv_libgpp_includes=no + + for ac_dir in \ + \ + /usr/include/g++ \ + /usr/include \ + /usr/unsupported/include \ + /opt/include \ + $extra_include \ + ; \ + do + if test -r "$ac_dir/$test_include"; then + kde_cv_libgpp_includes=$ac_dir + break + fi + done +]) + +AC_MSG_RESULT($kde_cv_libgpp_includes) +if test "$kde_cv_libgpp_includes" != "no"; then + all_includes="-I$kde_cv_libgpp_includes $all_includes $USER_INCLUDES" +fi +]) +]) + +AC_DEFUN([KDE_CHECK_LIBPTHREAD], +[ + dnl This code is here specifically to handle the + dnl various flavors of threading library on FreeBSD + dnl 4-, 5-, and 6-, and the (weird) rules around it. + dnl There may be an environment PTHREAD_LIBS that + dnl specifies what to use; otherwise, search for it. + dnl -pthread is special cased and unsets LIBPTHREAD + dnl below if found. + LIBPTHREAD="" + + if test -n "$PTHREAD_LIBS"; then + if test "x$PTHREAD_LIBS" = "x-pthread" ; then + LIBPTHREAD="PTHREAD" + else + PTHREAD_LIBS_save="$PTHREAD_LIBS" + PTHREAD_LIBS=`echo "$PTHREAD_LIBS_save" | sed -e 's,^-l,,g'` + AC_MSG_CHECKING([for pthread_create in $PTHREAD_LIBS]) + KDE_CHECK_LIB($PTHREAD_LIBS, pthread_create, [ + LIBPTHREAD="$PTHREAD_LIBS_save"]) + PTHREAD_LIBS="$PTHREAD_LIBS_save" + fi + fi + + dnl Is this test really needed, in the face of the Tru64 test below? + if test -z "$LIBPTHREAD"; then + AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD="-lpthread"]) + fi + + dnl This is a special Tru64 check, see BR 76171 issue #18. + if test -z "$LIBPTHREAD" ; then + AC_MSG_CHECKING([for pthread_create in -lpthread]) + kde_safe_libs=$LIBS + LIBS="$LIBS -lpthread" + AC_TRY_LINK([#include ],[(void)pthread_create(0,0,0,0);],[ + AC_MSG_RESULT(yes) + LIBPTHREAD="-lpthread"],[ + AC_MSG_RESULT(no)]) + LIBS=$kde_safe_libs + fi + + dnl Un-special-case for FreeBSD. + if test "x$LIBPTHREAD" = "xPTHREAD" ; then + LIBPTHREAD="" + fi + + AC_SUBST(LIBPTHREAD) +]) + +AC_DEFUN([KDE_CHECK_PTHREAD_OPTION], +[ + USE_THREADS="" + if test -z "$LIBPTHREAD"; then + KDE_CHECK_COMPILER_FLAG(pthread, [USE_THREADS="-D_THREAD_SAFE -pthread"]) + fi + + AH_VERBATIM(__svr_define, [ +#if defined(__SVR4) && !defined(__svr4__) +#define __svr4__ 1 +#endif +]) + case $host_os in + solaris*) + KDE_CHECK_COMPILER_FLAG(mt, [USE_THREADS="-mt"]) + CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_SOLARIS -DSVR4" + ;; + freebsd*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE $PTHREAD_CFLAGS" + ;; + aix*) + CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE" + LIBPTHREAD="$LIBPTHREAD -lc_r" + ;; + linux*) CPPFLAGS="$CPPFLAGS -D_REENTRANT" + if test "$CXX" = "KCC"; then + CXXFLAGS="$CXXFLAGS --thread_safe" + NOOPT_CXXFLAGS="$NOOPT_CXXFLAGS --thread_safe" + fi + ;; + *) + ;; + esac + AC_SUBST(USE_THREADS) + AC_SUBST(LIBPTHREAD) +]) + +AC_DEFUN([KDE_CHECK_THREADING], +[ + AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) + AC_REQUIRE([KDE_CHECK_PTHREAD_OPTION]) + dnl default is yes if libpthread is found and no if no libpthread is available + if test -z "$LIBPTHREAD"; then + if test -z "$USE_THREADS"; then + kde_check_threading_default=no + else + kde_check_threading_default=yes + fi + else + kde_check_threading_default=yes + fi + AC_ARG_ENABLE(threading,AC_HELP_STRING([--disable-threading],[disables threading even if libpthread found]), + kde_use_threading=$enableval, kde_use_threading=$kde_check_threading_default) + if test "x$kde_use_threading" = "xyes"; then + AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if you have a working libpthread (will enable threaded code)]) + fi +]) + +AC_DEFUN([KDE_TRY_LINK_PYTHON], +[ +if test "$kde_python_link_found" = no; then + +if test "$1" = normal; then + AC_MSG_CHECKING(if a Python application links) +else + AC_MSG_CHECKING(if Python depends on $2) +fi + +AC_CACHE_VAL(kde_cv_try_link_python_$1, +[ +kde_save_cflags="$CFLAGS" +CFLAGS="$CFLAGS $PYTHONINC" +kde_save_libs="$LIBS" +LIBS="$LIBS $LIBPYTHON $2 $LIBDL $LIBSOCKET" +kde_save_ldflags="$LDFLAGS" +LDFLAGS="$LDFLAGS $PYTHONLIB" + +AC_TRY_LINK( +[ +#include +],[ + PySys_SetArgv(1, 0); +], + [kde_cv_try_link_python_$1=yes], + [kde_cv_try_link_python_$1=no] +) +CFLAGS="$kde_save_cflags" +LIBS="$kde_save_libs" +LDFLAGS="$kde_save_ldflags" +]) + +if test "$kde_cv_try_link_python_$1" = "yes"; then + AC_MSG_RESULT(yes) + kde_python_link_found=yes + if test ! "$1" = normal; then + LIBPYTHON="$LIBPYTHON $2" + fi + $3 +else + AC_MSG_RESULT(no) + $4 +fi + +fi + +]) + +AC_DEFUN([KDE_CHECK_PYTHON_DIR], +[ +AC_MSG_CHECKING([for Python directory]) + +AC_CACHE_VAL(kde_cv_pythondir, +[ + if test -z "$PYTHONDIR"; then + kde_cv_pythondir=/usr/local + else + kde_cv_pythondir="$PYTHONDIR" + fi +]) + +AC_ARG_WITH(pythondir, +AC_HELP_STRING([--with-pythondir=pythondir],[use python installed in pythondir]), +[ + ac_python_dir=$withval +], ac_python_dir=$kde_cv_pythondir +) + +AC_MSG_RESULT($ac_python_dir) +]) + +AC_DEFUN([KDE_CHECK_PYTHON_INTERN], +[ +AC_REQUIRE([KDE_CHECK_LIBDL]) +AC_REQUIRE([KDE_CHECK_LIBPTHREAD]) +AC_REQUIRE([KDE_CHECK_PYTHON_DIR]) + +if test -z "$1"; then + version="1.5" +else + version="$1" +fi + +AC_MSG_CHECKING([for Python$version]) + +python_incdirs="$ac_python_dir/include /usr/include /usr/local/include/ $kde_extra_includes" +AC_FIND_FILE(Python.h, $python_incdirs, python_incdir) +if test ! -r $python_incdir/Python.h; then + AC_FIND_FILE(python$version/Python.h, $python_incdirs, python_incdir) + python_incdir=$python_incdir/python$version + if test ! -r $python_incdir/Python.h; then + python_incdir=no + fi +fi + +PYTHONINC=-I$python_incdir + +python_libdirs="$ac_python_dir/lib$kdelibsuff /usr/lib$kdelibsuff /usr/local /usr/lib$kdelibsuff $kde_extra_libs" +AC_FIND_FILE(libpython$version.so, $python_libdirs, python_libdir) +if test ! -r $python_libdir/libpython$version.so; then + AC_FIND_FILE(libpython$version.a, $python_libdirs, python_libdir) + if test ! -r $python_libdir/libpython$version.a; then + AC_FIND_FILE(python$version/config/libpython$version.a, $python_libdirs, python_libdir) + python_libdir=$python_libdir/python$version/config + if test ! -r $python_libdir/libpython$version.a; then + python_libdir=no + fi + fi +fi + +PYTHONLIB=-L$python_libdir +kde_orig_LIBPYTHON=$LIBPYTHON +if test -z "$LIBPYTHON"; then + LIBPYTHON=-lpython$version +fi + +AC_FIND_FILE(python$version/copy.py, $python_libdirs, python_moddir) +python_moddir=$python_moddir/python$version +if test ! -r $python_moddir/copy.py; then + python_moddir=no +fi + +PYTHONMODDIR=$python_moddir + +AC_MSG_RESULT(header $python_incdir library $python_libdir modules $python_moddir) + +if test x$python_incdir = xno || test x$python_libdir = xno || test x$python_moddir = xno; then + LIBPYTHON=$kde_orig_LIBPYTHON + test "x$PYTHONLIB" = "x-Lno" && PYTHONLIB="" + test "x$PYTHONINC" = "x-Ino" && PYTHONINC="" + $2 +else + dnl Note: this test is very weak + kde_python_link_found=no + KDE_TRY_LINK_PYTHON(normal) + KDE_TRY_LINK_PYTHON(m, -lm) + KDE_TRY_LINK_PYTHON(pthread, $LIBPTHREAD) + KDE_TRY_LINK_PYTHON(tcl, -ltcl) + KDE_TRY_LINK_PYTHON(db2, -ldb2) + KDE_TRY_LINK_PYTHON(m_and_thread, [$LIBPTHREAD -lm]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_util, [$LIBPTHREAD -lm -lutil]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db3, [$LIBPTHREAD -lm -ldb-3 -lutil]) + KDE_TRY_LINK_PYTHON(pthread_and_db3, [$LIBPTHREAD -ldb-3]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db, [$LIBPTHREAD -lm -ldb -ltermcap -lutil]) + KDE_TRY_LINK_PYTHON(pthread_and_dl, [$LIBPTHREAD $LIBDL -lutil -lreadline -lncurses -lm]) + KDE_TRY_LINK_PYTHON(pthread_and_panel_curses, [$LIBPTHREAD $LIBDL -lm -lpanel -lcurses]) + KDE_TRY_LINK_PYTHON(m_and_thread_and_db_special, [$LIBPTHREAD -lm -ldb -lutil], [], + [AC_MSG_WARN([it seems, Python depends on another library. + Please set LIBPYTHON to '-lpython$version -lotherlib' before calling configure to fix this + and contact the authors to let them know about this problem]) + ]) + + LIBPYTHON="$LIBPYTHON $LIBDL $LIBSOCKET" + AC_SUBST(PYTHONINC) + AC_SUBST(PYTHONLIB) + AC_SUBST(LIBPYTHON) + AC_SUBST(PYTHONMODDIR) + AC_DEFINE(HAVE_PYTHON, 1, [Define if you have the development files for python]) +fi + +]) + + +AC_DEFUN([KDE_CHECK_PYTHON], +[ + KDE_CHECK_PYTHON_INTERN("2.5", + [KDE_CHECK_PYTHON_INTERN("2.4", + [KDE_CHECK_PYTHON_INTERN("2.3", + [KDE_CHECK_PYTHON_INTERN("2.2", + [KDE_CHECK_PYTHON_INTERN("2.1", + [KDE_CHECK_PYTHON_INTERN("2.0", + [KDE_CHECK_PYTHON_INTERN($1, $2) ]) + ]) + ]) + ]) + ]) + ]) +]) + +AC_DEFUN([KDE_CHECK_STL], +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="`echo $CXXFLAGS | sed s/-fno-exceptions//`" + + AC_MSG_CHECKING([if C++ programs can be compiled]) + AC_CACHE_VAL(kde_cv_stl_works, + [ + AC_TRY_COMPILE([ +#include +using namespace std; +],[ + string astring="Hallo Welt."; + astring.erase(0, 6); // now astring is "Welt" + return 0; +], kde_cv_stl_works=yes, + kde_cv_stl_works=no) +]) + + AC_MSG_RESULT($kde_cv_stl_works) + + if test "$kde_cv_stl_works" = "yes"; then + # back compatible + AC_DEFINE_UNQUOTED(HAVE_SGI_STL, 1, [Define if you have a STL implementation by SGI]) + else + AC_MSG_ERROR([Your Installation isn't able to compile simple C++ programs. +Check config.log for details - if you're using a Linux distribution you might miss +a package named similar to libstdc++-dev.]) + fi + + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE +]) + +AC_DEFUN([AC_FIND_QIMGIO], + [AC_REQUIRE([AC_FIND_JPEG]) +AC_REQUIRE([KDE_CHECK_EXTRA_LIBS]) +AC_MSG_CHECKING([for qimgio]) +AC_CACHE_VAL(ac_cv_lib_qimgio, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_LIBS="$LIBS" +ac_save_CXXFLAGS="$CXXFLAGS" +LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT" +CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes" +AC_TRY_RUN(dnl +[ +#include +#include +int main() { + QString t = "hallo"; + t.fill('t'); + qInitImageIO(); +} +], + ac_cv_lib_qimgio=yes, + ac_cv_lib_qimgio=no, + ac_cv_lib_qimgio=no) +LIBS="$ac_save_LIBS" +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE +])dnl +if eval "test \"`echo $ac_cv_lib_qimgio`\" = yes"; then + LIBQIMGIO="-lqimgio -lpng -lz $LIBJPEG" + AC_MSG_RESULT(yes) + AC_DEFINE_UNQUOTED(HAVE_QIMGIO, 1, [Define if you have the Qt extension qimgio available]) + AC_SUBST(LIBQIMGIO) +else + AC_MSG_RESULT(not found) +fi +]) + +AC_DEFUN([AM_DISABLE_LIBRARIES], +[ + AC_PROVIDE([AM_ENABLE_STATIC]) + AC_PROVIDE([AM_ENABLE_SHARED]) + enable_static=no + enable_shared=yes +]) + + +AC_DEFUN([AC_CHECK_UTMP_FILE], +[ + AC_MSG_CHECKING([for utmp file]) + + AC_CACHE_VAL(kde_cv_utmp_file, + [ + kde_cv_utmp_file=no + + for ac_file in \ + \ + /var/run/utmp \ + /var/adm/utmp \ + /etc/utmp \ + ; \ + do + if test -r "$ac_file"; then + kde_cv_utmp_file=$ac_file + break + fi + done + ]) + + if test "$kde_cv_utmp_file" != "no"; then + AC_DEFINE_UNQUOTED(UTMP, "$kde_cv_utmp_file", [Define the file for utmp entries]) + $1 + AC_MSG_RESULT($kde_cv_utmp_file) + else + $2 + AC_MSG_RESULT([non found]) + fi +]) + + +AC_DEFUN([KDE_CREATE_SUBDIRSLIST], +[ + +DO_NOT_COMPILE="$DO_NOT_COMPILE CVS debian bsd-port admin" +TOPSUBDIRS="" + +if test ! -s $srcdir/subdirs; then + dnl Note: Makefile.common creates subdirs, so this is just a fallback + files=`cd $srcdir && ls -1` + dirs=`for i in $files; do if test -d $i; then echo $i; fi; done` + for i in $dirs; do + echo $i >> $srcdir/subdirs + done +fi + +ac_topsubdirs= +if test -s $srcdir/inst-apps; then + ac_topsubdirs="`cat $srcdir/inst-apps`" +elif test -s $srcdir/subdirs; then + ac_topsubdirs="`cat $srcdir/subdirs`" +fi + +for i in $ac_topsubdirs; do + AC_MSG_CHECKING([if $i should be compiled]) + if test -d $srcdir/$i; then + install_it="yes" + for j in $DO_NOT_COMPILE; do + if test $i = $j; then + install_it="no" + fi + done + else + install_it="no" + fi + AC_MSG_RESULT($install_it) + vari=`echo $i | sed -e 's,[[-+.@]],_,g'` + if test $install_it = "yes"; then + TOPSUBDIRS="$TOPSUBDIRS $i" + eval "$vari""_SUBDIR_included=yes" + else + eval "$vari""_SUBDIR_included=no" + fi +done + +AC_SUBST(TOPSUBDIRS) +]) + +AC_DEFUN([KDE_CHECK_NAMESPACES], +[ +AC_MSG_CHECKING(whether C++ compiler supports namespaces) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_TRY_COMPILE([ +], +[ +namespace Foo { + extern int i; + namespace Bar { + extern int i; + } +} + +int Foo::i = 0; +int Foo::Bar::i = 1; +],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_NAMESPACES) +], [ +AC_MSG_RESULT(no) +]) +AC_LANG_RESTORE +]) + +dnl ------------------------------------------------------------------------ +dnl Check for S_ISSOCK macro. Doesn't exist on Unix SCO. faure@kde.org +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_CHECK_S_ISSOCK], +[ +AC_MSG_CHECKING(for S_ISSOCK) +AC_CACHE_VAL(ac_cv_have_s_issock, +[ +AC_TRY_LINK( +[ +#include +], +[ +struct stat buff; +int b = S_ISSOCK( buff.st_mode ); +], +ac_cv_have_s_issock=yes, +ac_cv_have_s_issock=no) +]) +AC_MSG_RESULT($ac_cv_have_s_issock) +if test "$ac_cv_have_s_issock" = "yes"; then + AC_DEFINE_UNQUOTED(HAVE_S_ISSOCK, 1, [Define if sys/stat.h declares S_ISSOCK.]) +fi + +AH_VERBATIM(_ISSOCK, +[ +#ifndef HAVE_S_ISSOCK +#define HAVE_S_ISSOCK +#define S_ISSOCK(mode) (1==0) +#endif +]) + +]) + +dnl ------------------------------------------------------------------------ +dnl Check for MAXPATHLEN macro, defines KDEMAXPATHLEN. faure@kde.org +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([AC_CHECK_KDEMAXPATHLEN], +[ +AC_MSG_CHECKING(for MAXPATHLEN) +AC_CACHE_VAL(ac_cv_maxpathlen, +[ +cat > conftest.$ac_ext < +#endif +#include +#include +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +KDE_HELLO MAXPATHLEN + +EOF + +ac_try="$ac_cpp conftest.$ac_ext 2>/dev/null | grep '^KDE_HELLO' >conftest.out" + +if AC_TRY_EVAL(ac_try) && test -s conftest.out; then + ac_cv_maxpathlen=`sed 's#KDE_HELLO ##' conftest.out` +else + ac_cv_maxpathlen=1024 +fi + +rm conftest.* + +]) +AC_MSG_RESULT($ac_cv_maxpathlen) +AC_DEFINE_UNQUOTED(KDEMAXPATHLEN,$ac_cv_maxpathlen, [Define a safe value for MAXPATHLEN] ) +]) + +AC_DEFUN([KDE_CHECK_HEADER], +[ + kde_safe_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $all_includes" + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_CHECK_HEADER([$1], [$2], [$3], [$4]) + AC_LANG_RESTORE + CPPFLAGS=$kde_safe_cppflags +]) + +AC_DEFUN([KDE_CHECK_HEADERS], +[ + AH_CHECK_HEADERS([$1]) + AC_LANG_SAVE + kde_safe_cppflags=$CPPFLAGS + CPPFLAGS="$CPPFLAGS $all_includes" + AC_LANG_CPLUSPLUS + AC_CHECK_HEADERS([$1], [$2], [$3], [$4]) + CPPFLAGS=$kde_safe_cppflags + AC_LANG_RESTORE +]) + +AC_DEFUN([KDE_FAST_CONFIGURE], +[ + dnl makes configure fast (needs perl) + AC_ARG_ENABLE(fast-perl, AC_HELP_STRING([--disable-fast-perl],[disable fast Makefile generation (needs perl)]), + with_fast_perl=$enableval, with_fast_perl=yes) +]) + +AC_DEFUN([KDE_CONF_FILES], +[ + val= + if test -f $srcdir/configure.files ; then + val=`sed -e 's%^%\$(top_srcdir)/%' $srcdir/configure.files` + fi + CONF_FILES= + if test -n "$val" ; then + for i in $val ; do + CONF_FILES="$CONF_FILES $i" + done + fi + AC_SUBST(CONF_FILES) +])dnl + +dnl This sets the prefix, for arts and kdelibs +dnl Do NOT use in any other module. +dnl It only looks at --prefix, KDEDIR and falls back to /usr/local/kde +AC_DEFUN([KDE_SET_PREFIX_CORE], +[ + unset CDPATH + dnl make $KDEDIR the default for the installation + AC_PREFIX_DEFAULT(${KDEDIR:-/usr/local/kde}) + + if test "x$prefix" = "xNONE"; then + prefix=$ac_default_prefix + ac_configure_args="$ac_configure_args --prefix=$prefix" + fi + # And delete superfluous '/' to make compares easier + prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + + kde_libs_prefix='$(prefix)' + kde_libs_htmldir='$(kde_htmldir)' + AC_SUBST(kde_libs_prefix) + AC_SUBST(kde_libs_htmldir) + KDE_FAST_CONFIGURE + KDE_CONF_FILES +]) + + +AC_DEFUN([KDE_SET_PREFIX], +[ + unset CDPATH + dnl We can't give real code to that macro, only a value. + dnl It only matters for --help, since we set the prefix in this function anyway. + AC_PREFIX_DEFAULT(${KDEDIR:-the kde prefix}) + + KDE_SET_DEFAULT_BINDIRS + if test "x$prefix" = "xNONE"; then + dnl no prefix given: look for kde-config in the PATH and deduce the prefix from it + KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) + else + dnl prefix given: look for kde-config, preferrably in prefix, otherwise in PATH + kde_save_PATH="$PATH" + PATH="$exec_prefix/bin:$prefix/bin:$PATH" + KDE_FIND_PATH(kde-config, KDECONFIG, [$kde_default_bindirs], [KDE_MISSING_PROG_ERROR(kde-config)], [], prepend) + PATH="$kde_save_PATH" + fi + + kde_libs_prefix=`$KDECONFIG --prefix` + if test -z "$kde_libs_prefix" || test ! -x "$kde_libs_prefix"; then + AC_MSG_ERROR([$KDECONFIG --prefix outputed the non existant prefix '$kde_libs_prefix' for kdelibs. + This means it has been moved since you installed it. + This won't work. Please recompile kdelibs for the new prefix. + ]) + fi + kde_libs_htmldir=`$KDECONFIG --install html --expandvars` + + AC_MSG_CHECKING([where to install]) + if test "x$prefix" = "xNONE"; then + prefix=$kde_libs_prefix + AC_MSG_RESULT([$prefix (as returned by kde-config)]) + else + dnl --prefix was given. Compare prefixes and warn (in configure.in.bot.end) if different + given_prefix=$prefix + AC_MSG_RESULT([$prefix (as requested)]) + fi + + # And delete superfluous '/' to make compares easier + prefix=`echo "$prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + exec_prefix=`echo "$exec_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + given_prefix=`echo "$given_prefix" | sed 's,//*,/,g' | sed -e 's,/$,,'` + + AC_SUBST(KDECONFIG) + AC_SUBST(kde_libs_prefix) + AC_SUBST(kde_libs_htmldir) + + KDE_FAST_CONFIGURE + KDE_CONF_FILES +]) + +pushdef([AC_PROG_INSTALL], +[ + dnl our own version, testing for a -p flag + popdef([AC_PROG_INSTALL]) + dnl as AC_PROG_INSTALL works as it works we first have + dnl to save if the user didn't specify INSTALL, as the + dnl autoconf one overwrites INSTALL and we have no chance to find + dnl out afterwards + test -n "$INSTALL" && kde_save_INSTALL_given=$INSTALL + test -n "$INSTALL_PROGRAM" && kde_save_INSTALL_PROGRAM_given=$INSTALL_PROGRAM + test -n "$INSTALL_SCRIPT" && kde_save_INSTALL_SCRIPT_given=$INSTALL_SCRIPT + AC_PROG_INSTALL + + if test -z "$kde_save_INSTALL_given" ; then + # OK, user hasn't given any INSTALL, autoconf found one for us + # now we test, if it supports the -p flag + AC_MSG_CHECKING(for -p flag to install) + rm -f confinst.$$.* > /dev/null 2>&1 + echo "Testtest" > confinst.$$.orig + ac_res=no + if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then + if test -f confinst.$$.new ; then + # OK, -p seems to do no harm to install + INSTALL="${INSTALL} -p" + ac_res=yes + fi + fi + rm -f confinst.$$.* + AC_MSG_RESULT($ac_res) + fi + dnl the following tries to resolve some signs and wonders coming up + dnl with different autoconf/automake versions + dnl e.g.: + dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s + dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS) + dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s + dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has + dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the + dnl install-@DIR@PROGRAMS targets to explicitly use that flag + dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as + dnl INSTALL_SCRIPT, which breaks with automake <= 1.4 + dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure + dnl *sometimes KDE does not use the install-@DIR@PROGRAM targets from + dnl automake (due to broken Makefile.am or whatever) to install programs, + dnl and so does not see the -s flag in automake > 1.4 + dnl to clean up that mess we: + dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG + dnl which cleans KDE's program with automake > 1.4; + dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems + dnl with automake<=1.4 + dnl note that dues to this sometimes two '-s' flags are used (if KDE + dnl properly uses install-@DIR@PROGRAMS, but I don't care + dnl + dnl And to all this comes, that I even can't write in comments variable + dnl names used by automake, because it is so stupid to think I wanted to + dnl _use_ them, therefor I have written A_M_... instead of AM_ + dnl hmm, I wanted to say something ... ahh yes: Arghhh. + + if test -z "$kde_save_INSTALL_PROGRAM_given" ; then + INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)' + fi + if test -z "$kde_save_INSTALL_SCRIPT_given" ; then + INSTALL_SCRIPT='${INSTALL}' + fi +])dnl + +AC_DEFUN([KDE_LANG_CPLUSPLUS], +[AC_LANG_CPLUSPLUS +ac_link='rm -rf SunWS_cache; ${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&AC_FD_CC' +pushdef([AC_LANG_CPLUSPLUS], [popdef([AC_LANG_CPLUSPLUS]) KDE_LANG_CPLUSPLUS]) +]) + +pushdef([AC_LANG_CPLUSPLUS], +[popdef([AC_LANG_CPLUSPLUS]) +KDE_LANG_CPLUSPLUS +]) + +AC_DEFUN([KDE_CHECK_LONG_LONG], +[ +AC_MSG_CHECKING(for long long) +AC_CACHE_VAL(kde_cv_c_long_long, +[ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_LINK([], [ + long long foo = 0; + foo = foo+1; + ], + kde_cv_c_long_long=yes, kde_cv_c_long_long=no) + AC_LANG_RESTORE +]) +AC_MSG_RESULT($kde_cv_c_long_long) +if test "$kde_cv_c_long_long" = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, [Define if you have long long as datatype]) +fi +]) + +AC_DEFUN([KDE_CHECK_LIB], +[ + kde_save_LDFLAGS="$LDFLAGS" + dnl AC_CHECK_LIB modifies LIBS, so save it here + kde_save_LIBS="$LIBS" + LDFLAGS="$LDFLAGS $all_libraries" + case $host_os in + aix*) LDFLAGS="-brtl $LDFLAGS" + test "$GCC" = yes && LDFLAGS="-Wl,$LDFLAGS" + ;; + esac + AC_CHECK_LIB($1, $2, $3, $4, $5) + LDFLAGS="$kde_save_LDFLAGS" + LIBS="$kde_save_LIBS" +]) + +AC_DEFUN([KDE_JAVA_PREFIX], +[ + dir=`dirname "$1"` + base=`basename "$1"` + list=`ls -1 $dir 2> /dev/null` + for entry in $list; do + if test -d $dir/$entry/bin; then + case $entry in + $base) + javadirs="$javadirs $dir/$entry/bin" + ;; + esac + elif test -d $dir/$entry/jre/bin; then + case $entry in + $base) + javadirs="$javadirs $dir/$entry/jre/bin" + ;; + esac + fi + done +]) + +dnl KDE_CHEC_JAVA_DIR(onlyjre) +AC_DEFUN([KDE_CHECK_JAVA_DIR], +[ + +AC_ARG_WITH(java, +AC_HELP_STRING([--with-java=javadir],[use java installed in javadir, --without-java disables]), +[ ac_java_dir=$withval +], ac_java_dir="" +) + +AC_MSG_CHECKING([for Java]) + +dnl at this point ac_java_dir is either a dir, 'no' to disable, or '' to say look in $PATH +if test "x$ac_java_dir" = "xno"; then + kde_java_bindir=no + kde_java_includedir=no + kde_java_libjvmdir=no + kde_java_libgcjdir=no + kde_java_libhpidir=no +else + if test "x$ac_java_dir" = "x"; then + + + dnl No option set -> collect list of candidate paths + if test -n "$JAVA_HOME"; then + KDE_JAVA_PREFIX($JAVA_HOME) + fi + KDE_JAVA_PREFIX(/usr/j2se) + KDE_JAVA_PREFIX(/usr/lib/j2se) + KDE_JAVA_PREFIX(/usr/j*dk*) + KDE_JAVA_PREFIX(/usr/lib/j*dk*) + KDE_JAVA_PREFIX(/opt/j*sdk*) + KDE_JAVA_PREFIX(/usr/lib/java*) + KDE_JAVA_PREFIX(/usr/java*) + KDE_JAVA_PREFIX(/usr/java/j*dk*) + KDE_JAVA_PREFIX(/usr/java/j*re*) + KDE_JAVA_PREFIX(/usr/lib/SunJava2*) + KDE_JAVA_PREFIX(/usr/lib/SunJava*) + KDE_JAVA_PREFIX(/usr/lib/IBMJava2*) + KDE_JAVA_PREFIX(/usr/lib/IBMJava*) + KDE_JAVA_PREFIX(/opt/java*) + + kde_cv_path="NONE" + kde_save_IFS=$IFS + IFS=':' + for dir in $PATH; do + if test -d "$dir"; then + javadirs="$javadirs $dir" + fi + done + IFS=$kde_save_IFS + jredirs= + + dnl Now javadirs contains a list of paths that exist, all ending with bin/ + for dir in $javadirs; do + dnl Check for the java executable + if test -x "$dir/java"; then + sane_path=$(cd $dir; /bin/pwd) + dnl And also check for a libjvm.so somewhere under there + dnl Since we have to go to the parent dir, /usr/bin is excluded, /usr is too big. + if test "$sane_path" != "/usr/bin"; then + libjvmdir=`find $dir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` + if test ! -f $libjvmdir/libjvm.so; then continue; fi + jredirs="$jredirs $dir" + fi + fi + done + + dnl Now jredirs contains a reduced list, of paths where both java and ../**/libjvm.so was found + JAVAC= + JAVA= + kde_java_bindir=no + for dir in $jredirs; do + JAVA="$dir/java" + kde_java_bindir=$dir + if test -x "$dir/javac"; then + JAVAC="$dir/javac" + break + fi + done + + if test -n "$JAVAC"; then + dnl this substitution might not work - well, we test for jni.h below + kde_java_includedir=`echo $JAVAC | sed -e 's,bin/javac$,include/,'` + else + kde_java_includedir=no + fi + else + dnl config option set + kde_java_bindir=$ac_java_dir/bin + if test -x $ac_java_dir/bin/java && test ! -x $ac_java_dir/bin/javac; then + kde_java_includedir=no + else + kde_java_includedir=$ac_java_dir/include + fi + fi +fi + +dnl At this point kde_java_bindir and kde_java_includedir are either set or "no" +if test "x$kde_java_bindir" != "xno"; then + + dnl Look for libjvm.so + kde_java_libjvmdir=`find $kde_java_bindir/.. -name libjvm.so | sed 's,libjvm.so,,'|head -n 1` + dnl Look for libgcj.so + kde_java_libgcjdir=`find $kde_java_bindir/.. -name libgcj.so | sed 's,libgcj.so,,'|head -n 1` + dnl Look for libhpi.so and avoid green threads + kde_java_libhpidir=`find $kde_java_bindir/.. -name libhpi.so | grep -v green | sed 's,libhpi.so,,' | head -n 1` + + dnl Now check everything's fine under there + dnl the include dir is our flag for having the JDK + if test -d "$kde_java_includedir"; then + if test ! -x "$kde_java_bindir/javac"; then + AC_MSG_ERROR([javac not found under $kde_java_bindir - it seems you passed a wrong --with-java.]) + fi + if test ! -x "$kde_java_bindir/javah"; then + AC_MSG_ERROR([javah not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + if test ! -x "$kde_java_bindir/jar"; then + AC_MSG_ERROR([jar not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + if test ! -r "$kde_java_includedir/jni.h"; then + AC_MSG_ERROR([jni.h not found under $kde_java_includedir. Use --with-java or --without-java.]) + fi + + jni_includes="-I$kde_java_includedir" + dnl Strange thing, jni.h requires jni_md.h which is under genunix here.. + dnl and under linux here.. + + dnl not needed for gcj + + if test "x$kde_java_libgcjdir" = "x"; then + test -d "$kde_java_includedir/linux" && jni_includes="$jni_includes -I$kde_java_includedir/linux" + test -d "$kde_java_includedir/solaris" && jni_includes="$jni_includes -I$kde_java_includedir/solaris" + test -d "$kde_java_includedir/genunix" && jni_includes="$jni_includes -I$kde_java_includedir/genunix" + fi + + else + JAVAC= + jni_includes= + fi + + if test "x$kde_java_libgcjdir" = "x"; then + if test ! -r "$kde_java_libjvmdir/libjvm.so"; then + AC_MSG_ERROR([libjvm.so not found under $kde_java_libjvmdir. Use --without-java.]) + fi + else + if test ! -r "$kde_java_libgcjdir/libgcj.so"; then + AC_MSG_ERROR([libgcj.so not found under $kde_java_libgcjdir. Use --without-java.]) + fi + fi + + if test ! -x "$kde_java_bindir/java"; then + AC_MSG_ERROR([java not found under $kde_java_bindir. javac was found though! Use --with-java or --without-java.]) + fi + + dnl not needed for gcj compile + + if test "x$kde_java_libgcjdir" = "x"; then + if test ! -r "$kde_java_libhpidir/libhpi.so"; then + AC_MSG_ERROR([libhpi.so not found under $kde_java_libhpidir. Use --without-java.]) + fi + fi + + if test -n "$jni_includes"; then + dnl Check for JNI version + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_cxxflags_safe="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS $all_includes $jni_includes" + + AC_TRY_COMPILE([ + #include + ], + [ + #ifndef JNI_VERSION_1_2 + Syntax Error + #endif + ],[ kde_jni_works=yes ], + [ kde_jni_works=no ]) + + if test $kde_jni_works = no; then + AC_MSG_ERROR([Incorrect version of $kde_java_includedir/jni.h. + You need to have Java Development Kit (JDK) version 1.2. + + Use --with-java to specify another location. + Use --without-java to configure without java support. + Or download a newer JDK and try again. + See e.g. http://java.sun.com/products/jdk/1.2 ]) + fi + + CXXFLAGS="$ac_cxxflags_safe" + AC_LANG_RESTORE + + dnl All tests ok, inform and subst the variables + + JAVAC=$kde_java_bindir/javac + JAVAH=$kde_java_bindir/javah + JAR=$kde_java_bindir/jar + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + if test "x$kde_java_libgcjdir" = "x"; then + JVMLIBS="-L$kde_java_libjvmdir -ljvm -L$kde_java_libhpidir -lhpi" + else + JVMLIBS="-L$kde_java_libgcjdir -lgcj" + fi + AC_MSG_RESULT([java JDK in $kde_java_bindir]) + + else + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + AC_MSG_RESULT([java JRE in $kde_java_bindir]) + fi +elif test -d "/Library/Java/Home"; then + kde_java_bindir="/Library/Java/Home/bin" + jni_includes="-I/Library/Java/Home/include" + + JAVAC=$kde_java_bindir/javac + JAVAH=$kde_java_bindir/javah + JAR=$kde_java_bindir/jar + JVMLIBS="-Wl,-framework,JavaVM" + + AC_DEFINE_UNQUOTED(PATH_JAVA, "$kde_java_bindir/java", [Define where your java executable is]) + AC_MSG_RESULT([Apple Java Framework]) +else + AC_MSG_RESULT([none found]) +fi + +AC_SUBST(JAVAC) +AC_SUBST(JAVAH) +AC_SUBST(JAR) +AC_SUBST(JVMLIBS) +AC_SUBST(jni_includes) + +# for backward compat +kde_cv_java_includedir=$kde_java_includedir +kde_cv_java_bindir=$kde_java_bindir +]) + +dnl this is a redefinition of autoconf 2.5x's AC_FOREACH. +dnl When the argument list becomes big, as in KDE for AC_OUTPUT in +dnl big packages, m4_foreach is dog-slow. So use our own version of +dnl it. (matz@kde.org) +m4_define([mm_foreach], +[m4_pushdef([$1])_mm_foreach($@)m4_popdef([$1])]) +m4_define([mm_car], [[$1]]) +m4_define([mm_car2], [[$@]]) +m4_define([_mm_foreach], +[m4_if(m4_quote($2), [], [], + [m4_define([$1], mm_car($2))$3[]_mm_foreach([$1], + mm_car2(m4_shift($2)), + [$3])])]) +m4_define([AC_FOREACH], +[mm_foreach([$1], m4_split(m4_normalize([$2])), [$3])]) + +AC_DEFUN([KDE_NEED_FLEX], +[ +kde_libs_safe=$LIBS +LIBS="$LIBS $USER_LDFLAGS" +AM_PROG_LEX +LIBS=$kde_libs_safe +if test -z "$LEXLIB"; then + AC_MSG_ERROR([You need to have flex installed.]) +fi +AC_SUBST(LEXLIB) +]) + +AC_DEFUN([AC_PATH_QTOPIA], +[ + dnl TODO: use AC_CACHE_VAL + + if test -z "$1"; then + qtopia_minver_maj=1 + qtopia_minver_min=5 + qtopia_minver_pat=0 + else + qtopia_minver_maj=`echo "$1" | sed -e "s/^\(.*\)\..*\..*$/\1/"` + qtopia_minver_min=`echo "$1" | sed -e "s/^.*\.\(.*\)\..*$/\1/"` + qtopia_minver_pat=`echo "$1" | sed -e "s/^.*\..*\.\(.*\)$/\1/"` + fi + + qtopia_minver="$qtopia_minver_maj$qtopia_minver_min$qtopia_minver_pat" + qtopia_minverstr="$qtopia_minver_maj.$qtopia_minver_min.$qtopia_minver_pat" + + AC_REQUIRE([AC_PATH_QT]) + + AC_MSG_CHECKING([for Qtopia]) + + LIB_QTOPIA="-lqpe" + AC_SUBST(LIB_QTOPIA) + + kde_qtopia_dirs="$QPEDIR /opt/Qtopia" + + ac_qtopia_incdir=NO + + AC_ARG_WITH(qtopia-dir, + AC_HELP_STRING([--with-qtopia-dir=DIR],[where the root of Qtopia is installed]), + [ ac_qtopia_incdir="$withval"/include] ) + + qtopia_incdirs="" + for dir in $kde_qtopia_dirs; do + qtopia_incdirs="$qtopia_incdirs $dir/include" + done + + if test ! "$ac_qtopia_incdir" = "NO"; then + qtopia_incdirs="$ac_qtopia_incdir $qtopia_incdirs" + fi + + qtopia_incdir="" + AC_FIND_FILE(qpe/qpeapplication.h, $qtopia_incdirs, qtopia_incdir) + ac_qtopia_incdir="$qtopia_incdir" + + if test -z "$qtopia_incdir"; then + AC_MSG_ERROR([Cannot find Qtopia headers. Please check your installation.]) + fi + + qtopia_ver_maj=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION "\(.*\)\..*\..*".*,\1,p'`; + qtopia_ver_min=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\.\(.*\)\..*".*,\1,p'`; + qtopia_ver_pat=`cat $qtopia_incdir/qpe/version.h | sed -n -e 's,.*QPE_VERSION ".*\..*\.\(.*\)".*,\1,p'`; + + qtopia_ver="$qtopia_ver_maj$qtopia_ver_min$qtopia_ver_pat" + qtopia_verstr="$qtopia_ver_maj.$qtopia_ver_min.$qtopia_ver_pat" + if test "$qtopia_ver" -lt "$qtopia_minver"; then + AC_MSG_ERROR([found Qtopia version $qtopia_verstr but version $qtopia_minverstr +is required.]) + fi + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + ac_cxxflags_safe="$CXXFLAGS" + ac_ldflags_safe="$LDFLAGS" + ac_libs_safe="$LIBS" + + CXXFLAGS="$CXXFLAGS -I$qtopia_incdir $all_includes" + LDFLAGS="$LDFLAGS $QT_LDFLAGS $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" + LIBS="$LIBS $LIB_QTOPIA $LIBQT" + + cat > conftest.$ac_ext < +#include + +int main( int argc, char **argv ) +{ + QPEApplication app( argc, argv ); + return 0; +} +EOF + + if AC_TRY_EVAL(ac_link) && test -s conftest; then + rm -f conftest* + else + rm -f conftest* + AC_MSG_ERROR([Cannot link small Qtopia Application. For more details look at +the end of config.log]) + fi + + CXXFLAGS="$ac_cxxflags_safe" + LDFLAGS="$ac_ldflags_safe" + LIBS="$ac_libs_safe" + + AC_LANG_RESTORE + + QTOPIA_INCLUDES="-I$qtopia_incdir" + AC_SUBST(QTOPIA_INCLUDES) + + AC_MSG_RESULT([found version $qtopia_verstr with headers at $qtopia_incdir]) +]) + + +AC_DEFUN([KDE_INIT_DOXYGEN], +[ +AC_MSG_CHECKING([for Qt docs]) +kde_qtdir= +if test "${with_qt_dir+set}" = set; then + kde_qtdir="$with_qt_dir" +fi + +AC_FIND_FILE(qsql.html, [ $kde_qtdir/doc/html $QTDIR/doc/html /usr/share/doc/packages/qt3/html /usr/lib/qt/doc /usr/lib/qt3/doc /usr/lib/qt3/doc/html /usr/doc/qt3/html /usr/doc/qt3 /usr/share/doc/qt3-doc /usr/share/qt3/doc/html /usr/X11R6/share/doc/qt/html ], QTDOCDIR) +AC_MSG_RESULT($QTDOCDIR) + +AC_SUBST(QTDOCDIR) + +KDE_FIND_PATH(dot, DOT, [], []) +if test -n "$DOT"; then + KDE_HAVE_DOT="YES" +else + KDE_HAVE_DOT="NO" +fi +AC_SUBST(KDE_HAVE_DOT) +KDE_FIND_PATH(doxygen, DOXYGEN, [], []) +AC_SUBST(DOXYGEN) + +DOXYGEN_PROJECT_NAME="$1" +DOXYGEN_PROJECT_NUMBER="$2" +AC_SUBST(DOXYGEN_PROJECT_NAME) +AC_SUBST(DOXYGEN_PROJECT_NUMBER) + +KDE_HAS_DOXYGEN=no +if test -n "$DOXYGEN" && test -x "$DOXYGEN" && test -f $QTDOCDIR/qsql.html; then + KDE_HAS_DOXYGEN=yes +fi +AC_SUBST(KDE_HAS_DOXYGEN) + +]) + + +AC_DEFUN([AC_FIND_BZIP2], +[ +AC_MSG_CHECKING([for bzDecompress in libbz2]) +AC_CACHE_VAL(ac_cv_lib_bzip2, +[ +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kde_save_LIBS="$LIBS" +LIBS="$all_libraries $USER_LDFLAGS -lbz2 $LIBSOCKET" +kde_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $all_includes $USER_INCLUDES" +AC_TRY_LINK(dnl +[ +#define BZ_NO_STDIO +#include +], + [ bz_stream s; (void) bzDecompress(&s); ], + eval "ac_cv_lib_bzip2='-lbz2'", + eval "ac_cv_lib_bzip2=no") +LIBS="$kde_save_LIBS" +CXXFLAGS="$kde_save_CXXFLAGS" +AC_LANG_RESTORE +])dnl +AC_MSG_RESULT($ac_cv_lib_bzip2) + +if test ! "$ac_cv_lib_bzip2" = no; then + BZIP2DIR=bzip2 + + LIBBZ2="$ac_cv_lib_bzip2" + AC_SUBST(LIBBZ2) + +else + + cxx_shared_flag= + ld_shared_flag= + KDE_CHECK_COMPILER_FLAG(shared, [ + ld_shared_flag="-shared" + ]) + KDE_CHECK_COMPILER_FLAG(fPIC, [ + cxx_shared_flag="-fPIC" + ]) + + AC_MSG_CHECKING([for BZ2_bzDecompress in (shared) libbz2]) + AC_CACHE_VAL(ac_cv_lib_bzip2_prefix, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + kde_save_LIBS="$LIBS" + LIBS="$all_libraries $USER_LDFLAGS $ld_shared_flag -lbz2 $LIBSOCKET" + kde_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CFLAGS $cxx_shared_flag $all_includes $USER_INCLUDES" + + AC_TRY_LINK(dnl + [ + #define BZ_NO_STDIO + #include + ], + [ bz_stream s; (void) BZ2_bzDecompress(&s); ], + eval "ac_cv_lib_bzip2_prefix='-lbz2'", + eval "ac_cv_lib_bzip2_prefix=no") + LIBS="$kde_save_LIBS" + CXXFLAGS="$kde_save_CXXFLAGS" + AC_LANG_RESTORE + ])dnl + + AC_MSG_RESULT($ac_cv_lib_bzip2_prefix) + + if test ! "$ac_cv_lib_bzip2_prefix" = no; then + BZIP2DIR=bzip2 + + LIBBZ2="$ac_cv_lib_bzip2_prefix" + AC_SUBST(LIBBZ2) + + AC_DEFINE(NEED_BZ2_PREFIX, 1, [Define if the libbz2 functions need the BZ2_ prefix]) + dnl else, we just ignore this + fi + +fi +AM_CONDITIONAL(include_BZIP2, test -n "$BZIP2DIR") +]) + +dnl ------------------------------------------------------------------------ +dnl Try to find the SSL headers and libraries. +dnl $(SSL_LDFLAGS) will be -Lsslliblocation (if needed) +dnl and $(SSL_INCLUDES) will be -Isslhdrlocation (if needed) +dnl ------------------------------------------------------------------------ +dnl +AC_DEFUN([KDE_CHECK_SSL], +[ +LIBSSL="-lssl -lcrypto" +AC_REQUIRE([KDE_CHECK_LIB64]) + +ac_ssl_includes=NO ac_ssl_libraries=NO +ssl_libraries="" +ssl_includes="" +AC_ARG_WITH(ssl-dir, + AC_HELP_STRING([--with-ssl-dir=DIR],[where the root of OpenSSL is installed]), + [ ac_ssl_includes="$withval"/include + ac_ssl_libraries="$withval"/lib$kdelibsuff + ]) + +want_ssl=yes +AC_ARG_WITH(ssl, + AC_HELP_STRING([--without-ssl],[disable SSL checks]), + [want_ssl=$withval]) + +if test $want_ssl = yes; then + +AC_MSG_CHECKING(for OpenSSL) + +AC_CACHE_VAL(ac_cv_have_ssl, +[#try to guess OpenSSL locations + + ssl_incdirs="/usr/include /usr/local/include /usr/ssl/include /usr/local/ssl/include $prefix/include $kde_extra_includes" + ssl_incdirs="$ac_ssl_includes $ssl_incdirs" + AC_FIND_FILE(openssl/ssl.h, $ssl_incdirs, ssl_incdir) + ac_ssl_includes="$ssl_incdir" + + ssl_libdirs="/usr/lib$kdelibsuff /usr/local/lib$kdelibsuff /usr/ssl/lib$kdelibsuff /usr/local/ssl/lib$kdelibsuff $libdir $prefix/lib$kdelibsuff $exec_prefix/lib$kdelibsuff $kde_extra_libs" + if test ! "$ac_ssl_libraries" = "NO"; then + ssl_libdirs="$ac_ssl_libraries $ssl_libdirs" + fi + + test=NONE + ssl_libdir=NONE + for dir in $ssl_libdirs; do + try="ls -1 $dir/libssl*" + if test=`eval $try 2> /dev/null`; then ssl_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi + done + + ac_ssl_libraries="$ssl_libdir" + + ac_ldflags_safe="$LDFLAGS" + ac_libs_safe="$LIBS" + + LDFLAGS="$LDFLAGS -L$ssl_libdir $all_libraries" + LIBS="$LIBS $LIBSSL -lRSAglue -lrsaref" + + AC_TRY_LINK(,void RSAPrivateEncrypt(void);RSAPrivateEncrypt();, + ac_ssl_rsaref="yes" + , + ac_ssl_rsaref="no" + ) + + LDFLAGS="$ac_ldflags_safe" + LIBS="$ac_libs_safe" + + if test "$ac_ssl_includes" = NO || test "$ac_ssl_libraries" = NO; then + have_ssl=no + else + have_ssl=yes; + fi + + ]) + + eval "$ac_cv_have_ssl" + + AC_MSG_RESULT([libraries $ac_ssl_libraries, headers $ac_ssl_includes]) + + AC_MSG_CHECKING([whether OpenSSL uses rsaref]) + AC_MSG_RESULT($ac_ssl_rsaref) + + AC_MSG_CHECKING([for easter eggs]) + AC_MSG_RESULT([none found]) + +else + have_ssl=no +fi + +if test "$have_ssl" = yes; then + AC_MSG_CHECKING(for OpenSSL version) + dnl Check for SSL version + AC_CACHE_VAL(ac_cv_ssl_version, + [ + + cat >conftest.$ac_ext < +#include + int main() { + +#ifndef OPENSSL_VERSION_NUMBER + printf("ssl_version=\\"error\\"\n"); +#else + if (OPENSSL_VERSION_NUMBER < 0x00906000) + printf("ssl_version=\\"old\\"\n"); + else + printf("ssl_version=\\"ok\\"\n"); +#endif + return (0); + } +EOF + + ac_save_CPPFLAGS=$CPPFLAGS + if test "$ac_ssl_includes" != "/usr/include"; then + CPPFLAGS="$CPPFLAGS -I$ac_ssl_includes" + fi + + if AC_TRY_EVAL(ac_link); then + + if eval `./conftest 2>&5`; then + if test $ssl_version = error; then + AC_MSG_ERROR([$ssl_incdir/openssl/opensslv.h doesn't define OPENSSL_VERSION_NUMBER !]) + else + if test $ssl_version = old; then + AC_MSG_WARN([OpenSSL version too old. Upgrade to 0.9.6 at least, see http://www.openssl.org. SSL support disabled.]) + have_ssl=no + fi + fi + ac_cv_ssl_version="ssl_version=$ssl_version" + else + AC_MSG_ERROR([Your system couldn't run a small SSL test program. + Check config.log, and if you can't figure it out, send a mail to + David Faure , attaching your config.log]) + fi + + else + AC_MSG_ERROR([Your system couldn't link a small SSL test program. + Check config.log, and if you can't figure it out, send a mail to + David Faure , attaching your config.log]) + fi + CPPFLAGS=$ac_save_CPPFLAGS + + ]) + + eval "$ac_cv_ssl_version" + AC_MSG_RESULT($ssl_version) +fi + +if test "$have_ssl" != yes; then + LIBSSL=""; +else + AC_DEFINE(HAVE_SSL, 1, [If we are going to use OpenSSL]) + ac_cv_have_ssl="have_ssl=yes \ + ac_ssl_includes=$ac_ssl_includes ac_ssl_libraries=$ac_ssl_libraries ac_ssl_rsaref=$ac_ssl_rsaref" + + + ssl_libraries="$ac_ssl_libraries" + ssl_includes="$ac_ssl_includes" + + if test "$ac_ssl_rsaref" = yes; then + LIBSSL="-lssl -lcrypto -lRSAglue -lrsaref" + fi + + if test $ssl_version = "old"; then + AC_DEFINE(HAVE_OLD_SSL_API, 1, [Define if you have OpenSSL < 0.9.6]) + fi +fi + +SSL_INCLUDES= + +if test "$ssl_includes" = "/usr/include"; then + if test -f /usr/kerberos/include/krb5.h; then + SSL_INCLUDES="-I/usr/kerberos/include" + fi +elif test "$ssl_includes" != "/usr/local/include" && test -n "$ssl_includes"; then + SSL_INCLUDES="-I$ssl_includes" +fi + +if test "$ssl_libraries" = "/usr/lib" || test "$ssl_libraries" = "/usr/local/lib" || test -z "$ssl_libraries" || test "$ssl_libraries" = "NONE"; then + SSL_LDFLAGS="" +else + SSL_LDFLAGS="-L$ssl_libraries -R$ssl_libraries" +fi + +AC_SUBST(SSL_INCLUDES) +AC_SUBST(SSL_LDFLAGS) +AC_SUBST(LIBSSL) +]) + +AC_DEFUN([KDE_CHECK_STRLCPY], +[ + AC_REQUIRE([AC_CHECK_STRLCAT]) + AC_REQUIRE([AC_CHECK_STRLCPY]) + AC_CHECK_SIZEOF(size_t) + AC_CHECK_SIZEOF(unsigned long) + + AC_MSG_CHECKING([sizeof size_t == sizeof unsigned long]) + AC_TRY_COMPILE(,[ + #if SIZEOF_SIZE_T != SIZEOF_UNSIGNED_LONG + choke me + #endif + ],AC_MSG_RESULT([yes]),[ + AC_MSG_RESULT(no) + AC_MSG_ERROR([ + Apparently on your system our assumption sizeof size_t == sizeof unsigned long + does not apply. Please mail kde-devel@kde.org with a description of your system! + ]) + ]) +]) + +AC_DEFUN([KDE_CHECK_BINUTILS], +[ + AC_MSG_CHECKING([if ld supports unversioned version maps]) + + kde_save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS -Wl,--version-script=conftest.map" + echo "{ local: extern \"C++\" { foo }; };" > conftest.map + AC_TRY_LINK([int foo;], +[ +#ifdef __INTEL_COMPILER +icc apparently does not support libtools version-info and version-script +at the same time. Dunno where the bug is, but until somebody figured out, +better disable the optional version scripts. +#endif + + foo = 42; +], kde_supports_versionmaps=yes, kde_supports_versionmaps=no) + LDFLAGS="$kde_save_LDFLAGS" + rm -f conftest.map + AM_CONDITIONAL(include_VERSION_SCRIPT, + [test "$kde_supports_versionmaps" = "yes" && test "$kde_use_debug_code" = "no"]) + + AC_MSG_RESULT($kde_supports_versionmaps) +]) + +AC_DEFUN([AM_PROG_OBJC],[ +AC_CHECK_PROGS(OBJC, gcc, gcc) +test -z "$OBJC" && AC_MSG_ERROR([no acceptable objective-c gcc found in \$PATH]) +if test "x${OBJCFLAGS-unset}" = xunset; then + OBJCFLAGS="-g -O2" +fi +AC_SUBST(OBJCFLAGS) +_AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES(OBJC)]) +]) + +AC_DEFUN([KDE_CHECK_PERL], +[ + KDE_FIND_PATH(perl, PERL, [$bindir $exec_prefix/bin $prefix/bin], [ + AC_MSG_ERROR([No Perl found in your $PATH. +We need perl to generate some code.]) + ]) + AC_SUBST(PERL) +]) + +AC_DEFUN([KDE_CHECK_LARGEFILE], +[ +AC_SYS_LARGEFILE +if test "$ac_cv_sys_file_offset_bits" != no; then + CPPFLAGS="$CPPFLAGS -D_FILE_OFFSET_BITS=$ac_cv_sys_file_offset_bits" +fi + +if test "x$ac_cv_sys_large_files" != "xno"; then + CPPFLAGS="$CPPFLAGS -D_LARGE_FILES=1" +fi + +]) + +dnl A small extension to PKG_CHECK_MODULES (defined in pkg.m4.in) +dnl which allows to search for libs that get installed into the KDE prefix. +dnl +dnl Syntax: KDE_PKG_CHECK_MODULES(KSTUFF, libkexif >= 0.2 glib = 1.3.4, action-if, action-not) +dnl defines KSTUFF_LIBS, KSTUFF_CFLAGS, see pkg-config man page +dnl also defines KSTUFF_PKG_ERRORS on error +AC_DEFUN([KDE_PKG_CHECK_MODULES], [ + + PKG_CONFIG_PATH="$prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH" + if test "$prefix" != "$kde_libs_prefix"; then + PKG_CONFIG_PATH="$kde_libs_prefix/lib${kdelibsuff}/pkgconfig:$PKG_CONFIG_PATH" + fi + export PKG_CONFIG_PATH + PKG_CHECK_MODULES([$1],[$2],[$3],[$4]) +]) + + +dnl Check for PIE support in the compiler and linker +AC_DEFUN([KDE_CHECK_PIE_SUPPORT], +[ + AC_CACHE_CHECK([for PIE support], kde_cv_val_pie_support, + [ + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + safe_CXXFLAGS=$CXXFLAGS + safe_LDFLAGS=$LDFLAGS + CXXFLAGS="$CXXFLAGS -fPIE" + LDFLAGS="$LDFLAGS -pie" + + AC_TRY_LINK([int foo;], [], [kde_cv_val_pie_support=yes], [kde_cv_val_pie_support=no]) + + CXXFLAGS=$safe_CXXFLAGS + LDFLAGS=$safe_LDFLAGS + AC_LANG_RESTORE + ]) + + AC_MSG_CHECKING(if enabling -pie/fPIE support) + + AC_ARG_ENABLE(pie, + AC_HELP_STRING([--enable-pie],[platform supports PIE linking [default=detect]]), + [kde_has_pie_support=$enableval], + [kde_has_pie_support=detect]) + + if test "$kde_has_pie_support" = "detect"; then + kde_has_pie_support=$kde_cv_val_pie_support + fi + + AC_MSG_RESULT([$kde_has_pie_support]) + + KDE_USE_FPIE="" + KDE_USE_PIE="" + + AC_SUBST([KDE_USE_FPIE]) + AC_SUBST([KDE_USE_PIE]) + + if test "$kde_has_pie_support" = "yes"; then + KDE_USE_FPIE="-fPIE" + KDE_USE_PIE="-pie" + fi +]) +# libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- +## Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005 +## Free Software Foundation, Inc. +## Originally by Gordon Matzigkeit , 1996 +## +## This file is free software; the Free Software Foundation gives +## unlimited permission to copy and/or distribute it, with or without +## modifications, as long as this notice is preserved. + +# serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL + + +# AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) +# ----------------------------------------------------------- +# If this macro is not defined by Autoconf, define it here. +m4_ifdef([AC_PROVIDE_IFELSE], + [], + [m4_define([AC_PROVIDE_IFELSE], + [m4_ifdef([AC_PROVIDE_$1], + [$2], [$3])])]) + + +# AC_PROG_LIBTOOL +# --------------- +AC_DEFUN([AC_PROG_LIBTOOL], +[AC_REQUIRE([_AC_PROG_LIBTOOL])dnl +dnl If AC_PROG_CXX has already been expanded, run AC_LIBTOOL_CXX +dnl immediately, otherwise, hook it in at the end of AC_PROG_CXX. + AC_PROVIDE_IFELSE([AC_PROG_CXX], + [AC_LIBTOOL_CXX], + [define([AC_PROG_CXX], defn([AC_PROG_CXX])[AC_LIBTOOL_CXX + ])]) +dnl And a similar setup for Fortran 77 support + AC_PROVIDE_IFELSE([AC_PROG_F77], + [AC_LIBTOOL_F77], + [define([AC_PROG_F77], defn([AC_PROG_F77])[AC_LIBTOOL_F77 +])]) + +dnl Quote A][M_PROG_GCJ so that aclocal doesn't bring it in needlessly. +dnl If either AC_PROG_GCJ or A][M_PROG_GCJ have already been expanded, run +dnl AC_LIBTOOL_GCJ immediately, otherwise, hook it in at the end of both. + AC_PROVIDE_IFELSE([AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ], + [AC_LIBTOOL_GCJ], + [ifdef([AC_PROG_GCJ], + [define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([A][M_PROG_GCJ], + [define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[AC_LIBTOOL_GCJ])]) + ifdef([LT_AC_PROG_GCJ], + [define([LT_AC_PROG_GCJ], + defn([LT_AC_PROG_GCJ])[AC_LIBTOOL_GCJ])])])]) +])])# AC_PROG_LIBTOOL + + +# _AC_PROG_LIBTOOL +# ---------------- +AC_DEFUN([_AC_PROG_LIBTOOL], +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl +AC_BEFORE([$0],[AC_LIBTOOL_CXX])dnl +AC_BEFORE([$0],[AC_LIBTOOL_F77])dnl +AC_BEFORE([$0],[AC_LIBTOOL_GCJ])dnl + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Prevent multiple expansion +define([AC_PROG_LIBTOOL], []) +])# _AC_PROG_LIBTOOL + + +# AC_LIBTOOL_SETUP +# ---------------- +AC_DEFUN([AC_LIBTOOL_SETUP], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_LD_RELOAD_FLAG])dnl +AC_REQUIRE([AC_PROG_NM])dnl + +AC_REQUIRE([AC_PROG_LN_S])dnl +AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl +# Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! +AC_REQUIRE([AC_OBJEXT])dnl +AC_REQUIRE([AC_EXEEXT])dnl +dnl + +AC_LIBTOOL_SYS_MAX_CMD_LEN +AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +AC_LIBTOOL_OBJDIR + +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +_LT_AC_PROG_ECHO_BACKSLASH + +case $host_os in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +[sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g'] + +# Same as above, but do not quote variable references. +[double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g'] + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# Sed substitution to avoid accidental globbing in evaled expressions +no_glob_subst='s/\*/\\\*/g' + +# Constants: +rm="rm -f" + +# Global variables: +default_ofile=libtool +can_build_shared=yes + +# All known linkers require a `.a' archive for static linking (except MSVC, +# which needs '.lib'). +libext=a +ltmain="$ac_aux_dir/ltmain.sh" +ofile="$default_ofile" +with_gnu_ld="$lt_cv_prog_gnu_ld" + +AC_CHECK_TOOL(AR, ar, false) +AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_CHECK_TOOL(STRIP, strip, :) + +old_CC="$CC" +old_CFLAGS="$CFLAGS" + +# Set sane defaults for various variables +test -z "$AR" && AR=ar +test -z "$AR_FLAGS" && AR_FLAGS=cru +test -z "$AS" && AS=as +test -z "$CC" && CC=cc +test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$LD" && LD=ld +test -z "$LN_S" && LN_S="ln -s" +test -z "$MAGIC_CMD" && MAGIC_CMD=file +test -z "$NM" && NM=nm +test -z "$SED" && SED=sed +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$RANLIB" && RANLIB=: +test -z "$STRIP" && STRIP=: +test -z "$ac_objext" && ac_objext=o + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +if test -n "$RANLIB"; then + case $host_os in + openbsd*) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" + ;; + *) + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" + ;; + esac + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" +fi + +_LT_CC_BASENAME([$compiler]) + +# Only perform the check for file, if the check method requires it +case $deplibs_check_method in +file_magic*) + if test "$file_magic_cmd" = '$MAGIC_CMD'; then + AC_PATH_MAGIC + fi + ;; +esac + +AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +enable_win32_dll=yes, enable_win32_dll=no) + +AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +AC_ARG_WITH([pic], + [AC_HELP_STRING([--with-pic], + [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], + [pic_mode="$withval"], + [pic_mode=default]) +test -z "$pic_mode" && pic_mode=default + +# Use C for the default configuration in the libtool script +tagname= +AC_LIBTOOL_LANG_C_CONFIG +_LT_AC_TAGCONFIG +])# AC_LIBTOOL_SETUP + + +# _LT_AC_SYS_COMPILER +# ------------------- +AC_DEFUN([_LT_AC_SYS_COMPILER], +[AC_REQUIRE([AC_PROG_CC])dnl + +# If no C compiler was specified, use CC. +LTCC=${LTCC-"$CC"} + +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + +# Allow CC to be a program name with arguments. +compiler=$CC +])# _LT_AC_SYS_COMPILER + + +# _LT_CC_BASENAME(CC) +# ------------------- +# Calculate cc_basename. Skip known compiler wrappers and cross-prefix. +AC_DEFUN([_LT_CC_BASENAME], +[for cc_temp in $1""; do + case $cc_temp in + compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; + distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; + \-*) ;; + *) break;; + esac +done +cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` +]) + + +# _LT_COMPILER_BOILERPLATE +# ------------------------ +# Check for compiler boilerplate output or warnings with +# the simple compiler test code. +AC_DEFUN([_LT_COMPILER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_compiler_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_COMPILER_BOILERPLATE + + +# _LT_LINKER_BOILERPLATE +# ---------------------- +# Check for linker boilerplate output or warnings with +# the simple link test code. +AC_DEFUN([_LT_LINKER_BOILERPLATE], +[ac_outfile=conftest.$ac_objext +printf "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err +_lt_linker_boilerplate=`cat conftest.err` +$rm conftest* +])# _LT_LINKER_BOILERPLATE + + +# _LT_AC_SYS_LIBPATH_AIX +# ---------------------- +# Links a minimal program and checks the executable +# for the system default hardcoded library path. In most cases, +# this is /usr/lib:/lib, but when the MPI compilers are used +# the location of the communication and MPI libs are included too. +# If we don't find anything, use the default library path according +# to the aix ld manual. +AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], +[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi],[]) +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi +])# _LT_AC_SYS_LIBPATH_AIX + + +# _LT_AC_SHELL_INIT(ARG) +# ---------------------- +AC_DEFUN([_LT_AC_SHELL_INIT], +[ifdef([AC_DIVERSION_NOTICE], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], + [AC_DIVERT_PUSH(NOTICE)]) +$1 +AC_DIVERT_POP +])# _LT_AC_SHELL_INIT + + +# _LT_AC_PROG_ECHO_BACKSLASH +# -------------------------- +# Add some code to the start of the generated configure script which +# will find an echo command which doesn't interpret backslashes. +AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH], +[_LT_AC_SHELL_INIT([ +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} + +case X$ECHO in +X*--fallback-echo) + # Remove one level of quotation (which was required for Make). + ECHO=`echo "$ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` + ;; +esac + +echo=${ECHO-echo} +if test "X[$]1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X[$]1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t' ; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} +fi + +if test "X[$]1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null 2>&1 && unset CDPATH + +if test -z "$ECHO"; then +if test "X${echo_test_string+set}" != Xset; then +# find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null + then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + : +else + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for dir in $PATH /usr/ucb; do + IFS="$lt_save_ifs" + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$lt_save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`(print -r "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running configure again with it. + ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} + else + # Try using printf. + echo='printf %s\n' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + echo_testing_string=`($echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + # Cool, printf works + : + elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL [$]0 --fallback-echo" + elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && + test "X$echo_testing_string" = 'X\t' && + echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && + test "X$echo_testing_string" = "X$echo_test_string"; then + echo="$CONFIG_SHELL [$]0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null + then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "[$]0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi +fi + +# Copy echo and quote the copy suitably for passing to libtool from +# the Makefile, instead of quoting the original, which is used later. +ECHO=$echo +if test "X$ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then + ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" +fi + +AC_SUBST(ECHO) +])])# _LT_AC_PROG_ECHO_BACKSLASH + + +# _LT_AC_LOCK +# ----------- +AC_DEFUN([_LT_AC_LOCK], +[AC_ARG_ENABLE([libtool-lock], + [AC_HELP_STRING([--disable-libtool-lock], + [avoid locking (might break parallel builds)])]) +test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case $host in +ia64-*-hpux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.$ac_objext` in + *ELF-32*) + HPUX_IA64_MODE="32" + ;; + *ELF-64*) + HPUX_IA64_MODE="64" + ;; + esac + fi + rm -rf conftest* + ;; +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + if test "$lt_cv_prog_gnu_ld" = yes; then + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -melf32bsmip" + ;; + *N32*) + LD="${LD-ld} -melf32bmipn32" + ;; + *64-bit*) + LD="${LD-ld} -melf64bmip" + ;; + esac + else + case `/usr/bin/file conftest.$ac_objext` in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + fi + rm -rf conftest* + ;; + +x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *32-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_i386" + ;; + ppc64-*linux*|powerpc64-*linux*) + LD="${LD-ld} -m elf32ppclinux" + ;; + s390x-*linux*) + LD="${LD-ld} -m elf_s390" + ;; + sparc64-*linux*) + LD="${LD-ld} -m elf32_sparc" + ;; + esac + ;; + *64-bit*) + case $host in + x86_64-*linux*) + LD="${LD-ld} -m elf_x86_64" + ;; + ppc*-*linux*|powerpc*-*linux*) + LD="${LD-ld} -m elf64ppc" + ;; + s390*-*linux*) + LD="${LD-ld} -m elf64_s390" + ;; + sparc*-*linux*) + LD="${LD-ld} -m elf64_sparc" + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_LANG_PUSH(C) + AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) + AC_LANG_POP]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) LD="${LD-ld} -64" ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + +AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw* | *-*-pw32*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; + ]) +esac + +need_locks="$enable_libtool_lock" + +])# _LT_AC_LOCK + + +# AC_LIBTOOL_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) +# ---------------------------------------------------------------- +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], +[AC_REQUIRE([LT_AC_PROG_SED]) +AC_CACHE_CHECK([$1], [$2], + [$2=no + ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$3" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + fi + $rm conftest* +]) + +if test x"[$]$2" = xyes; then + ifelse([$5], , :, [$5]) +else + ifelse([$6], , :, [$6]) +fi +])# AC_LIBTOOL_COMPILER_OPTION + + +# AC_LIBTOOL_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, +# [ACTION-SUCCESS], [ACTION-FAILURE]) +# ------------------------------------------------------------ +# Check whether the given compiler option works +AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], +[AC_CACHE_CHECK([$1], [$2], + [$2=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $3" + printf "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&AS_MESSAGE_LOG_FD + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + $2=yes + fi + else + $2=yes + fi + fi + $rm conftest* + LDFLAGS="$save_LDFLAGS" +]) + +if test x"[$]$2" = xyes; then + ifelse([$4], , :, [$4]) +else + ifelse([$5], , :, [$5]) +fi +])# AC_LIBTOOL_LINKER_OPTION + + +# AC_LIBTOOL_SYS_MAX_CMD_LEN +# -------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], +[# find the maximum length of command line arguments +AC_MSG_CHECKING([the maximum length of command line arguments]) +AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl + i=0 + teststring="ABCD" + + case $build_os in + msdosdjgpp*) + # On DJGPP, this test can blow up pretty badly due to problems in libc + # (any single argument exceeding 2000 bytes causes a buffer overrun + # during glob expansion). Even if it were fixed, the result of this + # check would be larger than it should be. + lt_cv_sys_max_cmd_len=12288; # 12K is about right + ;; + + gnu*) + # Under GNU Hurd, this test is not required because there is + # no limit to the length of command line arguments. + # Libtool will interpret -1 as no limit whatsoever + lt_cv_sys_max_cmd_len=-1; + ;; + + cygwin* | mingw*) + # On Win9x/ME, this test blows up -- it succeeds, but takes + # about 5 minutes as the teststring grows exponentially. + # Worse, since 9x/ME are not pre-emptively multitasking, + # you end up with a "frozen" computer, even though with patience + # the test eventually succeeds (with a max line length of 256k). + # Instead, let's just punt: use the minimum linelength reported by + # all of the supported platforms: 8192 (on NT/2K/XP). + lt_cv_sys_max_cmd_len=8192; + ;; + + amigaos*) + # On AmigaOS with pdksh, this test takes hours, literally. + # So we just punt and use a minimum line length of 8192. + lt_cv_sys_max_cmd_len=8192; + ;; + + netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) + # This has been around since 386BSD, at least. Likely further. + if test -x /sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` + elif test -x /usr/sbin/sysctl; then + lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` + else + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs + fi + # And add a safety zone + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + + osf*) + # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure + # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not + # nice to cause kernel panics so lets avoid the loop below. + # First set a reasonable default. + lt_cv_sys_max_cmd_len=16384 + # + if test -x /sbin/sysconfig; then + case `/sbin/sysconfig -q proc exec_disable_arg_limit` in + *1*) lt_cv_sys_max_cmd_len=-1 ;; + esac + fi + ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; + *) + # If test is not a shell built-in, we'll probably end up computing a + # maximum length that is only half of the actual maximum length, but + # we can't tell. + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + = "XX$teststring") >/dev/null 2>&1 && + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + ;; + esac +]) +if test -n $lt_cv_sys_max_cmd_len ; then + AC_MSG_RESULT($lt_cv_sys_max_cmd_len) +else + AC_MSG_RESULT(none) +fi +])# AC_LIBTOOL_SYS_MAX_CMD_LEN + + +# _LT_AC_CHECK_DLFCN +# ------------------ +AC_DEFUN([_LT_AC_CHECK_DLFCN], +[AC_CHECK_HEADERS(dlfcn.h)dnl +])# _LT_AC_CHECK_DLFCN + + +# _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, +# ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) +# --------------------------------------------------------------------- +AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "$cross_compiling" = yes; then : + [$4] +else + lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 + lt_status=$lt_dlunknown + cat > conftest.$ac_ext < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LT_DLGLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LT_DLGLOBAL DL_GLOBAL +# else +# define LT_DLGLOBAL 0 +# endif +#endif + +/* We may have to define LT_DLLAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LT_DLLAZY_OR_NOW +# ifdef RTLD_LAZY +# define LT_DLLAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LT_DLLAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LT_DLLAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LT_DLLAZY_OR_NOW DL_NOW +# else +# define LT_DLLAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +#ifdef __cplusplus +extern "C" void exit (int); +#endif + +void fnord() { int i=42;} +int main () +{ + void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); + int status = $lt_dlunknown; + + if (self) + { + if (dlsym (self,"fnord")) status = $lt_dlno_uscore; + else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; + /* dlclose (self); */ + } + else + puts (dlerror ()); + + exit (status); +}] +EOF + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null + lt_status=$? + case x$lt_status in + x$lt_dlno_uscore) $1 ;; + x$lt_dlneed_uscore) $2 ;; + x$lt_dlunknown|x*) $3 ;; + esac + else : + # compilation failed + $3 + fi +fi +rm -fr conftest* +])# _LT_AC_TRY_DLOPEN_SELF + + +# AC_LIBTOOL_DLOPEN_SELF +# ---------------------- +AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], +[AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else + lt_cv_dlopen=no + lt_cv_dlopen_libs= + + case $host_os in + beos*) + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + + mingw* | pw32*) + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + + cygwin*) + lt_cv_dlopen="dlopen" + lt_cv_dlopen_libs= + ;; + + darwin*) + # if libdl is installed we need to link against it + AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ + lt_cv_dlopen="dyld" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ]) + ;; + + *) + AC_CHECK_FUNC([shl_load], + [lt_cv_dlopen="shl_load"], + [AC_CHECK_LIB([dld], [shl_load], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [AC_CHECK_FUNC([dlopen], + [lt_cv_dlopen="dlopen"], + [AC_CHECK_LIB([dl], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], + [AC_CHECK_LIB([svld], [dlopen], + [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], + [AC_CHECK_LIB([dld], [dld_link], + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + ]) + ]) + ]) + ]) + ]) + ;; + esac + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + else + enable_dlopen=no + fi + + case $lt_cv_dlopen in + dlopen) + save_CPPFLAGS="$CPPFLAGS" + test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + + save_LDFLAGS="$LDFLAGS" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + + save_LIBS="$LIBS" + LIBS="$lt_cv_dlopen_libs $LIBS" + + AC_CACHE_CHECK([whether a program can dlopen itself], + lt_cv_dlopen_self, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, + lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) + ]) + + if test "x$lt_cv_dlopen_self" = xyes; then + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" + AC_CACHE_CHECK([whether a statically linked program can dlopen itself], + lt_cv_dlopen_self_static, [dnl + _LT_AC_TRY_DLOPEN_SELF( + lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, + lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) + ]) + fi + + CPPFLAGS="$save_CPPFLAGS" + LDFLAGS="$save_LDFLAGS" + LIBS="$save_LIBS" + ;; + esac + + case $lt_cv_dlopen_self in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case $lt_cv_dlopen_self_static in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi +])# AC_LIBTOOL_DLOPEN_SELF + + +# AC_LIBTOOL_PROG_CC_C_O([TAGNAME]) +# --------------------------------- +# Check to see if options -c and -o are simultaneously supported by compiler +AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], + [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no + $rm -r conftest 2>/dev/null + mkdir conftest + cd conftest + mkdir out + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + lt_compiler_flag="-o out/conftest2.$ac_objext" + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) + (eval "$lt_compile" 2>out/conftest.err) + ac_status=$? + cat out/conftest.err >&AS_MESSAGE_LOG_FD + echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD + if (exit $ac_status) && test -s out/conftest2.$ac_objext + then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then + _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes + fi + fi + chmod u+w . 2>&AS_MESSAGE_LOG_FD + $rm conftest* + # SGI C++ compiler will create directory out/ii_files/ for + # template instantiation + test -d out/ii_files && $rm out/ii_files/* && rmdir out/ii_files + $rm out/* && rmdir out + cd .. + rmdir conftest + $rm conftest* +]) +])# AC_LIBTOOL_PROG_CC_C_O + + +# AC_LIBTOOL_SYS_HARD_LINK_LOCKS([TAGNAME]) +# ----------------------------------------- +# Check to see if we can do hard links to lock some files if needed +AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], +[AC_REQUIRE([_LT_AC_LOCK])dnl + +hard_links="nottested" +if test "$_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + AC_MSG_CHECKING([if we can lock with hard links]) + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + AC_MSG_RESULT([$hard_links]) + if test "$hard_links" = no; then + AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) + need_locks=warn + fi +else + need_locks=no +fi +])# AC_LIBTOOL_SYS_HARD_LINK_LOCKS + + +# AC_LIBTOOL_OBJDIR +# ----------------- +AC_DEFUN([AC_LIBTOOL_OBJDIR], +[AC_CACHE_CHECK([for objdir], [lt_cv_objdir], +[rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + lt_cv_objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + lt_cv_objdir=_libs +fi +rmdir .libs 2>/dev/null]) +objdir=$lt_cv_objdir +])# AC_LIBTOOL_OBJDIR + + +# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH([TAGNAME]) +# ---------------------------------------------- +# Check hardcoding attributes. +AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], +[AC_MSG_CHECKING([how to hardcode library paths into programs]) +_LT_AC_TAGVAR(hardcode_action, $1)= +if test -n "$_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)" || \ + test -n "$_LT_AC_TAGVAR(runpath_var, $1)" || \ + test "X$_LT_AC_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then + + # We can hardcode non-existant directories. + if test "$_LT_AC_TAGVAR(hardcode_direct, $1)" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)" != no && + test "$_LT_AC_TAGVAR(hardcode_minus_L, $1)" != no; then + # Linking always hardcodes the temporary library directory. + _LT_AC_TAGVAR(hardcode_action, $1)=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + _LT_AC_TAGVAR(hardcode_action, $1)=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + _LT_AC_TAGVAR(hardcode_action, $1)=unsupported +fi +AC_MSG_RESULT([$_LT_AC_TAGVAR(hardcode_action, $1)]) + +if test "$_LT_AC_TAGVAR(hardcode_action, $1)" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi +])# AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH + + +# AC_LIBTOOL_SYS_LIB_STRIP +# ------------------------ +AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP], +[striplib= +old_striplib= +AC_MSG_CHECKING([whether stripping libraries is possible]) +if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then + test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" + test -z "$striplib" && striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) +else +# FIXME - insert some real tests, host_os isn't really good enough + case $host_os in + darwin*) + if test -n "$STRIP" ; then + striplib="$STRIP -x" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) +fi + ;; + *) + AC_MSG_RESULT([no]) + ;; + esac +fi +])# AC_LIBTOOL_SYS_LIB_STRIP + + +# AC_LIBTOOL_SYS_DYNAMIC_LINKER +# ----------------------------- +# PORTME Fill in your ld.so characteristics +AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], +[AC_MSG_CHECKING([dynamic linker characteristics]) +library_names_spec= +libname_spec='lib$name' +soname_spec= +shrext_cmds=".so" +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + # if the path contains ";" then we assume it to be the separator + # otherwise default to the standard path separator (i.e. ":") - it is + # assumed that no part of a normal pathname contains ";" but that should + # okay in the real world where ";" in dirpaths is itself problematic. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi +else + sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +fi +need_lib_prefix=unknown +hardcode_into_libs=no + +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +need_version=unknown + +case $host_os in +aix3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX 3 has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}${shared_ext}$major' + ;; + +aix4* | aix5*) + version_type=linux + need_lib_prefix=no + need_version=no + hardcode_into_libs=yes + if test "$host_cpu" = ia64; then + # AIX 5 supports IA64 + library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + else + # With GCC up to 2.95.x, collect2 would create an import file + # for dependence libraries. The import file would start with + # the line `#! .'. This would cause the generated library to + # depend on `.', always an invalid library. This was fixed in + # development snapshots of GCC prior to 3.0. + case $host_os in + aix4 | aix4.[[01]] | aix4.[[01]].*) + if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' + echo ' yes ' + echo '#endif'; } | ${CC} -E - | grep yes > /dev/null; then + : + else + can_build_shared=no + fi + ;; + esac + # AIX (on Power*) has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + if test "$aix_use_runtimelinking" = yes; then + # If using run time linking (on AIX 4.2 or later) use lib.so + # instead of lib.a to let people know that these are not + # typical AIX shared libraries. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + else + # We preserve .a as extension for shared libraries through AIX4.2 + # and later when we are not doing run time linking. + library_names_spec='${libname}${release}.a $libname.a' + soname_spec='${libname}${release}${shared_ext}$major' + fi + shlibpath_var=LIBPATH + fi + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}${shared_ext}' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + ;; + +bsdi[[45]]*) + version_type=linux + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw* | pw32*) + version_type=windows + shrext_cmds=".dll" + need_version=no + need_lib_prefix=no + + case $GCC,$host_os in + yes,cygwin* | yes,mingw* | yes,pw32*) + library_names_spec='$libname.dll.a' + # DLL is installed to $(libdir)/../bin by postinstall_cmds + postinstall_cmds='base_file=`basename \${file}`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' + postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ + dlpath=$dir/\$dldll~ + $rm \$dlpath' + shlibpath_overrides_runpath=yes + + case $host_os in + cygwin*) + # Cygwin DLLs use 'cyg' prefix rather than 'lib' + soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" + ;; + mingw*) + # MinGW DLLs use traditional 'lib' prefix + soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$sys_lib_search_path_spec" | [grep ';[c-zC-Z]:/' >/dev/null]; then + # It is most probably a Windows format PATH printed by + # mingw gcc, but we are running on Cygwin. Gcc prints its search + # path with ; separators, and with drive letters. We can handle the + # drive letters (cygwin fileutils understands them), so leave them, + # especially as we might pass files found there to a mingw objdump, + # which wouldn't understand a cygwinified path. Ahh. + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + else + sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + fi + ;; + pw32*) + # pw32 DLLs use 'pw' prefix rather than 'lib' + library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' + ;; + esac + ;; + + *) + library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' + ;; + esac + dynamic_linker='Win32 ld.exe' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + ;; + +darwin* | rhapsody*) + dynamic_linker="$host_os dyld" + version_type=darwin + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${versuffix}$shared_ext ${libname}${release}${major}$shared_ext ${libname}$shared_ext' + soname_spec='${libname}${release}${major}$shared_ext' + shlibpath_overrides_runpath=yes + shlibpath_var=DYLD_LIBRARY_PATH + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. + if test "$GCC" = yes; then + sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` + else + sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' + fi + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd* | dragonfly*) + # DragonFly does not have aout. When/if they implement a new + # versioning mechanism, adjust this. + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi + version_type=freebsd-$objformat + case $version_type in + freebsd-elf*) + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' + need_version=yes + ;; + esac + shlibpath_var=LD_LIBRARY_PATH + case $host_os in + freebsd2*) + shlibpath_overrides_runpath=yes + ;; + freebsd3.[[01]]* | freebsdelf3.[[01]]*) + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + freebsd*) # from 4.6 on + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + version_type=sunos + need_lib_prefix=no + need_version=no + case $host_cpu in + ia64*) + shrext_cmds='.so' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.so" + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + if test "X$HPUX_IA64_MODE" = X32; then + sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" + else + sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" + fi + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + hppa*64*) + shrext_cmds='.sl' + hardcode_into_libs=yes + dynamic_linker="$host_os dld.sl" + shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH + shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" + sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec + ;; + *) + shrext_cmds='.sl' + dynamic_linker="$host_os dld.sl" + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + ;; + esac + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +interix3*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + +irix5* | irix6* | nonstopux*) + case $host_os in + nonstopux*) version_type=nonstopux ;; + *) + if test "$lt_cv_prog_gnu_ld" = yes; then + version_type=linux + else + version_type=irix + fi ;; + esac + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' + case $host_os in + irix5* | nonstopux*) + libsuff= shlibsuff= + ;; + *) + case $LD in # libtool.m4 will add one of these switches to LD + *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") + libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") + libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") + libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + hardcode_into_libs=yes + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux*oldld* | linux*aout* | linux*coff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + # This implies no fast_install, which is unacceptable. + # Some rework will be needed to allow for fast_install + # before this can be enabled. + hardcode_into_libs=yes + + # Append ld.so.conf contents to the search path + if test -f /etc/ld.so.conf; then + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" + fi + + # We used to test for /lib/ld.so.1 and disable shared libraries on + # powerpc, because MkLinux only supported shared libraries with the + # GNU dynamic linker. Since this was broken with cross compilers, + # most powerpc-linux boxes support dynamic linking these days and + # people can always --disable-shared, the test was removed, and we + # assume the GNU/Linux dynamic linker is in use. + dynamic_linker='GNU/Linux ld.so' + ;; + +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + +netbsd*) + version_type=sunos + need_lib_prefix=no + need_version=no + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; + +newsos6) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +nto-qnx*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + ;; + +openbsd*) + version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" + need_lib_prefix=no + # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. + case $host_os in + openbsd3.3 | openbsd3.3.*) need_version=yes ;; + *) need_version=no ;; + esac + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + case $host_os in + openbsd2.[[89]] | openbsd2.[[89]].*) + shlibpath_overrides_runpath=no + ;; + *) + shlibpath_overrides_runpath=yes + ;; + esac + else + shlibpath_overrides_runpath=yes + fi + ;; + +os2*) + libname_spec='$name' + shrext_cmds=".dll" + need_lib_prefix=no + library_names_spec='$libname${shared_ext} $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4* | osf5*) + version_type=osf + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}${shared_ext}$major' + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + shlibpath_var=LD_LIBRARY_PATH + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.3*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + case $host_vendor in + sni) + shlibpath_overrides_runpath=no + need_lib_prefix=no + export_dynamic_flag_spec='${wl}-Blargedynsym' + runpath_var=LD_RUN_PATH + ;; + siemens) + need_lib_prefix=no + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + ;; + esac + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' + soname_spec='$libname${shared_ext}.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +*) + dynamic_linker=no + ;; +esac +AC_MSG_RESULT([$dynamic_linker]) +test "$dynamic_linker" = no && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi +])# AC_LIBTOOL_SYS_DYNAMIC_LINKER + + +# _LT_AC_TAGCONFIG +# ---------------- +AC_DEFUN([_LT_AC_TAGCONFIG], +[AC_ARG_WITH([tags], + [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], + [include additional configurations @<:@automatic@:>@])], + [tagnames="$withval"]) + +if test -f "$ltmain" && test -n "$tagnames"; then + if test ! -f "${ofile}"; then + AC_MSG_WARN([output file `$ofile' does not exist]) + fi + + if test -z "$LTCC"; then + eval "`$SHELL ${ofile} --config | grep '^LTCC='`" + if test -z "$LTCC"; then + AC_MSG_WARN([output file `$ofile' does not look like a libtool script]) + else + AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) + fi + fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi + + # Extract list of available tagged configurations in $ofile. + # Note that this assumes the entire list is on one line. + available_tags=`grep "^available_tags=" "${ofile}" | $SED -e 's/available_tags=\(.*$\)/\1/' -e 's/\"//g'` + + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for tagname in $tagnames; do + IFS="$lt_save_ifs" + # Check whether tagname contains only valid characters + case `$echo "X$tagname" | $Xsed -e 's:[[-_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890,/]]::g'` in + "") ;; + *) AC_MSG_ERROR([invalid tag name: $tagname]) + ;; + esac + + if grep "^# ### BEGIN LIBTOOL TAG CONFIG: $tagname$" < "${ofile}" > /dev/null + then + AC_MSG_ERROR([tag name \"$tagname\" already exists]) + fi + + # Update the list of available tags. + if test -n "$tagname"; then + echo appending configuration tag \"$tagname\" to $ofile + + case $tagname in + CXX) + if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_LIBTOOL_LANG_CXX_CONFIG + else + tagname="" + fi + ;; + + F77) + if test -n "$F77" && test "X$F77" != "Xno"; then + AC_LIBTOOL_LANG_F77_CONFIG + else + tagname="" + fi + ;; + + GCJ) + if test -n "$GCJ" && test "X$GCJ" != "Xno"; then + AC_LIBTOOL_LANG_GCJ_CONFIG + else + tagname="" + fi + ;; + + RC) + AC_LIBTOOL_LANG_RC_CONFIG + ;; + + *) + AC_MSG_ERROR([Unsupported tag name: $tagname]) + ;; + esac + + # Append the new tag name to the list of available tags. + if test -n "$tagname" ; then + available_tags="$available_tags $tagname" + fi + fi + done + IFS="$lt_save_ifs" + + # Now substitute the updated list of available tags. + if eval "sed -e 's/^available_tags=.*\$/available_tags=\"$available_tags\"/' \"$ofile\" > \"${ofile}T\""; then + mv "${ofile}T" "$ofile" + chmod +x "$ofile" + else + rm -f "${ofile}T" + AC_MSG_ERROR([unable to update list of available tagged configurations.]) + fi +fi +])# _LT_AC_TAGCONFIG + + +# AC_LIBTOOL_DLOPEN +# ----------------- +# enable checks for dlopen support +AC_DEFUN([AC_LIBTOOL_DLOPEN], + [AC_BEFORE([$0],[AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_DLOPEN + + +# AC_LIBTOOL_WIN32_DLL +# -------------------- +# declare package support for building win32 DLLs +AC_DEFUN([AC_LIBTOOL_WIN32_DLL], +[AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) +])# AC_LIBTOOL_WIN32_DLL + + +# AC_ENABLE_SHARED([DEFAULT]) +# --------------------------- +# implement the --enable-shared flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_SHARED], +[define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([shared], + [AC_HELP_STRING([--enable-shared@<:@=PKGS@:>@], + [build shared libraries @<:@default=]AC_ENABLE_SHARED_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_shared=yes ;; + no) enable_shared=no ;; + *) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_shared=]AC_ENABLE_SHARED_DEFAULT) +])# AC_ENABLE_SHARED + + +# AC_DISABLE_SHARED +# ----------------- +# set the default shared flag to --disable-shared +AC_DEFUN([AC_DISABLE_SHARED], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no) +])# AC_DISABLE_SHARED + + +# AC_ENABLE_STATIC([DEFAULT]) +# --------------------------- +# implement the --enable-static flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_STATIC], +[define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([static], + [AC_HELP_STRING([--enable-static@<:@=PKGS@:>@], + [build static libraries @<:@default=]AC_ENABLE_STATIC_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_static=yes ;; + no) enable_static=no ;; + *) + enable_static=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_static=]AC_ENABLE_STATIC_DEFAULT) +])# AC_ENABLE_STATIC + + +# AC_DISABLE_STATIC +# ----------------- +# set the default static flag to --disable-static +AC_DEFUN([AC_DISABLE_STATIC], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no) +])# AC_DISABLE_STATIC + + +# AC_ENABLE_FAST_INSTALL([DEFAULT]) +# --------------------------------- +# implement the --enable-fast-install flag +# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. +AC_DEFUN([AC_ENABLE_FAST_INSTALL], +[define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE([fast-install], + [AC_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], + [optimize for fast installation @<:@default=]AC_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], + [p=${PACKAGE-default} + case $enableval in + yes) enable_fast_install=yes ;; + no) enable_fast_install=no ;; + *) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," + for pkg in $enableval; do + IFS="$lt_save_ifs" + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$lt_save_ifs" + ;; + esac], + [enable_fast_install=]AC_ENABLE_FAST_INSTALL_DEFAULT) +])# AC_ENABLE_FAST_INSTALL + + +# AC_DISABLE_FAST_INSTALL +# ----------------------- +# set the default to --disable-fast-install +AC_DEFUN([AC_DISABLE_FAST_INSTALL], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no) +])# AC_DISABLE_FAST_INSTALL + + +# AC_LIBTOOL_PICMODE([MODE]) +# -------------------------- +# implement the --with-pic flag +# MODE is either `yes' or `no'. If omitted, it defaults to `both'. +AC_DEFUN([AC_LIBTOOL_PICMODE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +pic_mode=ifelse($#,1,$1,default) +])# AC_LIBTOOL_PICMODE + + +# AC_PROG_EGREP +# ------------- +# This is predefined starting with Autoconf 2.54, so this conditional +# definition can be removed once we require Autoconf 2.54 or later. +m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], +[AC_CACHE_CHECK([for egrep], [ac_cv_prog_egrep], + [if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi]) + EGREP=$ac_cv_prog_egrep + AC_SUBST([EGREP]) +])]) + + +# AC_PATH_TOOL_PREFIX +# ------------------- +# find a file program which can recognise shared library +AC_DEFUN([AC_PATH_TOOL_PREFIX], +[AC_REQUIRE([AC_PROG_EGREP])dnl +AC_MSG_CHECKING([for $1]) +AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, +[case $MAGIC_CMD in +[[\\/*] | ?:[\\/]*]) + lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. + ;; +*) + lt_save_MAGIC_CMD="$MAGIC_CMD" + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR +dnl $ac_dummy forces splitting on constant user-supplied paths. +dnl POSIX.2 word splitting is done only on the output of word expansions, +dnl not every word. This closes a longstanding sh security hole. + ac_dummy="ifelse([$2], , $PATH, [$2])" + for ac_dir in $ac_dummy; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$1; then + lt_cv_path_MAGIC_CMD="$ac_dir/$1" + if test -n "$file_magic_test_file"; then + case $deplibs_check_method in + "file_magic "*) + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` + MAGIC_CMD="$lt_cv_path_MAGIC_CMD" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + $EGREP "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac + fi + break + fi + done + IFS="$lt_save_ifs" + MAGIC_CMD="$lt_save_MAGIC_CMD" + ;; +esac]) +MAGIC_CMD="$lt_cv_path_MAGIC_CMD" +if test -n "$MAGIC_CMD"; then + AC_MSG_RESULT($MAGIC_CMD) +else + AC_MSG_RESULT(no) +fi +])# AC_PATH_TOOL_PREFIX + + +# AC_PATH_MAGIC +# ------------- +# find a file program which can recognise a shared library +AC_DEFUN([AC_PATH_MAGIC], +[AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) +if test -z "$lt_cv_path_MAGIC_CMD"; then + if test -n "$ac_tool_prefix"; then + AC_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) + else + MAGIC_CMD=: + fi +fi +])# AC_PATH_MAGIC + + +# AC_PROG_LD +# ---------- +# find the pathname to the GNU or non-GNU linker +AC_DEFUN([AC_PROG_LD], +[AC_ARG_WITH([gnu-ld], + [AC_HELP_STRING([--with-gnu-ld], + [assume the C compiler uses GNU ld @<:@default=no@:>@])], + [test "$withval" = no || with_gnu_ld=yes], + [with_gnu_ld=no]) +AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$GCC" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by $CC]) + case $host in + *-*-mingw*) + # gcc leaves a trailing carriage return which upsets mingw + ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; + *) + ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; + esac + case $ac_prog in + # Accept absolute paths. + [[\\/]]* | ?:[[\\/]]*) + re_direlt='/[[^/]][[^/]]*/\.\./' + # Canonicalize the pathname of ld + ac_prog=`echo $ac_prog| $SED 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| $SED "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(lt_cv_path_LD, +[if test -z "$LD"; then + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + lt_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some variants of GNU ld only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null; then + case $host_cpu in + i*86 ) + # Not sure whether the presence of OpenBSD here was a mistake. + # Let's accept both of them until this is cleared up. + lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` + ;; + esac + else + lt_cv_deplibs_check_method=pass_all + fi + ;; + +gnu*) + lt_cv_deplibs_check_method=pass_all + ;; + +hpux10.20* | hpux11*) + lt_cv_file_magic_cmd=/usr/bin/file + case $host_cpu in + ia64*) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' + lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so + ;; + hppa*64*) + [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] + lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl + ;; + *) + lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' + lt_cv_file_magic_test_file=/usr/lib/libc.sl + ;; + esac + ;; + +interix3*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + +irix5* | irix6* | nonstopux*) + case $LD in + *-32|*"-32 ") libmagic=32-bit;; + *-n32|*"-n32 ") libmagic=N32;; + *-64|*"-64 ") libmagic=64-bit;; + *) libmagic=never-match;; + esac + lt_cv_deplibs_check_method=pass_all + ;; + +# This must be Linux ELF. +linux* | k*bsd*-gnu) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' + fi + ;; + +newos6*) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' + lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_test_file=/usr/lib/libnls.so + ;; + +nto-qnx*) + lt_cv_deplibs_check_method=unknown + ;; + +openbsd*) + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' + else + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' + fi + ;; + +osf3* | osf4* | osf5*) + lt_cv_deplibs_check_method=pass_all + ;; + +solaris*) + lt_cv_deplibs_check_method=pass_all + ;; + +sysv4 | sysv4.3*) + case $host_vendor in + motorola) + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' + lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + ncr) + lt_cv_deplibs_check_method=pass_all + ;; + sequent) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' + ;; + sni) + lt_cv_file_magic_cmd='/bin/file' + lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" + lt_cv_file_magic_test_file=/lib/libc.so + ;; + siemens) + lt_cv_deplibs_check_method=pass_all + ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; + esac + ;; + +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + lt_cv_deplibs_check_method=pass_all + ;; +esac +]) +file_magic_cmd=$lt_cv_file_magic_cmd +deplibs_check_method=$lt_cv_deplibs_check_method +test -z "$deplibs_check_method" && deplibs_check_method=unknown +])# AC_DEPLIBS_CHECK_METHOD + + +# AC_PROG_NM +# ---------- +# find the pathname to a BSD-compatible name lister +AC_DEFUN([AC_PROG_NM], +[AC_CACHE_CHECK([for BSD-compatible nm], lt_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + lt_cv_path_NM="$NM" +else + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" + break + ;; + *) + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac + ;; + esac + fi + done + IFS="$lt_save_ifs" + done + test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm +fi]) +NM="$lt_cv_path_NM" +])# AC_PROG_NM + + +# AC_CHECK_LIBM +# ------------- +# check for math library +AC_DEFUN([AC_CHECK_LIBM], +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case $host in +*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) + # These system don't have libm, or don't need it + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, cos, LIBM="-lm") + ;; +esac +])# AC_CHECK_LIBM + + +# AC_LIBLTDL_CONVENIENCE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl convenience library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. +AC_DEFUN([AC_LIBLTDL_CONVENIENCE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case $enable_ltdl_convenience in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_CONVENIENCE + + +# AC_LIBLTDL_INSTALLABLE([DIRECTORY]) +# ----------------------------------- +# sets LIBLTDL to the link flags for the libltdl installable library and +# LTDLINCL to the include flags for the libltdl header and adds +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN([AC_LIBLTDL_INSTALLABLE], +[AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, lt_dlinit, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + LTDLINCL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + LTDLINCL= + fi + # For backwards non-gettext consistent compatibility... + INCLTDL="$LTDLINCL" +])# AC_LIBLTDL_INSTALLABLE + + +# AC_LIBTOOL_CXX +# -------------- +# enable support for C++ libraries +AC_DEFUN([AC_LIBTOOL_CXX], +[AC_REQUIRE([_LT_AC_LANG_CXX]) +])# AC_LIBTOOL_CXX + + +# _LT_AC_LANG_CXX +# --------------- +AC_DEFUN([_LT_AC_LANG_CXX], +[AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) +])# _LT_AC_LANG_CXX + +# _LT_AC_PROG_CXXCPP +# ------------------ +AC_DEFUN([_LT_AC_PROG_CXXCPP], +[ +AC_REQUIRE([AC_PROG_CXX]) +if test -n "$CXX" && ( test "X$CXX" != "Xno" && + ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || + (test "X$CXX" != "Xg++"))) ; then + AC_PROG_CXXCPP +fi +])# _LT_AC_PROG_CXXCPP + +# AC_LIBTOOL_F77 +# -------------- +# enable support for Fortran 77 libraries +AC_DEFUN([AC_LIBTOOL_F77], +[AC_REQUIRE([_LT_AC_LANG_F77]) +])# AC_LIBTOOL_F77 + + +# _LT_AC_LANG_F77 +# --------------- +AC_DEFUN([_LT_AC_LANG_F77], +[AC_REQUIRE([AC_PROG_F77]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}F77]) +])# _LT_AC_LANG_F77 + + +# AC_LIBTOOL_GCJ +# -------------- +# enable support for GCJ libraries +AC_DEFUN([AC_LIBTOOL_GCJ], +[AC_REQUIRE([_LT_AC_LANG_GCJ]) +])# AC_LIBTOOL_GCJ + + +# _LT_AC_LANG_GCJ +# --------------- +AC_DEFUN([_LT_AC_LANG_GCJ], +[AC_PROVIDE_IFELSE([AC_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([A][M_PROG_GCJ],[], + [AC_PROVIDE_IFELSE([LT_AC_PROG_GCJ],[], + [ifdef([AC_PROG_GCJ],[AC_REQUIRE([AC_PROG_GCJ])], + [ifdef([A][M_PROG_GCJ],[AC_REQUIRE([A][M_PROG_GCJ])], + [AC_REQUIRE([A][C_PROG_GCJ_OR_A][M_PROG_GCJ])])])])])]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) +])# _LT_AC_LANG_GCJ + + +# AC_LIBTOOL_RC +# ------------- +# enable support for Windows resource files +AC_DEFUN([AC_LIBTOOL_RC], +[AC_REQUIRE([LT_AC_PROG_RC]) +_LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}RC]) +])# AC_LIBTOOL_RC + + +# AC_LIBTOOL_LANG_C_CONFIG +# ------------------------ +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG], [_LT_AC_LANG_C_CONFIG]) +AC_DEFUN([_LT_AC_LANG_C_CONFIG], +[lt_save_CC="$CC" +AC_LANG_PUSH(C) + +# Source file extension for C test sources. +ac_ext=c + +# Object file extension for compiled C test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(){return(0);}\n' + +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) +AC_LIBTOOL_SYS_LIB_STRIP +AC_LIBTOOL_DLOPEN_SELF + +# Report which library types will actually be built +AC_MSG_CHECKING([if libtool supports shared libraries]) +AC_MSG_RESULT([$can_build_shared]) + +AC_MSG_CHECKING([whether to build shared libraries]) +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case $host_os in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4* | aix5*) + if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then + test "$enable_shared" = yes && enable_static=no + fi + ;; +esac +AC_MSG_RESULT([$enable_shared]) + +AC_MSG_CHECKING([whether to build static libraries]) +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes +AC_MSG_RESULT([$enable_static]) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC="$lt_save_CC" +])# AC_LIBTOOL_LANG_C_CONFIG + + +# AC_LIBTOOL_LANG_CXX_CONFIG +# -------------------------- +# Ensure that the configuration vars for the C compiler are +# suitably defined. Those variables are subsequently used by +# AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. +AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG], [_LT_AC_LANG_CXX_CONFIG(CXX)]) +AC_DEFUN([_LT_AC_LANG_CXX_CONFIG], +[AC_LANG_PUSH(C++) +AC_REQUIRE([AC_PROG_CXX]) +AC_REQUIRE([_LT_AC_PROG_CXXCPP]) + +_LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no +_LT_AC_TAGVAR(allow_undefined_flag, $1)= +_LT_AC_TAGVAR(always_export_symbols, $1)=no +_LT_AC_TAGVAR(archive_expsym_cmds, $1)= +_LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_direct, $1)=no +_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= +_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= +_LT_AC_TAGVAR(hardcode_libdir_separator, $1)= +_LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported +_LT_AC_TAGVAR(hardcode_automatic, $1)=no +_LT_AC_TAGVAR(module_cmds, $1)= +_LT_AC_TAGVAR(module_expsym_cmds, $1)= +_LT_AC_TAGVAR(link_all_deplibs, $1)=unknown +_LT_AC_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds +_LT_AC_TAGVAR(no_undefined_flag, $1)= +_LT_AC_TAGVAR(whole_archive_flag_spec, $1)= +_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + +# Dependencies to place before and after the object being linked: +_LT_AC_TAGVAR(predep_objects, $1)= +_LT_AC_TAGVAR(postdep_objects, $1)= +_LT_AC_TAGVAR(predeps, $1)= +_LT_AC_TAGVAR(postdeps, $1)= +_LT_AC_TAGVAR(compiler_lib_search_path, $1)= + +# Source file extension for C++ test sources. +ac_ext=cpp + +# Object file extension for compiled C++ test sources. +objext=o +_LT_AC_TAGVAR(objext, $1)=$objext + +# Code to be used in simple compile tests +lt_simple_compile_test_code="int some_variable = 0;\n" + +# Code to be used in simple link tests +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }\n' + +# ltmain only uses $CC for tagged configurations so make sure $CC is set. +_LT_AC_SYS_COMPILER + +# save warnings/boilerplate of simple test code +_LT_COMPILER_BOILERPLATE +_LT_LINKER_BOILERPLATE + +# Allow CC to be a program name with arguments. +lt_save_CC=$CC +lt_save_LD=$LD +lt_save_GCC=$GCC +GCC=$GXX +lt_save_with_gnu_ld=$with_gnu_ld +lt_save_path_LD=$lt_cv_path_LD +if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then + lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx +else + $as_unset lt_cv_prog_gnu_ld +fi +if test -n "${lt_cv_path_LDCXX+set}"; then + lt_cv_path_LD=$lt_cv_path_LDCXX +else + $as_unset lt_cv_path_LD +fi +test -z "${LDCXX+set}" || LD=$LDCXX +CC=${CXX-"c++"} +compiler=$CC +_LT_AC_TAGVAR(compiler, $1)=$CC +_LT_CC_BASENAME([$compiler]) + +# We don't want -fno-exception wen compiling C++ code, so set the +# no_builtin_flag separately +if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' +else + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= +fi + +if test "$GXX" = yes; then + # Set up default GNU C++ configuration + + AC_PROG_LD + + # Check if GNU C++ uses GNU ld as the underlying linker, since the + # archiving commands below assume that GNU ld is being used. + if test "$with_gnu_ld" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # If archive_cmds runs LD, not CC, wlarc should be empty + # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to + # investigate it a little bit more. (MM) + wlarc='${wl}' + + # ancient GNU ld didn't support --whole-archive et. al. + if eval "`$CC -print-prog-name=ld` --help 2>&1" | \ + grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + with_gnu_ld=no + wlarc= + + # A generic and very simple default shared library creation + # command for GNU C++ for the case where it uses the native + # linker, instead of GNU ld. If possible, this setting should + # overridden to take advantage of the native linker features on + # the platform it is being used on. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + fi + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + +else + GXX=no + with_gnu_ld=no + wlarc= +fi + +# PORTME: fill in a description of your system's C++ link characteristics +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +_LT_AC_TAGVAR(ld_shlibs, $1)=yes +case $host_os in + aix3*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + case $ld_flag in + *-brtl*) + aix_use_runtimelinking=yes + break + ;; + esac + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + chorus*) + case $cc_basename in + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GXX" = yes ; then + lt_int_apple_cc_single_mod=no + output_verbose_link_cmd='echo' + if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then + lt_int_apple_cc_single_mod=yes + fi + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + fi + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + if test "X$lt_int_apple_cc_single_mod" = Xyes ; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + fi + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + case $cc_basename in + ec++*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + ghcx*) + # Green Hills C++ Compiler + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + freebsd[[12]]*) + # C++ shared libraries reported to be fairly broken before switch to ELF + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + freebsd-elf*) + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + ;; + freebsd* | dragonfly*) + # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF + # conventions + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + ;; + gnu*) + ;; + hpux9*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "[[-]]L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + hpux10*|hpux11*) + if test $with_gnu_ld = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + ;; + *) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + esac + fi + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, + # but as the default + # location of the library. + ;; + esac + + case $cc_basename in + CC*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + aCC*) + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | grep "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes; then + if test $with_gnu_ld = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + esac + fi + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + irix5* | irix6*) + case $cc_basename in + CC*) + # SGI C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + # Archives containing C++ object files must be created using + # "CC -ar", where "CC" is the IRIX C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' + ;; + *) + if test "$GXX" = yes; then + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` -o $lib' + fi + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + esac + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | grep "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + ;; + icpc*) + # Intel C++ + with_gnu_ld=yes + # version 8.0 and above of icpc choke on multiply defined symbols + # if we add $predep_objects and $postdep_objects, however 7.1 and + # earlier do not add the objects themselves. + case `$CC -V 2>&1` in + *"Version 7."*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + *) # Version 8.0 or newer + tmp_idyn= + case $host_cpu in + ia64*) tmp_idyn=' -i_dynamic';; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' + ;; + pgCC*) + # Portland Group C++ compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + ;; + cxx*) + # Compaq C++ + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' + + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + esac + ;; + lynxos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + m88k*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + mvs*) + case $cc_basename in + cxx*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + fi + # Workaround some broken pre-1.5 toolchains + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' + ;; + openbsd2*) + # C++ shared libraries are fairly broken + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + ;; + osf3*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # "CC -Bstatic", where "CC" is the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' + + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && echo ${wl}-set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + osf4* | osf5*) + case $cc_basename in + KCC*) + # Kuck and Associates, Inc. (KAI) C++ Compiler + + # KCC will only create a shared library if the output file + # ends with ".so" (or ".sl" for HP-UX), so rename the library + # to its proper name (with version) after linking. + _LT_AC_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Archives containing C++ object files must be created using + # the KAI C++ compiler. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' + ;; + RCC*) + # Rational C++ 2.4.1 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + cxx*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ + echo "-hidden">> $lib.exp~ + $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname -Wl,-input -Wl,$lib.exp `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~ + $rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + # + # There doesn't appear to be a way to prevent this compiler from + # explicitly linking system object files so we need to strip them + # from the output so that they don't get included in the library + # dependencies. + output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld" | grep -v "ld:"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + ;; + *) + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "\-L"' + + else + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + psos*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + lcc*) + # Lucid + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The C++ compiler is used as linker so we must use $wl + # flag to pass the commands to the underlying system + # linker. We must also pass each convience library through + # to the system linker between allextract/defaultextract. + # The C++ compiler will combine linker options so we + # cannot just pass the convience library names through + # without $wl. + # Supported since Solaris 2.6 (maybe 2.5.1?) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + + # The C++ compiler must be used to create the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' + ;; + *) + # GNU C++ compiler with Solaris linker + if test "$GXX" = yes && test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' + if $CC --version | grep -v '^2\.7' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + else + # g++ 2.7 appears to require `-G' NOT `-shared' on this + # platform. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + + # Commands to make compiler produce verbose output that lists + # what "hidden" libraries, object files and flags are used when + # linking a shared library. + output_verbose_link_cmd="$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep \"\-L\"" + fi + + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + fi + ;; + esac + ;; + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + ;; + vxworks*) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + *) + # FIXME: insert proper C++ library support + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; +esac +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +_LT_AC_TAGVAR(GCC, $1)="$GXX" +_LT_AC_TAGVAR(LD, $1)="$LD" + +## CAVEAT EMPTOR: +## There is no encapsulation within the following macros, do not change +## the running order or otherwise move them around unless you know exactly +## what you are doing... +AC_LIBTOOL_POSTDEP_PREDEP($1) +AC_LIBTOOL_PROG_COMPILER_PIC($1) +AC_LIBTOOL_PROG_CC_C_O($1) +AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) +AC_LIBTOOL_PROG_LD_SHLIBS($1) +AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) +AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) + +AC_LIBTOOL_CONFIG($1) + +AC_LANG_POP +CC=$lt_save_CC +LDCXX=$LD +LD=$lt_save_LD +GCC=$lt_save_GCC +with_gnu_ldcxx=$with_gnu_ld +with_gnu_ld=$lt_save_with_gnu_ld +lt_cv_path_LDCXX=$lt_cv_path_LD +lt_cv_path_LD=$lt_save_path_LD +lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld +lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld +])# AC_LIBTOOL_LANG_CXX_CONFIG + +# AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) +# ------------------------------------ +# Figure out "hidden" library dependencies from verbose +# compiler output when linking a shared library. +# Parse the compiler output and extract the necessary +# objects, libraries and library flags. +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +dnl we can't use the lt_simple_compile_test_code here, +dnl because it contains code intended for an executable, +dnl not a library. It's possible we should let each +dnl tag define a new lt_????_link_test_code variable, +dnl but it's only used here... +ifelse([$1],[],[cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <> "$cfgfile" +ifelse([$1], [], +[#! $SHELL + +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltmain.sh. +# +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. +# +# This file is part of GNU Libtool: +# Originally by Gordon Matzigkeit , 1996 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A sed program that does not truncate output. +SED=$lt_SED + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="$SED -e 1s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +(unset CDPATH) >/dev/null 2>&1 && unset CDPATH + +# The names of the tagged configurations supported by this script. +available_tags= + +# ### BEGIN LIBTOOL CONFIG], +[# ### BEGIN LIBTOOL TAG CONFIG: $tagname]) + +# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: + +# Shell to use when invoking shell scripts. +SHELL=$lt_SHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to add -lc for building shared libraries. +build_libtool_need_lc=$_LT_AC_TAGVAR(archive_cmds_need_lc, $1) + +# Whether or not to disallow shared libs when runtime libs are static +allow_libtool_libs_with_static_runtimes=$_LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1) + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host +host_os=$host_os + +# The build system. +build_alias=$build_alias +build=$build +build_os=$build_os + +# An echo program that does not interpret backslashes. +echo=$lt_echo + +# The archiver. +AR=$lt_AR +AR_FLAGS=$lt_AR_FLAGS + +# A C compiler. +LTCC=$lt_LTCC + +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + +# A language-specific compiler. +CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) + +# Is the compiler the GNU C compiler? +with_gcc=$_LT_AC_TAGVAR(GCC, $1) + +# An ERE matcher. +EGREP=$lt_EGREP + +# The linker used to build libraries. +LD=$lt_[]_LT_AC_TAGVAR(LD, $1) + +# Whether we need hard or soft links. +LN_S=$lt_LN_S + +# A BSD-compatible nm program. +NM=$lt_NM + +# A symbol stripping program +STRIP=$lt_STRIP + +# Used to examine libraries when file_magic_cmd begins "file" +MAGIC_CMD=$MAGIC_CMD + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$lt_reload_flag +reload_cmds=$lt_reload_cmds + +# How to pass a linker flag through the compiler. +wl=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + +# Object file suffix (normally "o"). +objext="$ac_objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Shared library suffix (normally ".so"). +shrext_cmds='$shrext_cmds' + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) +pic_mode=$pic_mode + +# What is the maximum length of a command? +max_cmd_len=$lt_cv_sys_max_cmd_len + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$lt_[]_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) + +# Must we lock files when doing compilation? +need_locks=$lt_need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen_support=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_static, $1) + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$lt_[]_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$lt_[]_LT_AC_TAGVAR(export_dynamic_flag_spec, $1) + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$lt_[]_LT_AC_TAGVAR(whole_archive_flag_spec, $1) + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$lt_[]_LT_AC_TAGVAR(thread_safe_flag_spec, $1) + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$lt_libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$lt_library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$lt_soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$lt_RANLIB +old_archive_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_cmds, $1) +old_postinstall_cmds=$lt_old_postinstall_cmds +old_postuninstall_cmds=$lt_old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_new_cmds, $1) + +# Create a temporary old-style archive to link instead of a shared archive. +old_archive_from_expsyms_cmds=$lt_[]_LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1) + +# Commands used to build and install a shared archive. +archive_cmds=$lt_[]_LT_AC_TAGVAR(archive_cmds, $1) +archive_expsym_cmds=$lt_[]_LT_AC_TAGVAR(archive_expsym_cmds, $1) +postinstall_cmds=$lt_postinstall_cmds +postuninstall_cmds=$lt_postuninstall_cmds + +# Commands used to build a loadable module (assumed same as above if empty) +module_cmds=$lt_[]_LT_AC_TAGVAR(module_cmds, $1) +module_expsym_cmds=$lt_[]_LT_AC_TAGVAR(module_expsym_cmds, $1) + +# Commands to strip libraries. +old_striplib=$lt_old_striplib +striplib=$lt_striplib + +# Dependencies to place before the objects being linked to create a +# shared library. +predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1) + +# Dependencies to place before the objects being linked to create a +# shared library. +predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) + +# Dependencies to place after the objects being linked to create a +# shared library. +postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) + +# The library search path used internally by the compiler when linking +# a shared library. +compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$lt_deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$lt_file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$lt_[]_LT_AC_TAGVAR(allow_undefined_flag, $1) + +# Flag that forces no undefined symbols. +no_undefined_flag=$lt_[]_LT_AC_TAGVAR(no_undefined_flag, $1) + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$lt_finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$lt_finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl + +# Transform the output of nm in a C name address pair +global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$_LT_AC_TAGVAR(hardcode_action, $1) + +# Whether we should hardcode library paths into libraries. +hardcode_into_libs=$hardcode_into_libs + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) + +# If ld is used when linking, flag to hardcode \$libdir into +# a binary during linking. This must work even if \$libdir does +# not exist. +hardcode_libdir_flag_spec_ld=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1) + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$lt_[]_LT_AC_TAGVAR(hardcode_libdir_separator, $1) + +# Set to yes if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$_LT_AC_TAGVAR(hardcode_direct, $1) + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$_LT_AC_TAGVAR(hardcode_minus_L, $1) + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$_LT_AC_TAGVAR(hardcode_shlibpath_var, $1) + +# Set to yes if building a shared library automatically hardcodes DIR into the library +# and all subsequent libraries and executables linked against it. +hardcode_automatic=$_LT_AC_TAGVAR(hardcode_automatic, $1) + +# Variables whose values should be saved in libtool wrapper scripts and +# restored at relink time. +variables_saved_for_relink="$variables_saved_for_relink" + +# Whether libtool must link a program against all its dependency libraries. +link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1) + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$lt_sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" + +# Set to yes if exported symbols are required. +always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) + +# The commands to list exported symbols. +export_symbols_cmds=$lt_[]_LT_AC_TAGVAR(export_symbols_cmds, $1) + +# The commands to extract the exported symbol list from a shared archive. +extract_expsyms_cmds=$lt_extract_expsyms_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$lt_[]_LT_AC_TAGVAR(exclude_expsyms, $1) + +# Symbols that must always be exported. +include_expsyms=$lt_[]_LT_AC_TAGVAR(include_expsyms, $1) + +ifelse([$1],[], +[# ### END LIBTOOL CONFIG], +[# ### END LIBTOOL TAG CONFIG: $tagname]) + +__EOF__ + +ifelse([$1],[], [ + case $host_os in + aix3*) + cat <<\EOF >> "$cfgfile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "X${COLLECT_NAMES+set}" != Xset; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # We use sed instead of cat because bash on DJGPP gets confused if + # if finds mixed CR/LF and LF-only lines. Since sed operates in + # text mode, it properly converts lines to CR/LF. This bash problem + # is reportedly fixed, but why not run on old versions too? + sed '$q' "$ltmain" >> "$cfgfile" || (rm -f "$cfgfile"; exit 1) + + mv -f "$cfgfile" "$ofile" || \ + (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") + chmod +x "$ofile" +]) +else + # If there is no Makefile yet, we rely on a make rule to execute + # `config.status --recheck' to rerun these tests and create the + # libtool script then. + ltmain_in=`echo $ltmain | sed -e 's/\.sh$/.in/'` + if test -f "$ltmain_in"; then + test -f Makefile && make "$ltmain" + fi +fi +])# AC_LIBTOOL_CONFIG + + +# AC_LIBTOOL_PROG_COMPILER_NO_RTTI([TAGNAME]) +# ------------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], +[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl + +_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= + +if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' + + AC_LIBTOOL_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], + lt_cv_prog_compiler_rtti_exceptions, + [-fno-rtti -fno-exceptions], [], + [_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) +fi +])# AC_LIBTOOL_PROG_COMPILER_NO_RTTI + + +# AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE +# --------------------------------- +AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], +[AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([AC_PROG_NM]) +AC_REQUIRE([AC_OBJEXT]) +# Check for command to grab the raw symbol name followed by C symbol from nm. +AC_MSG_CHECKING([command to parse $NM output from $compiler object]) +AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], +[ +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[[BCDEGRST]]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' + +# Transform an extracted symbol line into a proper C declaration +lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern int \1;/p'" + +# Transform an extracted symbol line into symbol name and symbol address +lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + +# Define system-specific variables. +case $host_os in +aix*) + symcode='[[BCDT]]' + ;; +cygwin* | mingw* | pw32*) + symcode='[[ABCDGISTW]]' + ;; +hpux*) # Its linker distinguishes data from code symbols + if test "$host_cpu" = ia64; then + symcode='[[ABCDEGRST]]' + fi + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + ;; +linux* | k*bsd*-gnu) + if test "$host_cpu" = ia64; then + symcode='[[ABCDGIRSTW]]' + lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" + lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" + fi + ;; +irix* | nonstopux*) + symcode='[[BCDEGRST]]' + ;; +osf*) + symcode='[[BCDEGQRST]]' + ;; +solaris*) + symcode='[[BDRT]]' + ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; +sysv4) + symcode='[[DFNSTU]]' + ;; +esac + +# Handle CRLF in mingw tool chain +opt_cr= +case $build_os in +mingw*) + opt_cr=`echo 'x\{0,1\}' | tr x '\015'` # option cr in regexp + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +case `$NM -V 2>&1` in +*GNU* | *'with BFD'*) + symcode='[[ABCDGIRSTW]]' ;; +esac + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. + symxfrm="\\1 $ac_symprfx\\2 \\2" + + # Write the raw and C identifiers. + lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + + rm -f conftest* + cat > conftest.$ac_ext < $nlist) && test -s "$nlist"; then + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if grep ' nm_test_var$' "$nlist" >/dev/null; then + if grep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.$ac_ext +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | grep -v main >> conftest.$ac_ext' + + cat <> conftest.$ac_ext +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[[]] = +{ +EOF + $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (lt_ptr_t) \&\2},/" < "$nlist" | grep -v main >> conftest.$ac_ext + cat <<\EOF >> conftest.$ac_ext + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$ac_objext conftstm.$ac_objext + lt_save_LIBS="$LIBS" + lt_save_CFLAGS="$CFLAGS" + LIBS="conftstm.$ac_objext" + CFLAGS="$CFLAGS$_LT_AC_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" + if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then + pipe_works=yes + fi + LIBS="$lt_save_LIBS" + CFLAGS="$lt_save_CFLAGS" + else + echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD + fi + else + echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD + fi + else + echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD + cat conftest.$ac_ext >&5 + fi + rm -f conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + lt_cv_sys_global_symbol_pipe= + fi +done +]) +if test -z "$lt_cv_sys_global_symbol_pipe"; then + lt_cv_sys_global_symbol_to_cdecl= +fi +if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then + AC_MSG_RESULT(failed) +else + AC_MSG_RESULT(ok) +fi +]) # AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE + + +# AC_LIBTOOL_PROG_COMPILER_PIC([TAGNAME]) +# --------------------------------------- +AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC], +[_LT_AC_TAGVAR(lt_prog_compiler_wl, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= +_LT_AC_TAGVAR(lt_prog_compiler_static, $1)= + +AC_MSG_CHECKING([for $compiler option to produce PIC]) + ifelse([$1],[CXX],[ + # C++ specific cases for pic, static, wl, etc. + if test "$GXX" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + mingw* | os2* | pw32*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + *djgpp*) + # DJGPP does not support shared libraries at all + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + case $host_os in + aix4* | aix5*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + chorus*) + case $cc_basename in + cxch68*) + # Green Hills C++ Compiler + # _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" + ;; + esac + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + dgux*) + case $cc_basename in + ec++*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + ghcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + freebsd* | dragonfly*) + # FreeBSD uses GNU C++ + ;; + hpux9* | hpux10* | hpux11*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + fi + ;; + aCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + ;; + *) + ;; + esac + ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; + irix5* | irix6* | nonstopux*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + # CC pic flag -KPIC is the default. + ;; + *) + ;; + esac + ;; + linux* | k*bsd*-gnu) + case $cc_basename in + KCC*) + # KAI C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + icpc* | ecpc*) + # Intel C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgCC*) + # Portland Group C++ compiler. + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + cxx*) + # Compaq C++ + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + lynxos*) + ;; + m88k*) + ;; + mvs*) + case $cc_basename in + cxx*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' + ;; + *) + ;; + esac + ;; + netbsd* | netbsdelf*-gnu) + ;; + osf3* | osf4* | osf5*) + case $cc_basename in + KCC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' + ;; + RCC*) + # Rational C++ 2.4.1 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + cxx*) + # Digital/Compaq C++ + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # Make sure the PIC flag is empty. It appears that all Alpha + # Linux and Compaq Tru64 Unix objects are PIC. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + *) + ;; + esac + ;; + psos*) + ;; + solaris*) + case $cc_basename in + CC*) + # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + gcx*) + # Green Hills C++ Compiler + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + ;; + *) + ;; + esac + ;; + sunos4*) + case $cc_basename in + CC*) + # Sun C++ 4.x + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + lcc*) + # Lucid + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + ;; + *) + ;; + esac + ;; + tandem*) + case $cc_basename in + NCC*) + # NonStop-UX NCC 3.20 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + ;; + *) + ;; + esac + ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac + ;; + vxworks*) + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +], +[ + if test "$GCC" = yes; then + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + + case $host_os in + aix*) + # All AIX code is PIC. + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' + ;; + + beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' + ;; + + interix3*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + enable_shared=no + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic + fi + ;; + + hpux*) + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + if test "$host_cpu" = ia64; then + # AIX 5 now supports IA64 processor + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + else + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' + fi + ;; + darwin*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + case $cc_basename in + xlc*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-qnocommon' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + esac + ;; + + mingw* | pw32* | os2*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + ;; + + hpux9* | hpux10* | hpux11*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # PIC (with -KPIC) is the default. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + newsos6) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + linux* | k*bsd*-gnu) + case $cc_basename in + icc* | ecc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + ccc*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All Alpha code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + esac + ;; + + osf3* | osf4* | osf5*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + # All OSF/1 code is PIC. + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' + ;; + + solaris*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + case $cc_basename in + f77* | f90* | f95*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; + *) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + unicos*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + + uts4*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-pic' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + + *) + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then + AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], + _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], + [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in + "" | " "*) ;; + *) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)" ;; + esac], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) +fi +case $host_os in + # For platforms which do not support PIC, -DPIC is meaningless: + *djgpp*) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= + ;; + *) + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" + ;; +esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) +]) + + +# AC_LIBTOOL_PROG_LD_SHLIBS([TAGNAME]) +# ------------------------------------ +# See if the linker supports building shared libraries. +AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], +[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +ifelse([$1],[CXX],[ + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + case $host_os in + aix4* | aix5*) + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + ;; + pw32*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" + ;; + cygwin* | mingw*) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + ;; + linux* | k*bsd*-gnu) + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + ;; + *) + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + ;; + esac +],[ + runpath_var= + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)= + _LT_AC_TAGVAR(archive_expsym_cmds, $1)= + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)= + _LT_AC_TAGVAR(old_archive_from_expsyms_cmds, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + _LT_AC_TAGVAR(thread_safe_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(link_all_deplibs, $1)=unknown + _LT_AC_TAGVAR(hardcode_automatic, $1)=no + _LT_AC_TAGVAR(module_cmds, $1)= + _LT_AC_TAGVAR(module_expsym_cmds, $1)= + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' + # include_expsyms should be a list of space-separated symbols to be *always* + # included in the symbol list + _LT_AC_TAGVAR(include_expsyms, $1)= + # exclude_expsyms can be an extended regexp of symbols to exclude + # it will be wrapped by ` (' and `)$', so one must not match beginning or + # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', + # as well as any symbol that contains `d'. + _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out + # platforms (ab)use it in PIC code, but their linkers get confused if + # the symbol is explicitly referenced. Since portable code cannot + # rely on this symbol name, it's probably fine to never include it in + # preloaded symbol tables. + extract_expsyms_cmds= + # Just being paranoid about ensuring that cc_basename is set. + _LT_CC_BASENAME([$compiler]) + case $host_os in + cygwin* | mingw* | pw32*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$GCC" != yes; then + with_gnu_ld=no + fi + ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; + openbsd*) + with_gnu_ld=no + ;; + esac + + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # Set some defaults for GNU ld with shared library support. These + # are reset later if shared libraries are not supported. Putting them + # here allows them to be overridden if necessary. + runpath_var=LD_RUN_PATH + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' + # ancient GNU ld didn't support --whole-archive et. al. + if $LD --help 2>&1 | grep 'no-whole-archive' > /dev/null; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + supports_anon_versioning=no + case `$LD -v 2>/dev/null` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 + *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... + *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... + *\ 2.11.*) ;; # other 2.11 versions + *) supports_anon_versioning=yes ;; + esac + + # See if GNU ld supports shared libraries. + case $host_os in + aix3* | aix4* | aix5*) + # On AIX/PPC, the GNU linker is very broken + if test "$host_cpu" != ia64; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can't use + # them. + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + cygwin* | mingw* | pw32*) + # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, + # as there is no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=no + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + + if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + # If the export-symbols file already is a .def file (1st line + # is EXPORTS), use it as is; otherwise, prepend... + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then + cp $export_symbols $output_objdir/$soname.def; + else + echo EXPORTS > $output_objdir/$soname.def; + cat $export_symbols >> $output_objdir/$soname.def; + fi~ + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + interix3*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + linux* | k*bsd*-gnu) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + tmp_addflag= + case $cc_basename,$host_cpu in + pgcc*) # Portland Group C compiler + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag' + ;; + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_addflag=' $pic_flag -Mnomain' ;; + ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 + tmp_addflag=' -i_dynamic' ;; + efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 + tmp_addflag=' -i_dynamic -nofor_main' ;; + ifc* | ifort*) # Intel Fortran compiler + tmp_addflag=' -nofor_main' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + + if test $supports_anon_versioning = yes; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ + cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + $echo "local: *; };" >> $output_objdir/$libname.ver~ + $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + fi + _LT_AC_TAGVAR(link_all_deplibs, $1)=no + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' + wlarc= + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + fi + ;; + + solaris*) + if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + + sunos4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' + wlarc= + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + + if test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no; then + runpath_var= + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)= + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)= + fi + else + # PORTME fill in a description of your system's linker (not GNU ld) + case $host_os in + aix3*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + fi + ;; + + aix4* | aix5*) + if test "$host_cpu" = ia64; then + # On IA64, the linker does run time linking by default, so we don't + # have to do anything special. + aix_use_runtimelinking=no + exp_sym_flag='-Bexport' + no_entry_flag="" + else + # If we're using GNU nm, then we don't want the "-C" option. + # -C means demangle to AIX nm, but means don't demangle with GNU nm + if $NM -V 2>&1 | grep 'GNU' > /dev/null; then + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + else + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\[$]2 == "T") || (\[$]2 == "D") || (\[$]2 == "B")) && ([substr](\[$]3,1,1) != ".")) { print \[$]3 } }'\'' | sort -u > $export_symbols' + fi + aix_use_runtimelinking=no + + # Test if we are trying to use run time linking or normal + # AIX style linking. If -brtl is somewhere in LDFLAGS, we + # need to do runtime linking. + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + for ld_flag in $LDFLAGS; do + if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then + aix_use_runtimelinking=yes + break + fi + done + ;; + esac + + exp_sym_flag='-bexport' + no_entry_flag='-bnoentry' + fi + + # When large executables or shared objects are built, AIX ld can + # have problems creating the table of contents. If linking a library + # or program results in "error TOC overflow" add -mminimal-toc to + # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not + # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. + + _LT_AC_TAGVAR(archive_cmds, $1)='' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + + if test "$GCC" = yes; then + case $host_os in aix4.[[012]]|aix4.[[012]].*) + # We only want to do this on AIX 4.2 and lower, the check + # below for broken collect2 doesn't work under 4.3+ + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + else + # We have old collect2 + _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= + fi + ;; + esac + shared_flag='-shared' + if test "$aix_use_runtimelinking" = yes; then + shared_flag="$shared_flag "'${wl}-G' + fi + else + # not using gcc + if test "$host_cpu" = ia64; then + # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release + # chokes on -Wl,-G. The following line is correct: + shared_flag='-G' + else + if test "$aix_use_runtimelinking" = yes; then + shared_flag='${wl}-G' + else + shared_flag='${wl}-bM:SRE' + fi + fi + fi + + # It seems that -bexpall does not export symbols beginning with + # underscore (_), so it is better to generate a list of symbols to export. + _LT_AC_TAGVAR(always_export_symbols, $1)=yes + if test "$aix_use_runtimelinking" = yes; then + # Warning - without using the other runtime loading flags (-brtl), + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(allow_undefined_flag, $1)='-berok' + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' + _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + _LT_AC_SYS_LIBPATH_AIX + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" + # Warning - without using the other run time loading flags, + # -berok will link without error, but may produce a broken library. + _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' + # Exported symbols can be pulled into shared objects from archives + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + fi + fi + ;; + + amigaos*) + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + # see comment about different semantics on the GNU ld section + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + bsdi[[45]]*) + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic + ;; + + cygwin* | mingw* | pw32*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # Tell ltmain to make .dll files, not .so files. + shrext_cmds=".dll" + # FIXME: Setting linknames here is a bad hack. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `echo "$deplibs" | $SED -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' + # FIXME: Should let the user specify the lib program. + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' + _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + ;; + + darwin* | rhapsody*) + case $host_os in + rhapsody* | darwin1.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' + ;; + *) # Darwin 1.3 on + if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + else + case ${MACOSX_DEPLOYMENT_TARGET} in + 10.[[012]]) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' + ;; + 10.*) + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' + ;; + esac + fi + ;; + esac + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_automatic, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + if test "$GCC" = yes ; then + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + else + case $cc_basename in + xlc*) + output_verbose_link_cmd='echo' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + ;; + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi + ;; + + dgux*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + freebsd1*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd* | dragonfly*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + hpux9*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$rm $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + ;; + + hpux10*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + else + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + *) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + ;; + esac + fi + ;; + + irix5* | irix6* | nonstopux*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + netbsd* | netbsdelf*-gnu) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + newsos6) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + openbsd*) + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi + ;; + + os2*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + _LT_AC_TAGVAR(archive_cmds, $1)='$echo "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$echo DATA >> $output_objdir/$libname.def~$echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~$echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' + _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' + ;; + + osf3*) + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + osf4* | osf5*) # as osf3* with the addition of -msym flag + if test "$GCC" = yes; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' + else + _LT_AC_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linker_flags -msym -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; echo "-hidden">> $lib.exp~ + $LD -shared${allow_undefined_flag} -input $lib.exp $linker_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${output_objdir}/so_locations -o $lib~$rm $lib.exp' + + # Both c and cxx compiler support -rpath directly + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' + fi + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + ;; + + solaris*) + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' + if test "$GCC" = yes; then + wlarc='${wl}' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $CC -shared ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$rm $lib.exp' + else + wlarc='' + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + # The compiler driver will combine linker options so we + # cannot just pass the convience library names through + # without $wl, iff we do not link with $LD. + # Luckily, gcc supports the same syntax we need for Sun Studio. + # Supported since Solaris 2.6 (maybe 2.5.1?) + case $wlarc in + '') + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; + esac ;; + esac + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + ;; + + sunos4*) + if test "x$host_vendor" = xsequent; then + # Use $CC to link under sequent, because it throws in some extra .o + # files that make .init and .fini sections work. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' + fi + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4) + case $host_vendor in + sni) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=yes # is this really true??? + ;; + siemens) + ## LD is ld it makes a PLAMLIB + ## CC just makes a GrossModule. + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + ;; + motorola) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie + ;; + esac + runpath_var='LD_RUN_PATH' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + sysv4.3*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + _LT_AC_TAGVAR(ld_shlibs, $1)=yes + fi + ;; + + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi + ;; + + uts4*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + ;; + + *) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + ;; + esac + fi +]) +AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) +test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no + +# +# Do we need to explicitly link libc? +# +case "x$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)" in +x|xyes) + # Assume -lc should be added + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + + if test "$enable_shared" = yes && test "$GCC" = yes; then + case $_LT_AC_TAGVAR(archive_cmds, $1) in + *'~'*) + # FIXME: we may have to deal with multi-command sequences. + ;; + '$CC '*) + # Test whether the compiler implicitly links with -lc since on some + # systems, -lgcc has to come before -lc. If gcc already passes -lc + # to ld, don't add -lc before -lgcc. + AC_MSG_CHECKING([whether -lc should be explicitly linked in]) + $rm conftest* + printf "$lt_simple_compile_test_code" > conftest.$ac_ext + + if AC_TRY_EVAL(ac_compile) 2>conftest.err; then + soname=conftest + lib=conftest + libobjs=conftest.$ac_objext + deplibs= + wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) + compiler_flags=-v + linker_flags=-v + verstring= + output_objdir=. + libname=conftest + lt_save_allow_undefined_flag=$_LT_AC_TAGVAR(allow_undefined_flag, $1) + _LT_AC_TAGVAR(allow_undefined_flag, $1)= + if AC_TRY_EVAL(_LT_AC_TAGVAR(archive_cmds, $1) 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) + then + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + else + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes + fi + _LT_AC_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag + else + cat conftest.err 1>&5 + fi + $rm conftest* + AC_MSG_RESULT([$_LT_AC_TAGVAR(archive_cmds_need_lc, $1)]) + ;; + esac + fi + ;; +esac +])# AC_LIBTOOL_PROG_LD_SHLIBS + + +# _LT_AC_FILE_LTDLL_C +# ------------------- +# Be careful that the start marker always follows a newline. +AC_DEFUN([_LT_AC_FILE_LTDLL_C], [ +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ +])# _LT_AC_FILE_LTDLL_C + + +# _LT_AC_TAGVAR(VARNAME, [TAGNAME]) +# --------------------------------- +AC_DEFUN([_LT_AC_TAGVAR], [ifelse([$2], [], [$1], [$1_$2])]) + + +# old names +AC_DEFUN([AM_PROG_LIBTOOL], [AC_PROG_LIBTOOL]) +AC_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) +AC_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) +AC_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) +AC_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) +AC_DEFUN([AM_PROG_LD], [AC_PROG_LD]) +AC_DEFUN([AM_PROG_NM], [AC_PROG_NM]) + +# This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL]) + +AC_DEFUN([LT_AC_PROG_GCJ], +[AC_CHECK_TOOL(GCJ, gcj, no) + test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" + AC_SUBST(GCJFLAGS) +]) + +AC_DEFUN([LT_AC_PROG_RC], +[AC_CHECK_TOOL(RC, windres, no) +]) + +############################################################ +# NOTE: This macro has been submitted for inclusion into # +# GNU Autoconf as AC_PROG_SED. When it is available in # +# a released version of Autoconf we should remove this # +# macro and use it instead. # +############################################################ +# LT_AC_PROG_SED +# -------------- +# Check for a fully-functional sed program, that truncates +# as few characters as possible. Prefer GNU sed if found. +AC_DEFUN([LT_AC_PROG_SED], +[AC_MSG_CHECKING([for a sed that does not truncate output]) +AC_CACHE_VAL(lt_cv_path_SED, +[# Loop through the user's path and test for sed and gsed. +# Then use that list of sed's as ones to test for truncation. +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for lt_ac_prog in sed gsed; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" + fi + done + done +done +lt_ac_max=0 +lt_ac_count=0 +# Add /usr/xpg4/bin/sed as it is typically found on Solaris +# along with /bin/sed that truncates output. +for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do + test ! -f $lt_ac_sed && continue + cat /dev/null > conftest.in + lt_ac_count=0 + echo $ECHO_N "0123456789$ECHO_C" >conftest.in + # Check for GNU sed and select it if it is found. + if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then + lt_cv_path_SED=$lt_ac_sed + break + fi + while true; do + cat conftest.in conftest.in >conftest.tmp + mv conftest.tmp conftest.in + cp conftest.in conftest.nl + echo >>conftest.nl + $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break + cmp -s conftest.out conftest.nl || break + # 10000 chars as input seems more than enough + test $lt_ac_count -gt 10 && break + lt_ac_count=`expr $lt_ac_count + 1` + if test $lt_ac_count -gt $lt_ac_max; then + lt_ac_max=$lt_ac_count + lt_cv_path_SED=$lt_ac_sed + fi + done +done +]) +SED=$lt_cv_path_SED +AC_MSG_RESULT([$SED]) +]) + +dnl PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +dnl defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +dnl also defines GSTUFF_PKG_ERRORS on error +AC_DEFUN([PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) + else + ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + + diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 000000000..0e9094464 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,892 @@ +# generated automatically by aclocal 1.9.6 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, +# 2005 Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9.6])]) + +# AM_AUX_DIR_EXPAND -*- Autoconf -*- + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 7 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +#serial 3 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 8 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 12 + +# This macro actually does too much. Some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# Copyright (C) 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + +# Add --enable-maintainer-mode option to configure. -*- Autoconf -*- +# From Jim Meyering + +# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +AC_DEFUN([AM_MAINTAINER_MODE], +[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) + dnl maintainer-mode is disabled by default + AC_ARG_ENABLE(maintainer-mode, +[ --enable-maintainer-mode enable make rules and dependencies not useful + (and sometimes confusing) to the casual installer], + USE_MAINTAINER_MODE=$enableval, + USE_MAINTAINER_MODE=no) + AC_MSG_RESULT([$USE_MAINTAINER_MODE]) + AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes]) + MAINT=$MAINTAINER_MODE_TRUE + AC_SUBST(MAINT)dnl +] +) + +AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- + +# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. +# +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 3 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# Check to make sure that the build environment is sane. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 +# Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 4 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# AM_PROG_INSTALL_STRIP +# --------------------- +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004, 2005 Free Software Foundation, Inc. +# +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# serial 2 + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + +m4_include([acinclude.m4]) diff --git a/autocorrect/Makefile.am b/autocorrect/Makefile.am new file mode 100644 index 000000000..fde9d50b8 --- /dev/null +++ b/autocorrect/Makefile.am @@ -0,0 +1,6 @@ +# (Is autocorrect.xml still used?) + +# WARNING: Do not add any other language here - use kde-i18n/*/data/koffice/autocorrect for that. +scripts_DATA = autocorrect.xml en_US.xml +scriptsdir = $(kde_datadir)/koffice/autocorrect + diff --git a/autocorrect/autocorrect.xml b/autocorrect/autocorrect.xml new file mode 100644 index 000000000..0b252d573 --- /dev/null +++ b/autocorrect/autocorrect.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/autocorrect/en_US.xml b/autocorrect/en_US.xml new file mode 100644 index 000000000..bb5785b39 --- /dev/null +++ b/autocorrect/en_US.xml @@ -0,0 +1,4141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/changes-1.4 b/changes-1.4 new file mode 100644 index 000000000..f3b4666cf --- /dev/null +++ b/changes-1.4 @@ -0,0 +1,210 @@ +New applications: krita, kexi + +Krita +===== + +Krita is an image editor and paint application with a wide range of +applications, from photo editing to the creation of original artwork. +Sporting a clear and uncluttered interface (for a paint app...) it makes the +features it delivers accessible and intuitive to use. + +This is the first public release of Krita and while it provides a coherent set +of features, it is only the first stepping stone towards a flexible paint +application for artists and image editors. + +Krita offers: + +* Layers (without fixed boundaries). +* A familiar set of tools -- brushes, selection tools and shape tools. +* Painting with filters. +* An extensible system for the addition of new color and paint models. +* Support for pressure sensitive tablets. +* The ability to read most graphics file formats, including gimp and photoshop files. +* Exporting to many graphics file formats (but not gimp or photoshop) +* A complete colour management system based on lcms. +* A useful set of filters (implemented as plugins, so the set of filters + is extensible) including a CImg based image restoration plugin. +* The ability to use Gimp palettes, brushes, patterns and gradients + +Caveats: + +* In this beta version exif data embedded in jpeg images is not preserved. +* Some tools and menu options do not yet function completely correctly. + +=============== + +Kexi [ this is from http://www.kexi-project.org/wiki/wikiview/index.php?AnnouncementForKOffice1.4 ] +==== + +KOffice 1.4 is the first official release to include Kexi - the KOffice database management application. + Kexi is an integrated environment for managing data. It can be used for creating database schemas; inserting data; performing queries, and processing data. Forms can be created to provide a custom interface to your data. All database objects - tables, queries and forms - are stored in the database, making it easy to share databases. + + Kexi is considered as a long awaited Open Source competitor for MS Access, Filemaker and Oracle Forms. Its development is motivated by the lack of Rapid Application Development (RAD) tools for database systems that are sufficiently powerful, inexpensive, open standards driven and portable across many OSes and hardware platforms. + +Overview + Supports database storage in files and on database servers. + Graphical interface for creating and altering table structures. + Form entry, with visual form designer. + Advanced tabular data view. + Intuitive query designer - no knowledge of SQL required! + Integrated SQL Editor available for advanced users. + +Data Processing and Access + Data migration from MySQL, PostgreSQL and MS Access databases (MS Access available as an external plugin). + KexiDB API available for developers for integration with other applications. + Scripting support with Python language - hidden for 0.1 version. + (JavaScript/ECMA-Script support is planned) + Easy data report generation (planned). + +Database Storage + Kexi can store databases in files and on database servers, while providing a common user interface. Database drivers for the following database engines are available: + - SQLite (Native file format: version 2 and 3) + - PostgreSQL + - MySQL + Support for other database systems is planned for future versions, including the ODBC interface, for simpler and more flexible integration in corporate environments. + +=================== + +KOffice Workspace (koshell): +* New sidebar +* Tab support + +KOffice-wide changes: +* Document information dialog: Added keywords and subject for the document, as well as + position, company, and telephone (home/work) for the author +* Make the default unit be inch or cm depending on the KDE-wide measure system (imperial or metric) +* Improvements to the DCOP interface for loading and saving. +* -dpi command line option to override the DPI detected by X. You can set one value for x and y, or use -dpi x,y +* Improve filter chains to avoid absurd chains (e.g. kword -> plain text -> kspread) +* Startup dialog: themeable icons, correct initial tab, hide non-existent recent local files +* Page layout dialog: better preview, new GUI for margins +* Rulers: made more readable at all resolutions, added tooltips + +kotext (shared by KWord and KPresenter): +* Word completion with tooltip +* Open links by clicking on them, use hand pointer, show link target in statusbar. +* Tab/Shift+Tab for changing indentation in lists +* Rewritten spell-checking support (based on kspell2, the main reason for the kdelibs >= 3.3 requirement) + which is much faster and solves many problems (e.g. KOffice-1.3's hanging right-click-menu) +* Improved autocorrection (better URL detection among other things) + +KWord: +* OASIS file format support (almost complete) +* Copy/Paste and Drag-n-drop use the OASIS format. +* Make it possible to select entire paragraphs from the left margin again. +* Inline text frames can be navigated into using Left and Right keys. +* New "statistic" variables (number of words, number of lines etc.) +* "Select All Frames" features +* Non-breaking hyphen, which can be inserted with Ctrl+Shift+Minus +* Alt+Right and Alt+Left shortcuts for increasing/decreasing the numbering level +* Removed non-working feature "Type anywhere cursor" +* When dropping a link to an image, let the user choose between inserting a URL and the image +* Rewritten "convert to text box" and "convert table to text" features so that they + don't use the clipboard anymore. +* PageUp/PageDown now moves the caret by default (it's still configurable). +* When saving a new document, suggest a file name based on the beginning of the document +* Reorganized and simplified GUI of the configuration dialog +* Support for "protect content" in all types of framesets +* Support for different run-around-gaps on every side of the frame + +KPresenter: +* Master page feature +* Reworked property editor +* Reworked object/page effects +* Footer and headers can be shown/hidden in each page +* Custom Slide Show +* OASIS file format support (incomplete) +* Flip now works as in Gimp. Horizontal flip flips on y-axis, vertical flip on x-axis +* Group objects: The grouped object is now in the z-order of the upperst + object grouped and no longer on the top. +* Ungroup object: The objects are now in the z-order where the group object + was and no longer on top. +* If a page is shown more than once during a presentation add the time for + the duration instead of showing only the last duration. +* Per-page presentation speed and per-object effect (animation) speed +* PageUp/PageDown during presentation now goes to beginning of the next/previous slide +* New "statistic" variables (number of words, number of lines etc.) + +KSpread: +* OASIS file format support (incomplete) +* Support for right-to-left spreadsheets +* Calendar plugin +* dependencies are handled correctly +* much improved value parsing and formatting +* Generic format support (the cell format remains 'generic' until explicitely set) +* Cell validity + + new type added: list + + new data added: differentto + + Add Input help (allow to display help) + + Allow blanks cell +* Conditional cell attribute: + + Add new data "differentto" +* New functions: + + ACOT + + RANDNORM (gaussian random numbers) + + REGEXP + + REGEXPRE (regexp replace) + + SUMIF (conditional sum) +* Multiple steps undo and redo +* Improved handling of hyperlinks +* Better icons for toolbar and templates + +KChart: +* New maintainer. Many, *many* bugfixes. +* Removed a lot of old non-working stuff. It will reappear, working, in future versions. +* New, much improved, data editor +* Same startup dialog as the rest of KOffice +* Templates (only one so far) +* Data as rows or columns +* Linear or logarithmic scale +* Export to PNG format +* Export to SVG format +* Import data from text files (not finished in the beta) +* Much improved manual +* Print support + +KFormula: +* OASIS file format support (incomplete) + +Kivio: +* Non blocking stencilset loading +* Added Nassi Schneiderman stencils +* Moving selected stencils with the keyboard +* Added a docker for adding stencils to the document +* Added a tool for adding connector targets to stencils +* Added a polyline connector + +Karbon: +* OASIS file format support (incomplete) +* New color dialog +* Small preview widget +* ZoomIn/ZoomOut actions +* Build system fixes + +Filters: +* WordPerfect import filter for KWord: brand new, now based on libwpd + +* new Microsoft Excel import filter for KSpread + +* KWord HTML filter + + Ability to link an external stylesheet to a HTML page + +* Gnumeric import/export: now supports + + Text rotation + + Cell validation + + Print repeated columns + + Document information + + Area name + +* KSpread HTML export + + Sheets can be exported to separate HTML pages + + Sheets are browsable by a table of contents + + User can define which sheets to export + + Ability to link an external stylesheet to a HTML page + + The encoding of the HTML page is configurable + + Borders are optional + + The cell spacing is configurable + +* OoImpress: + + Custom slide show + diff --git a/changes-1.5 b/changes-1.5 new file mode 100644 index 000000000..30af96936 --- /dev/null +++ b/changes-1.5 @@ -0,0 +1,195 @@ +* General: + + - Paragraph background color can now be set (in addition to text background color) + - Palettes now remember their position between sessions (Krita, Kivio, Karbon) + - Palettes now have a smart mode where they start floating on small screens and + docked on larger screens + - ToolBox is no longer duplicated for every view + - Accessibility: Allow speaking texts using the kdeaccessibility tools (KTTS). + - Accessibility: Alt-F8 to set focus to any focusable widget. + - Accessibility: F8 and Shift-F8 for mouseless splitter and dock widget sizing. + +* Bug fixes: + +** KWord: + - Statistic variables are not saved in KWord format (#111478) + - Fix bug where inserting a large image would not make it a size that fits the page + - Fix bug where images in headers were only shown in the first page. + - Fix RMB in table-cell should not unselect text + + +** Krita: + - Krita now compiles on NetBSD + - Fix rotation bugs + - When "Select Similar Colors" a transparant area, add only transparant areas instead + of the entire image to the selection. + - Fix loading and saving of grayscale images + - Fix ImageMagick 16/8 bit image confusion when loading and saving. + - BUG: 110296 Display is now restored on cancel + - many crash fixes + - Warn when applying a filter that will convert the layer data + - create and save new brushes + - show image in center of window + - group layers in folders + - cmyk8, cmyk16, rgb16, gray16, rgb-half, rgb-float16 and lab16 colorspaces + + +** KSpread: + - Fixed spreadsheets containing formulae being marked as modified immediately after being opened. + - 115948 format changes of an automerged cell affects all cells in the set. + +** Karbon: +- 114421 Transform palette has a strange layout when it is tall +- 114424 Stroke properties palette has a strange layout when it is... +- 114425 Color palette has title "Fill color" even when it shows s... +- 114428 The last created object should stay selected +- 114577 The Document/Layers/History palette is not shown on start +- 114579 Deleting polyline segment moves the mouse pointer to (0, 0) +- 114580 JJ: The line thickness SpinBox has no tooltip +- 112765 Selecting a polyline and running the "round corners" plug... +- 60438 undo confusion between point and shape action +- 92974 svg export creates useless svg file (from text tool) +- 115752 Make paste operation undo:able +- 116612 svg import/rendering bugs +- 111372 karbon: KLibrary: Undefined symbol "init_libkarbonpart" +- 114578 A polyline spline has a too big surrounding box +- 89596 Switching between Karbon14 and KSVGPlugin view in Konquer... +- 38555 segv when opening a file svg or kontour native +- 116422 un-usable selecting behaviour multple moving +- 116972 Transform palette is not updated when moving or scaling an object +- 115213 The color and opacity bars in the color chooser palette are backwards. + (thanks Marijn Kruisselbrink for the initial patch) +- 96944 Wanted: good right-click actions for polyline tool, zoom ... +- 111619 Page layout: size alias and margins doesn't get saved +- 111717 How to bring back the overview window if you close it? +- 111618 Rename plugins menu to "Effects" +- 109520 Change Align Center (Vertical) to Align Middle and add some extra separators +- 108789 Keybindings like krita, and other tweaks +- 108755 Always use this document at startup, Karbon has no way to stop doing this. Add a basic karbon template. +- 91376, 111207, 60844 Dockers now use the KoPalette library. This means a huge improvement when it comes to docker management +- 112691 Usability: The tools should be grouped +- 114429 The color picker is bad: Karbon now uses the Krita color choosers. +- 99927 karbon prints empty page the same in preview +- 119452 Printing scales the entire drawing down +- 116494 [usability] polyline interaction suggestions +- 119024 Color chooser doesn't move crosshair/sliders when switching from foreground to background color +- 112680 JJ: All the dockers lack tooltips +- 39138 selecting inside groups +- 124691 crash when adding pattern +- 126006 Duplicated "Snap to grid" in "View" menu +- 126095 deleted objects saved in in odg +- 125957 l10n for Russian: different "width" for stroke and other ... +- 102860 karbon crashes when pasting text +- 126341 Can't undo after using whirl/pinch effect +- 129039 Reordering layer elements reorders layers themselves +- 126094 polyline tool does not work as expected + +** Kivio: + - Fix grid painting + - Fix loading of remote documents + +* Features: + +** Krita: + - Add histograms + - Histograms for images with more than 8-bit to the channel can be zoomed + - Add histogram docker + - Many filters are now colorspace independent + - Add CMYK (8 and 16 bit) + - Add 16-bit grayscale + - Image separation feature + - Add openEXR support + - Separate painting styles from tools; now every tool, from freehand to star can use any + painting style (eraser, brush, pen, airbrush...) + - Create better and more modern selection visualisation + - Put brush, gradient, pattern and paint style in popups in a toolbar, reducing the amount + of space Krita needs for its dockers + - Make hardness of tablet pressure curve configurable + - Many performance improvements to the backend (allocation cache, transform cache) + - Use color profiles everywhere + - New curves widget for color adjustments + - Add feather selection feature + - Pasted clipboard contents are placed in the middle of the image initially + - Brush shape is shown as an outline cursor when painting freehand + - Krita now adds itself to the Open With menu in Konqueror + - support more modes from GImp image hose brushes + - Much work on documentation + - Allow the user to choose between contiguous fill behaviour in combination with selections. + Either fill the entire selection, or floodfill the image, but taking the selection into + account (default behaviour). + - Add a 16-bit float half format RGB colourspace and change the OpenEXR filters to use it. + Will probably add the option to load into 32-bit float as that should be faster. + - 16-bit LAB is now the fallback colormodel when a particular colormodel doesn't implement + a certain function + - Filter gallery feature + - Add an option to the colorpicker to pick colors not just from the active or + from all visible layers, but from any layer, while still working on this layer. + - Tools and most menu items now are disabled when a layer is invisible or locked. + - Add noise reduction filter + - Made scrolling with a scrollwheel work better + - Add round corners filter + - Add sobel filter + - Made crop tool much more usable + - Add small tiles filter + - Add pixellize filter + - Remove the text brush + +** KWord: + - Undo and redo for resizing of tables and columns + - Grid for objects + - allow documents to start at any page number (no gui yet) + - Accessiblity: keyboard navigation across frames, create frame using the keyboard + - cleanups and usability improvements for the document structure widget + - make the Fit to Width zoommode work properly, even when you resize the window later. + - make Fit to Width zoommode the default for new users + - KWord makes selecting/moving/resizing frames easier by implementing all features from http://www.koffice.org/developer/keyboardmodifiers.php + - paint the cursor in a color that is always readable, even if you set the background color to black + - make positioning the caret at frame edge easier. + - make frame handling much easier + - Center page on screen + - Create new set of templates, based on usability and user feedback. + - make deleting a page (in dtp mode) actually work when there was still content on the page. + - frame selections are now per view. + - Remember picture insert directory + - Accessibility: Enhanced mouseless navigation using document structure area. + - KWord now uses OASIS OpenDocument + - Accessibility: Improvement: "Menu" key shows RMB popup in document structure area. + - Add a dot as the suffix of numbered lists (1, a, A, III) + +** KSpread: + - Added cell reference highlighting when editing formulae. Also added click-and-drag resizing + of ranges referenced in formulae. + - Greatly improved OpenDocument support + - Sort dialog displays column & row names instead of "Column A","Column B" for selecting sort criteria + - new formula engine implemented - parsing and evaluation much faster and + more robust and flexible + +** Karbon + - Duplicate object. + - Minor new feature: make it able to change docker font sizes. + - Enabled right mouse click to zoom out of canvas, partially fixing bug 96944 + - Load SVG and Gimp gradients + - Support for changing gradient or pattern fills on the canvas (wish 119344) + +** KPresenter: + - Display or not background + - Display or not slide master object + - QWhatsThis help added in COnfigure KPresenter... dialog + - User manual is up-to-date + +** KChart: + - Correctly set a background color/image + +** Kivio: + - Port to the new KoGuides which adds auto guide lines + - Port to KoPalette and cleaned up the palettes (toolwindows) + - Make it possible to rearrange the pages with d'n'd in the tab bar + - Add undo support for Add Connector Target + - New stencil text editor + - Added an object list palette + - Made the old stencil set toolwindow a dialog and cleaned it up a bit + - Made text properties editable for each textbox and not only each stencil + +** Filters: + - Kpresenter can export page as image file (png/bmp/svg/mng/jpeg/xbm) + - Kivio can export page as image file diff --git a/config.h.in b/config.h.in new file mode 100644 index 000000000..84789ce52 --- /dev/null +++ b/config.h.in @@ -0,0 +1,396 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#undef HAVE_CARBON_CARBON_H + +/* Define if you have the CoreAudio API */ +#undef HAVE_COREAUDIO + +/* Define to 1 if you have the header file. */ +#undef HAVE_CRT_EXTERNS_H + +/* Defines if your system has the crypt function */ +#undef HAVE_CRYPT + +/* Define to 1 if you have the declaration of `round', and to 0 if you don't. + */ +#undef HAVE_DECL_ROUND + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_DIRENT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_DLFCN_H + +/* Define if you have DPMS support */ +#undef HAVE_DPMS + +/* Define if you have the DPMSCapable prototype in */ +#undef HAVE_DPMSCAPABLE_PROTO + +/* Define if you have the DPMSInfo prototype in */ +#undef HAVE_DPMSINFO_PROTO + +/* Define to 1 if you have the `fabsl' function. */ +#undef HAVE_FABSL + +/* Define to 1 if you have the header file. */ +#undef HAVE_FLOATINGPOINT_H + +/* Defines if your system has the libfontconfig library */ +#undef HAVE_FONTCONFIG + +/* Define to 1 if you have the `fseek64' function. */ +#undef HAVE_FSEEK64 + +/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +#undef HAVE_FSEEKO + +/* Define to 1 if you have the `ftell64' function. */ +#undef HAVE_FTELL64 + +/* Define if you have isinf */ +#undef HAVE_FUNC_ISINF + +/* Defines if you have GL (Mesa, OpenGL, ...) */ +#undef HAVE_GL + +/* GraphicsMagick is available */ +#undef HAVE_GMAGICK + +/* Define to 1 if you have the header file. */ +#undef HAVE_IEEEFP_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Defines if your system has the fontconfig and freetype libraries */ +#undef HAVE_KARBONTEXT + +/* Define to 1 if you have the header file. */ +#undef HAVE_KSPELL2_BROKER_H + +/* Defines if your system has the libart library */ +#undef HAVE_LIBART + +/* Define if you have libjpeg */ +#undef HAVE_LIBJPEG + +/* If we are going to use libkspell2 for spell-checking */ +#undef HAVE_LIBKSPELL2 + +/* Define if you have libpng */ +#undef HAVE_LIBPNG + +/* Define if you have a working libpthread (will enable threaded code) */ +#undef HAVE_LIBPTHREAD + +/* Define if you have libtiff */ +#undef HAVE_LIBTIFF + +/* Define if you have libz */ +#undef HAVE_LIBZ + +/* Define if you have support for long double in printf */ +#undef HAVE_LONG_DOUBLE + +/* ImageMagick is available */ +#undef HAVE_MAGICK + +/* ImageMagick Version 6 */ +#undef HAVE_MAGICK6 + +/* ImageMagick Version 6.1 */ +#undef HAVE_MAGICK61 + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the `mkstemp' function. */ +#undef HAVE_MKSTEMP + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +#undef HAVE_NDIR_H + +/* Define if your system needs _NSGetEnviron to set up the environment */ +#undef HAVE_NSGETENVIRON + +/* GetMagickInfoList has different number of arguments with versions >= 6.1.3 + */ +#undef HAVE_OLD_GETMAGICKINFOLIST + +/* Defines if your system has the OpenEXR library */ +#undef HAVE_OPENEXR + +/* Define to 1 if you have the header file. */ +#undef HAVE_PAPER_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_PATHS_H + +/* Define to 1 if you have the `popen' function. */ +#undef HAVE_POPEN + +/* Define to 1 if your system has powf in */ +#undef HAVE_POWF + +/* Define if you have the development files for python */ +#undef HAVE_PYTHON + +/* define if you have libreadline available */ +#undef HAVE_READLINE + +/* Define if you have res_init */ +#undef HAVE_RES_INIT + +/* Define if you have the res_init prototype */ +#undef HAVE_RES_INIT_PROTO + +/* Define to 1 if you have the `rewinddir' function. */ +#undef HAVE_REWINDDIR + +/* Define if you have a STL implementation by SGI */ +#undef HAVE_SGI_STL + +/* Define to 1 if you have the `snprintf' function. */ +#undef HAVE_SNPRINTF + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define if you have strlcat */ +#undef HAVE_STRLCAT + +/* Define if you have the strlcat prototype */ +#undef HAVE_STRLCAT_PROTO + +/* Define if you have strlcpy */ +#undef HAVE_STRLCPY + +/* Define if you have the strlcpy prototype */ +#undef HAVE_STRLCPY_PROTO + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_BITYPES_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_DIR_H + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#undef HAVE_SYS_NDIR_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vsnprintf' function. */ +#undef HAVE_VSNPRINTF + +/* Defines if your system has the libwpd library */ +#undef HAVE_WPD + +/* Defines if your system has the wv2 library */ +#undef HAVE_WV2 + +/* Define if you have the X11 Input Extension */ +#undef HAVE_XINPUTEXT + +/* Suffix for lib directories */ +#undef KDELIBSUFF + +/* Define a safe value for MAXPATHLEN */ +#undef KDEMAXPATHLEN + +/* build Kexi macros plugin */ +#undef KEXI_MACROS_SUPPORT + +/* The correct header */ +#undef LCMS_HEADER + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define the PREFIX where to install this package */ +#undef PREFIX + +/* The size of `char *', as computed by sizeof. */ +#undef SIZEOF_CHAR_P + +/* The size of `int', as computed by sizeof. */ +#undef SIZEOF_INT + +/* The size of `long', as computed by sizeof. */ +#undef SIZEOF_LONG + +/* The size of `short', as computed by sizeof. */ +#undef SIZEOF_SHORT + +/* The size of `size_t', as computed by sizeof. */ +#undef SIZEOF_SIZE_T + +/* The size of `unsigned long', as computed by sizeof. */ +#undef SIZEOF_UNSIGNED_LONG + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Version number of package */ +#undef VERSION + +/* Defined if compiling without arts */ +#undef WITHOUT_ARTS + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* Defines the executable of xmllint */ +#undef XMLLINT + +/* + * jpeg.h needs HAVE_BOOLEAN, when the system uses boolean in system + * headers and I'm too lazy to write a configure test as long as only + * unixware is related + */ +#ifdef _UNIXWARE +#define HAVE_BOOLEAN +#endif + + + +/* + * AIX defines FD_SET in terms of bzero, but fails to include + * that defines bzero. + */ + +#if defined(_AIX) +#include +#endif + + + +#if defined(HAVE_NSGETENVIRON) && defined(HAVE_CRT_EXTERNS_H) +# include +# include +# define environ (*_NSGetEnviron()) +#endif + + +/* Number of bits in a file offset, on hosts where this is settable. */ +#undef _FILE_OFFSET_BITS + + +#if !defined(HAVE_RES_INIT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +int res_init(void); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCAT_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcat(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + + +#if !defined(HAVE_STRLCPY_PROTO) +#ifdef __cplusplus +extern "C" { +#endif +unsigned long strlcpy(char*, const char*, unsigned long); +#ifdef __cplusplus +} +#endif +#endif + + +/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +#undef _LARGEFILE_SOURCE + +/* Define for large files, on AIX-style hosts. */ +#undef _LARGE_FILES + + +/* + * On HP-UX, the declaration of vsnprintf() is needed every time ! + */ + +#if !defined(HAVE_VSNPRINTF) || defined(hpux) +#if __STDC__ +#include +#include +#else +#include +#endif +#ifdef __cplusplus +extern "C" +#endif +int vsnprintf(char *str, size_t n, char const *fmt, va_list ap); +#ifdef __cplusplus +extern "C" +#endif +int snprintf(char *str, size_t n, char const *fmt, ...); +#endif + + + +#if defined(__SVR4) && !defined(__svr4__) +#define __svr4__ 1 +#endif + + +/* don't use magick filter */ +#undef include_imagemagick_filter + +/* type to use in place of socklen_t if not defined */ +#undef kde_socklen_t + +/* type to use in place of socklen_t if not defined (deprecated, use + kde_socklen_t) */ +#undef ksize_t diff --git a/configure.files b/configure.files new file mode 100644 index 000000000..dc5dd4b88 --- /dev/null +++ b/configure.files @@ -0,0 +1,45 @@ +./admin/configure.in.min +configure.in.in +./example/configure.in.in +./filters/configure.in.mid +./filters/krita/configure.in.in +./filters/krita/gmagick/configure.in.bot +./filters/krita/jpeg/configure.in.bot +./filters/krita/magick/configure.in.bot +./filters/krita/openexr/configure.in.bot +./filters/krita/pdf/configure.in.bot +./filters/krita/pdf/configure.in.in +./filters/krita/png/configure.in.bot +./filters/krita/tiff/configure.in.bot +./filters/kword/msword/configure.in.bot +./filters/kword/msword/configure.in.in +./filters/kword/pdf/xpdf/configure.in.in +./filters/kword/wordperfect/configure.in.bot +./filters/kword/wordperfect/configure.in.in +./filters/xsltfilter/configure.in.bot +./filters/xsltfilter/configure.in.in +./karbon/configure.in.bot +./karbon/configure.in.in +./kexi/3rdparty/configure.in.in +./kexi/configure.in.in +./kexi/kexidb/drivers/configure.in.bot +./kexi/kexidb/drivers/configure.in.in +./kexi/main/configure.in.in +./kexi/migration/configure.in.in +./kexi/plugins/configure.in.in +./kexi/plugins/configure.in.mid +./kexi/plugins/macros/configure.in.in +./kivio/configure.in.in +./kpresenter/configure.in.in +./krita/configure.in.bot +./krita/configure.in.in +./krita/plugins/configure.in.in +./krita/plugins/viewplugins/imagesize/configure.in.in +./kspread/plugins/calculator/configure.in.in +./kword/mailmerge/configure.in.in +./lib/configure.in.in +./lib/configure.in.mid +./lib/kotext/configure.in.bot +./lib/kotext/configure.in.in +./lib/kross/configure.in.bot +./lib/kross/configure.in.in diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..add03463f --- /dev/null +++ b/configure.in @@ -0,0 +1,2666 @@ +dnl ======================================================= +dnl FILE: ./admin/configure.in.min +dnl ======================================================= + +dnl This file is part of the KDE libraries/packages +dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org) + +dnl This file is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Library General Public +dnl License as published by the Free Software Foundation; either +dnl version 2 of the License, or (at your option) any later version. + +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Library General Public License for more details. + +dnl You should have received a copy of the GNU Library General Public License +dnl along with this library; see the file COPYING.LIB. If not, write to +dnl the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +dnl Boston, MA 02110-1301, USA. + +# Original Author was Kalle@kde.org +# I lifted it in some mater. (Stephan Kulow) +# I used much code from Janos Farkas + +dnl Process this file with autoconf to produce a configure script. + +AC_INIT(acinclude.m4) dnl a source file from your sub dir + +dnl This is so we can use kde-common +AC_CONFIG_AUX_DIR(admin) + +dnl This ksh/zsh feature conflicts with `cd blah ; pwd` +unset CDPATH + +dnl Checking host/target/build systems, for make, install etc. +AC_CANONICAL_SYSTEM +dnl Perform program name transformation +AC_ARG_PROGRAM + +dnl Automake doc recommends to do this only here. (Janos) +AM_INIT_AUTOMAKE(koffice, "1.6.3") dnl searches for some needed programs + +AM_MAINTAINER_MODE + +KDE_SET_PREFIX + +dnl generate the config header +AM_CONFIG_HEADER(config.h) dnl at the distribution this done + +dnl Checks for programs. +AC_CHECK_COMPILERS +AC_ENABLE_SHARED(yes) +AC_ENABLE_STATIC(no) +KDE_PROG_LIBTOOL + +dnl for NLS support. Call them in this order! +dnl WITH_NLS is for the po files +AM_KDE_WITH_NLS + +KDE_USE_QT(3.3) +AC_PATH_KDE +dnl ======================================================= +dnl FILE: configure.in.in +dnl ======================================================= + +#MIN_CONFIG(3.3) + +# Remember to synchronize the version number with the file koffice/lib/kofficecore/kofficeversion.h +dnl PACKAGE set before + +CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS" + +AC_CHECK_HEADERS(unistd.h sys/param.h floatingpoint.h paths.h) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + +KDE_INIT_DOXYGEN([The KOffice API Reference], [Version $VERSION]) + +# Check for GraphicsMagick... + +have_graphicsmagick=no +KDE_FIND_PATH(GraphicsMagick-config, GRAPHICS_MAGICK_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find GraphicsMagick anywhere, check http://www.graphicsmagick.org/ for GraphicsMagick >= 1.1.7.]) +]) + +if test -n "$GRAPHICS_MAGICK_CONFIG"; then + vers=`$GRAPHICS_MAGICK_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1001007; then + LIBGMAGICK_LIBS="`$GRAPHICS_MAGICK_CONFIG --libs`" + LIBGMAGICK_LDFLAGS="`$GRAPHICS_MAGICK_CONFIG --ldflags`" + LIBGMAGICK_RPATH= + for args in $LIBGMAGICK_LIBS; do + case $args in + -L*) + LIBGMAGICK_RPATH="$LIBMAGICK_RPATH $args" + ;; + esac + done + LIBGMAGICK_RPATH=`echo $LIBGMAGICK_RPATH | $SED -e "s/-L/-R/g"` + LIBGMAGICK_CPPFLAGS="`$GRAPHICS_MAGICK_CONFIG --cppflags`" + AC_DEFINE(HAVE_GMAGICK,1, [GraphicsMagick is available]) + have_graphicsmagick=yes + else + AC_MSG_WARN([You need at least GraphicsMagick 1.1.7]) + fi + +fi + +if test ! "$USE_RPATH" = "yes"; then + LIBGMAGICK_RPATH= +fi + +AC_SUBST(LIBGMAGICK_LIBS) +AC_SUBST(LIBGMAGICK_LDFLAGS) +AC_SUBST(LIBGMAGICK_CPPFLAGS) +AC_SUBST(LIBGMAGICK_RPATH) +AM_CONDITIONAL(include_graphicsmagick_filter, test "$have_graphicsmagick" = "yes" -a HAVE_GMAGICK) + +# End of GraphicsMagick check + +# Check for ImageMagick... + +have_imagemagick=no +KDE_FIND_PATH(Magick-config, MAGICK_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find ImageMagick anywhere, check http://www.imagemagick.org/ for ImageMagick >= 5.5.2.]) +]) + +if test -n "$MAGICK_CONFIG"; then + vers=`$MAGICK_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 5005002 + then + if test "$vers" -ge 6000003 + then + AC_DEFINE(HAVE_MAGICK6, 1, [ImageMagick Version 6]) + fi + if test "$vers" -ge 6001000 + then + AC_DEFINE(HAVE_MAGICK61, 1, [ImageMagick Version 6.1]) + fi + LIBMAGICK_LIBS="`$MAGICK_CONFIG --libs`" + LIBMAGICK_LDFLAGS="`$MAGICK_CONFIG --ldflags`" + LIBMAGICK_RPATH= + for args in $LIBMAGICK_LIBS; do + case $args in + -L*) + LIBMAGICK_RPATH="$LIBMAGICK_RPATH $args" + ;; + esac + done + LIBMAGICK_RPATH=`echo $LIBMAGICK_RPATH | $SED -e "s/-L/-R/g"` + LIBMAGICK_CPPFLAGS="`$MAGICK_CONFIG --cppflags`" + AC_DEFINE(HAVE_MAGICK,1, [ImageMagick is available]) + have_imagemagick=yes + else + AC_MSG_WARN([You need at least ImageMagick 5.5.2]) + fi +fi + +if test ! "$USE_RPATH" = "yes"; then + LIBMAGICK_RPATH= +fi + +AC_SUBST(LIBMAGICK_LIBS) +AC_SUBST(LIBMAGICK_LDFLAGS) +AC_SUBST(LIBMAGICK_CPPFLAGS) +AC_SUBST(LIBMAGICK_RPATH) +AM_CONDITIONAL(include_imagemagick_filter, test "$have_imagemagick" = "yes" -a HAVE_MAGICK61 -a ! "$have_graphicsmagick" = "yes" -a ! HAVE_GMAGICK) + +# End of ImageMagick check + +########################################################################## +# This last check is copied from kdenonbeta/gsf/configure.in.in +########################################################################## +# KOFFICE_PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +# defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +# also defines GSTUFF_PKG_ERRORS on error +# Note: This is specially tweaked for karbon's fontconfig check. Please fix +# it before using it for other tests :-) +AC_DEFUN([KOFFICE_PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + echo "***" + echo "*** Due to that we can't perform the check for fontconfig..." # added for karbon (Werner) + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) +# else # removed for karbon (Werner) +# ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + +# --- Check for KDE 3.2 or 3.3 --- + +AC_MSG_CHECKING([for KDE version]) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kdeversion_save_CXXFLAGS="$CXXFLAGS" +kdeversion_safe_LIBS="$LIBS" +LIBS="$LIBS $X_EXTRA_LIBS" +CXXFLAGS="$CXXFLAGS $all_includes" + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 2, 90 ) ) +#error KDE 3.2 +#endif +], + need_kde32_compat="no" +, + need_kde32_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 3, 90 ) ) +#error KDE 3.3 +#endif +], + need_kde33_compat="no" +, + need_kde33_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 4, 90 ) ) +#error KDE 3.4 +#endif +], + need_kde34_compat="no" +, + need_kde34_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 5, 2 ) ) +#error KDE 3.5.x (x < 2) +#endif +], + need_kde351_compat="no" +, + need_kde351_compat="yes" +) +CXXFLAGS="$kdeversion_save_CXXFLAGS" +LIBS="$kdeversion_safe_LIBS" +AC_LANG_RESTORE + +if test "$need_kde32_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.2.x]) +else + if test "$need_kde33_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.3.x]) + else + if test "$need_kde34_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.4.x]) + else + if test "$need_kde351_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.5.x (x < 2)]) + else + AC_MSG_RESULT([KDE 3.5.x (x >=2) or SVN trunk]) + fi + fi + fi +fi + +AM_CONDITIONAL(need_kde32_compatibility, test "$need_kde32_compat" = "yes") +AM_CONDITIONAL(need_kde33_compatibility, test "$need_kde33_compat" = "yes") +AM_CONDITIONAL(need_kde34_compatibility, test "$need_kde34_compat" = "yes") +AM_CONDITIONAL(need_kde351_compatibility, test "$need_kde351_compat" = "yes") + +# Keep the old KDE 3.1 test, as long as it is still used +AM_CONDITIONAL(need_kde31_compatibility, test "supported" = "no") + +# --- End KDE 3.2 check --- + +# --- OpenEXR check --- + +KDE_FIND_PATH(pkg-config, PKGCONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find pkg-config]) +]) + +AC_MSG_CHECKING([for OpenEXR]) + +if test -n "$PKGCONFIG"; then + vers=`$PKGCONFIG OpenEXR --modversion 2>/dev/null` + if test -n "$vers" + then + OPENEXR_LIBS="`$PKGCONFIG OpenEXR --libs`" + OPENEXR_RPATH= + for args in $OPENEXR_LIBS; do + case $args in + -L*) + OPENEXR_RPATH="$OPENEXR_RPATH $args" + ;; + esac + done + OPENEXR_RPATH=`echo $OPENEXR_RPATH | $SED -e "s/-L/-R/g"` + OPENEXR_CFLAGS="`$PKGCONFIG OpenEXR --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_OPENEXR, 1, [Defines if your system has the OpenEXR library]) + fi +fi + +if test ! "$USE_RPATH" = "yes"; then + OPENEXR_RPATH= +fi + +if test -n "$OPENEXR_LIBS" +then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([not found]) +fi + +AC_SUBST(OPENEXR_LIBS) +AC_SUBST(OPENEXR_CFLAGS) +AC_SUBST(OPENEXR_RPATH) + +AM_CONDITIONAL(have_openexr, test -n "$OPENEXR_LIBS") + +# --- End of OpenEXR check --- +dnl ======================================================= +dnl FILE: ./example/configure.in.in +dnl ======================================================= + +dnl This is here so that example isn't compiled and intalled by default. +dnl Do NOT put this file in your application, if you want it compiled ! + +DO_NOT_COMPILE="$DO_NOT_COMPILE example" +dnl ======================================================= +dnl FILE: ./filters/krita/configure.in.in +dnl ======================================================= + +# Check if the tiff lib is available +AC_FIND_TIFF +AM_CONDITIONAL(have_tiff, test -n "$LIBTIFF") + +AC_FIND_PNG +AM_CONDITIONAL(have_png, test -n "$LIBPNG") + +AC_FIND_JPEG +AM_CONDITIONAL(have_jpeg, test -n "$LIBJPEG") + +#--------------------------------------------------------- +# libexif detection +# taken from libkexif's configure.in.in +#--------------------------------------------------------- + +LIBEXIF=no + +#PKG_CHECK_MODULES(LIBEXIF, libexif >= 0.5.7, , +# [ AC_MSG_WARN([libexif >= 0.5.7 not found.]) +# LIBEXIF=yes ]) + + +#PKG_CHECK_MODULES(LIBEXIF06, libexif >= 0.6.9, +# AC_DEFINE(HAVE_EXIF06,1,[check for libexif > 0.6]), +# AC_MSG_WARN([Using old version of libexif.])) + +PKG_CHECK_MODULES(LIBEXIF, libexif >= 0.6.12 , , + [ AC_MSG_WARN([libexif >= 0.6.12 not found.]) + LIBEXIF=yes ]) + +AC_SUBST(LIBEXIF_LIBS) +AC_SUBST(LIBEXIF_CFLAGS) + +#--------------------------------------------------------- +# libexif detection +#--------------------------------------------------------- +AC_MSG_CHECKING([if C++ program with exif can be compiled]) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $LIBEXIF_CFLAGS" +AC_CACHE_VAL(exif_build, +[ + AC_TRY_COMPILE([ + extern "C" { +#include +#include +} + ],[ + ExifLoader *l = exif_loader_new (); + exif_loader_write_file (l,"kikoo"); + return 0; + ], exif_build=yes, + exif_build=no) +]) +AC_MSG_RESULT($exif_build) +if test "$exif_build" = "no"; then + LIBEXIF="" +fi +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE + + +AM_CONDITIONAL(have_exif, test -n "$LIBEXIF") +AM_CONDITIONAL(include_jpeg_filter, test -n "$LIBJPEG" -a -n "$LIBEXIF") +AM_CONDITIONAL(include_tiff_filter, test -n "$LIBTIFF" -a -n "$LIBEXIF") +dnl ======================================================= +dnl FILE: ./filters/krita/pdf/configure.in.in +dnl ======================================================= + +# Compile the pdf import filter only if Poppler is available +PKG_CHECK_MODULES(POPPLER, poppler-qt >= 0.5.1, have_poppler=yes, have_poppler=no) + +AM_CONDITIONAL(include_PDF, test "x$have_poppler" = xyes) +dnl ======================================================= +dnl FILE: ./filters/kword/msword/configure.in.in +dnl ======================================================= + +AC_ARG_WITH(libwv2,AC_HELP_STRING([--with-libwv2=DIR],[use libwv2 in DIR]),[ + if [ test "x$withval" != "xno" ]; then + if [ test "x$withval" != "xyes" ]; then + WV2_DIR=$withval + fi + search_for_wv2=yes + else + search_for_wv2=no + fi +],[ search_for_wv2=yes +]) + +if [ test $search_for_wv2 != no ]; then + if [ test -n "$WV2_DIR" ]; then + KDE_FIND_PATH(wv2-config, WV2_CONFIG, [$WV2_DIR/bin], [ + AC_MSG_WARN([Could not find libwv2, check http://www.sourceforge.net/projects/wvware/]) + ]) + else + KDE_FIND_PATH(wv2-config, WV2_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find libwv2 anywhere, check http://www.sourceforge.net/projects/wvware/]) + ]) + fi +fi + +if test -n "$WV2_CONFIG"; then + vers=`$WV2_CONFIG --version 2>/dev/null | $SED -e 's/libwv2 //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1009 + then + LIBWV2_LIBS="`$WV2_CONFIG --libs`" + LIBWV2_RPATH= + for args in $LIBWV2_LIBS; do + case $args in + -L*) + LIBWV2_RPATH="$LIBWV2_RPATH $args" + ;; + esac + done + LIBWV2_RPATH=`echo $LIBWV2_RPATH | $SED -e "s/-L/-R/g"` + LIBWV2_CFLAGS="`$WV2_CONFIG --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_WV2, 1, [Defines if your system has the wv2 library]) + else + AC_MSG_WARN([You need at least version 0.1.9 of libwv2]) + fi +fi + + +AC_SUBST(LIBWV2_LIBS) +AC_SUBST(LIBWV2_CFLAGS) +AC_SUBST(LIBWV2_RPATH) +AM_CONDITIONAL(include_wv2_msword_filter, test -n "$LIBWV2_LIBS") +dnl ======================================================= +dnl FILE: ./filters/kword/pdf/xpdf/configure.in.in +dnl ======================================================= + + +AC_HEADER_DIRENT +AC_HEADER_STDC +AC_CHECK_FUNCS(rewinddir popen mkstemp) + +dnl ##### Check for fseeko/ftello or fseek64/ftell64 +dnl The LARGEFILE and FSEEKO macros have to be called in C, not C++, mode. +AC_SYS_LARGEFILE +AC_FUNC_FSEEKO +AC_CHECK_FUNCS(fseek64) +AC_CHECK_FUNCS(ftell64) + +dnl ##### Check for libpaper (Debian). +KDE_CHECK_HEADERS(paper.h) +KDE_CHECK_LIB(paper, paperinit, [LIBPAPER="-lpaper"]) +AC_SUBST(LIBPAPER) +dnl ======================================================= +dnl FILE: ./filters/kword/wordperfect/configure.in.in +dnl ======================================================= + +KDE_FIND_PATH(pkg-config, PKGCONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find pkg-config]) +]) + +if test -n "$PKGCONFIG"; then + vers=`$PKGCONFIG libwpd-0.8 --modversion 2>/dev/null` + if test -n "$vers" + then + LIBWPD_LIBS="`$PKGCONFIG libwpd-0.8 --libs`" + LIBWPD_RPATH= + for args in $LIBWPD_LIBS; do + case $args in + -L*) + LIBWPD_RPATH="$LIBWPD_RPATH $args" + ;; + esac + done + LIBWPD_RPATH=`echo $LIBWPD_RPATH | $SED -e "s/-L/-R/g"` + LIBWPD_CFLAGS="`$PKGCONFIG libwpd-0.8 --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_WPD, 1, [Defines if your system has the libwpd library]) + fi +fi + + +AC_SUBST(LIBWPD_LIBS) +AC_SUBST(LIBWPD_CFLAGS) +AC_SUBST(LIBWPD_RPATH) + +AM_CONDITIONAL(include_wpd_filter, test -n "$LIBWPD_LIBS") + +dnl ======================================================= +dnl FILE: ./filters/xsltfilter/configure.in.in +dnl ======================================================= + + +KDE_FIND_PATH(xml2-config, XML_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find libxml2 anywhere, check ftp://xmlsoft.org/ for libxml >= 2.4.8. (we also keep a version of it in kdesupport for CVS users' convience)]) + HELP_SUBDIR= +]) + +if test -n "$XML_CONFIG"; then + vers=`$XML_CONFIG --version 2>/dev/null | $SED -e 's/libxml //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 2004008 + then + LIBXML_LIBS="`$XML_CONFIG --libs`" + LIBXML_RPATH= + for args in $LIBXML_LIBS; do + case $args in + -L*) + LIBXML_RPATH="$LIBXML_RPATH $args" + ;; + esac + done + LIBXML_RPATH=`echo $LIBXML_RPATH | $SED -e "s/-L/-R/g"` + LIBXML_CFLAGS="`$XML_CONFIG --cflags`" + + KDE_FIND_PATH(xmllint, XMLLINT, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [XMLLINT=""]) + AC_DEFINE_UNQUOTED(XMLLINT, "$XMLLINT", [Defines the executable of xmllint]) + else + AC_MSG_WARN([You need at least libxml 2.4.8]) + HELP_SUBDIR= + fi +fi + +KDE_FIND_PATH(xslt-config, XSLT_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find libxslt anywhere, check ftp://xmlsoft.org/ for libxslt >= 1.0.7. (we also keep a version of it in kdesupport for CVS users' convience)]) + HELP_SUBDIR= +]) + +if test -n "$XSLT_CONFIG"; then + vers=`$XSLT_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1000007; then + LIBXSLT_LIBS="`$XSLT_CONFIG --libs`" + LIBXSLT_RPATH= + for args in $LIBXSLT_LIBS; do + case $args in + -L*) + LIBXSLT_RPATH="$LIBXSLT_RPATH $args" + ;; + esac + done + LIBXSLT_RPATH=`echo $LIBXSLT_RPATH | $SED -e "s/-L/-R/g"` + LIBXSLT_CFLAGS="`$XSLT_CONFIG --cflags`" + + else + AC_MSG_WARN([You need at least libxslt 1.0.7]) + HELP_SUBDIR= + fi +fi + +if test ! "$USE_RPATH" = "yes"; then + LIBXSLT_RPATH= + LIBXML_RPATH= +fi + +AC_SUBST(LIBXSLT_LIBS) +AC_SUBST(LIBXSLT_CFLAGS) +AC_SUBST(LIBXSLT_RPATH) + +AC_SUBST(LIBXML_LIBS) +AC_SUBST(LIBXML_CFLAGS) +AC_SUBST(LIBXML_RPATH) + +AM_CONDITIONAL(include_XSLTFILTERS, test -n "$LIBXML_LIBS" -a -n "$LIBXSLT_LIBS") +dnl ======================================================= +dnl FILE: ./karbon/configure.in.in +dnl ======================================================= + + +KDE_FIND_PATH(freetype-config, FREETYPE_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find libfreetype anywhere, check http://www.freetype.org/]) +]) + +if test -n "$FREETYPE_CONFIG"; then + vers=`$FREETYPE_CONFIG --version 2>/dev/null | $SED -e 's/libfreetype //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 5000000 + then + LIBFREETYPE_LIBS="`$FREETYPE_CONFIG --libs`" + LIBFREETYPE_RPATH= + for args in $LIBFREETYPE_LIBS; do + case $args in + -L*) + LIBFREETYPE_RPATH="$LIBFREETYPE_RPATH $args" + ;; + esac + done + LIBFREETYPE_RPATH=`echo $LIBFREETYPE_RPATH | $SED -e "s/-L/-R/g"` + LIBFREETYPE_CFLAGS="`$FREETYPE_CONFIG --cflags`" + else + AC_MSG_WARN([You need at least libfreetype 5.0]) + fi +fi + +AC_SUBST(LIBFREETYPE_LIBS) +AC_SUBST(LIBFREETYPE_CFLAGS) +AC_SUBST(LIBFREETYPE_RPATH) + + +KDE_FIND_PATH(libart2-config, LIBART_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find libart anywhere, check http://www.levien.com/libart/]) +]) + +if test -n "$LIBART_CONFIG"; then + vers=`$LIBART_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 2003008 + then + LIBART_LIBS="`$LIBART_CONFIG --libs`" + LIBART_RPATH= + for args in $LIBART_LIBS; do + case $args in + -L*) + LIBART_RPATH="$LIBART_RPATH $args" + ;; + esac + done + LIBART_RPATH=`echo $LIBART_RPATH | $SED -e "s/-L/-R/g"` + LIBART_CFLAGS="`$LIBART_CONFIG --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_LIBART, 1, [Defines if your system has the libart library]) + else + AC_MSG_WARN([You need at least libart 2.3.8]) + fi +fi + +AC_SUBST(LIBART_LIBS) +AC_SUBST(LIBART_CFLAGS) +AC_SUBST(LIBART_RPATH) + + +# Check for fontconfig +KDE_FIND_PATH(fontconfig-config, FONTCONFIG_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + KDE_FIND_PATH(pkg-config, PKGCONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find neither pkg-config nor fontconfig-config, check http://www.fontconfig.org/ ]) + ]) +]) + +if test -n "$PKGCONFIG"; then + vers=`$PKGCONFIG fontconfig --modversion 2>/dev/null | $SED -e 's/libfontconfig //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1000001 + then + LIBFONTCONFIG_LIBS="`$PKGCONFIG fontconfig --libs`" + LIBFONTCONFIG_RPATH= + for args in $LIBFONTCONFIG_LIBS; do + case $args in + -L*) + LIBFONTCONFIG_RPATH="$LIBFONTCONFIG_RPATH $args" + ;; + esac + done + LIBFONTCONFIG_RPATH=`echo $LIBFONTCONFIG_RPATH | $SED -e "s/-L/-R/g"` + LIBFONTCONFIG_CFLAGS="`$PKGCONFIG fontconfig --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_FONTCONFIG, 1, [Defines if your system has the libfontconfig library]) + fi +fi + +if test -n "$FONTCONFIG_CONFIG"; then + vers=`$FONTCONFIG_CONFIG --version 2>/dev/null | $SED -e 's/libfontconfig //' | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1000001 + then + LIBFONTCONFIG_LIBS="`$FONTCONFIG_CONFIG --libs`" + LIBFONTCONFIG_RPATH= + for args in $LIBFONTCONFIG_LIBS; do + case $args in + -L*) + LIBFONTCONFIG_RPATH="$LIBFONTCONFIG_RPATH $args" + ;; + esac + done + LIBFONTCONFIG_RPATH=`echo $LIBFONTCONFIG_RPATH | $SED -e "s/-L/-R/g"` + LIBFONTCONFIG_CFLAGS="`$FONTCONFIG_CONFIG --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_FONTCONFIG, 1, [Defines if your system has the libfontconfig library]) + fi +fi + +AC_SUBST(LIBFONTCONFIG_LIBS) +AC_SUBST(LIBFONTCONFIG_CFLAGS) +AC_SUBST(LIBFONTCONFIG_RPATH) + +if test -z "$LIBART_LIBS"; then + DO_NOT_COMPILE="$DO_NOT_COMPILE karbon" +fi + +if test -n "$LIBFREETYPE_LIBS" -a -n "$LIBFONTCONFIG_LIBS"; then + AC_DEFINE_UNQUOTED(HAVE_KARBONTEXT, 1, [Defines if your system has the fontconfig and freetype libraries]) +fi +dnl ======================================================= +dnl FILE: ./kexi/3rdparty/configure.in.in +dnl ======================================================= + +dnl This is copied from gpsim-0.21.1/acinclude.m4, which was itself +dnl copied from the NcFTP distribution. +dnl Modified by David Faure for kexi's purposes. +dnl +dnl Original author Mike Gleason mgleason@NcFTP.com +dnl +dnl +AC_DEFUN([kexi_LIB_READLINE], [ +AC_MSG_CHECKING([for Readline library]) + +kexi_cv_lib_readline=no +ac_save_LIBS="$LIBS" +# Note: $LIBCURSES is permitted to be empty. +for LIBREADLINE in "-lreadline" "-lreadline $LIBCURSES" "-lreadline -ltermcap" "-lreadline -lncurses" "-lreadline -lcurses" +do + LIBS="$ac_save_LIBS $LIBREADLINE" + AC_TRY_RUN([ + /* program */ +#include +#include +#include + +main(int argc, char **argv) +{ + /* Note: don't actually call readline, since it may block; + * We just want to see if it (dynamic) linked in okay. + */ + if (argc == 0) /* never true */ + readline(0); + exit(0); +} +],[ + # action if true + kexi_cv_lib_readline=yes +],[ + # action if false + kexi_cv_lib_readline=no +],[ + # action if cross compiling + kexi_cv_lib_readline=no +]) + + if test "$kexi_cv_lib_readline" = yes ; then break ; fi +done +# restore LIBS +LIBS="$ac_save_LIBS" + +if test "$kexi_cv_lib_readline" = no ; then + LIBREADLINE="" + AC_MSG_RESULT("not found - kexisql will not be compiled") +else + AC_MSG_RESULT($LIBREADLINE) + AC_DEFINE(HAVE_READLINE, 1, [define if you have libreadline available]) +fi + +AM_CONDITIONAL(have_readline, test "$kexi_cv_lib_readline" = "yes") +AC_SUBST(LIBREADLINE) +]) + +kexi_LIB_READLINE +dnl ======================================================= +dnl FILE: ./kexi/configure.in.in +dnl ======================================================= + + +#KEXI_VERSION= +AC_SUBST(LIB_KEXI_KMDI, '-lkmdi') +AC_SUBST(LIB_KEXI_KMDI_INCLUDES, '') + +dnl ======================================================= +dnl FILE: ./kexi/kexidb/drivers/configure.in.in +dnl ======================================================= + +dnl ======================================== +dnl checks for MySQL +dnl taken form KDEDB +dnl ======================================== + +AC_ARG_ENABLE(mysql, + AC_HELP_STRING([--enable-mysql],[build MySQL-plugin [default=yes]]), + mysql_plugin=$enableval, mysql_plugin=yes) + +if test "x$mysql_plugin" = "xyes"; then + compile_mysql_plugin="yes" +else + compile_mysql_plugin="no" +fi + +AC_ARG_WITH(mysql_includes, +AC_HELP_STRING([--with-mysql-includes=DIR],[use MySQL-includes installed in this directory]), +[ + ac_mysql_incdir=$withval +], ac_mysql_incdir= +) + +AC_ARG_WITH(mysql_libraries, +AC_HELP_STRING([--with-mysql-libraries=DIR],[use MySQL-libs installed in this directory ]), +[ + ac_mysql_libdir=$withval +], ac_mysql_libdir= +) + +dnl ============================================== +dnl check whether MySQL should be compiled +dnl and where headers and libraries are installed +dnl if present compile mysql-plugin +dnl ============================================== + +AC_MSG_CHECKING([for MySQL]) + +if test "$compile_mysql_plugin" = "yes"; then + if test -n "$ac_mysql_incdir" -o -n "$ac_mysql_libdir"; then +dnl *** Configure arguments for includes or libs given *** +dnl *** and MySQL not explicitly disabled. *** +dnl *** Check that the paths given to configure are valid *** + AC_MSG_CHECKING([for MySQL headers]) + mysql_incdirs="$ac_mysql_incdir /usr/local/include /usr/include" + AC_FIND_FILE(mysql/mysql.h, $mysql_incdirs, mysql_incdir) + if test -r $mysql_incdir/mysql/mysql.h; then + MYSQL_INC=$mysql_incdir + AC_MSG_RESULT([$MYSQL_INC]) + AC_SUBST(MYSQL_INC) + else + compile_mysql_plugin="no" + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for MySQL libraries]) + mysql_libdirs="$ac_mysql_libdir /usr/local/lib$kdelibsuff /usr/lib$kdelibsuff" + AC_FIND_FILE(mysql/libmysqlclient.so, $mysql_libdirs, mysql_libdir) + if test -r $mysql_libdir/mysql/libmysqlclient.so; then + MYSQL_LIBS=$mysql_libdir + AC_MSG_RESULT([$MYSQL_LIBS]) + AC_SUBST(MYSQL_LIBS) + else + compile_mysql_plugin="no" + AC_MSG_RESULT([not found]) + fi + else +dnl *** No configure arguments for includes or libs given *** +dnl *** and MySQL not explicitly disabled. *** + KDE_FIND_PATH(mysql_config, MYSQL_CONFIG, + [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /usr/bin ], [ + AC_MSG_RESULT([not found]) + ]) + + if test -n "$MYSQL_CONFIG"; then + mysql_incdir=`$MYSQL_CONFIG --cflags| $SED -e "s,-I,,g" | cut -d " " -f 1` + mysql_libdir=`$MYSQL_CONFIG --libs| $SED -e "s,',,g"` + MYSQL_INC=$mysql_incdir + MYSQL_LIBS=$mysql_libdir + AC_SUBST(MYSQL_INC) + AC_SUBST(MYSQL_LIBS) + compile_mypsql_plugin="yes" + AC_MSG_RESULT([headers $mysql_incdir, libraries $mysql_libdir]) + else + compile_mysql_plugin="no" + fi + fi +else +dnl *** MySQL plugin explicitly disabled. *** +dnl *** Show that we are doing as requested. *** + AC_MSG_NOTICE([Not attempting to configure MySQL as requested]) +fi + +AM_CONDITIONAL(compile_mysql_plugin, test "$compile_mysql_plugin" = "yes") + +dnl ======================================== +dnl Checks for PostgreSQL +dnl ======================================== + +dnl ======================================== +dnl libpq +dnl Add configure-args +dnl ======================================== + +dnl Assume we're building until something fails, unless explicitly disabled +AC_ARG_ENABLE(pgsql, +AC_HELP_STRING([--enable-pgsql],[build PostgreSQL-plugin [default=yes]]), + pgsql_plugin=$enableval, pgsql_plugin=yes) + +if test "x$pgsql_plugin" = "xyes"; then + compile_pgsql_plugin="yes" +else + compile_pgsql_plugin="no" +fi + +AC_ARG_WITH(pgsql-includes, +AC_HELP_STRING([--with-pgsql-includes=DIR],[use PostgreSQL(libpq)-includes installed in this directory ]), +[ + ac_pgsql_incdir=$withval +], ac_pgsql_incdir= +) + +AC_ARG_WITH(pgsql-libraries, +AC_HELP_STRING([--with-pgsql-libraries=DIR],[use PostgreSQL(libpq)-libraries installed in this directory ]), +[ + ac_pgsql_libdir=$withval +], ac_pgsql_libdir= +) + + +dnl ======================================== +dnl header/library directories +dnl ======================================== + +if test "$compile_pgsql_plugin" = "yes"; then + if test -n "$ac_pgsql_incdir" -o -n "$ac_pgsql_libdir"; then +dnl *** Configure arguments for includes or libs given *** +dnl *** and PostgreSQL not explicitly disabled. *** +dnl *** Check that the paths given to configure are valid *** + AC_MSG_CHECKING([for PostgreSQL C API headers]) + pgsql_incdirs="$ac_pgsql_incdir /usr/local/include /usr/include" + AC_FIND_FILE(libpq-fe.h, $pgsql_incdirs, pgsql_incdir) + if test -r $pgsql_incdir/libpq-fe.h; then + PG_INCDIR=$pgsql_incdir + AC_MSG_RESULT([$PG_INCDIR]) + AC_SUBST(PG_INCDIR) + else + compile_pgsql_plugin="no" + AC_MSG_RESULT([not found]) + fi + + AC_MSG_CHECKING([for PostgreSQL C API libraries]) + pgsql_libdirs="$ac_pgsql_libdir /usr/local/lib$kdelibsuff /usr/lib$kdelibsuff" + AC_FIND_FILE(libpq.so, $pgsql_libdirs, pgsql_libdir) + if test -r $pgsql_libdir/libpq.so; then + PG_LIBDIR=$pgsql_libdir + AC_MSG_RESULT([$PG_LIBDIR]) + AC_SUBST(PG_LIBDIR) + else + compile_pgsql_plugin="no" + AC_MSG_RESULT([not found]) + fi + else +dnl *** No configure arguments for includes or libs given *** +dnl *** and PostgreSQL not explicitly disabled. *** + KDE_FIND_PATH(pg_config, PG_CONFIG, + [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /usr/bin ], [ + AC_MSG_RESULT([not found]) + ]) + + if test -n "$PG_CONFIG"; then + pgsql_incdir=`$PG_CONFIG --includedir` + pgsql_libdir=`$PG_CONFIG --libdir` + PG_INCDIR=$pgsql_incdir + PG_LIBDIR=$pgsql_libdir + AC_SUBST(PG_LIBDIR) + compile_pgsql_plugin="yes" + AC_MSG_RESULT([headers $pgsql_incdir, libraries $pgsql_libdir]) + else + compile_pgsql_plugin="no" + fi + fi +else +dnl *** PostgreSQL plugin explicitly disabled. *** +dnl *** Show that we are doing as requested. *** + AC_MSG_NOTICE([Not attempting to configure PostgreSQL as requested]) +fi + +AM_CONDITIONAL(compile_pgsql_plugin, test "$compile_pgsql_plugin" = "yes") + + +dnl ======================================== +dnl libpqxx checks +dnl ======================================== + +AC_ARG_WITH(pqxx-includes, +AC_HELP_STRING([--with-pqxx-includes=DIR],[use PostgreSQL(libpqxx)-includes installed in this directory ]), +[ + ac_pqxx_incdir=$withval +], ac_pqxx_incdir= +) + +AC_ARG_WITH(pqxx-libraries, +AC_HELP_STRING([--with-pqxx-libraries=DIR],[use PostgreSQL(libpqxx)-libraries installed in this directory ]), +[ + ac_pqxx_libdir=$withval +], ac_pqxx_libdir= +) + + +dnl ======================================== +dnl libpqxx headers +dnl ======================================== +if test "$compile_pgsql_plugin" = "yes"; then + AC_MSG_CHECKING([for PostgreSQL C++ includes]) + pqxx_incdirs="$ac_pqxx_incdir /usr/local/include /usr/include" + AC_FIND_FILE(pqxx/pqxx, $pqxx_incdirs, pqxx_incdir) + if test -r $pqxx_incdir/pqxx/pqxx; then + PQXX_INCDIR=$pqxx_incdir + AC_MSG_RESULT([$PQXX_INCDIR]) + AC_SUBST(PQXX_INCDIR) + else + compile_pgsql_plugin="no" + AC_MSG_RESULT([not found]) + fi +fi + +dnl ======================================== +dnl libpqxx libraries +dnl ======================================== +if test "$compile_pgsql_plugin" = "yes"; then + AC_MSG_CHECKING([for PostgreSQL C++ libraries]) + pqxx_libdirs="$ac_pqxx_libdir /usr/local/lib$kdelibsuff /usr/lib$kdelibsuff" + AC_FIND_FILE(libpqxx.so, $pqxx_libdirs, pqxx_libdir) + if test -r $pqxx_libdir/libpqxx.so; then + PQXX_LIBDIR=$pqxx_libdir + AC_MSG_RESULT([$PQXX_LIBDIR]) + AC_SUBST(PQXX_LIBDIR) + else + compile_pgsql_plugin="no" + AC_MSG_RESULT([not found]) + fi +fi + +AM_CONDITIONAL(compile_pgsql_plugin, test "$compile_pgsql_plugin" = "yes") +dnl ======================================================= +dnl FILE: ./kexi/main/configure.in.in +dnl ======================================================= + + +dnl ====================================== +dnl KNewStuff Configuration +dnl ====================================== +dnl +dnl Copyright (C) 2004 Josef Spillner +dnl This file is to be used within KDE's build system. +dnl It defines $(LIB_KNEWSTUFF) if knewstuff has been found, +dnl and a HAVE_KNEWSTUFF #define statement is added. +dnl + +AC_MSG_CHECKING([for KDE library: knewstuff]) + +ac_knewstuff_includes=NO ac_knewstuff_libraries=NO +knewstuff_libraries="" +knewstuff_includes="" + +AC_CACHE_VAL(ac_cv_have_knewstuff, +[ +AC_FIND_FILE(knewstuff/downloaddialog.h, $kde_incdirs, knewstuff_incdir) +ac_knewstuff_includes="$knewstuff_incdir" + +AC_FIND_FILE(libknewstuff.so, $kde_libdirs, knewstuff_libdir) +ac_knewstuff_libraries="$knewstuff_libdir" + +if test "$ac_knewstuff_includes" = NO || test "$ac_knewstuff_libraries" = NO; then + ac_cv_have_knewstuff="have_knewstuff=no" + ac_knewstuff_notfound="" +else + have_knewstuff="yes" +fi +]) + +eval "$ac_cv_have_knewstuff" + +if test "$have_knewstuff" != yes; then + AC_MSG_RESULT([$have_knewstuff]) +else + AC_MSG_RESULT([$have_knewstuff (libraries $ac_knewstuff_libraries, headers $ac_knewstuff_includes)]) + +dnl AC_DEFINE_UNQUOTED(HAVE_KNEWSTUFF, 1, [Add KNewStuff functionality.]) + CXXFLAGS="$CXXFLAGS -DHAVE_KNEWSTUFF" + + LIB_KNEWSTUFF='-lknewstuff' + AC_SUBST(LIB_KNEWSTUFF) +fi + +AC_CHECK_FILE([kexi/3rdparty/kexifeedbackwizard/lib/kexifeedbackwizard.cpp], + have_internal_feedback="yes" +, + have_internal_feedback="no" +) + +AC_MSG_CHECKING([for KDE library: kfeedbackwizard]) + +ac_kfeedback_includes=NO ac_kfeedback_libraries=NO +kfeedback_libraries="" +kfeedback_includes="" + +AC_CACHE_VAL(ac_cv_have_kfeedback, +[ +AC_FIND_FILE(kfeedbackwizard.h, $kde_incdirs, kfeedback_incdir) +ac_kfeedback_includes="$kfeedback_incdir" + +AC_FIND_FILE(libkfeedbackwizard.so, $kde_libdirs, kfeedback_libdir) +ac_kfeedback_libraries="$kfeedback_libdir" + +if test "$ac_kfeedback_includes" = NO || test "$ac_kfeedback_libraries" = NO; then + ac_cv_have_kfeedback="have_kfeedback=no" + ac_kfeedback_notfound="" +else + have_kfeedback="yes" +fi +]) + +eval "$ac_cv_have_kfeedback" + +INC_KFEEDBACK='' +LIB_KFEEDBACK='' +if test "$have_kfeedback" != yes; then + if test "$have_internal_feedback" = yes; then + CXXFLAGS="$CXXFLAGS -DFEEDBACK_CLASS=KexiFeedbackWizard -DFEEDBACK_INCLUDE=\"\"" + use_kexifb="yes" + AC_MSG_RESULT([using internal]) + INC_KFEEDBACK='-I../3rdparty/kexifeedbackwizard/lib' + LIB_KFEEDBACK='../3rdparty/kexifeedbackwizard/lib/libkexifeedbackwizard.la' + else + use_kexifb="no" + AC_MSG_RESULT([dont use]) + fi +else + use_kexifb="no" + AC_MSG_RESULT([$have_kfeedback (libraries $ac_kfeedback_libraries, headers $ac_kfeedback_includes)]) + +dnl AC_DEFINE_UNQUOTED(HAVE_KFEEDBACK, 1, [Add KNewStuff functionality.]) + CXXFLAGS="$CXXFLAGS -DFEEDBACK_CLASS=KFeedbackWizard -DFEEDBACK_INCLUDE=\"\"" + + LIB_KFEEDBACK='-lkfeedbackwizard' +fi +AC_SUBST(LIB_KFEEDBACK) +AC_SUBST(INC_KFEEDBACK) +AM_CONDITIONAL(use_kexifeedback, test "$use_kexifb" = "yes") +dnl ======================================================= +dnl FILE: ./kexi/migration/configure.in.in +dnl ======================================================= + +# KexiMDB isn't built as part of Kexi right now. +#AC_ARG_ENABLE(keximdb, +# AC_HELP_STRING([--enable-keximdb], +# [build KexiMDB (MS Access) plugin [default=no]]), +# compile_keximdb_plugin=$enableval, compile_keximdb_plugin=no) +# +#AM_CONDITIONAL(compile_keximdb_plugin, test "x$compile_keximdb_plugin" != "xno") +dnl ======================================================= +dnl FILE: ./kexi/plugins/configure.in.in +dnl ======================================================= + +# disabled +#AC_ARG_ENABLE(kexi-reports, +# AC_HELP_STRING([--enable-kexi-reports], +# [build Kexi reports plugin (EXPERIMENTAL) [default=no]]), +# compile_kexi_reports_plugin=$enableval, compile_kexi_reports_plugin=no) +#AM_CONDITIONAL(compile_kexi_reports_plugin, test "x$compile_kexi_reports_plugin" != "xno") +# +#if test "$compile_kexi_reports_plugin" == "yes"; then +# AC_DEFINE(KEXI_REPORTS_SUPPORT, 1, [build Kexi reports plugin]) +#fi + +AC_ARG_ENABLE(kexi-macros, + AC_HELP_STRING([--enable-kexi-macros], + [build Kexi macro plugin (EXPERIMENTAL) [default=yes]]), + compile_kexi_macros_plugin=$enableval, compile_kexi_macros_plugin=no) +AM_CONDITIONAL(compile_kexi_macros_plugin, test "x$compile_kexi_macros_plugin" == "xyes") + +if test "$compile_kexi_macros_plugin" == "yes"; then + AC_DEFINE(KEXI_MACROS_SUPPORT, 1, [build Kexi macros plugin]) +fi +dnl ======================================================= +dnl FILE: ./kexi/plugins/macros/configure.in.in +dnl ======================================================= + +# Check for kunittest +AC_MSG_CHECKING([for kunittest]) + +# First we check if the console unittester could be compiled +have_kunittest_header="no" +KDE_CHECK_HEADER(kunittest/tester.h, have_kunittest_header="yes", , ) +AM_CONDITIONAL(include_kunittest, test "$have_kunittest_header" = "yes") + +# Second we check if the GUI-unittester could be compiled +have_kunittestgui_header="no" +KDE_CHECK_HEADER(kunittest/runnergui.h, have_kunittestgui_header="yes", , ) +AM_CONDITIONAL(include_kunittestgui, test "$have_kunittestgui_header" = "yes") + +dnl ======================================================= +dnl FILE: ./kivio/configure.in.in +dnl ======================================================= + +dnl Do we have Python? +KDE_CHECK_PYTHON +dnl ======================================================= +dnl FILE: ./kpresenter/configure.in.in +dnl ======================================================= + +AC_HAVE_DPMS() +dnl ======================================================= +dnl FILE: ./krita/configure.in.in +dnl ======================================================= + +KDE_CHECK_LIB(Xi, XOpenDisplay, [ + LIB_XINPUTEXT="-lXi" + AC_DEFINE(HAVE_XINPUTEXT, 1, [Define if you have the X11 Input Extension]) + ]) +AC_SUBST(LIB_XINPUTEXT) + +# Check for lcms +AC_MSG_CHECKING([for lcms >= 1.15]) + +have_lcms_header='no' +KDE_CHECK_HEADER(lcms/lcms.h,have_lcms_header='yes',,) +if test "$have_lcms_header" = 'yes' +then + AC_DEFINE(LCMS_HEADER, , [The correct header]) + + echo "#include " > conftest.$ac_ext + echo "#if LCMS_VERSION < 115" >> conftest.$ac_ext + echo "#error Need lcms >= 1.15" >> conftest.$ac_ext + echo "#endif" >> conftest.$ac_ext + echo "int main() {}" >> conftest.$ac_ext + +else + # Alternative! Debian does it this way... + KDE_CHECK_HEADER(lcms.h,have_lcms_header='yes',,) + + if test "$have_lcms_header" = 'yes' + then + AC_DEFINE(LCMS_HEADER, , [The correct header]) + + echo "#include " > conftest.$ac_ext + echo "#if LCMS_VERSION < 115" >> conftest.$ac_ext + echo "#error Need lcms >= 1.15" >> conftest.$ac_ext + echo "#endif" >> conftest.$ac_ext + echo "int main() {}" >> conftest.$ac_ext + else + KDE_CHECK_HEADER(lcms.h,have_lcms_header='yes',,) + # and now debian also does it this way... can't they decide for one way of doing stuff ? + + AC_DEFINE(LCMS_HEADER, , [The correct header]) + + echo "#include " > conftest.$ac_ext + echo "#if LCMS_VERSION < 115" >> conftest.$ac_ext + echo "#error Need lcms >= 1.15" >> conftest.$ac_ext + echo "#endif" >> conftest.$ac_ext + echo "int main() {}" >> conftest.$ac_ext + + fi +fi + + +ac_link='$LIBTOOL_SHELL --mode=link ${CXX-g++} -o conftest $CXXFLAGS $all_includes $CPPFLAGS $LDFLAGS $all_libraries conftest.$ac_ext -llcms 1>&5' + +if AC_TRY_EVAL(ac_link) && test -s conftest; then + AC_MSG_RESULT(yes) + HAVELCMS="yes" + LCMS_LIBS="-llcms" +else + AC_MSG_RESULT(no) + HAVELCMS="no" + LCMS_LIBS="" + DO_NOT_COMPILE="$DO_NOT_COMPILE krita" +fi + +AC_SUBST(LCMS_LIBS) + +# IM 6.1.3 changed the number of arguments to GetMagickInfoList + +AC_MSG_CHECKING(if GetMagickInfoList has only 2 arguments) +CPPFLAGS_TMP="$CPPFLAGS" # Save preprocessor flags +CPPFLAGS="$LIBMAGICK_CPPFLAGS" + +AC_TRY_COMPILE( + [#include + #if HAVE_SYS_TYPES_H + #include + #endif + #include "magick/api.h"], + [const char *pattern; unsigned long ncolors; (void)GetMagickInfoList(pattern, &ncolors)], + magick_info_list='yes', + magick_info_list='no') + +CPPFLAGS="$CPPFLAGS_TMP" # Restore preprocessor flags + +if test "$magick_info_list" = 'yes'; then + AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_OLD_GETMAGICKINFOLIST], 1, [GetMagickInfoList has different number of arguments with versions >= 6.1.3]) +else + AC_MSG_RESULT(no) +fi + +# Check for kunittest +AC_MSG_CHECKING([for kunittest]) + +have_kunittest_header="no" +KDE_CHECK_HEADER(kunittest/tester.h, have_kunittest_header="yes", , ) +AM_CONDITIONAL(include_kunittest_tests, test "$have_kunittest_header" = "yes") + +# --- OpenGL check --- + +AC_HAVE_GL( [], [] ) + +# --- End of OpenGL check --- + +# Check for powf. + +AC_CHECK_FUNC(powf, [have_powf="yes"], [AC_CHECK_LIB(m, powf, [have_powf="yes"], [have_powf="no"])]) + +if test "$have_powf" = 'yes'; then + AC_DEFINE([HAVE_POWF], 1, [Define to 1 if your system has powf in ]) +fi\ +dnl ======================================================= +dnl FILE: ./krita/plugins/configure.in.in +dnl ======================================================= + +KDE_CHECK_HEADER(kjsembed/jsproxy_imp.h, have_kjsembed=yes, have_kjsembed=no) +AM_CONDITIONAL(use_kjsembed, test x$have_kjsembed = xyes) +dnl ======================================================= +dnl FILE: ./krita/plugins/viewplugins/imagesize/configure.in.in +dnl ======================================================= + +AC_CHECK_DECLS([round], [], [], [#include ]) +dnl ======================================================= +dnl FILE: ./kspread/plugins/calculator/configure.in.in +dnl ======================================================= + +AC_CHECK_HEADERS(ieeefp.h) + +AC_CHECK_FUNCS(fabsl) + +AC_DEFUN([KDE_C_LONG_DOUBLE], +[ + AC_CACHE_CHECK(for long double, ac_cv_c_long_double, + [ + AC_TRY_RUN( + [ +#include +#include +#include +#include + +int main() { +/* The Stardent Vistra knows sizeof(long double), but does not support it. */ +long double foo = 1.0; +char buffer[10]; +/* On Ultrix 4.3 cc, long double is 4 and double is 8. */ +int result = (sizeof(long double) < sizeof(double)); +/* the following is needed for a broken printf in glibc2 */ +if (!result) { + foo = foo * 3; + sprintf(buffer,"%0.0Lf",foo); + result = strcmp(buffer, "3"); +/* and now something mean ;-) */ + foo = powl(fabsl(foo), 1); +} +exit(result); } + ], + ac_cv_c_long_double=yes, ac_cv_c_long_double=no, + ac_cv_c_long_double=no + ) + ]) + if test $ac_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have support for long double in printf]) + fi +]) +KDE_C_LONG_DOUBLE + +AC_LANG_C +KDE_CHECK_LIB(m, isinf, [ + AC_DEFINE_UNQUOTED(HAVE_FUNC_ISINF, 1, [Define if you have isinf]) +]) +dnl ======================================================= +dnl FILE: ./kword/mailmerge/configure.in.in +dnl ======================================================= + +dnl only compile the sql plugin if qt was compiled with sql support + + +AC_MSG_CHECKING([for SQL support in QT]) + +LIBS_SAVE_KWSL="$LIBS" +CXXFLAGS_SAVE_KWSL="$CXXFLAGS" +CFLAGS_SAVE_KWSL="$CFLAGS" + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS + +LIBS="$all_libraries -lqimgio -lpng -lz $LIBJPEG $LIBQT" +CXXFLAGS="$CXXFLAGS -I$qt_includes $all_includes" + +AC_TRY_COMPILE([ +#include +], +[ +#ifdef QT_NO_SQL +#error "No QT-SQL support" +#endif +], +ac_trycompile_kwsl_qtsql=yes, +ac_trycompile_kwsl_qtsql=no) + +CXXFLAGS="$CXXFLAGS_SAVE_KWSL" +LIBS="$LIBS_SAVE_KWSL" +AC_LANG_RESTORE + +if eval "test \"`echo $ac_trycompile_kwsl_qtsql`\" = yes"; then + SQLDIR=sql + AC_SUBST(SQLDIR) + AC_MSG_RESULT([QT supports SQL - compile qtsqlmailmerge]) +else + SQLDIR= + AC_SUBST(SQLDIR) + AC_MSG_RESULT([QT supports SQL -- qtsqlmailmerge will not be built]) +fi + +AM_CONDITIONAL(include_sql, test -n "$SQLDIR") +dnl ======================================================= +dnl FILE: ./lib/configure.in.in +dnl ======================================================= + +AC_SUBST(KWMF_INCLUDES, '-I$(top_srcdir)/lib/kwmf -I$(top_builddir)/lib/kwmf') +AC_SUBST(KSTORE_INCLUDES, '-I$(top_srcdir)/lib/store -I$(top_builddir)/lib/store') +AC_SUBST(KOTEXT_INCLUDES, '-I$(top_srcdir)/lib/kotext -I$(top_builddir)/lib/kotext') +AC_SUBST(KOPAINTER_INCLUDES, '-I$(top_srcdir)/lib/kopainter -I$(top_builddir)/lib/kopainter') +AC_SUBST(KOPALETTE_INCLUDES, '-I$(top_srcdir)/lib/kopalette -I$(top_builddir)/lib/kopalette') +AC_SUBST(KOFFICECORE_INCLUDES, '-I$(top_srcdir)/lib/kofficecore -I$(top_builddir)/lib/kofficecore') +AC_SUBST(KOFFICEUI_INCLUDES, '-I$(top_srcdir)/lib/kofficeui -I$(top_builddir)/lib/kofficeui') +AC_SUBST(KFORMULA_INCLUDES, '-I$(top_srcdir)/lib/kformula -I$(top_builddir)/lib/kformula') +dnl those are included with e.g. +AC_SUBST(KOPROPERTY_INCLUDES, '-I$(top_srcdir)/lib -I$(top_builddir)/lib') +AC_SUBST(KROSS_INCLUDES, '-I$(top_srcdir)/lib/kross -I$(top_builddir)/lib/kross') +AC_SUBST(LIB_KOFFICEUI, '$(top_builddir)/lib/kofficeui/libkofficeui.la') +AC_SUBST(LIB_KOFFICECORE, '$(top_builddir)/lib/kofficecore/libkofficecore.la') +AC_SUBST(LIB_KSTORE, '$(top_builddir)/lib/store/libkstore.la') +AC_SUBST(LIB_KOTEXT, '$(top_builddir)/lib/kotext/libkotext.la') +AC_SUBST(LIB_KOPAINTER, '$(top_builddir)/lib/kopainter/libkopainter.la') +AC_SUBST(LIB_KOPALETTE, '$(top_builddir)/lib/kopalette/libkopalette.la') +AC_SUBST(LIB_KWMF, '$(top_builddir)/lib/kwmf/libkwmf.la') +AC_SUBST(LIB_KOWMF, '$(top_builddir)/lib/kwmf/libkowmf.la') +AC_SUBST(LIB_KFORMULA, '$(top_builddir)/lib/kformula/libkformulalib.la') +AC_SUBST(LIB_KOPROPERTY, '$(top_builddir)/lib/koproperty/libkoproperty.la') +AC_SUBST(LIB_KROSS_API, '$(top_builddir)/lib/kross/api/libkrossapi.la') +AC_SUBST(LIB_KROSS_MAIN, '$(top_builddir)/lib/kross/main/libkrossmain.la') + +AC_SUBST(interfacedir, '$(top_srcdir)/lib/interfaces') +AC_SUBST(KOFFICE_LIBS, '$(LIB_KOFFICEUI) $(LIB_KOFFICECORE) $(LIB_KSTORE)') +AC_SUBST(KOFFICE_INCLUDES, '$(KOFFICEUI_INCLUDES) $(KOFFICECORE_INCLUDES) $(KSTORE_INCLUDES) $(KWMF_INCLUDES) $(KOPALETTE_INCLUDES)') + +AC_DEFINE_UNQUOTED(PREFIX,"$prefix",[Define the PREFIX where to install this package]) + +dnl ======================================================= +dnl FILE: ./lib/kotext/configure.in.in +dnl ======================================================= + + AC_LANG_SAVE + AC_LANG_C + dnl Check for aspell library + KDE_CHECK_HEADERS([kspell2/broker.h]) + if test "x$ac_cv_header_kspell2_broker_h" = "xyes"; then + dnl the header and the lib exist -> ok + dnl this is for config.h + AC_DEFINE(HAVE_LIBKSPELL2, 1, [If we are going to use libkspell2 for spell-checking]) + LIBKSPELL2="-lkspell2" + AC_MSG_RESULT([found in $ac_kspell2_includes]) + else + LIBKSPELL2="" + AC_MSG_RESULT([not found -- spell-checking will be disabled]) + fi + AC_SUBST(LIBKSPELL2) + AC_LANG_RESTORE +dnl ======================================================= +dnl FILE: ./lib/kross/configure.in.in +dnl ======================================================= + +AC_ARG_ENABLE(scripting, + AC_HELP_STRING([--enable-scripting], + [build scripting library (Kross) [default=yes]]), + compile_kross=$enableval, compile_kross=yes) +AM_CONDITIONAL(compile_kross, test "x$compile_kross" = "xyes") + +############################### +# Check if Python is installed. + +if test "x$compile_kross" = "xyes" ; then + #KDE_CHECK_PYTHON(2.3) + KDE_CHECK_PYTHON +fi + +# Compile the Kross python plugin only if both, $LIBPYTHON and +# $PYTHONINC, are defined. +AM_CONDITIONAL(compile_kross_python, + test -n "$LIBPYTHON" && test -n "$PYTHONINC") + +############################### +# Check for Ruby + +if test "x$compile_kross" = "xyes" ; then + AC_CHECK_PROGS([RUBY], [ruby ruby1.8 ruby18], ruby) + + if test -n "$RUBY"; then + AC_MSG_CHECKING(for Ruby dirs) + RUBY_ARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"archdir"@:>@)'` + RUBY_SITEARCHDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitearchdir"@:>@)'` + RUBY_SITEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"sitelibdir"@:>@)'` + RUBY_INCLUDEDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"rubyincludedir"@:>@)'` + RUBY_LIBDIR=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"libdir"@:>@)'` + RUBY_LIBRUBYARG=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"LIBRUBYARG_SHARED"@:>@)'` + RUBY_ENABLESHARED=`$RUBY -r rbconfig -e 'printf("%s",Config::CONFIG@<:@"ENABLE_SHARED"@:>@)'` + AC_MSG_RESULT([ + archdir $RUBY_ARCHDIR, + sitearchdir $RUBY_SITEARCHDIR, + sitedir $RUBY_SITEDIR, + includedir $RUBY_INCLUDEDIR, + libdir $RUBY_LIBDIR, + librubyarg $RUBY_LIBRUBYARG, + rubysharedenabled $RUBY_ENABLESHARED]) + AC_SUBST(RUBY_ARCHDIR) + AC_SUBST(RUBY_SITEARCHDIR) + AC_SUBST(RUBY_SITEDIR) + AC_SUBST(RUBY_INCLUDEDIR) + AC_SUBST(RUBY_LIBDIR) + AC_SUBST(RUBY_LIBRUBYARG) + AC_SUBST(RUBY_ENABLESHARED) + + AC_MSG_CHECKING(for Ruby header) + + if test ! -r $RUBY_INCLUDEDIR/ruby.h; then + # if $RUBY_INCLUDEDIR is not valid try to use $RUBY_ARCHDIR + RUBY_INCLUDEDIR=$RUBY_ARCHDIR + fi + + if test ! -r $RUBY_INCLUDEDIR/ruby.h; then + RUBY_LIBDIR="" + AC_MSG_RESULT([not found]) + else + AC_MSG_RESULT([found]) # header + + AC_MSG_CHECKING(Ruby shared library) + if test "x$RUBY_ENABLESHARED" != "xyes" ; then + AC_MSG_RESULT([shared library not found]) + RUBY_LIBDIR="" + else + if test -z "$RUBY_LIBRUBYARG" ; then + AC_MSG_RESULT([link argument not found]) + RUBY_LIBDIR="" + else + AC_MSG_RESULT([found]) # shared library link arg + + AC_MSG_CHECKING([if C++ program with ruby can be compiled]) + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + ac_save_CXXFLAGS="$CXXFLAGS" + CXXFLAGS="$CXXFLAGS -I$RUBY_INCLUDEDIR" + AC_CACHE_VAL(ruby_build, + [ + AC_TRY_COMPILE([ + #include + #include + ],[ + +#if(RUBY_VERSION_MAJOR==1 && RUBY_VERSION_MINOR == 8 && RUBY_VERSION_TEENY <= 1) +#error "need at least ruby 1.8.2\n" +#endif + + ruby_init(); + return 0; + ], ruby_build=yes, + ruby_build=no) + ]) + AC_MSG_RESULT($ruby_build) + if test "$ruby_build" = "no"; then + RUBY_LIBDIR="" + fi + CXXFLAGS="$ac_save_CXXFLAGS" + AC_LANG_RESTORE + fi # have ruby shared lib argument + fi # have shared lib + fi # have ruby header + fi # have ruby +fi # compiling kross + +AM_CONDITIONAL(compile_kross_ruby, test -n "$RUBY_LIBDIR") +KDE_CREATE_SUBDIRSLIST +AM_CONDITIONAL(lib_SUBDIR_included, test "x$lib_SUBDIR_included" = xyes) +AM_CONDITIONAL(interfaces_SUBDIR_included, test "x$interfaces_SUBDIR_included" = xyes) +AM_CONDITIONAL(autocorrect_SUBDIR_included, test "x$autocorrect_SUBDIR_included" = xyes) +AM_CONDITIONAL(doc_SUBDIR_included, test "x$doc_SUBDIR_included" = xyes) +AM_CONDITIONAL(example_SUBDIR_included, test "x$example_SUBDIR_included" = xyes) +AM_CONDITIONAL(karbon_SUBDIR_included, test "x$karbon_SUBDIR_included" = xyes) +AM_CONDITIONAL(kchart_SUBDIR_included, test "x$kchart_SUBDIR_included" = xyes) +AM_CONDITIONAL(kdgantt_SUBDIR_included, test "x$kdgantt_SUBDIR_included" = xyes) +AM_CONDITIONAL(kformula_SUBDIR_included, test "x$kformula_SUBDIR_included" = xyes) +AM_CONDITIONAL(kivio_SUBDIR_included, test "x$kivio_SUBDIR_included" = xyes) +AM_CONDITIONAL(koshell_SUBDIR_included, test "x$koshell_SUBDIR_included" = xyes) +AM_CONDITIONAL(kounavail_SUBDIR_included, test "x$kounavail_SUBDIR_included" = xyes) +AM_CONDITIONAL(kpresenter_SUBDIR_included, test "x$kpresenter_SUBDIR_included" = xyes) +AM_CONDITIONAL(krita_SUBDIR_included, test "x$krita_SUBDIR_included" = xyes) +AM_CONDITIONAL(kspread_SUBDIR_included, test "x$kspread_SUBDIR_included" = xyes) +AM_CONDITIONAL(kugar_SUBDIR_included, test "x$kugar_SUBDIR_included" = xyes) +AM_CONDITIONAL(mimetypes_SUBDIR_included, test "x$mimetypes_SUBDIR_included" = xyes) +AM_CONDITIONAL(pics_SUBDIR_included, test "x$pics_SUBDIR_included" = xyes) +AM_CONDITIONAL(plugins_SUBDIR_included, test "x$plugins_SUBDIR_included" = xyes) +AM_CONDITIONAL(servicetypes_SUBDIR_included, test "x$servicetypes_SUBDIR_included" = xyes) +AM_CONDITIONAL(templates_SUBDIR_included, test "x$templates_SUBDIR_included" = xyes) +AM_CONDITIONAL(tools_SUBDIR_included, test "x$tools_SUBDIR_included" = xyes) +AM_CONDITIONAL(kword_SUBDIR_included, test "x$kword_SUBDIR_included" = xyes) +AM_CONDITIONAL(kplato_SUBDIR_included, test "x$kplato_SUBDIR_included" = xyes) +AM_CONDITIONAL(kexi_SUBDIR_included, test "x$kexi_SUBDIR_included" = xyes) +AM_CONDITIONAL(filters_SUBDIR_included, test "x$filters_SUBDIR_included" = xyes) +AC_CONFIG_FILES([ Makefile ]) +AC_CONFIG_FILES([ autocorrect/Makefile ]) +AC_CONFIG_FILES([ doc/Makefile ]) +AC_CONFIG_FILES([ doc/karbon/Makefile ]) +AC_CONFIG_FILES([ doc/kchart/Makefile ]) +AC_CONFIG_FILES([ doc/kexi/Makefile ]) +AC_CONFIG_FILES([ doc/kformula/Makefile ]) +AC_CONFIG_FILES([ doc/kivio/Makefile ]) +AC_CONFIG_FILES([ doc/koffice/Makefile ]) +AC_CONFIG_FILES([ doc/koshell/Makefile ]) +AC_CONFIG_FILES([ doc/kplato/Makefile ]) +AC_CONFIG_FILES([ doc/kpresenter/Makefile ]) +AC_CONFIG_FILES([ doc/krita/Makefile ]) +AC_CONFIG_FILES([ doc/kspread/Makefile ]) +AC_CONFIG_FILES([ doc/kugar/Makefile ]) +AC_CONFIG_FILES([ doc/kword/Makefile ]) +AC_CONFIG_FILES([ doc/thesaurus/Makefile ]) +AC_CONFIG_FILES([ example/Makefile ]) +AC_CONFIG_FILES([ filters/Makefile ]) +AC_CONFIG_FILES([ filters/generic_wrapper/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/ai/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/applixgraphics/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/eps/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/kontour/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/msod/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/oodraw/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/png/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/svg/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/wmf/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/xaml/Makefile ]) +AC_CONFIG_FILES([ filters/karbon/xcf/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/bmp/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/jpeg/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/libimageexport/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/mng/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/png/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/svg/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/xbm/Makefile ]) +AC_CONFIG_FILES([ filters/kchart/xpm/Makefile ]) +AC_CONFIG_FILES([ filters/kformula/Makefile ]) +AC_CONFIG_FILES([ filters/kformula/latex/Makefile ]) +AC_CONFIG_FILES([ filters/kformula/mathml/Makefile ]) +AC_CONFIG_FILES([ filters/kformula/png/Makefile ]) +AC_CONFIG_FILES([ filters/kformula/svg/Makefile ]) +AC_CONFIG_FILES([ filters/kivio/Makefile ]) +AC_CONFIG_FILES([ filters/kivio/imageexport/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/bmp/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/jpeg/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/kword/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/libimageexport/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/magicpoint/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/mng/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/ooimpress/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/png/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/powerpoint/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/powerpoint/import/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/powerpoint/libppt/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/svg/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/xbm/Makefile ]) +AC_CONFIG_FILES([ filters/kpresenter/xpm/Makefile ]) +AC_CONFIG_FILES([ filters/krita/Makefile ]) +AC_CONFIG_FILES([ filters/krita/gmagick/Makefile ]) +AC_CONFIG_FILES([ filters/krita/jpeg/Makefile ]) +AC_CONFIG_FILES([ filters/krita/libkisexif/Makefile ]) +AC_CONFIG_FILES([ filters/krita/magick/Makefile ]) +AC_CONFIG_FILES([ filters/krita/openexr/Makefile ]) +AC_CONFIG_FILES([ filters/krita/pdf/Makefile ]) +AC_CONFIG_FILES([ filters/krita/png/Makefile ]) +AC_CONFIG_FILES([ filters/krita/raw/Makefile ]) +AC_CONFIG_FILES([ filters/krita/tiff/Makefile ]) +AC_CONFIG_FILES([ filters/krita/xcf/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/applixspread/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/csv/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/dbase/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/excel/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/excel/import/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/excel/sidewinder/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/gnumeric/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/html/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/kexi/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/latex/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/latex/export/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/libkspreadexport/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/opencalc/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/qpro/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/qpro/libqpro/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/qpro/libqpro/qpro/Makefile ]) +AC_CONFIG_FILES([ filters/kspread/qpro/libqpro/src/Makefile ]) +AC_CONFIG_FILES([ filters/kugar/Makefile ]) +AC_CONFIG_FILES([ filters/kugar/kugarnop/Makefile ]) +AC_CONFIG_FILES([ filters/kword/Makefile ]) +AC_CONFIG_FILES([ filters/kword/abiword/Makefile ]) +AC_CONFIG_FILES([ filters/kword/amipro/Makefile ]) +AC_CONFIG_FILES([ filters/kword/applixword/Makefile ]) +AC_CONFIG_FILES([ filters/kword/ascii/Makefile ]) +AC_CONFIG_FILES([ filters/kword/docbook/Makefile ]) +AC_CONFIG_FILES([ filters/kword/hancomword/Makefile ]) +AC_CONFIG_FILES([ filters/kword/html/Makefile ]) +AC_CONFIG_FILES([ filters/kword/html/export/Makefile ]) +AC_CONFIG_FILES([ filters/kword/html/import/Makefile ]) +AC_CONFIG_FILES([ filters/kword/kword1.3/Makefile ]) +AC_CONFIG_FILES([ filters/kword/kword1.3/import/Makefile ]) +AC_CONFIG_FILES([ filters/kword/latex/Makefile ]) +AC_CONFIG_FILES([ filters/kword/latex/export/Makefile ]) +AC_CONFIG_FILES([ filters/kword/latex/import/Makefile ]) +AC_CONFIG_FILES([ filters/kword/latex/import/generator/Makefile ]) +AC_CONFIG_FILES([ filters/kword/latex/import/parser/Makefile ]) +AC_CONFIG_FILES([ filters/kword/libexport/Makefile ]) +AC_CONFIG_FILES([ filters/kword/msword/Makefile ]) +AC_CONFIG_FILES([ filters/kword/mswrite/Makefile ]) +AC_CONFIG_FILES([ filters/kword/oowriter/Makefile ]) +AC_CONFIG_FILES([ filters/kword/palmdoc/Makefile ]) +AC_CONFIG_FILES([ filters/kword/pdf/Makefile ]) +AC_CONFIG_FILES([ filters/kword/pdf/xpdf/Makefile ]) +AC_CONFIG_FILES([ filters/kword/pdf/xpdf/goo/Makefile ]) +AC_CONFIG_FILES([ filters/kword/pdf/xpdf/xpdf/Makefile ]) +AC_CONFIG_FILES([ filters/kword/rtf/Makefile ]) +AC_CONFIG_FILES([ filters/kword/rtf/export/Makefile ]) +AC_CONFIG_FILES([ filters/kword/rtf/import/Makefile ]) +AC_CONFIG_FILES([ filters/kword/starwriter/Makefile ]) +AC_CONFIG_FILES([ filters/kword/wml/Makefile ]) +AC_CONFIG_FILES([ filters/kword/wordperfect/Makefile ]) +AC_CONFIG_FILES([ filters/kword/wordperfect/export/Makefile ]) +AC_CONFIG_FILES([ filters/kword/wordperfect/import/Makefile ]) +AC_CONFIG_FILES([ filters/libdialogfilter/Makefile ]) +AC_CONFIG_FILES([ filters/liboofilter/Makefile ]) +AC_CONFIG_FILES([ filters/olefilters/Makefile ]) +AC_CONFIG_FILES([ filters/olefilters/lib/Makefile ]) +AC_CONFIG_FILES([ filters/olefilters/powerpoint97/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/export/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/export/xsl/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/export/xsl/kword/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/export/xsl/kword/xslfo/Makefile ]) +AC_CONFIG_FILES([ filters/xsltfilter/import/Makefile ]) +AC_CONFIG_FILES([ interfaces/Makefile ]) +AC_CONFIG_FILES([ karbon/Makefile ]) +AC_CONFIG_FILES([ karbon/commands/Makefile ]) +AC_CONFIG_FILES([ karbon/core/Makefile ]) +AC_CONFIG_FILES([ karbon/data/Makefile ]) +AC_CONFIG_FILES([ karbon/dialogs/Makefile ]) +AC_CONFIG_FILES([ karbon/dockers/Makefile ]) +AC_CONFIG_FILES([ karbon/pics/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/flattenpath/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/imagetool/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/insertknots/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/roundcorners/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/shadoweffect/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/whirlpinch/Makefile ]) +AC_CONFIG_FILES([ karbon/plugins/zoomtool/Makefile ]) +AC_CONFIG_FILES([ karbon/render/Makefile ]) +AC_CONFIG_FILES([ karbon/render/xrgbrender/Makefile ]) +AC_CONFIG_FILES([ karbon/shapes/Makefile ]) +AC_CONFIG_FILES([ karbon/templates/Makefile ]) +AC_CONFIG_FILES([ karbon/templates/basic/Makefile ]) +AC_CONFIG_FILES([ karbon/tools/Makefile ]) +AC_CONFIG_FILES([ karbon/visitors/Makefile ]) +AC_CONFIG_FILES([ karbon/widgets/Makefile ]) +AC_CONFIG_FILES([ kchart/Makefile ]) +AC_CONFIG_FILES([ kchart/kdchart/Makefile ]) +AC_CONFIG_FILES([ kchart/pics/Makefile ]) +AC_CONFIG_FILES([ kchart/templates/Makefile ]) +AC_CONFIG_FILES([ kchart/toolbar/Makefile ]) +AC_CONFIG_FILES([ kchart/toolbar/crystalsvg/Makefile ]) +AC_CONFIG_FILES([ kchart/toolbar/locolor/Makefile ]) +AC_CONFIG_FILES([ kdgantt/Makefile ]) +AC_CONFIG_FILES([ kexi/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kexisql/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kexisql/src/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kexisql/tool/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kexisql3/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kexisql3/src/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/kolibs/Makefile ]) +AC_CONFIG_FILES([ kexi/3rdparty/uuid/Makefile ]) +AC_CONFIG_FILES([ kexi/core/Makefile ]) +AC_CONFIG_FILES([ kexi/data/Makefile ]) +AC_CONFIG_FILES([ kexi/data/kde34compat/Makefile ]) +AC_CONFIG_FILES([ kexi/examples/Makefile ]) +AC_CONFIG_FILES([ kexi/formeditor/Makefile ]) +AC_CONFIG_FILES([ kexi/formeditor/factories/Makefile ]) +AC_CONFIG_FILES([ kexi/formeditor/kdevelop_plugin/Makefile ]) +AC_CONFIG_FILES([ kexi/formeditor/scripting/Makefile ]) +AC_CONFIG_FILES([ kexi/formeditor/test/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/mySQL/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/odbc/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/pqxx/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/sqlite/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/drivers/sqlite2/Makefile ]) +AC_CONFIG_FILES([ kexi/kexidb/parser/Makefile ]) +AC_CONFIG_FILES([ kexi/kexiutils/Makefile ]) +AC_CONFIG_FILES([ kexi/main/Makefile ]) +AC_CONFIG_FILES([ kexi/main/printing/Makefile ]) +AC_CONFIG_FILES([ kexi/main/startup/Makefile ]) +AC_CONFIG_FILES([ kexi/migration/Makefile ]) +AC_CONFIG_FILES([ kexi/migration/mysql/Makefile ]) +AC_CONFIG_FILES([ kexi/migration/pqxx/Makefile ]) +AC_CONFIG_FILES([ kexi/migration/txt/Makefile ]) +AC_CONFIG_FILES([ kexi/pics/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/forms/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/forms/widgets/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/importexport/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/importexport/csv/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/macros/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/macros/kexiactions/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/macros/kexipart/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/macros/lib/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/macros/tests/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/migration/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/queries/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/relations/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/reports/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/kexiapp/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/kexidb/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/kexiscripting/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/copycenter/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/exportxhtml/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/importxhtml/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/projectdocumentor/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/python/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/scripting/scripts/python/kexiapp/Makefile ]) +AC_CONFIG_FILES([ kexi/plugins/tables/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/altertable/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/newapi/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/parser/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/startup/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/tableview/Makefile ]) +AC_CONFIG_FILES([ kexi/tests/widgets/Makefile ]) +AC_CONFIG_FILES([ kexi/tools/Makefile ]) +AC_CONFIG_FILES([ kexi/tools/add_column/Makefile ]) +AC_CONFIG_FILES([ kexi/tools/delete_column/Makefile ]) +AC_CONFIG_FILES([ kexi/widget/Makefile ]) +AC_CONFIG_FILES([ kexi/widget/relations/Makefile ]) +AC_CONFIG_FILES([ kexi/widget/tableview/Makefile ]) +AC_CONFIG_FILES([ kexi/widget/utils/Makefile ]) +AC_CONFIG_FILES([ kformula/Makefile ]) +AC_CONFIG_FILES([ kformula/pics/Makefile ]) +AC_CONFIG_FILES([ kivio/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/config/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/kiviosdk/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/pics/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Assorted/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Circuit/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Cisco/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Civil/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Contact/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Electric/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Jigsaw/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/MSE/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Network/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Pneumatic/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/SDL/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Dia/Sybase/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Flowcharting/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Flowcharting/BasicFlowcharting/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Flowcharting/Extended/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Flowcharting/Logic/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Geographic/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Geographic/Flags/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Geographic/Maps/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Hardware/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Hardware/Computer/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Hardware/Miscellaneous/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/Arrows/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/Buildings/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/ER/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/NassiShneiderman/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/People/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/Miscellaneous/Transport/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/UML/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/UML/ActivityDiagrams/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/stencils/UML/ClassDiagrams/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/tiles/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/tools/Makefile ]) +AC_CONFIG_FILES([ kivio/kiviopart/ui/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kivioconnectortool/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kivioconnectortool/straight_connector/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kivioselecttool/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kivioselecttool/select_pics/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviosmlconnector/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviosmlconnector/sml_connector/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviotargettool/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviotexttool/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviozoomtool/Makefile ]) +AC_CONFIG_FILES([ kivio/plugins/kiviozoomtool/zoom_pics/Makefile ]) +AC_CONFIG_FILES([ kivio/templates/Makefile ]) +AC_CONFIG_FILES([ kivio/templates/basic/Makefile ]) +AC_CONFIG_FILES([ koshell/Makefile ]) +AC_CONFIG_FILES([ kounavail/Makefile ]) +AC_CONFIG_FILES([ kplato/Makefile ]) +AC_CONFIG_FILES([ kplato/pics/Makefile ]) +AC_CONFIG_FILES([ kplato/reports/Makefile ]) +AC_CONFIG_FILES([ kplato/templates/Makefile ]) +AC_CONFIG_FILES([ kplato/templates/Simple/Makefile ]) +AC_CONFIG_FILES([ kplato/tests/Makefile ]) +AC_CONFIG_FILES([ kplato/toolbar/Makefile ]) +AC_CONFIG_FILES([ kpresenter/Makefile ]) +AC_CONFIG_FILES([ kpresenter/autoformEdit/Makefile ]) +AC_CONFIG_FILES([ kpresenter/autoforms/Makefile ]) +AC_CONFIG_FILES([ kpresenter/autoforms/Arrows/Makefile ]) +AC_CONFIG_FILES([ kpresenter/autoforms/Connections/Makefile ]) +AC_CONFIG_FILES([ kpresenter/dtd/Makefile ]) +AC_CONFIG_FILES([ kpresenter/pics/Makefile ]) +AC_CONFIG_FILES([ kpresenter/pics/rotate/Makefile ]) +AC_CONFIG_FILES([ kpresenter/slideshow/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/A4/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/Screen/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/Screenpresentations/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/common_icon/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/legal/Makefile ]) +AC_CONFIG_FILES([ kpresenter/templates/letter/Makefile ]) +AC_CONFIG_FILES([ kpresenter/toolbar/Makefile ]) +AC_CONFIG_FILES([ krita/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/cmyk_u16/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/cmyk_u8/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/cmyk_u8/templates/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/gray_u16/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/gray_u8/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/gray_u8/templates/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/gray_u8/tests/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/lms_f32/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_f16half/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_f16half/tests/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_f32/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_f32/tests/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_u16/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_u16/tests/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_u8/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_u8/templates/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/rgb_u8/tests/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/wet/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/wetsticky/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/wetsticky/brushop/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/ycbcr_u16/Makefile ]) +AC_CONFIG_FILES([ krita/colorspaces/ycbcr_u8/Makefile ]) +AC_CONFIG_FILES([ krita/core/Makefile ]) +AC_CONFIG_FILES([ krita/core/tests/Makefile ]) +AC_CONFIG_FILES([ krita/core/tiles/Makefile ]) +AC_CONFIG_FILES([ krita/core/tiles/tests/Makefile ]) +AC_CONFIG_FILES([ krita/data/Makefile ]) +AC_CONFIG_FILES([ krita/data/brushes/Makefile ]) +AC_CONFIG_FILES([ krita/data/gradients/Makefile ]) +AC_CONFIG_FILES([ krita/data/images/Makefile ]) +AC_CONFIG_FILES([ krita/data/palettes/Makefile ]) +AC_CONFIG_FILES([ krita/data/patterns/Makefile ]) +AC_CONFIG_FILES([ krita/data/profiles/Makefile ]) +AC_CONFIG_FILES([ krita/dtd/Makefile ]) +AC_CONFIG_FILES([ krita/kritacolor/Makefile ]) +AC_CONFIG_FILES([ krita/kritacolor/colorspaces/Makefile ]) +AC_CONFIG_FILES([ krita/kritacolor/tests/Makefile ]) +AC_CONFIG_FILES([ krita/pics/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/blur/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/bumpmap/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/cimg/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/colorify/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/colors/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/colorsfilters/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/convolutionfilters/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/cubismfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/embossfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/example/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/fastcolortransfer/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/imageenhancement/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/lenscorrectionfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/levelfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/noisefilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/oilpaintfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/pixelizefilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/raindropsfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/randompickfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/roundcorners/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/smalltilesfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/sobelfilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/threadtest/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/unsharp/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/filters/wavefilter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/paintops/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/paintops/defaultpaintops/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/defaulttools/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/selectiontools/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_crop/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_curves/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_filter/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_perspectivegrid/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_perspectivetransform/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_polygon/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_polyline/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_selectsimilar/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_star/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/tools/tool_transform/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/colorrange/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/colorspaceconversion/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/dropshadow/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/filtersgallery/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/histogram/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/histogram_docker/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/history_docker/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/imagesize/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/modify_selection/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/performancetest/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/rotateimage/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/screenshot/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/kritacore/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/kritascripting/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/samples/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/samples/python/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/scripting/samples/ruby/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/selectopaque/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/separate_channels/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/shearimage/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/substrate/Makefile ]) +AC_CONFIG_FILES([ krita/plugins/viewplugins/variations/Makefile ]) +AC_CONFIG_FILES([ krita/sdk/Makefile ]) +AC_CONFIG_FILES([ krita/ui/Makefile ]) +AC_CONFIG_FILES([ kspread/Makefile ]) +AC_CONFIG_FILES([ kspread/dialogs/Makefile ]) +AC_CONFIG_FILES([ kspread/dtd/Makefile ]) +AC_CONFIG_FILES([ kspread/extensions/Makefile ]) +AC_CONFIG_FILES([ kspread/pics/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/calculator/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/calculator/pics/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/insertcalendar/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/scripting/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/scripting/kspreadcore/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/scripting/scripts/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/scripting/scripts/exporthtml/Makefile ]) +AC_CONFIG_FILES([ kspread/plugins/scripting/scripts/scripteditor/Makefile ]) +AC_CONFIG_FILES([ kspread/sheetstyles/Makefile ]) +AC_CONFIG_FILES([ kspread/templates/Makefile ]) +AC_CONFIG_FILES([ kspread/templates/Business/Makefile ]) +AC_CONFIG_FILES([ kspread/templates/General/Makefile ]) +AC_CONFIG_FILES([ kspread/templates/HomeFamily/Makefile ]) +AC_CONFIG_FILES([ kspread/tests/Makefile ]) +AC_CONFIG_FILES([ kspread/toolbar/Makefile ]) +AC_CONFIG_FILES([ kspread/toolbar/crystalsvg/Makefile ]) +AC_CONFIG_FILES([ kugar/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner/pics/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner/templates/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner/templates/General/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner/toolbar/Makefile ]) +AC_CONFIG_FILES([ kugar/kudesigner_lib/Makefile ]) +AC_CONFIG_FILES([ kugar/lib/Makefile ]) +AC_CONFIG_FILES([ kugar/part/Makefile ]) +AC_CONFIG_FILES([ kugar/samples/Makefile ]) +AC_CONFIG_FILES([ kword/Makefile ]) +AC_CONFIG_FILES([ kword/data/Makefile ]) +AC_CONFIG_FILES([ kword/dtd/Makefile ]) +AC_CONFIG_FILES([ kword/expression/Makefile ]) +AC_CONFIG_FILES([ kword/horizontalline/Makefile ]) +AC_CONFIG_FILES([ kword/mailmerge/Makefile ]) +AC_CONFIG_FILES([ kword/mailmerge/kabc/Makefile ]) +AC_CONFIG_FILES([ kword/mailmerge/kspread/Makefile ]) +AC_CONFIG_FILES([ kword/mailmerge/sql/Makefile ]) +AC_CONFIG_FILES([ kword/pics/Makefile ]) +AC_CONFIG_FILES([ kword/templates/Makefile ]) +AC_CONFIG_FILES([ kword/templates/CardsAndLabels/Makefile ]) +AC_CONFIG_FILES([ kword/templates/Envelopes/Makefile ]) +AC_CONFIG_FILES([ kword/templates/Wordprocessing/Makefile ]) +AC_CONFIG_FILES([ kword/tests/Makefile ]) +AC_CONFIG_FILES([ kword/toolbar/Makefile ]) +AC_CONFIG_FILES([ lib/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/config/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/dtd/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/fonts/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/pics/Makefile ]) +AC_CONFIG_FILES([ lib/kformula/pics/crystalsvg/Makefile ]) +AC_CONFIG_FILES([ lib/kofficecore/Makefile ]) +AC_CONFIG_FILES([ lib/kofficecore/tests/Makefile ]) +AC_CONFIG_FILES([ lib/kofficeui/Makefile ]) +AC_CONFIG_FILES([ lib/kofficeui/pics/Makefile ]) +AC_CONFIG_FILES([ lib/kofficeui/tests/Makefile ]) +AC_CONFIG_FILES([ lib/kopainter/Makefile ]) +AC_CONFIG_FILES([ lib/kopalette/Makefile ]) +AC_CONFIG_FILES([ lib/koproperty/Makefile ]) +AC_CONFIG_FILES([ lib/koproperty/editors/Makefile ]) +AC_CONFIG_FILES([ lib/koproperty/test/Makefile ]) +AC_CONFIG_FILES([ lib/kotext/Makefile ]) +AC_CONFIG_FILES([ lib/kotext/kohyphen/Makefile ]) +AC_CONFIG_FILES([ lib/kotext/kohyphen/hyphdicts/Makefile ]) +AC_CONFIG_FILES([ lib/kotext/tests/Makefile ]) +AC_CONFIG_FILES([ lib/kross/Makefile ]) +AC_CONFIG_FILES([ lib/kross/api/Makefile ]) +AC_CONFIG_FILES([ lib/kross/main/Makefile ]) +AC_CONFIG_FILES([ lib/kross/python/Makefile ]) +AC_CONFIG_FILES([ lib/kross/python/cxx/Makefile ]) +AC_CONFIG_FILES([ lib/kross/python/scripts/Makefile ]) +AC_CONFIG_FILES([ lib/kross/python/scripts/RestrictedPython/Makefile ]) +AC_CONFIG_FILES([ lib/kross/ruby/Makefile ]) +AC_CONFIG_FILES([ lib/kross/runner/Makefile ]) +AC_CONFIG_FILES([ lib/kross/test/Makefile ]) +AC_CONFIG_FILES([ lib/kwmf/Makefile ]) +AC_CONFIG_FILES([ lib/store/Makefile ]) +AC_CONFIG_FILES([ lib/store/tests/Makefile ]) +AC_CONFIG_FILES([ mimetypes/Makefile ]) +AC_CONFIG_FILES([ mimetypes/kde33/Makefile ]) +AC_CONFIG_FILES([ mimetypes/kde351/Makefile ]) +AC_CONFIG_FILES([ pics/Makefile ]) +AC_CONFIG_FILES([ pics/crystalsvg/Makefile ]) +AC_CONFIG_FILES([ plugins/Makefile ]) +AC_CONFIG_FILES([ plugins/scan/Makefile ]) +AC_CONFIG_FILES([ servicetypes/Makefile ]) +AC_CONFIG_FILES([ templates/Makefile ]) +AC_CONFIG_FILES([ tools/Makefile ]) +AC_CONFIG_FILES([ tools/converter/Makefile ]) +AC_CONFIG_FILES([ tools/kfile-plugins/Makefile ]) +AC_CONFIG_FILES([ tools/kfile-plugins/abiword/Makefile ]) +AC_CONFIG_FILES([ tools/kfile-plugins/gnumeric/Makefile ]) +AC_CONFIG_FILES([ tools/kfile-plugins/koffice/Makefile ]) +AC_CONFIG_FILES([ tools/kfile-plugins/ooo/Makefile ]) +AC_CONFIG_FILES([ tools/kthesaurus/Makefile ]) +AC_CONFIG_FILES([ tools/quickprint/Makefile ]) +AC_CONFIG_FILES([ tools/spell/Makefile ]) +AC_CONFIG_FILES([ tools/thesaurus/Makefile ]) +AC_CONFIG_FILES([ tools/thumbnail/Makefile ]) +AC_MSG_CHECKING([for filters to be compiled]) + +if test -s $srcdir/inst-apps ; then + SUBDIRLIST=`cat $srcdir/inst-apps` +else + SUBDIRLIST=`cat $srcdir/subdirs` +fi + +# fallback (KDE_CREATE_SUBDIRLIST has this fallback, so I have put it here too.) +if test -z "$SUBDIRLIST" ; then + SUBDIRLIST=`ls -1 $srcdir` +fi + +# first check which main apllication we could compile +for args in $SUBDIRLIST ; do + case $args in + kword) COMPILE_FILTER_KWORD="$args " ;; + kspread) COMPILE_FILTER_KSPREAD="$args " ;; + kchart) COMPILE_FILTER_KCHART="$args " ;; + karbon) COMPILE_FILTER_KARBON="$args " ;; + kpresenter) COMPILE_FILTER_KPRESENTER="$args " ;; + kformula) COMPILE_FILTER_KFORMULA="$args " ;; + kugar) COMPILE_FILTER_KUGAR="$args " ;; + krita) COMPILE_FILTER_KRITA="$args " ;; + kivio) COMPILE_FILTER_KIVIO="$args " ;; + kexi) COMPILE_FILTER_KEXI="$args " ;; + esac +done + +# now remove the applications the user has asked not to compile +for args in $DO_NOT_COMPILE ; do + case $args in + kword) COMPILE_FILTER_KWORD= ;; + kspread) COMPILE_FILTER_KSPREAD= ;; + kchart) COMPILE_FILTER_KCHART= ;; + karbon) COMPILE_FILTER_KARBON= ;; + kpresenter) COMPILE_FILTER_KPRESENTER= ;; + kformula) COMPILE_FILTER_KFORMULA= ;; + kugar) COMPILE_FILTER_KUGAR= ;; + krita) COMPILE_FILTER_KRITA= ;; + kivio) COMPILE_FILTER_KIVIO= ;; + kexi) COMPILE_FILTER_KEXI= ;; + esac +done + +USERFEEDBACKCOMPILE="$COMPILE_FILTER_KWORD$COMPILE_FILTER_KSPREAD$COMPILE_FILTER_KCHART$COMPILE_FILTER_KARBON$COMPILE_FILTER_KPRESENTER$COMPILE_FILTER_KFORMULA$COMPILE_FILTER_KUGAR" +AC_MSG_RESULT([$USERFEEDBACKCOMPILE]) + +AM_CONDITIONAL(compile_filter_KWORD, test -n "$COMPILE_FILTER_KWORD") +AM_CONDITIONAL(compile_filter_KSPREAD, test -n "$COMPILE_FILTER_KSPREAD") +AM_CONDITIONAL(compile_filter_KCHART, test -n "$COMPILE_FILTER_KCHART") +AM_CONDITIONAL(compile_filter_KARBON, test -n "$COMPILE_FILTER_KARBON") +AM_CONDITIONAL(compile_filter_KPRESENTER, test -n "$COMPILE_FILTER_KPRESENTER") +AM_CONDITIONAL(compile_filter_KFORMULA, test -n "$COMPILE_FILTER_KFORMULA") +AM_CONDITIONAL(compile_filter_KUGAR, test -n "$COMPILE_FILTER_KUGAR") +AM_CONDITIONAL(compile_filter_KRITA, test -n "$COMPILE_FILTER_KRITA") +AM_CONDITIONAL(compile_filter_KIVIO, test -n "$COMPILE_FILTER_KIVIO") +AM_CONDITIONAL(compile_filter_KEXI, test -n "$COMPILE_FILTER_KEXI") +if test -s $srcdir/inst-apps ; then + SUBDIRLIST=`cat $srcdir/inst-apps` +else + SUBDIRLIST=`cat $srcdir/subdirs` +fi + +# fallback (KDE_CREATE_SUBDIRLIST has this fallback, so I have put it here too.) +if test -z "$SUBDIRLIST" ; then + SUBDIRLIST=`ls -1 $srcdir` +fi + +# first check which main apllication we could compile +for args in $SUBDIRLIST ; do + case $args in + kugar) COMPILE_PLUGIN_KUGAR="$args " ;; + esac +done + +# now remove the applications the user has asked not to compile +for args in $DO_NOT_COMPILE ; do + case $args in + kugar) COMPILE_PLUGIN_KUGAR= ;; + esac +done + +AM_CONDITIONAL(compile_plugin_KUGAR, test -n "$COMPILE_PLUGIN_KUGAR") +if test -s $srcdir/inst-apps ; then + SUBDIRLIST=`cat $srcdir/inst-apps` +else + SUBDIRLIST=`cat $srcdir/subdirs` +fi + +# fallback (KDE_CREATE_SUBDIRLIST has this fallback, so I have put it here too.) +if test -z "$SUBDIRLIST" ; then + SUBDIRLIST=`ls -1 $srcdir` +fi + +AC_MSG_CHECKING([whether only Kexi is being built]) +KEXI_ONLY=yes +for args in $SUBDIRLIST ; do + case $args in + lib) ;; + kexi) ;; + *) if test -d $srcdir/$args ; then + KEXI_ONLY=no + fi + ;; + esac +done +AC_MSG_RESULT([$KEXI_ONLY]) +AM_CONDITIONAL(compile_kexionly, test "$KEXI_ONLY" = "yes" ) + +AC_MSG_CHECKING([whether kopainter should be compiled]) + +# first check which main application we could compile +for args in $SUBDIRLIST ; do + case $args in + krita) COMPILE_LIB_FOR_KRITA="$args " ;; + karbon) COMPILE_LIB_FOR_KARBON="$args " ;; + kivio) COMPILE_LIB_FOR_KIVIO="$args " ;; + esac +done + +# now remove the applications the user has asked not to compile +COMPILE_LIB_FOR_KPRESENTER="#" +for args in $DO_NOT_COMPILE ; do + case $args in + krita) COMPILE_LIB_FOR_KRITA= ;; + karbon) COMPILE_LIB_FOR_KARBON= ;; + kivio) COMPILE_LIB_FOR_KIVIO= ;; + kpresenter) COMPILE_LIB_FOR_KPRESENTER= ;; + esac +done + +if test -n "$COMPILE_LIB_FOR_KRITA$COMPILE_LIB_FOR_KARBON$COMPILE_LIB_FOR_KIVIO$COMPILE_LIB_FOR_KPRESENTER" ; then + USERFEEDBACKCOMPILELIB="yes" +else + USERFEEDBACKCOMPILELIB="no" +fi + +AC_MSG_RESULT([$USERFEEDBACKCOMPILELIB]) + +AM_CONDITIONAL(compile_lib_KOPAINTER, test "$USERFEEDBACKCOMPILELIB" = "yes" ) + +AC_OUTPUT +if test -z "$LIBGMAGICK_LIBS" -a -z "$LIBMAGICK_LIBS"; then + echo "" + echo "You're missing GraphicsMagick (>=1.1.7). krita's GraphicsMagick import/export" + echo "filter will not be compiled. You can download GraphicsMagick from" + echo "http://www.graphicsmagick.org/. The GraphicsMagick filter allows krita to" + echo "read and write XCF, PSD, GIF, BMP, and many other image formats." + echo "" + echo "If you have problems compiling GraphicsMagick, please try configuring it using" + echo "the --without-magick-plus-plus flag, the C++ API isn't needed for krita." + echo "" + all_tests=bad + AC_DEFINE([include_imagemagick_filter],"",[don't use magick filter]) +fi + +if test -z "$LIBGMAGICK_LIBS" -a ! -z "$LIBMAGICK_LIBS"; then + + echo "" + echo "You're missing GraphicsMagick (>=1.1.7). krita's GraphicsMagick import/export" + echo "filter will not be compiled. But ImageMagick was found, which mean that krita" + echo "will be able to read and write XCF, PSD, GIF, BMP, and many other image formats." + echo "But the ImageMagick filter is deprecated and we strongly advise you to install" + echo "GraphicsMagick either from your distribution or from http://www.graphicsmagick.org/" +fi +if test -z "$LIBJPEG" -o -z "$LIBEXIF"; then + echo "" + echo "You're missing libjpeg or libexif 0.6.12 or later (binaries and/or headers)." + echo "krita won't be able to import/export jpeg" + echo "" + all_tests=bad +fi +# ImageMagick is deprecated, we don't care anymore if it's not here +# +#if test -z "$LIBMAGICK_LIBS"; then +# echo "" +# echo "You're missing ImageMagick (>=6.1.0). krita's ImageMagick import/export" +# echo "filter will not be compiled. You can download ImageMagick from" +# echo "http://www.imagemagick.org/. The ImageMagick filter allows krita to" +# echo "read and write XCF, PSD, GIF, BMP, and many other image formats." +# echo "" +# echo "If you have problems compiling ImageMagick, please try configuring it using" +# echo "the --without-magick-plus-plus flag, the C++ API isn't needed for krita." +# echo "" +# all_tests=bad +#fi + +if test -z "$OPENEXR_LIBS"; then + echo "" + echo "You're missing the OpenEXR library. Krita's OpenEXR import/export filter will " + echo "not be compiled. You can download OpenEXR from http://www.openexr.com or " + echo "install it from an appropriate binary package." + echo "" + all_tests=bad +fi + +if test -z "$POPPLER_LIBS"; then + echo "" + echo "You're missing libpoppler 0.5.1 or later (binaries and/or headers)." + echo "krita won't be able to import pdf" + echo "note that the qt-binding of libpoppler is required" + echo "" +fi +if test -z "$LIBPNG"; then + echo "" + echo "You're missing libpng (binaries and/or headers), krita won't be able" + echo "to import/export png" + echo "" + all_tests=bad +fi + +if test -z "$LIBTIFF"; then + echo "" + echo "You're missing libtiff (binaries and/or headers), krita won't be able" + echo "to import/export tiff" + echo "" + all_tests=bad +fi +if test -z "$LIBWV2_LIBS"; then + echo "" + echo "You're missing libwv2 0.1.9 or newer. KWord's MS Word filter will not be" + echo "compiled. You can download wv2 using anonymous CVS from the Sourceforge" + echo "repository (http://sourceforge.net/cvs/?group_id=10501) or get a" + echo "tarball at http://sourceforge.net/projects/wvware/" +# echo "The MS Word filter won't be compiled due to experimental changes." + echo "" + all_tests=bad +fi +if test -z "$LIBWPD_LIBS"; then + echo "" + echo "You're missing libwpd 0.8 or newer. KWord's WordPerfect import filter will " + echo "not be compiled. You can download libwpd from http://libwpd.sf.net or " + echo "install it from appropriate binary package." + echo "" + all_tests=bad +fi +if test -z "$LIBXML_LIBS"; then + echo "" + echo "You're missing libxml2 (at least version 2.4.8)." + echo "The XSLT filters will not be compiled." + echo "Please download libxml2 from http://xmlsoft.org ." + echo "" + all_tests=bad +fi + +if test -z "$LIBXSLT_LIBS"; then + echo "" + echo "You're missing libxslt (at least version 1.0.7)." + echo "The XSLT filters will not be compiled." +# TODO: URL is not exacly right anymore + echo "Please download libxml2 from http://xmlsoft.org ." + echo "" + all_tests=bad +fi + +if test -z "$LIBART_LIBS"; then + echo "" + echo "You're missing libart 2.3.8. karbon will not be compiled." + echo "You can download libart from" + echo "http://svg.kde.org/download.html" + echo "" + all_tests=bad +else + if test -z "$LIBFONTCONFIG_LIBS"; then + echo "" + echo "You're missing fontconfig 1.0.1 or newer. karbon will not have text support." + echo "You can download fontconfig from http://fontconfig.org/" + echo "" + all_tests=bad + fi + + if test -z "$LIBFREETYPE_LIBS"; then + echo "" + echo "You're missing libfreetype 5.0 or newer. karbon will not have text support." + echo "You can download libfreetype from http://www.freetype.org/" + echo "" + all_tests=bad + fi +fi +if test -z "$MYSQL_INC" -o -z "$MYSQL_LIBS"; then + + echo "----------------------------------------------------------------------" + + echo " + The MySQL development files were not found." + cat <=2) + +EOS + fi + +# SUMMARY messages + cat <&1 >/dev/null + if test $? -ne 0; then + echo "" + echo "Warning: you chose to install this package in $given_prefix," + echo "but KDE was found in $kde_libs_prefix." + echo "For this to work, you will need to tell KDE about the new prefix, by ensuring" + echo "that KDEDIRS contains it, e.g. export KDEDIRS=$given_prefix:$kde_libs_prefix" + echo "Then restart KDE." + echo "" + fi + fi +fi + +if test x$GXX = "xyes" -a x$kde_have_gcc_visibility = "xyes" -a x$kde_cv_val_qt_gcc_visibility_patched = "xno"; then + echo "" + echo "Your GCC supports symbol visibility, but the patch for Qt supporting visibility" + echo "was not included. Therefore, GCC symbol visibility support remains disabled." + echo "" + echo "For better performance, consider including the Qt visibility supporting patch" + echo "located at:" + echo "" + echo "http://bugs.kde.org/show_bug.cgi?id=109386" + echo "" + echo "and recompile all of Qt and KDE. Note, this is entirely optional and" + echo "everything will continue to work just fine without it." + echo "" +fi + +if test "$all_tests" = "bad"; then + if test ! "$cache_file" = "/dev/null"; then + echo "" + echo "Please remove the file $cache_file after changing your setup" + echo "so that configure will find the changes next time." + echo "" + fi +else + echo "" + echo "Good - your configure finished. Start make now" + echo "" +fi diff --git a/configure.in.in b/configure.in.in new file mode 100644 index 000000000..bec764e0e --- /dev/null +++ b/configure.in.in @@ -0,0 +1,299 @@ +#MIN_CONFIG(3.3) + +# Remember to synchronize the version number with the file koffice/lib/kofficecore/kofficeversion.h +AM_INIT_AUTOMAKE(koffice, "1.6.3") + +CXXFLAGS="$CXXFLAGS $KDE_DEFAULT_CXXFLAGS" + +AC_CHECK_HEADERS(unistd.h sys/param.h floatingpoint.h paths.h) +AC_C_BIGENDIAN +AC_CHECK_KDEMAXPATHLEN + +KDE_INIT_DOXYGEN([The KOffice API Reference], [Version $VERSION]) + +# Check for GraphicsMagick... + +have_graphicsmagick=no +KDE_FIND_PATH(GraphicsMagick-config, GRAPHICS_MAGICK_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find GraphicsMagick anywhere, check http://www.graphicsmagick.org/ for GraphicsMagick >= 1.1.7.]) +]) + +if test -n "$GRAPHICS_MAGICK_CONFIG"; then + vers=`$GRAPHICS_MAGICK_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1001007; then + LIBGMAGICK_LIBS="`$GRAPHICS_MAGICK_CONFIG --libs`" + LIBGMAGICK_LDFLAGS="`$GRAPHICS_MAGICK_CONFIG --ldflags`" + LIBGMAGICK_RPATH= + for args in $LIBGMAGICK_LIBS; do + case $args in + -L*) + LIBGMAGICK_RPATH="$LIBMAGICK_RPATH $args" + ;; + esac + done + LIBGMAGICK_RPATH=`echo $LIBGMAGICK_RPATH | $SED -e "s/-L/-R/g"` + LIBGMAGICK_CPPFLAGS="`$GRAPHICS_MAGICK_CONFIG --cppflags`" + AC_DEFINE(HAVE_GMAGICK,1, [GraphicsMagick is available]) + have_graphicsmagick=yes + else + AC_MSG_WARN([You need at least GraphicsMagick 1.1.7]) + fi + +fi + +if test ! "$USE_RPATH" = "yes"; then + LIBGMAGICK_RPATH= +fi + +AC_SUBST(LIBGMAGICK_LIBS) +AC_SUBST(LIBGMAGICK_LDFLAGS) +AC_SUBST(LIBGMAGICK_CPPFLAGS) +AC_SUBST(LIBGMAGICK_RPATH) +AM_CONDITIONAL(include_graphicsmagick_filter, test "$have_graphicsmagick" = "yes" -a HAVE_GMAGICK) + +# End of GraphicsMagick check + +# Check for ImageMagick... + +have_imagemagick=no +KDE_FIND_PATH(Magick-config, MAGICK_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find ImageMagick anywhere, check http://www.imagemagick.org/ for ImageMagick >= 5.5.2.]) +]) + +if test -n "$MAGICK_CONFIG"; then + vers=`$MAGICK_CONFIG --version 2>/dev/null | $AWK 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 5005002 + then + if test "$vers" -ge 6000003 + then + AC_DEFINE(HAVE_MAGICK6, 1, [ImageMagick Version 6]) + fi + if test "$vers" -ge 6001000 + then + AC_DEFINE(HAVE_MAGICK61, 1, [ImageMagick Version 6.1]) + fi + LIBMAGICK_LIBS="`$MAGICK_CONFIG --libs`" + LIBMAGICK_LDFLAGS="`$MAGICK_CONFIG --ldflags`" + LIBMAGICK_RPATH= + for args in $LIBMAGICK_LIBS; do + case $args in + -L*) + LIBMAGICK_RPATH="$LIBMAGICK_RPATH $args" + ;; + esac + done + LIBMAGICK_RPATH=`echo $LIBMAGICK_RPATH | $SED -e "s/-L/-R/g"` + LIBMAGICK_CPPFLAGS="`$MAGICK_CONFIG --cppflags`" + AC_DEFINE(HAVE_MAGICK,1, [ImageMagick is available]) + have_imagemagick=yes + else + AC_MSG_WARN([You need at least ImageMagick 5.5.2]) + fi +fi + +if test ! "$USE_RPATH" = "yes"; then + LIBMAGICK_RPATH= +fi + +AC_SUBST(LIBMAGICK_LIBS) +AC_SUBST(LIBMAGICK_LDFLAGS) +AC_SUBST(LIBMAGICK_CPPFLAGS) +AC_SUBST(LIBMAGICK_RPATH) +AM_CONDITIONAL(include_imagemagick_filter, test "$have_imagemagick" = "yes" -a HAVE_MAGICK61 -a ! "$have_graphicsmagick" = "yes" -a ! HAVE_GMAGICK) + +# End of ImageMagick check + +########################################################################## +# This last check is copied from kdenonbeta/gsf/configure.in.in +########################################################################## +# KOFFICE_PKG_CHECK_MODULES(GSTUFF, gtk+-2.0 >= 1.3 glib = 1.3.4, action-if, action-not) +# defines GSTUFF_LIBS, GSTUFF_CFLAGS, see pkg-config man page +# also defines GSTUFF_PKG_ERRORS on error +# Note: This is specially tweaked for karbon's fontconfig check. Please fix +# it before using it for other tests :-) +AC_DEFUN([KOFFICE_PKG_CHECK_MODULES], [ + succeeded=no + + if test -z "$PKG_CONFIG"; then + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) + fi + + if test "$PKG_CONFIG" = "no" ; then + echo "*** The pkg-config script could not be found. Make sure it is" + echo "*** in your path, or set the PKG_CONFIG environment variable" + echo "*** to the full path to pkg-config." + echo "*** Or see http://www.freedesktop.org/software/pkgconfig to get pkg-config." + echo "***" + echo "*** Due to that we can't perform the check for fontconfig..." # added for karbon (Werner) + else + PKG_CONFIG_MIN_VERSION=0.9.0 + if $PKG_CONFIG --atleast-pkgconfig-version $PKG_CONFIG_MIN_VERSION; then + AC_MSG_CHECKING(for $2) + + if $PKG_CONFIG --exists "$2" ; then + AC_MSG_RESULT(yes) + succeeded=yes + + AC_MSG_CHECKING($1_CFLAGS) + $1_CFLAGS=`$PKG_CONFIG --cflags "$2"` + AC_MSG_RESULT($$1_CFLAGS) + + AC_MSG_CHECKING($1_LIBS) + $1_LIBS=`$PKG_CONFIG --libs "$2"` + AC_MSG_RESULT($$1_LIBS) + else + $1_CFLAGS="" + $1_LIBS="" + ## If we have a custom action on failure, don't print errors, but + ## do set a variable so people can do so. + $1_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"` + ifelse([$4], ,echo $$1_PKG_ERRORS,) + fi + + AC_SUBST($1_CFLAGS) + AC_SUBST($1_LIBS) + else + echo "*** Your version of pkg-config is too old. You need version $PKG_CONFIG_MIN_VERSION or newer." + echo "*** See http://www.freedesktop.org/software/pkgconfig" + fi + fi + + if test $succeeded = yes; then + ifelse([$3], , :, [$3]) +# else # removed for karbon (Werner) +# ifelse([$4], , AC_MSG_ERROR([Library requirements ($2) not met; consider adjusting the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can find them.]), [$4]) + fi +]) + +# --- Check for KDE 3.2 or 3.3 --- + +AC_MSG_CHECKING([for KDE version]) + +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +kdeversion_save_CXXFLAGS="$CXXFLAGS" +kdeversion_safe_LIBS="$LIBS" +LIBS="$LIBS $X_EXTRA_LIBS" +CXXFLAGS="$CXXFLAGS $all_includes" + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 2, 90 ) ) +#error KDE 3.2 +#endif +], + need_kde32_compat="no" +, + need_kde32_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 3, 90 ) ) +#error KDE 3.3 +#endif +], + need_kde33_compat="no" +, + need_kde33_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 4, 90 ) ) +#error KDE 3.4 +#endif +], + need_kde34_compat="no" +, + need_kde34_compat="yes" +) + +AC_COMPILE_IFELSE([ +#include +#if ! ( KDE_IS_VERSION( 3, 5, 2 ) ) +#error KDE 3.5.x (x < 2) +#endif +], + need_kde351_compat="no" +, + need_kde351_compat="yes" +) +CXXFLAGS="$kdeversion_save_CXXFLAGS" +LIBS="$kdeversion_safe_LIBS" +AC_LANG_RESTORE + +if test "$need_kde32_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.2.x]) +else + if test "$need_kde33_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.3.x]) + else + if test "$need_kde34_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.4.x]) + else + if test "$need_kde351_compat" = "yes"; then + AC_MSG_RESULT([KDE 3.5.x (x < 2)]) + else + AC_MSG_RESULT([KDE 3.5.x (x >=2) or SVN trunk]) + fi + fi + fi +fi + +AM_CONDITIONAL(need_kde32_compatibility, test "$need_kde32_compat" = "yes") +AM_CONDITIONAL(need_kde33_compatibility, test "$need_kde33_compat" = "yes") +AM_CONDITIONAL(need_kde34_compatibility, test "$need_kde34_compat" = "yes") +AM_CONDITIONAL(need_kde351_compatibility, test "$need_kde351_compat" = "yes") + +# Keep the old KDE 3.1 test, as long as it is still used +AM_CONDITIONAL(need_kde31_compatibility, test "supported" = "no") + +# --- End KDE 3.2 check --- + +# --- OpenEXR check --- + +KDE_FIND_PATH(pkg-config, PKGCONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find pkg-config]) +]) + +AC_MSG_CHECKING([for OpenEXR]) + +if test -n "$PKGCONFIG"; then + vers=`$PKGCONFIG OpenEXR --modversion 2>/dev/null` + if test -n "$vers" + then + OPENEXR_LIBS="`$PKGCONFIG OpenEXR --libs`" + OPENEXR_RPATH= + for args in $OPENEXR_LIBS; do + case $args in + -L*) + OPENEXR_RPATH="$OPENEXR_RPATH $args" + ;; + esac + done + OPENEXR_RPATH=`echo $OPENEXR_RPATH | $SED -e "s/-L/-R/g"` + OPENEXR_CFLAGS="`$PKGCONFIG OpenEXR --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_OPENEXR, 1, [Defines if your system has the OpenEXR library]) + fi +fi + +if test ! "$USE_RPATH" = "yes"; then + OPENEXR_RPATH= +fi + +if test -n "$OPENEXR_LIBS" +then + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([not found]) +fi + +AC_SUBST(OPENEXR_LIBS) +AC_SUBST(OPENEXR_CFLAGS) +AC_SUBST(OPENEXR_RPATH) + +AM_CONDITIONAL(have_openexr, test -n "$OPENEXR_LIBS") + +# --- End of OpenEXR check --- diff --git a/doc/.directory b/doc/.directory new file mode 100644 index 000000000..6aa9870a7 --- /dev/null +++ b/doc/.directory @@ -0,0 +1,4 @@ +# KDE Config File +[KDE Desktop Entry] +BgImage= +Icon= diff --git a/doc/CookBook.odt b/doc/CookBook.odt new file mode 100644 index 000000000..7e950e34d Binary files /dev/null and b/doc/CookBook.odt differ diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 000000000..8016c1508 --- /dev/null +++ b/doc/Makefile.am @@ -0,0 +1,7 @@ + + +KDE_LANG = en +KDE_DOCS = koffice +SUBDIRS = $(AUTODIRS) + +xdg_apps_DATA = koffice.desktop diff --git a/doc/TODO b/doc/TODO new file mode 100644 index 000000000..a3bd38ba6 --- /dev/null +++ b/doc/TODO @@ -0,0 +1,2 @@ +You can find status information and TODO items for KOffice +documentation in the CookBook.odt diff --git a/doc/api/Doxyfile.am b/doc/api/Doxyfile.am new file mode 100644 index 000000000..05aa7591a --- /dev/null +++ b/doc/api/Doxyfile.am @@ -0,0 +1,153 @@ +## generate API documentation with doxygen +apidox-am-yes: + @if test "$(subdir)" != "."; then \ + $(mkinstalldirs) $(top_builddir)/apidocs/$(subdir) ;\ + cp $(top_srcdir)/doc/api/Doxyfile.pim Doxyfile; \ + echo "PROJECT_NAME = \"$(subdir)\"" >> Doxyfile; \ + echo "PROJECT_NUMBER = \"Version $(VERSION)\"" >> Doxyfile; \ + echo "INPUT = $(srcdir)" >> Doxyfile; \ + echo "IMAGE_PATH = $(top_srcdir)/doc/api" >> Doxyfile ;\ + echo "OUTPUT_DIRECTORY = $(top_builddir)/apidocs" >> Doxyfile; \ + echo "HTML_OUTPUT = $(subdir)/html" >> Doxyfile; \ + echo "HTML_HEADER = $(top_srcdir)/doc/api/header.html" >> Doxyfile; \ + echo "HTML_FOOTER = $(top_srcdir)/doc/api/footer.html" >> Doxyfile; \ + echo "HTML_STYLESHEET = $(top_builddir)/apidocs/doxygen.css" >> Doxyfile; \ + echo "LATEX_OUTPUT = $(subdir)/latex" >> Doxyfile; \ + echo "RTF_OUTPUT = $(subdir)/rtf" >> Doxyfile; \ + echo "MAN_OUTPUT = $(subdir)/man" >> Doxyfile; \ + $(DOXYGEN) Doxyfile ;\ + sh $(top_srcdir)/doc/api/doxyndex.sh $(top_builddir)/apidocs $(subdir)/html ; \ + fi + +apidox-am-no: + +install-data-local: install-apidox + +## install API documentation +install-apidox: + @if test "$(subdir)" != "."; then \ + $(mkinstalldirs) $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir)/html ; \ + if test -f $(top_builddir)/apidocs/$(subdir)/$(subdir).tag; then \ + echo $(INSTALL_DATA) $(top_builddir)/apidocs/$(subdir)/$(subdir).tag $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir); \ + $(INSTALL_DATA) $(top_builddir)/apidocs/$(subdir)/$(subdir).tag $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir); \ + fi; \ + if test -d $(top_builddir)/apidocs/$(subdir)/html; then \ + list=`ls $(top_builddir)/apidocs/$(subdir)/html`; \ + echo "installing $(top_builddir)/apidocs/$(subdir)/html" ;\ + for file in $$list; do \ + $(INSTALL_DATA) $(top_builddir)/apidocs/$(subdir)/html/$$file $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir)/html; \ + done; \ + fi; \ + rm -f $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/common; \ + $(LN_S) $(kde_libs_htmldir)/en/common $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/common; \ + else\ + if test -d $(top_builddir)/apidocs; then \ + $(mkinstalldirs) $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs ;\ + list=`cd $(top_builddir)/apidocs && ls -1`; \ + echo "installing $(top_builddir)/apidocs/$$file" ;\ + for file in $$list; do \ + if test -f $(top_builddir)/apidocs/$$file; then \ + $(INSTALL_DATA) $(top_builddir)/apidocs/$$file $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs; \ + fi; \ + done ; fi; \ + fi + +uninstall-local: uninstall-apidox + +## uninstall API documentation +uninstall-apidox: + @if test "$(subdir)" != "."; then \ + if test -d $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir); then \ + rm -rfv $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs/$(subdir); \ + fi\ + else\ + if test -d $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs; then \ + rm -rfv $(DESTDIR)$(kde_htmldir)/en/$(PACKAGE)-apidocs; \ + fi\ + fi + +apidox: + @if test "$(subdir)" != "."; then \ + $(MAKE) apidox-am-@KDE_HAS_DOXYGEN@ ;\ + else \ + $(MAKE) apidox-am-toplevel-@KDE_HAS_DOXYGEN@ ;\ + fi + @set fnord $(MAKEFLAGS); amf=$$2; if test -n '$(SUBDIRS)'; then \ + list='$(SUBDIRS)'; \ + for subdir in $$list; do \ + if grep '^include .*Doxyfile.am' $(srcdir)/$$subdir/Makefile.am > /dev/null ; then \ + echo "Making apidox in $$subdir"; \ + if test "$$subdir" != "."; then \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) GENERATE_FLAG=no apidox) || exit 1; \ + fi ; fi ;\ + done; \ + for subdir in $$list; do \ + if grep '^include .*Doxyfile.am' $(srcdir)/$$subdir/Makefile.am > /dev/null ; then \ + echo "Making apidox in $$subdir"; \ + if test "$$subdir" != "."; then \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) GENERATE_FLAG=yes apidox) || exit 1; \ + fi ; fi ;\ + done; \ + fi + +apidox-am-toplevel-no: +apidox-am-toplevel-yes: + @echo "*** Creating API documentation main page"; \ + cp $(top_srcdir)/admin/Doxyfile.global Doxyfile; \ + echo "PROJECT_NAME = \"$(DOXYGEN_PROJECT_NAME)\"" >> Doxyfile ; \ + echo "PROJECT_NUMBER = \"$(DOXYGEN_PROJECT_NUMBER)\"" >> Doxyfile ; \ + echo "INPUT = $(top_srcdir)" >> Doxyfile ; \ + echo "OUTPUT_DIRECTORY = $(top_builddir)/apidocs" >> Doxyfile ; \ + echo "FILE_PATTERNS = *.dox" >> Doxyfile ; \ + echo "RECURSIVE = NO" >> Doxyfile ; \ + echo "SOURCE_BROWSER = NO" >> Doxyfile ; \ + echo "ALPHABETICAL_INDEX = NO" >> Doxyfile ; \ + echo "HTML_OUTPUT = ." >> Doxyfile ; \ + echo "HTML_HEADER = $(top_srcdir)/doc/api/mainheader.html" >> Doxyfile ; \ + echo "HTML_FOOTER = $(top_srcdir)/doc/api/mainfooter.html" >> Doxyfile ; \ + echo "HTML_STYLESHEET = $(top_builddir)/apidocs/common/doxygen.css" >> Doxyfile ; \ + echo "GENERATE_LATEX = NO" >> Doxyfile ; \ + echo "GENERATE_RTF = NO" >> Doxyfile ; \ + echo "GENERATE_MAN = NO" >> Doxyfile ; \ + echo "GENERATE_XML = NO" >> Doxyfile ; \ + echo "GENERATE_AUTOGEN_DEF = NO" >> Doxyfile ; \ + echo "ENABLE_PREPROCESSING = NO" >> Doxyfile ; \ + echo "CLASS_DIAGRAMS = NO" >> Doxyfile ; \ + echo "HAVE_DOT = NO" >> Doxyfile ; \ + echo "GENERATE_HTML = YES" >> Doxyfile ;\ + $(mkinstalldirs) $(top_builddir)/apidocs ; \ + rm -f $(top_builddir)/apidocs/common ; \ + if test -d $(top_srcdir)/doc/common; then \ + common_dir=`cd $(top_srcdir)/doc/common && pwd` ;\ + else \ + common_dir=$(kde_libs_htmldir)/en/common ;\ + fi ;\ + $(LN_S) $$common_dir $(top_builddir)/apidocs/common ;\ + doxygen Doxyfile; \ + rm -f Doxyfile + @true > $(top_builddir)/apidocs/subdirs + @$(MAKE) apidox-am-tree PARENT="" PARENTINDENT="" + @sort $(top_builddir)/apidocs/subdirs | sed -e 's+++' > $(top_builddir)/apidocs/subdirs_ && mv $(top_builddir)/apidocs/subdirs_ $(top_builddir)/apidocs/subdirs + @sh $(top_srcdir)/doc/api/doxyndex.sh $(top_builddir)/apidocs . + + +apidox-am-tree: + @if test -n '$(SUBDIRS)' ; then \ + list='$(SUBDIRS)' ; \ + for subdir in $$list ; do \ + if test "x$$subdir" != "x."; then \ + if grep '^include .*Doxyfile.am' $(srcdir)/$$subdir/Makefile.am > /dev/null ; then \ + echo "Making apidox index in $$subdir"; \ + echo "
  • $(PARENTINDENT)$$subdir
  • " >> $(top_builddir)/apidocs/subdirs ; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) apidox-am-tree PARENT="$(PARENT)/$$subdir" PARENTINDENT='\ \ $(PARENTINDENT)' ) || exit 1; \ + fi ; \ + fi ; \ + done ; \ + fi + +.PHONY: apidox-am-yes apidox-am-no install-data-local install-apidox install-apidox uninstall-local uninstall-apidox uninstall-apidox apidox apidox-am-toplevel-no apidox-am-toplevel-yes apidox-am-tree + + +# Local Variables: +# mode: makefile +# End: diff --git a/doc/api/Doxyfile.koffice b/doc/api/Doxyfile.koffice new file mode 100644 index 000000000..76049d36d --- /dev/null +++ b/doc/api/Doxyfile.koffice @@ -0,0 +1,191 @@ +PROJECT_NAME = +PROJECT_NUMBER = +OUTPUT_DIRECTORY = ../apidocs/ +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = NO +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 4 +ALIASES = obsolete=@deprecated +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +EXTRACT_ALL = NO +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = YES +EXTRACT_LOCAL_CLASSES = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = YES +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +QUIET = YES +WARNINGS = NO +WARN_IF_UNDOCUMENTED = NO +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = +WARN_LOGFILE = +INPUT = +FILE_PATTERNS = *.h \ + *.cpp \ + *.cc \ + *.hpp \ + *.dox \ + *.c++ \ + *.cxx \ + *.h++ \ + *.hh +RECURSIVE = YES +EXCLUDE = +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = *.moc.* \ + moc* \ + *.all_cpp.* \ + *unload.* \ + */test/* \ + */tests/* \ + *_p.h +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_SOURCE_FILES = NO +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +ALPHABETICAL_INDEX = YES +COLS_IN_ALPHA_INDEX = 3 +IGNORE_PREFIX = K +GENERATE_HTML = NO +HTML_OUTPUT = +HTML_FILE_EXTENSION = .html +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = YES +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +GENERATE_LATEX = NO +LATEX_OUTPUT = +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +GENERATE_RTF = NO +RTF_OUTPUT = +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +GENERATE_MAN = NO +MAN_OUTPUT = +MAN_EXTENSION = .kde3 +MAN_LINKS = YES +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = NO +GENERATE_AUTOGEN_DEF = NO +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = NO +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = QT_VERSION=320 \ + __cplusplus \ + Q_WS_X11 +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +PERL_PATH = +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = NO +HAVE_DOT = NO +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 800 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +SEARCHENGINE = NO + +#----------------------------------------------------------------------- +# KOffice Settings +#----------------------------------------------------------------------- + +HTML_ALIGN_MEMBERS = NO +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = NO +VERBATIM_HEADERS = NO +GENERATE_LATEX = NO +GENERATE_RTF = NO +GENERATE_MAN = NO +GENERATE_XML = NO +GENERATE_HTML = YES +SOURCE_BROWSER = NO +GENERATE_AUTOGEN_DEF = NO +ENABLE_PREPROCESSING = NO +CLASS_DIAGRAMS = NO +HAVE_DOT = NO +IGNORE_PREFIX = K +EXTRACT_ALL = NO + diff --git a/doc/api/doxyndex.sh b/doc/api/doxyndex.sh new file mode 100644 index 000000000..a310c8e9b --- /dev/null +++ b/doc/api/doxyndex.sh @@ -0,0 +1,60 @@ +#! /bin/sh +# +# A shell script to post-process doxy-generated files; the purpose +# is to make the menu on the left in the file match the actually +# generated files (ie. leave out namespaces if there are none). +# +# Usage: doxyndex.sh +# +# Typically, this means $(top_builddir)/apidocs and something like +# libfoo/html for the output. For the top-level dig, set relative-html +# to "." . In non-top directories, both and +# are calculated and replaced. Top directories get an empty +# if any. + +WRKDIR="$1/$2" +TOPDIR=`echo "$2" | sed -e 's+[^/][^/]*/+../+g' -e 's+html$+..+'` +echo "Postprocessing files in $WRKDIR ($TOPDIR)" + +# Special case top-level to have an empty MENU. +if test "x$2" = "x." ; then +MENU="" +else +MENU="
      " + +# This is a list of pairs, with / separators so we can use basename +# and dirname (a crude shell hack) to split them into parts. For +# each, if the file part exists (as a html file) tack it onto the +# MENU variable as a
    • with link. +for i in "Main Page/index" \ + "Modules/modules" \ + "Namespace List/namespaces" \ + "Class Hierarchy/hierarchy" \ + "Alphabetical List/classes" \ + "Class List/annotated" \ + "File List/files" \ + "Namespace Members/namespacemembers" \ + "Class Members/functions" \ + "Related Pages/pages" +do + NAME=`dirname "$i"` + FILE=`basename "$i"` + test -f "$WRKDIR/$FILE.html" && MENU="$MENU
    • $NAME
    • " +done + +MENU="$MENU
    " +fi + + +# Get the list of global Menu entries. +GMENU=`cat "$1"/subdirs | tr -d '\n'` + +PMENU=`grep '++' | awk '{ c=split($0,a,"/"); for (j=1; j<=c; j++) { printf " / %s\n" , a[j]; } }' | tr -d '\n'` + +# Now substitute in the MENU in every file. This depends +# on HTML_HEADER (ie. header.html) containing the comment. +for i in "$WRKDIR"/*.html +do + sed -e "s++$MENU+" -e "s++$GMENU+" -e "s++$PMENU+" < "$i" | sed -e "s+@topdir@+$TOPDIR+g" > "$i.new" && mv "$i.new" "$i" +done + diff --git a/doc/api/header.html b/doc/api/header.html new file mode 100644 index 000000000..b6b7b8777 --- /dev/null +++ b/doc/api/header.html @@ -0,0 +1,70 @@ + + + + + + $title ($projectname) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +

    $projectname

    + + diff --git a/doc/api/kfontdialog.png b/doc/api/kfontdialog.png new file mode 100644 index 000000000..8d834d46f Binary files /dev/null and b/doc/api/kfontdialog.png differ diff --git a/doc/api/mainheader.html b/doc/api/mainheader.html new file mode 100644 index 000000000..780ae3d71 --- /dev/null +++ b/doc/api/mainheader.html @@ -0,0 +1,71 @@ + + + + + + $title ($projectname) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Name +Tel No. + + +Joan +699 23 43 12 + + +Adam +711 19 77 21 + + + + + + +Terms and definitions: +A single data which constitutes a part of a greater collection can be called a +row or more professionally a +record. +The collection is normally called a table. +Moreover, the most natural name for the table is one describing the data it +offers/stores which is Contacts. +Furthermore, each row in the table consists of columns +often also called fields. In the table +Contacts there are two columns (fields): +Name and Tel No.. + + +For simple uses a single table can make up a database. +Many people consider these two equivalent. +As you will see, for real databases we usually need more than one table. + + +To sum up, you have already got a simple database with one table +Contacts. + + + + + +Database and Spreadsheet + +It is very likely that you have already used spreadsheet applications like +KSpread, OpenOffice.org Calc or Microsoft Excel. If so, you will probably +wonder: since both spreadsheets and databases have tables, why should I use +the latter? + + +While comparing spreadsheets and databases you may encounter the following issues which you will later see in greater detail: + + +Referential +data integrity +Data redundancy + +Data integrity +and validity +Limiting data view +Performance and +capacity +Convenient data entry +Reports +Programming +Multiuse +Security + + + +How Is a Database Different From a Spreadsheet? + + +Gradually exceeding the capacity of a mobile phone, expand your table +Contacts adding a column (field) +Address. Add more telephone numbers +(office, home) for each person and add surnames to names. +To make it simpler we assume the following: + + +the table is limited to two people (obviously, +there could be hundreds and thousands of them in a real +database) +there are no two persons with the same name and surname + + +Contacts table + + + + +Name and surname +Tel +Address + + +Joan Smith +699 23 43 12 +Western Gate 1, Warsaw + + +Adam Willson +711 19 77 21 +London, Frogs Drive 5 + + +Joan Smith +110 98 98 00 +Western Gate 1 + + +Smith Joan +312 43 42 22 +Warsaw, Western Gate 1 + + +ADAM Willson +231 83 02 04 +Frogs Drive 5, London + + + + + + +Such a table can be made both in a spreadsheet and in a database. +Using a spreadsheet is very easy, of couse. What problems do we +encounter at this stage? + + + +Referential data integrity + +Suppose you are using a spreadsheet and you need to change the address of at +least one person. You have a small problem: you often have to change the +address in many rows. For example, Joan takes three rows. A real problem +will arise if you forget to change one of the rows - the address asigned +to this person will be ambiguous, hence +your data loses integrity. + + +Moreover there is no simple way of deleting a chosen person from the table +since you have to remember about deleting all rows releted to him or her. + + + + + +Data redundancy + +This is directly connected to the previous problem. In fields +Name and surname and Address +the same data is entered many times. This is typical of a spreadsheets' +ineffective way of storing data because the database grows unnecessarily, +thus requiring more computer resources (larger size of data and slower access). + + +How can you solve these problems with a database? You can split information +into smaller chunks by creating an additional table Persons +with only two columns: Name and surname +and Address: + + +Persons table + + + + +Name and surname +Address + + +Joan Smith +Western Gate 1, Warsaw + + +Adam Willson +Frogs Drive 5, London + + + + + + +Each row in the table Persons corresponds to a +single person. Table Contacts +is from now on a relation to the table Persons +. + + + + + +Data integrity and validity + +Note the way data is entered in the fields Name and surname +and Address. People entering data can be fallible, +sometimes even negligent. In our sample data we have both different sequence +of entering name and surname (Joan Smith and Smith Joan; Adam and ADAM) and +many more ways of entering the same address. Surely you can think of many +other ways. + + +The above problem shows that ⪚ when searching the telephone number of a +person whose address is "Western Gate 1, Warsaw" you will not get a full +result. You will get only one row instead of three. Moreover You will also +not find all the telephone numbers searching for the value "Joan Smith" in +the field Name and surname, because "Smith Joan" will +not fit to "Joan Smith". + + +How can you solve these problems using a database? You can do this by changing the design of the table Persons by: + + + +Dividing data in the field Name and +surname into two separate fields: Name +and Surname. + + +Dividing data in the field Address +into three separate fields: Street, House +number and City. + + +Guaranteeing data correctness: by ensuring that no fields +are empty, ⪚ you must always enter house number. + + + + +A modified table looks something like this: + + +Persons table + + + + + + + + + +Name +Surname +Street +House number +City + + +Joan +Smith +Western Gate +1 +Warsaw + + +Adam +Willson +Frogs Drive +5 +London + + +Conditions + + +required field +required field +required field +required field +required field + + + + + + +Thanks to introducing the condition required field we can +be sure that the entered data is complete. In case of other tables you may +of course allow omitting certain fields while entering data. + + + + + +Limiting data view + +A spreadsheet displays all rows and columns of the table which is bothersome +in case of very large data sheets. You may of course filter and sort rows +in spreadsheets, however you must be extra careful while doing so. Spreadsheet +users are in risk of forgetting that their data view has been filtered what +can lead to mistakes. For example, while calculating sums you may think you +have 100 rows of data while in fact there are 20 rows more hidden. + + +If you want to work on a small subset of data, ⪚ to send it for others to edit, you can copy and paste it to another spreadsheet and after editing paste the changed data back to the main spreadsheet. Such "manual" editing may cause data loss or incorect calculations. + + +To limit the data view database applications offer +queries, forms +and reports. + + +A very practical way of limitting is the following extended version of +the previously described table Persons: + + +Persons table + + + + +Name +Surname +Street +House number +City +Income + + +Joan +Smith +Western Gate +1 +Warsaw +2300 + + +Adam +Willson +Frogs Drive +5 +London +1900 + + + + + + +Let's assume that the newly introduced column Income +contains confidential data. How can you share ⪚ contact details of the +persons with your coworkers but without revealing their +income? It is possible if you share only a query and +not the whole table. The query could select all columns except +for the column Income. In database world such a query +is often known as a view. + + + + + +Performance and capacity + +Your computer is probably quite fast, however you will easily see that it +doesn't help with slow, large spreadsheets. Their low efficiency is first +of all due to lack of indexes accelertaing the process of data search +(databases do offer them). Moreover if you use things like system clipboard, +even copying data may become troublesome with time. + + +Spreadsheets containing large data sets may take ages to open. A spreadsheet +loads lots of data to the computer's memory while opening. Most of the data +loaded are probably useless/unneccessary for you at the moment. Databases +unlike spreadsheets load data from computer storage only when needed. + + +In most cases you will not have to worry how the database stores its data. +This means that unlike spreadsheets, databases do not care about: + + + +The sequence of rows since you can order the rows according to your needs. +Moreover, you can view the same data in many views with different orders. + + +The same goes for columns (fields) of the table. + + + + +Together with Limiting data view +described in the previous paragraph these qualities constitute the +advantage of databases. + + + + + +Data entry + +The latest editions of applications for creating spreadsheets enable you +to design data-entry forms. Such forms are most useful if your data cannot +be conveniently displayed in tabular view, ⪚ if the text occupies +too many rows or if all the columns do not fit on the screen. + + +In this case the very way the spreadsheet works is problematic. +Fields for data entry are placed loosely within the spreadsheet +and very often are not secure against the user's (intentional +or accidental) intervention. + + + + +Reports + +Databases enable grouping, limiting and summing up data in a form of a +report. Spreadsheets are usually printed in a form +of small tables without fully automatic control over page divisions and +the layout of fields. + + + + +Programming + +Applications for creating databases often contain full programming languages. +Newer spreadsheets have this capability too, however calculations come down +to modifying the spreadsheet's fields and simple data copying, regardless of +the relevance and integrity rules mentioned in previous paragraphs. + + +Data processing within a spreadsheet is usually done via a graphical user's +interface which may slow down the data processing speed. Databases are +capable of working in background, outside of graphical interfaces. + + + + +Multiuse + +It is hard to imagine a multiuse of one spreadsheet. Even if it is technically +possible in the case of the latest applications, it requires a lot of +discipline, attention and knowledge from the users, and these cannot +be guaranteed. + + +A classical way to sharing data saved in a spreadsheet with other person is +to send a file as a whole (usually using e-mail) or providing a spreadsheet +file in a computer network. This way of work is ineffective for larger +groups of people - data that could be needed in a particular time may +be currently locked by another person. + + +On the other hand, databases have been designed mainly with multiuser +access in mind. Even for the simplest version locking at a particular table +row's level is possible, which enables easy sharing of table data. + + + + +Security + +Securing a spreadsheet or its particular sections with a password is only +symbolic activity. After providing a spreadsheet file in a computer network, +every person being able to copy the file can try to break the password. +It is sometimes not so hard as the password is stored in the same file +as the spreadsheet. + + +Features for edit locking or copy locking of a spreadsheet (or its part) +is equally easy to break. + + +Databases (except these saved in a file instead of a server) do not need +to be available in a single file. You're accessing them using a computer +network, usually by providing a user name and a password. You are gaining +access only to these areas (tables, forms or even selected rows and columns) +which were assigned to you by setting appropriate access rights. + + +Access rights can affect ability of data editing or only data reading. +If any data is not avaliable to you, it will not be even sent to your +computer, so there is no possibility of making a copy of the data in such +easy way as in case of spreadsheet files. + + + + + + + +Database Design + +Database design needs careful planning. Note that Contacts +table redesign proposed in section 1.2 can generate problems when the +table is filled with data. For example, renaming a field is a simple task, +but splitting the Address field into separate fields +requires careful and tedious work. + + +To avoid such situations, rethink your database project +before you create it in your computer, and before you and others will start +to use it. Thus, by investing some time initially, you will most probably +save your time on everyday use. + + + + +Who Needs a Database? + +Stick to spreadsheets if: + +Your needs are limited and your data will never grow to +large volumes (can you actually forecast that now?) + + +You are unable to acquire the methodology of database construction. +You may however consider either outsourcing this task to someone else +or using simpler tools. + + +You use complicated spreadsheets and you lack time or money to switch +to databases. Think or ask someone whether this does not lead down a +blind alley. Don't count on magical tools that would change your +spreadsheet (regardless how well made) into a database. + + + + +Consider using databases if: +Your data collection expands every week. + +You often create new spreadsheets, copy within these and you feel +that this work is getting more and more tedious. In this case the +effort of switching to databases easily pays off. + + +You create reports and statements for which the table view of +a spreadsheet is not suitable. You can then consider switch +to using a database with form views. + + + + + +Database Creation Software + +So far you have learnt the general characteristics of databases without +going into much detail about specific applications for designing them. + + +The first databases were built together with large mainframe computers +in the 60s, ⪚ IBM System/360. Those were not the days of PCs, +therefore these databases required a highly specialized personnel. +Although the old computers' hardware was unreliable, they were immeasurably +slower and had less storage capacity, one feature of databases still remains +most attractive: the data access by many users through a network. + + +In the 70s scientists formed the theory of relational databases +(terms like: table, record, +column (field) and relationality +and many others). +On the basis of this theory IBM DB2 and Oracle databases were created, +which have been developed and used till today. In the late 70s the first +PCs were constructed. Their users could (gradually) utilize many types of +applications, including those for database construction. + +When it comes to large databases in companies, the situation +hasn't changed: +they still require powerful computers or computer complexes called +clusters. This goes, however, beyond the topic +of this manual. + + +In the area of "accessible" databases with graphic user interface +for PCs you can choose from the following: + + + + +DBase +- a tool for databases operation for DOS popular in the 80s. Files in DBase format +are still used in some specific cases due to their simplicity. + + +FoxPro +- an application similar to DBase (early 90s). After being taken over by +Microsoft, graphic user interfaces were introduced and therefore it is +used for creating databases on PCs. This product is still offered, though +seems a bit obsolete. + + +Microsoft Access +- an application for databases (data and graphic interface design) with many +simplifications, therefore suitable for beginners, designed in the late 80s, +based on 16-Bit Architecture. This product is offered and widely used till today, especially +by small companies, where efficiency and multiuser requirements are not very demanding. + + +FileMaker +- popular application similar to MS Access in simplicity, operating on Windows +and Macintosh platforms, offered since 1985. + + +&kexi; +- a multiplatform application (Unix/Linux, Windows, Mac OS X) designed in 2003, +developed according to OpenSource principles, part of the global +K Desktop Environment project, +&ie; graphic environment for Unix/Linux systems. A significant contributor +to &kexi;'s development is the OpenOffice Poland company. + + + + + + diff --git a/doc/kexi/designingforms.docbook b/doc/kexi/designingforms.docbook new file mode 100644 index 000000000..b205fe712 --- /dev/null +++ b/doc/kexi/designingforms.docbook @@ -0,0 +1,1480 @@ + + + + Designing Forms + + + Most important terms + + + Form + + + A window provided for easy data entry and presentation on the + computer screen. + + + + + Form's data source + + + Database table or query providing data displayed in the + form. The data source is needed because forms itself are only + tools for displaying and entering data, + while tables and queries are the source of data. New, empty + forms have no data source assigned, so they are not displaying + any data from your database unless you assign a data source + to them. + + + + + Form field + + + Direct equivalent of a column in a table or query. Most frequently + used are fields for displaying text and numbers. Entering a new + value or changing the existing value of such a field causes a change + in the bound table or query column (after accepting the change). + + + + + Form design + + + Tasks you are performing to define the appearance and functions of + the form. To do this, you need to provide + data source, + insert form fields + of various types and place them at the appropriate location. + + + + + Form widget + + Form's element. Main widget types are: + + + + Widgets displaying information, ⪚ a text box or an image box. Each + widget of this type can be bound to a data + source field (a table or a query column). Therefore, such widgets + are called in short form fields. + + + + + Widgets able to perform a specified action, ⪚ a push button + that can close the current form. Within other applications this + widget type is sometimes called form control + because it can perform previously defined action of + controlling your database application's + behavior. + + + + + Other widgets allowing to enrich a form's appearance, ⪚ + a line widget can visually separate two form + areas. + + + + + + + Container widget + + + A widget that can contain other widgets within + its area. For example, frame widget or tab widget are containers. + The form's surface itself is a container as well. A command button cannot + be called as container because it is not possible to insert a widget + inside it. In more complex cases, container widgets can be inserted + inside a container, so nesting is possible. + + + + + + + + + Forms versus tables + + In chapter + 5.2 you learned about how to enter data directly into tables using their + data sheet view. However, in many cases forms are better suited for data + entry: + + + + + A table can contain too many columns to display them on your + screen. A form can display such a data using multiple rows. + + + + + A form allows to visually split data fields + into logical groups, thus increasing readability. Labels with + additional information can be inserted to give users more hints + on how to use the form or what given data fields mean. + + + + + Command buttons can be used within forms for commonly used commands + so users can use forms in a similar way as a standalone applications they + know. + + + + In data sheet view displaying multi-row data text + fields or images + is as easy as within forms. + + + + + + + Working with form design + As with table or query design, you are able to use Data View + and Design View. Form designing is performed in + Design View. We will often refer to the form design window as to + Form Designer. + + + + To create a new empty form, select + Insert + Form + from the Menubar. Optionally, you can use + + New Form + command from drop-down button on the Project Navigator's + toolbar or Create Object: Form command from the context menu. + + + + A new frame will appear, you can resize the form by moving the + borders. The form is covered with a grid which simplifies + accurate positioning of the widgets. + + + + + As with table design, Form Designer provides + Property pane. To save some space on the screen, + the pane has three tabs related to the currently + selected form: + + + + The Properties tab + + Contains a list of properties for the currently selected widget. + + + + + + The Data source tab + + + + Contains properties related specifically to the data source + of the currently selected widget or the form itself. + + + + + + + The Widgets tab + + + + Contains a hierarchy of all widgets of the form. The list simplifies + widgets lookup by name and navigation between them. + + + + + + There is information about currently selected widget's name and type displayed + on the first and second tab. + + Additional toolbars are also available: + + + + The Widgets toolbar used for inserting new widgets + into the form + + + + + The Format toolbar used to format form's elements (⪚ + adjusting widget's size, grouping). Formatting commands are also available + in the Format menu. More about these commands can be found + in . + + + + + + + + Using the <guilabel>Widgets</guilabel> tab + + The Widgets tab in the Property pane provides + a list of form widgets and their hierarchy. Each widget is presented + within the hierarchy beside other widgets being on the same level + (the same parent container). Child widgets (inside containers) are + presented using indented names. + + + + Each widget has displayed its name and type. The type has also an icon + displayed - the same as the one displayed on the toolbar used while + form designing is performed. + + + + + + Changing the current selection on the list causes appropriate selection + on the designed form. This allows for easier widget lookup by name and + easier navigation. For example, it is possible to select a widget by + name, and then switch to the Properties tab to change the + widget's properties. + + + + Keeping the Ctrl key pressed while an item on the + widgets list is being selected allows to select multiple widgets at a time. + Keeping the Shift key pressed allows to select entire lists + of widgets. + + + + + + Giving widgets reasonable names can be useful but is not mandatory. Note + that widget's name is a property that is not visible to the user of your form. + Users will only see a widget text, provided by Text property + or similar. + + + + + Inserting widgets - text fields + + Let's create a form providing information about persons, i.e. a form connected + it with Persons table. + + + If the form being designed should present data obtained from the database, + you need to place appropriate fields + on it. To do this, use the buttons on the Widgets toolbar. Each button corresponds to a single widget type. + + + + + Click + Text Box button on the Widgets toolbar. + + + + + Click on the form surface with the left mouse + button. A new text box widget will be placed in the point where you clicked. + Before you release you can drag your mouse to specify a desired size for the widget. + + + + + If needed, move the inserted widget using drag & drop to a desired + position. You can resize the widget afterwards by dragging one of the + small boxes appearing near its corners. Note that the boxes are only + visible when the widget is selected. If you select another widget or the + form surface, the boxes disappear. + + + + Click the Text Box toolbar button again and click + on the form surface to insert another widget. Repeat this action once + again until you get three text boxes inserted in your form. For sake of + simplicity we will limit ourselves to three data + fields. + + + + + + + + There is a context menu available in form's design mode, activated by a + right mouse button click the desired widget + or the form's surface. The menu offers commands like + Cut, + Copy, + Paste, + Delete + and other, more complex. Many of the commands are also provided in the + Menubar, usually Edit. + Keyboard shortcuts are also available for these commands. Some of the + commands are only available for certain types of widgets. + + + + + The commands + Cut, + Copy and + Paste + makes it possible to move or copy widgets between forms, even between separate + database projects. + + + + + Holding the Ctrl key down while clicking a widget allows to select + multiple widgets. + + + + + Instead of using + Copy + and + Paste + commands, to duplicate a widget within the same form you can hold down the + Ctrl key while moving the widget. After the Ctrl + key is released, the dragged widget will not be moved but copied in the new location. + + + + + + + + Assigning data sources + + The fields you inserted + have no data source assigned yet, + so these are not able to display information from the database. To assign data + source, use the + Data Source tab of the Property pane. + + + The very first step is to specify the form's data source, + i.e. a place the displayed data will be fetched from. As mentioned above, you + will use table persons as a + data source + for your new form. + + + + Click on the form's surface, as you will alter its properties. + + + + Switch to the + Data Source tab and enter persons + table name in the Form's data source drop down list. + Alternatively, you can select this name from the drop down list. + + + + + + You have assigned form's data source. Now you need to do specify + widget's data source. + + + + Click the first text field widget at the top of the form. + + + + In the Data Source + tab of the property pane enter field name name in the + Widget's data source drop down list. Alternatively, you can select + this name from the drop down list. + + + + + Click on next text field widget and enter surname as the data source. + + + + Enter data sources for street, house_number + and city text fields + in a similar way. + + + + + You can now save the form's design (this is not mandatory to test the + form in action). To save, click the + + Save object changes toolbar button or use the + CtrlS + File + Save + menu command. Upon saving you will be asked for entering the form's name. Enter + Persons as caption and click the OK + button. The form's name will be filled automatically. + + + This is the right moment for testing your form. Click the + Switch to data view toolbar button. Unless you made a + mistake while entering data sources, you should see + form's fields filled + with data from the persons table. + + + + + + + If you want to remove widget's data source + assignment for a form widget, you can use + Clear widget's data source button near + the Widet's data source drop down list. Similarly, you can use the + + Clear form's data source button near the + Form's data source drop down list. + + + + + Use the + Go to selected form's data source button to select + appropriate table or query in the Project Navigator, + so you can quickly open a table or query being the + data source + of the form. + + + + + + + + + Inserting text labels + + To make it easier for the form's user to identify the meaning of every field + widget, these should have added text labels with appropriate titles. To + create text labels the + Label widget is used. + + + Insert three text label widgets onto the form, placing them on the left + side of the text fields (or on the right hand if your operating system + uses right-to-left layout). On inserting a new label, a text cursor + appears at the location where you can enter the desired title. Enter consecutively: + Name, Surname and Street. Additionally, + on the top of the form insert another label displaying name of the form, + i.e. Persons. Enlarge this label's size and and increase the font size using + + FormatFont... + + menu command. + + + + + + Actions + + An Action is a single activity isolated in the application, + available for the user to execute. It can also be executed automatically as a + reaction for a given event (⪚ after opening a form). + + + + Assigning actions to form buttons + + Many actions can be assigned to form button. The assigned action is executed + after button is clicked. + + To assign action: + + + Switch to form's Design view if you have not done yet. + + + + Select the existing button widget by clicking on it or put a new button + widget onto the form. If you inserted a new button, enter its title and + press Enter key. + + + + + Click the button widget with the right mouse + button to display the context menu. + + + + + From the context menu select + + Assign action... command. + + + + + An Assigning Action to Command Button dialog window + will appear presenting a list of available actions. One of the actions + is selected if the widget already has action assigned. Otherwise the + Action type drop down list has the No type + item selected. + + + + + From the Action type drop down list select + Application item. Available application-wide actions + will be listed. + + + + Select one of the actions on the list (⪚ Delete Row). + + + + Click the OK button or press + the Enter key to + accept your selection. + + + + + + After switching to the form's data view you can try + whether the action works. For example, if you assigned Delete Row + action, clicking the button, the current database row will be deleted, similarly + to executing CtrlDeleteEditDelete Row + menu command (depending on your settings you may be asked to confirm the removal). + + + + + + + To remove an action assignment, select No type item from + the Action type drop down list of the + Assigning Action to Command Button dialog window. + + + + + Actions only work in the form's data view. Not every + action's assignment is reasonable. For example, the + Font... action is available in data view, but + only if you have a widget selected in the Design view. If you + make changes to the font settings the changes are applied to the text + of that selected widget. + + + + + + + + + Widget layouts + + In most cases form widgets should be conveniently arranged and aligned. + Positioning, aligning and resizing widgets by hand is not easy and these + parameters are not adjusted when the user resizes the form. In fact the + situation is even worse because you cannot assume a given form requires + a given space because users have different font sizes and display resolutions. + + + + Using special tool called widget layouts can help to automatically lay + out the form widgets. Widget layout is an action of grouping two or more + widgets so these are well positioned and have appropriate sizes. + + + Using layout in a form improves alignment. Moreover, its space is + better used. Text fields are closer to each other, spacing is constant. + + + There are two methods to create widget layout. + + + + Select two or more widgets that should be placed in a common layout, + and select one of the layout types from the context menu item + + Layout Widgets + . + + + + + Click a container widget (or a form surface itself), where widgets are + inserted and select one of the layout types from the context menu item + Layout Widgets + . + All widgets existing within the container or within the + form, being on the same level will be put into a single common layout. + + + + + In each of these cases you can also use + FormatLayout Widgets + menu. + + + + Widget layout is presented in the design view using a blue, green or + red box drawn with a broken line. This line is displayed only in the + form's design view. + + + Besides the grid type, there are other widget layout types. + + + vertical + + Vertical widget layout + + + + + horizontal + + Horizontal widget layout + + + + + + + + Springs in widget layouts + + A spring in widget layouts is a special, invisible element allowing + to adjust widget's position and size within layouts. Such a spring + stretches or squeezes a widget on the right, top, bottom or left hand, + so it can have desired size and position. + + To use a spring: + + + + Select spring icon on the + Widgets toolbar. + + + + Click on a selected point of the form to insert the spring. + + + + + To make springs work you need to create a global widget layout, i.e. a + layout for the form itself. Then, springs can use edges of the form as + a boundary for expanding. + + + + + + Removing widget layouts + + To remove widget layout without removing widgets, perform one of + these actions: + + + + + Click with the right mouse button on + the layout's border and select Break Layout + command from the context menu. + + + + + Click with the left mouse button on + the layout's border and select + FormatBreak Layout + menu command. + + + + + + Removing widget layout using the Break Layout + command will not remove widgets contained in the layout. If you want to + remove the widgets as well, just select the layout by clicking on its + border and press Delete key or use + Edit + Delete + menu command or context menu command. + + + + + + Size policies for widgets within a layout + + Instead of setting a fixed size for your widgets, in &kexi; you can + choose between various widget's size policies. A size policy + is a flexible strategy for controlling how a widget is stretched (or shrunk) + depending on other neighbouring widgets and space available within the form. + + + After putting widgets into a layout, typically each widget + gets a proportional (Preferred) size policy. These widgets + will be automatically resized with preferred settings, depending on their + type and size of the entire layout itself. For example, three buttons put + into the horizontal layout will be resized to fit their visible text. + + For each widget inserted into the form, there are settings for size policy + available in the Property Editor. The settings are presented + as a group of properties called Size Policy. + + + This group of properties contains: + + + Horizontal Size Policy + + defining horizontal size of the widget, + + + + Vertical Size Policy + + defining vertical size of the widget, + + + + Horizontal Stretch + + + defining strength of activity of the + Horizontal Size Policy, + + + + + Vertical Stretch + + + defining strength of activity of the + Vertical Size Policy + + + + + + + Values of size policies + + The following values are available in the drop down list for + Horizontal Size Policy and + Vertical Size Policy properties visible + in the Property Editor: + + + + Fixed + + + this value means that the widget cannot be automatically resized; it + should maintain the constant size defined at design time (width or height), + + + + + Minimum + + + this value means that the original size of the widget is set as minimal + allowed, it is sufficient and there is no need for expanding the widget, + but the widget will be expanded if needed. This type of policy can be used + to force the widget to be expanded to the whole width or height, especially + if you set a stretch value greater than 0. + + + + + + Maximum + + + this value means that the original size of the widget is set as maximum + allowed and can be decreased without breaking the widget's usability + and readability if other widgets need more space, + + + + + Preferred + + + this value means that the original size of the widget is the best and + preferred; the widget can be shrunk or expanded however and it + will stay readable, + + + + + + Expanding + + + this value means that the original size of the widget is reasonable but + the widget can be also shrunk; it can be expanded as well to take + as much space as possible, + + + + + Minimum Expanding + + + this value means that the original size of the widget is allowed; it + can be expanded to take as much space as possible, + + + + + Ignored + + + this value means that the original size of the widget is ignored; the + widget can be expanded to take as much space as possible but other + widgets usually will not allow for that + + + + + + Different widget types have various default size policies; for example, + button widgets have default size policy set to Minimum (in both directions), + while text field widgets have vertical size policy set to Fixed. + + + The most frequently used size policies are Preferred, + Minimum and Maximum. + + + + + Vertical and horizontal stretch + + The Vertical Stretch and Horizontal Stretch + properties accept integer values greater than or equal to 0. These properties allow to fine-tune the + behavior of size policies. The default value for the properties is 0. + A higher value of the stretch means that the widget will be expanded + more than widgets for which a lower stretch value is set. + + + + + + + + Setting widgets size and position by hand + In case when your form has no main layout set for auto-positioning and + auto-resizing its widgets, you will probably want to modify the position and size of widgets so the form can look cleaner and be easier to use. The &kexi; form + designer simplifies this task by offering the following groups of commands: + + + + + Adjusting sizes of selected widgets. The commands are available in the + FormatAdjust Widgets Size + submenu of the menubar and in the + Adjust Widgets Size + submenu of the context menu. The toolbar's drop down + button Adjust Widgets Size + is also available. + + + + To Fit + + + The size of the selected widgets will be altered so each widget will be + resized to its preferred size and its contents; for example, a text + label's size will be changed to fit its text. The position of the widgets + will not be changed. + + + + + To Grid + + + The size of the selected widgets will be altered so each widget's corner + will be placed on the form's (or other container's) grid point. + The widget's position can be slightly altered. + + + + + To Shortest + + + The height of the selected widgets will be altered so that each of them + will have the same height as the shortest one. The position of the widgets + will not be changed. + + + + + To Tallest + + + The height of the selected widgets will be altered so that each of them + will have the same height as the tallest one. The position of the widgets + will not be changed. + + + + + To Narrowest + + + The width of the selected widgets will be altered so that each of them + will have the same height as the narrowest one. The position of the + widgets will not be changed. + + + + + To Widest + + + The width of the selected widgets will be altered so that each of them + will have the same height as the widest one. The position of the widgets + will not be changed. + + + + + + + + Aligning positions of the selected widgets. The commands are available + in the + FormatAlign Widgets Position + submenu of the menubar and in the + Align Widgets Position + submenu of the context menu. The toolbar's drop + down button + Align Widgets Position is also available. + + + + To Left + + + All the selected widgets' left positions will be moved to the + position of the leftmost widget's left edge. + + + + + To Right + + + All the selected widgets' right positions will be moved to the + position of the rightmost widget's right edge. + + + + + To Top + + + All the selected widgets' top positions will be moved to the + position of the uppermost widget's upper edge. + + + + + To Bottom + + + All the selected widgets' bottom positions will be moved to the + position of the bottommost widget's bottom edge. + + + + + To Grid + + + All the selected widgets' top-left corners will be moved so that + they are positioned in the nearest grid point. + + + + + None of the above commands resizes the widgets. + + + + There are also additional commands available: + Bring Widget to Front + (i.e. above all other widgets) and + Send Widget to Back (i.e. below all + other widgets). These two commands are rarely used, as it is not + common to place one widget on top of an other (except when a + container widget contains other widget inside). Also note that clicking + a widget with a mouse button is enough to bring the widget to front. + + + + + Setting the tab order + + A widget's focus determines that widget's activity available using keyboard. + Focus is related to widgets displayed in the form's data view. Exactly one + form widget can have focus at the same time. The most frequent use of focus + is text entry (when a given text field is active, i.e. it is focused). + An other example is a button widget - when focused, it is possible to + press it using the Enter + or Space key instead of a mouse button. + + + There are a few methods of making the widgets active (moving the focus + to the widget): clicking with a mouse button, rotating the mouse wheel + over the widget, or using the Tab + key. The latter method is often used because of its speed and convenience + for users. Availability of the focusing methods is controlled by + Focus Policy property of a given widget. + + + There is a relationship between focusing (activating) widgets using Tab + key and tab order setting of a form. After pressing the Tab key, the + next widget should be focused, so the form should know about the tab order. + + To alter tab order for a form's widget: + + + Switch to design view of the form. + + + + Execute EditEdit Tab Order... + menu command. The Edit Tab Order dialog will appear with settings for this form. + + + + The window contains a list with two columns: the first column displays + widget names, the second - types of the widgets. To make it easier to + recognize meaning of the names and types for the user, icons related + to the types are also displayed. The list contains only widgets having + focus policy allowing to use the Tab key. The window + allows you to change the tab order or set the automatic tab order. + + + + To change tab order, either: + + + + Click a selected widget name in the widgets list and drag it + to a desired position (up or down) using the mouse. + + + + + Click a selected widget name on the widgets list and use + Move Up or Move Down + buttons, to move the widgets to a desired position. + + + + + Click the Handle tab order automatically check box to set the + automatic tab order for the form. If this option has been switched + on, any changes made to the list of widgets by hand are not taken + into account - &kexi; will be handling the tab orders on its own. + The automatic ordering means that the top-left widget will be focused + first (or the top-right if your operating system uses right-to-left + layout), and the order comes from the left to right (from the right + to left, respectively) and from the top to bottom. + + + + + + + + Click the OK button to accept the changes or Cancel button to dismiss + the changes. + + + + + diff --git a/doc/kexi/enteringdataintotables.docbook b/doc/kexi/enteringdataintotables.docbook new file mode 100644 index 000000000..d65c17d34 --- /dev/null +++ b/doc/kexi/enteringdataintotables.docbook @@ -0,0 +1,130 @@ + + + + Entering Data Into Tables + + You have designed the two tables Persons and + phone_numbers. None of them contain any data yet. You can + enter some, and in this chapter you will learn how to do this fast and effectively. + + + + + Start with the persons table. Open it in Data View using the Project Navigtor's context menu. + The current cell is marked with + (usually black) thicker border, a cell cursor. The contents + of the cell, if present, are highlighted with a different color. The current + row, i.e. the one you have placed your rectangular cursor in, is marked + on the left hand with an arrow symbol. + + + + You can navigate through table cells using the arrow keys, Page Down, + Page Down, Home, End keys; you can also + click with the mouse in a cell to select it. + + + Initially, after opening the table Persons, the cursor is placed in + the id column. The column has autonumber property defined, + marked with blue (autonumber) text in the last row. It + means you do not have to enter values there by hand when entering data for a new + row because the cell will be filled automatically with successive numbers. + + + + + + Inserting new rows and entering data for them in &kexi; is different from + the way of doing this in spreadsheets. To enter data for a new row, you need + to use the arrow keys or mouse, to move your cursor to the special empty last + row marked with a plus + sign. Place your cursor in the (second) name column and enter a + person's name. Also enter surname, street, house number and city. When + done, move the cell cursor to the last empty row either by using the + Arrow Down key or by clicking in the last + row with the mouse to append a new row. + + + Details About Actions Available While Entering Data Into Tables + + + + As soon as you enter the first character, the current row is being edited. A pencil symbol appears on the left side of the data table. + + + + + Double clicking a cell with the &LMB; or pressing Enter or the F2 key also starts + editing of the current row. + + + + + Pressing the Esc key when the contents of a cell is edited + cancels changes made to this cell. However, the pencil + + symbol will not disappear because you can still move to a different cell + of the edited row to change its contents. To + cancel changes made to the entire edited row, press the + Esc key again. + + + + + Instead of pressing the Esc key, you can click the + Cancel + toolbar button or select + DataCancel Row Changes + from the menubar. + + + + + Click the ShiftEnter + keys to accept changes made to all cells in the currently edited row. You can also click + OK toolbar + button or select DataSave Row + from the menubar. + + + + + + + + Fill the phone_numbers table with data. In the persons column you + need to provide a number of the person existing in the persons + table. + + + + + diff --git a/doc/kexi/enteringdatausingforms.docbook b/doc/kexi/enteringdatausingforms.docbook new file mode 100644 index 000000000..08fcb627f --- /dev/null +++ b/doc/kexi/enteringdatausingforms.docbook @@ -0,0 +1,33 @@ + + + + Entering Data Using Forms + + Data entering and editing is usually the task of the user of the database application. The designer of the database should check the form in terms of valid + data entry, and see whether the form works as expected. + + + To test your form, switch to its data view. A single database row (record) + of data will be displayed and a text cursor will be set inside the first + data field. You can move between fields using the &LMB; or the Tab and + ShiftTab + keys. While editing, there will be a + + pencil icon visible near the record navigator. After entering the row's (record) + data you can press the + ShiftEnter + keys or click the + OK + toolbar button to accept changes made to the current row. Clicking the + Cancel + toolbar button discards changes made to the current row and restores the contents of + the data fields. You can use the + record navigator's button to move to a new row. All the navigator's functions are + also available in a similar way as in the data table view + . + + + diff --git a/doc/kexi/index.docbook b/doc/kexi/index.docbook new file mode 100644 index 000000000..04692e4c5 --- /dev/null +++ b/doc/kexi/index.docbook @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + +]> + + + + + + The &kexi; Handbook + + + + + + Martin + A. + Ellis + + martin.ellis@kdemail.net + + + + Jaroslaw + Staniek + + js@iidea.pl + + + + + + 2004 + 2005 + 2006 + Jaroslaw Staniek + Martin Ellis + + + + +&FDLNotice; + + + +2006-09-07 +1.6 + + + + + &kexi; is the application for creating databases and for data management + in the &koffice; productivity suite. + + + + + + KDE + KOffice + Kexi + database + + + + + + +&intro; +&basics; +&building; +&configuration; +&menus; +&credits; +&database; +&comparing; + +&documentation.index; + + + diff --git a/doc/kexi/intro.docbook b/doc/kexi/intro.docbook new file mode 100644 index 000000000..dc62ba008 --- /dev/null +++ b/doc/kexi/intro.docbook @@ -0,0 +1,78 @@ + + + +Introduction + + + + + &kexi; is a database management application. It can be used for + creating databases, inserting data, performing queries, and processing + data. Forms can be created to provide a custom interface to your + data. All database objects - tables, queries and forms - are stored in + the database, making it easy to share data and design. + + + + &kexi; is part of the &koffice; productivity suite for the K Desktop + Environment. + + + + In addition to storing your &kexi; databases in files, &kexi; can also + store your data on a database server. Using + a database server allows you to share your database with other + people, and also allows more than one person to use the database at + one time. The following database servers are supported by &kexi;: + + + + MySQL (See http://www.mysql.com/) + + + + + PostgreSQL (See http://www.postgresql.org/) + + + + + + + More information about &kexi; can be found at the &kexi; page on the + &koffice; website + at http://www.koffice.org/kexi/, + and on the website for &kexi; itself + at http://www.kexi-project.org/about.html. + + + + If you have any questions about &kexi;, there are two mailing lists + you can use. The Kexi user mailing + list can be used to ask questions about using &kexi; or about + the &kexi; project. The Kexi + development mailing list can be used to ask questions about + the development of &kexi;. Further information on how to subscribe + to these lists, together with a few other ways of making contact with + &kexi; developers, can be found at: + + + + http://www.kexi-project.org/support.html + + + + + + diff --git a/doc/kexi/menus.docbook b/doc/kexi/menus.docbook new file mode 100644 index 000000000..8428fcaf5 --- /dev/null +++ b/doc/kexi/menus.docbook @@ -0,0 +1,701 @@ + + + + + + + Anne-Marie + Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + + + Jarosław + Staniek + + js@iidea.pl + + +
    +
    + Command Reference + + + The <guimenu>File</guimenu> Menu + + + + + + &Ctrl;N + + File + New... + + Create a new project. Currently opened project is not affected. + + + + + + &Ctrl;O + + File + Open... + + Open an existing project. Currently opened project is not affected. + + + + + + File + Download Example Databases... + + + + Open the KNewStuff dialog which + allows you to download example databases via the + Internet. This is currently not available for MS Windows. + + + + + + + + &Ctrl;S + + File + Save + + + + Saves object changes from the active window. + + + + + + + File + Import + Data Table... + + + + Imports table data from a file in Comma Separated Value (CSV) format. + + + + + + + File + Export + Table or Query as Data Table... + + + + Export data from the active table or query data to a file in Comma Separated Value (CSV) format. + + + + + + +&Ctrl;P + +File +Print... + +Print data from the active (opened) table or query. +Note for KDE: Make sure the proper print system is selected in the +Print system currently used: section. This option can +be seen after clicking on the Options>> button. + + + + +File +Print Preview... + +Show print preview for the active (opened) table or query. + + + + +File +Page Setup... + +Set Font... for the Page title:, +Change... Page Size & Margins and +Add table borders. + + + + + + + &Ctrl;W + + File + Close Project + + + + Close the currently opened project but leave &kexi; running. + + + + + + + + + &Ctrl;Q + + File + Quit + + + + Quit &kexi;. + + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + + +&Ctrl;Z + +Edit +Undo + +Undoes an action. You can revert to the state that existed +before your last change. + + + + + +&Ctrl; &Shift; Z + +Edit +Redo + +Undoes an undo. Reverse the action of Undo. This will restore the change +you originally made. + + + + + +&Ctrl;X + +Edit +Cut + +Remove currently selected text and put it on the clipboard. +This command is unavailable if there is no text currently selected. If this action is used +in the Form Designer, currently selected widget or group of widgets are removed and put on the clipboard. + + + + + + +&Ctrl;C + +Edit +Copy + +Copy currently selected text onto the clipboard. +This command is unavailable if there is no text currently selected. If this action is used +in the Form Designer, currently selected widget or group of widgets are copied onto +the clipboard. + + + + + +&Ctrl;V + +Edit +Paste + +Copy of the clipboard contents at the insertion point. +This command is unavailable if the clipboard is empty. If this action is used +in the Form Designer and the clipboard contains copied widgets, they will be inserted +onto the form. + + + + +Edit +Copy Special +Table or Query As Data Table... + +Copy selected table or query data to clipboard. + + + + +Edit +Paste Special +As Data Table... + +Paste clipboard data to a new table within the current project. + + + + + + +&Ctrl;A + +Edit +Select All + +Select all characters in the edited text box or all widgets in the Form Designer. + + + + + +Edit +Delete + +Delete the currently selected object. + + + + + +&Ctrl;Delete + +Edit +Delete Row + +Delete currently selected row from a table. + + + + + + +The <guimenu>View</guimenu> Menu + + + + +F6 +View +Data View + +Switch to Data View. + + + + +F7 +View +Design View + +Switch to Design View. + + + + +F8 +View +Text View + +Switch to Text View. Currently, only available for database queries +and means switching to the SQL View of the Query Designer. + + + + + +&Alt;1 + +View +Project Navigator + +Go to Project Navigator pane. + + + + + +&Alt;2 + +View +Main Area + +Go to the main area. + + + + + +&Alt;3 + +View +Property Editor + +Go to the Property Editor pane. + + + + +View +Show/Hide Properties + +Display or hide the Property Editor pane. + + + + +View +Show/Hide Project Navigator + +Display or hide the Project Navigator pane. + + + + + + +The <guimenu>Insert</guimenu> Menu + + + + +Insert +Table... + +Inserts a new, empty table design without saving it. +The Table Designer window will appear. + + + + +Insert +Query... + +Inserts a new, empty query design without saving it. +The Query Designer window will appear. + + + + +Insert +Form... + +Inserts a new, empty form design without saving it. +The Form Designer window will appear. + + + + +Insert +Script... + +Inserts a new, empty script design without saving it. +The Script Editor window will appear. The command is available only if scripting +is enabled in &kexi;. + + + + + + +The <guimenu>Format</guimenu> Menu + + + + +Format +Font... + +Change font for selected object. +Can be used in the Form Designer to set widget's font. + + + + + + +Format +Snap to Grid + +If this is enabled, when moving widgets on the form surface +the top left corner of the widget will snap or move to the nearest grid point. +This does reduce your freedom to freely position widgets on the form surface, +however it also helps to line up widgets precisely. + + + + +Format +Layout Widgets + +Creates a new layout for widgets. Widgets can be layed out Horizontally, Vertically, In Grid, Horizontally in Splitter, Vertically in Splitter. + + + + +Format +Break Layout + +Breaks the currently selected layout. + + + + +Format +Align Widgets Position + +Align the currently selected widgets' position: +To Left, To Right, To Top, To Bottom, To Grid. + + + + +Format +Align Widgets Size + +Align the currently selected widgets' size: +To Fit, To Grid, To Shortest, To Tallest, To Narrowest, To Widest. + + + + +Format +Bring Widget to Front + +Bring the currently selected widgets to front. + + + + +Format +Send Widget to Back + +Send the currently selected widgets to back. + + + + + + +The <guimenu>Data</guimenu> Menu + + + + + + +&Shift;Return + +Data +Save Row + +Save currently selected table row's data. + + + + +Data +Cancel Row Changes + +Cancel changes made to currently selected table row. + + + + +Data +Sort +Ascending + +Sorts data in ascending order (from A to Z and from 0 to 9). +Data from selected column is used for sorting. + + + + +Data +Sort +Descending + +Sorts data in descending (from Z to A and from 9 to 0). +Data from selected column is used for sorting. + + + + + + +The <guimenu>Tools</guimenu> Menu + + + + +Tools +Import Database... + +Opens the Data Base Importing Wizard +to import an existing database into a &kexi; database. + + + + +Tools +Execute Script File... + +Displays the file dialog +to open an existing script file. + + + + +Tools +Scripts Manager... + +Displays &kexi;'s Scripts Manager +dialog to execute, load, unload, install, unistall or download scripts. + + + + +Tools +Scripts + +Executes an already loaded script. + + + + + + +The <guimenu>Window</guimenu> Menu + + + + + +&Ctrl;W + +Window +Close + +Close the active window. + + + + +Window +Close All + +Close all opened windows. + + + + +Window +MDI Mode +Childframe Mode + +Switch to Childframe user interface mode. + + + + +Window +MDI Mode +IDEAl Mode + +Switch to IDEAl user interface mode. + + + + + +&Alt;Right + +Window +Next Window + +Switch to the next window. + + + + + +&Alt;Left + +Window +Previous Window + +Switch to the previous window. + + + +The last items in this menu show the currently opened window names. + + + + The <guimenu>Settings</guimenu> Menu + + + + + + + Settings + Toolbars + + + + Show or hide one of the toolbars. + + + + + + + Settings + Configure Shortcuts... + + + + Configure the keyboard shortcuts used by &kexi;. + See the section on configuring shortcuts for more + details. + + + + + + + + + The <guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + +
    diff --git a/doc/kexi/querydesigning.docbook b/doc/kexi/querydesigning.docbook new file mode 100644 index 000000000..5114dbd0a --- /dev/null +++ b/doc/kexi/querydesigning.docbook @@ -0,0 +1,109 @@ + + + + Designing Database Queries + + A database's primary purpose is to store and help extract information + you are looking for. Unlike databases written on a paper sheets, &kexi; + database allows you to specify more search criteria. Results + are returend faster even for large data sets. All this is a power of + databases, however to be able to perform efffective queries + in your database, you need to learn how to tell the database what you are + looking for. + + + With database queries you can limit data coming from a table to a predefined + set of rows and columns as well as dynamically join + data coming from multiple tables. + + + To see how queries work in practice you will create a contacts + query joining data from two tables: persons and + phone_numbers (designed in + chapter 3.1i + + and filled with data in + chapter 3.2 + ). + + + + + Create a new empty query by selecting + InsertQuery from + the menubar. The design window will appear. The window is split into two areas: query + relationships at the top and query columns below. + + + + + + Select the table persons in the drop down list Table: + located at the top of the window and click the Add button. A graphical + representation of the table will appear in the relations area. Do the same for the + phone_numbers table to insert it too, as in the figure below. + + + + + + Add query relationship using mouse drag & drop technique: click the field + id in the table persons table, drag it + and drop into the person field of the phone_numbers + table. This will join both fields by creating a new relationship. + + + + + Double-click the name field in the persons + table, to add the field as a query column. In a similar way, + add surname, street, house_number, + city fields from the persons table and + phone from the phone_numbers table. + + + + + Query design is now ready for testing. Click the + Switch to data view button on the toolbar, to switch from + design to viewing the data provided as query results. + + + + + + Save the query design for later use by clicking the + Save button on the toolbar. You can also use + FileSave + from the menubar or press the CtrlS + keys. Because the query design has not been saved yet, you will be asked to + specify a name for it. Enter Contacts text in the + caption field and click the OK button. + + + + diff --git a/doc/kformula/Makefile.am b/doc/kformula/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kformula/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kformula/ambiguous-string.png b/doc/kformula/ambiguous-string.png new file mode 100644 index 000000000..83aafdc57 Binary files /dev/null and b/doc/kformula/ambiguous-string.png differ diff --git a/doc/kformula/correct_index_location.png b/doc/kformula/correct_index_location.png new file mode 100644 index 000000000..65f07d186 Binary files /dev/null and b/doc/kformula/correct_index_location.png differ diff --git a/doc/kformula/definite_integral.png b/doc/kformula/definite_integral.png new file mode 100644 index 000000000..16af377eb Binary files /dev/null and b/doc/kformula/definite_integral.png differ diff --git a/doc/kformula/file-toolbar.png b/doc/kformula/file-toolbar.png new file mode 100644 index 000000000..39ea201d2 Binary files /dev/null and b/doc/kformula/file-toolbar.png differ diff --git a/doc/kformula/file-toolbar2.png b/doc/kformula/file-toolbar2.png new file mode 100644 index 000000000..3c2f94d38 Binary files /dev/null and b/doc/kformula/file-toolbar2.png differ diff --git a/doc/kformula/green1.png b/doc/kformula/green1.png new file mode 100644 index 000000000..880f57682 Binary files /dev/null and b/doc/kformula/green1.png differ diff --git a/doc/kformula/green2.png b/doc/kformula/green2.png new file mode 100644 index 000000000..132cfb9fc Binary files /dev/null and b/doc/kformula/green2.png differ diff --git a/doc/kformula/greens.png b/doc/kformula/greens.png new file mode 100644 index 000000000..8f1abfc34 Binary files /dev/null and b/doc/kformula/greens.png differ diff --git a/doc/kformula/incorrect_index_location.png b/doc/kformula/incorrect_index_location.png new file mode 100644 index 000000000..33b7238b9 Binary files /dev/null and b/doc/kformula/incorrect_index_location.png differ diff --git a/doc/kformula/index.docbook b/doc/kformula/index.docbook new file mode 100644 index 000000000..f142b6898 --- /dev/null +++ b/doc/kformula/index.docbook @@ -0,0 +1,1246 @@ + + + + + +]> + + + + +The &kformula; Handbook + + + + +Jonathan +Drews +
    j.e.drews@att.net
    +
    + +Anne-Marie +Mahfouf +
    annma@kde.org
    +
    + +Alfredo +Beaumont Sainz +
    alfredo.beaumont@gmail.com
    +
    + +Ulrich +Küttler +Developer + + + +
    + +2002 +Jonathan Drews + + +2005 +Anne-Marie Mahfouf + + +2006 +Alfredo Beaumont Sainz + +&FDLNotice; + +2006-09-09 +1.5.90 + + + +&kformula; is used to layout formulas. + + + + + +KDE +KOffice +kformula +formula + + +
    + + +Introduction +&kformula; is used to write formulas. It doesn't evaluate +anything. All it does is print them. +&kformula; was designed for your editing pleasure. It makes it +delightful to enter Greek letters, fractions and all the stuff that +makes a formula look like a formula. +But most of the time you won't want to use &kformula; itself. +Instead you might choose to use it from within &kword; or any other +&koffice; application. That is &kformula; is not a useful application +on its own but an extension to all the other &koffice; applications +you've fallen in love with. + +Where ever &kformula; gets embedded, it will +behave the same. + + + + +Basics +A new (empty) &kformula; document looks like a small blue square. +This square stands for the central idea of &kformula;. It represents an +empty list. The idea of &kformula; is to have different elements +arranged in lists. An element in this respect might be a single char +or a root symbol or something like that. The lists are put together so +that they form a formula. That is there are lists for indexes, lower +and upper bounds and so on. And of course there is the main +list, which we've already seen. + +Writing a formula means to fill the empty list with letters, +figures and mathematical symbols. That is straightforward: use your +keyboard. As soon as you type something the empty +symbol will vanish and you will see whatever you have inserted +instead. New characters are always put at the current cursor +position. + +There is a toolbar called Add that allows +you to create more complex elements. There are indices, fractions, +roots and matrices to name a few. All these elements +consist of at least one list, you can move the cursor into and insert +new items. + + + + +Using &kformula; + Below is a typical formula entry in &kformula;. To enter the partial +derivatives and Greek letters click on the symbol combo box, on the +right, and select the appropriate symbol. The symbol combo box, in the figure +below, has the word +Cap on it. Click on the return key symbol to the right of it, +to enter a symbol. + +Screenshot of &kformula; + + + + + + Screenshot of &kformula; + + + + + The Greens formula above can be printed to a &PostScript; +file. To do that choose FilePrint + and configure print as shown below: + + +Here's a screenshot of Greens Formula in &kformula; + + + + +Here's a screenshot of Greens Formula in &kformula; + + + + +Here is what the the resulting &PostScript; file should look +like: + + +Here is the &PostScript; output from &kformula; + + + + + + + + +More &kformula; features + +More on formulas +To enter matrices, click on the [ ] and then click +on the matrix symbol + + . +You can move from matrix element to matrix element using the arrow +keys Right arrow, Up arrow, +Down arrow and Left arrow. An example matrix +is shown below. + + +Here is the resulting matrix; + + + + + + + + + + +Command Reference + + +The Main &kformula; Window + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N + +File +New + +Creates a new &kformula; +document. + + + + + +&Ctrl;O + +File +Open... + +Opens a previously saved +document. + + + + +File +Open Recent + +Displays a selection of recently opened documents. + + + + + +&Ctrl;S + +File +Save + +Saves the document. + + + + +File +Save As... + +Saves the document with a name you provide. + + + + +File +Reload + +Reloads the more recently opened document. + + + + +File +Import + +Imports formulas from other formats. + + + + +File +Export + +Exports the current document in another format. + + + + +File +Mail... + +Invokes &kmail; so you can email the file. +The file is already attached to the email. + + + + + +&Ctrl;P + +File +Print... + +Prints the document. + + + + +File +Print Preview... + +Shows how the printed document will appear. + + + + +File +Document Information + +Provides a dialog box where you can enter your name, +email address and a short description about the document. + + + + + +&Ctrl;W + +File +Close + +Closes the current document. + + + + + +&Ctrl;Q + +File +Quit + +Quits &kformula;. + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + + +&Ctrl;Z + +Edit +Undo + +Undoes an action. You can revert to the state that existed +before your last change. + + + + + +&Ctrl; &Shift; Z + +Edit +Redo + +Undoes an undo. Reverse the action of Undo. This will restore the change +you originally made. + + + + + +&Ctrl;X + +Edit +Cut + +Cuts a highlighted piece of text from the &kformula; screen. + + + + + +&Ctrl;C + +Edit +Copy + +Copies a highlighted piece of text from the &kformula; screen. + + + + + +&Ctrl;V + +Edit +Paste + +Pastes the text you selected with Cut or Copy to the &kformula; screen. + + + + + +&Ctrl;A + +Edit +Select All + +Highlights all the text in the &kformula; screen for +either Cut or Copy. + + + + + +&Ctrl;R + +Edit +Remove Enclosing Element + +Removes enclosing braces, brackets or absolute value bars. +This action takes place on the braces just outside the cursor. + + + + + +&Ctrl;G + +Edit +Convert to Greek + +Converts a Latin character to a Greek symbol. + + + + +Edit +Edit Formula String... + +Brings up an editor where you can edit the existing formula. + + + + +See the Advanced editing +section for details. + + + + +The <guimenu>Element</guimenu> Menu + + + + + +Element +Add +Add Root + +Inserts the square root. + + + + +Element +Add +Add Fraction + +Inserts a fraction. + + + + +Element +Add +Add Bracket + +Inserts a pair of brackets, &ie; ( ). You can also just +type ( to insert a pair of brackets. + + + + +Element +Add +Add Integral + +Inserts the integral sign. + + + + +Element +Add +Add Sum + +Inserts the summation sign. +(sigma). + + + + +Element +Add +Add Product + +Inserts the product sign. + + + + +Element +Add +Add Matrix... + +Inserts a matrix. A dialog box pops up, with the default size being 3x3. +You can specify the number of rows and columns in this box. + + + + +Element +Add +Add 1x2 Matrix + +Inserts a two rowed column vector. + + + + +Element +Add +Add Overline + +Inserts an overline in this box. + + + + +Element +Add +Add Underline + +Inserts an underline in this box. + + + + +Element +Add +Add Multiline + +Inserts a new line each time you type Enter in the square. + + + + + +&Ctrl;U + +Element +Add +Add Upper Index + +Adds an upper index like so: + + . + + + + + +&Ctrl;L + +Element +Add +Add Lower Index + +Adds a lower index: + + . + See the Definite Integrals and +Indices section for details about indices. + + + + + +Element +Add +Add Negative Thin Space + +Inserts a small reduced space, here between the o and the e: + + . + + + + +Element +Add +Add Thin Space + +Inserts a small space. + + + + +Element +Add +Add Medium Space + +Inserts a space that is one and a half times wider. + + + + + +Element +Add +Add Thick Space + +Inserts a double space. + + + + +Element +Add +Add Quad Space + +Inserts a quadruple wide space. + + + + +Element +Matrix +Insert Column + +Inserts a column in an existing matrix. The column is inserted where the cursor is at. + + + + +Element +Matrix +Append Column + +Appends a column to an existing matrix. The column is appended on the right. + + + + +Element +Matrix +Remove Column + +Removes a column from an existing matrix. Removal occurs where the cursor is positioned. + + + + +Element +Matrix +Insert Row + +Inserts a row in an existing matrix. The row is inserted where the cursor is at. + + + + +Element +Matrix +Append Row + +Appends a row to an existing matrix. The row is appended on the bottom. + + + + +Element +Matrix +Remove Row + +Removes a row from an existing matrix. Removal occurs where the cursor is positioned. + + + + +Element +Size + +Allows to set the size of the font (from 6 to 72). + + + + +Element +Left Delimiter + +Allows insertion of various delimiters &ie; (, {, and +[. + + + + +Element +Right Delimiter + +Allows insertion of various delimiters &ie; ), }, and +]. + + + + + +&Ctrl;I + +Element +Insert Symbol + +Inserts the symbol, selected in the symbol +toolbar. + + + + + + +The <guimenu>Settings</guimenu> Menu +Here you can choose how &kformula; is configured. + You can select the toolbars you want displayed or the type of fonts to be +used. + + + + + +Settings +Toolbars +File (KFormula) + +Toggles the toolbar that contains clickable icons for +new, open and save files. +Print and print preview are here also. + + + + +Settings +Toolbars +Edit (KFormula) + +Toggles the edit toolbar. Here are clickable icons for +cut and paste as well as Undo and Redo. + + + + +Settings +Toolbars +Add (KFormula) + +This toolbar contains all the mathematical elements such +as Sum, Integral, Exponent &etc; + + + + +Settings +Toolbars +Font (KFormula) + +This toolbar contains the font settings (size, bold, italic, &etc;). + + + + +Settings +Toolbars +Symbol (KFormula) + +This toggles the combo box that contains Del, the +partial derivative symbol, limit arrows, +boolean operators and other mathematical symbols. + + + + + +Settings +Toolbars +Matrix (KFormula) + +This toggles the matrix toolbar. It contains clickable +icons that pertain to matrix creation and editing. + + + + +Settings +Syntax Highlighting + +Checking this item determines if the numbers will be +displayed in color. + + + + + + + + + +Configuring Shortcuts + +The +SettingsConfigure Shortcuts... +allows you to specify shortcuts. + + +Below is an example of how to configure a shortcut for a +print preview. + + + +Picture of shortcut dialog + + + + + + + + + +Click on Custom. + + + +Next click on the button Advanced >> and then Primary shortcut:. + + + +Do &Ctrl;Space +and the dialog should disappear. The shortcut is now entered. + + + + +Picture of shortcut dialog + + + + + + + +Pressing the keys &Ctrl;Space +now displays the print preview. + + + + + +Configuring Toolbars +The +SettingsConfigure Toolbars... +is used to add additional buttons to the toolbars. + + +Picture of toolbars dialog + + + + + + + + + + + +To add a button to the File toolbar, + + + +Picture of toolbars dialog + + + + + + + + make sure File + <&koffice;> is displayed in the top combo box. + + + +Click on one of the items in the left hand pane. This item will now be +highlighted to show that it has been selected. + + + +Next click on the Right arrow button to place it in +the right pane. + + + +Click on Apply and then +click on OK. + + + + +The new Item should be in the toolbar. + + + + + + + + + + +Configuring &kformula; +The +SettingsConfigure +&kformula;... is where the font sizes and font styles are +selected. + + + +The Formula section allows you to select fonts +and font highlight colors. + + + + + + + +The <guimenu>Help</guimenu> Menu + + + +Help +Tip of the Day + +Opens the Tip of the Day dialog which displays a random tip about &kformula;. + + +&help.menu.documentation; + + + + + + + +Advanced Editing + + +Name insertion + +A special feature is the name insertion. The blue square you +type into is actual a list. Furthermore, that list can contain other +lists. When you type a backslash (\) you get a new +empty list right away. But this one is special. It uses a different +font and is meant to insert things like function names. There is, +however, a second idea here. Your keyboard only has a limited number of keys. +The wealth of mathematical symbols on the other side is overwhelming. To get one +of those you can type its name and press the space bar afterwards. The name you +typed will be replaced by the symbol then. In this context, the +Space bar means get out of here, that +is move the cursor to the containing list. The cursor will be +positioned at the end of what you just entered but will also enclose part of the original +formula, after pressing the space bar. + + +Another thing you might want to insert are spaces. We all know, +printing formulae is all about the right spacing. And you can do just +that using a name list. + +Inside the blue square do: \,SPACE to get a small space. + + +Do: \<Space to get a medium space. + + +Do: \;Space to get a thick space. + + +Do: \ quad Space to get +a quadruple wide space. + + +In the same way, specific mathematical symbols can be inserted. +\ oint Space inserts +the path integral about a closed contour. Below is the result of +\ oint Space: + +Picture of path integral + + + + + + + + + +Editing Formulas + +The +Edit +Edit Formula String + allows the user to edit the ASCII formulas that have been copied from other applications, +such as Scilab, and transform them directly into mathematical type. An example will make this clear. Below is a screenshot of INRIA Scilab. + + + +Scilab picture + + + + + + + Copy and paste the text beginning with x*sin(30*x) into the formula editor as +shown below: + + +Scilab formula edit picture + + + + + + + +If you click on OK, the editor will complain about aborted parsing. It cannot +recognize one of the symbols in the formula. The displayed formula would show that the Pi symbol is +not correctly rendered. This means that the % must be deleted. Do this and &kformula; will +render the mathematical font properly, as shown below. + + +Scilab formula rendered in &kformula; + + + + + + + + The formula editor will accept most C language mathematical expressions, like the formulas from a +Runge-Kutta program below: +void derives(float x, float y[], float dydx[]) +{ + dydx[1] = y[2]; + dydx[2] = -0.8*x*y[2] - sin(x)*y[1]; +} + +Here dydx[1] is the first order derivative and dydx[2] is the second order +derivative. After copying the formula, you will have to edit the derivatives with &kformula;. Here is how it is done. +First copy and paste the bottom expression into the formula editor. + + +Runge-Kutta in editor; + + + + + + + +Next remove the [ ], leaving just y's. + + +Runge-Kutta edited + + + + + + + +Now click OK and place the cursor by a y and delete it. Insert the appropriate symbols as +shown below. + + +Runge-Kutta in &kformula; + + + + + + + +Not every expression that &kformula; is capable of translates into a valid C expression. For example the +superscript expression: + + +Superscript in &kformula; + + + + + + + +is displayed as ()**(), which is not a valid C statement for exponentiation. Similarly the 1 by 2 +matrix displays as ()/(). This is not a valid array in C. + + + + +Definite Integrals and Indices + +Definite Integrals + A definite integral is made by using &Ctrl;U for the upper limit +of integration and &Ctrl;L +for the lower limit of integration. + + + +definite integral + + + + + + +Reposition the cursor in front of the integral after making the +first of the limits. + + + +Positioning Indices + +The upper or lower index can be positioned by highlighting the desired +text. In this example, an arrow is needed above the P, in dP. Using &Ctrl;U places the desired vector +symbol in the wrong place; namely above the d. + + + + + +The problem is solved by + highlighting only the P in + + and then entering &Ctrl;U. Here is the correct + result. + + + + + + + + + + + +Credits and Licenses + +&kformula; Copyright by The KFormula Team + + +&kformula; Developers (Alphabetically) +Alfredo Beaumont Sainz alfredo.beaumont@gmail.com +Ulrich Küttler +Andrea Rizzi + + +Documentation copyright 2002 Jonathan Drews +j.e.drews@att.net + +Documentation copyright 2005 Anne-Marie Mahfouf +annma@kde.org + +Documentation copyright 2006 Alfredo Beaumont Sainz +alfredo.beaumont@gmail.com + +&underFDL; +&underGPL; + + + + +Installation + + +How to obtain &kformula; + +&install.intro.documentation; + + + + +Requirements + + +&kformula; is part of &koffice; +on The &kformula; home +page +You must have &koffice; installed. &kformula; will not work without the rest of +&koffice; + + + + + +Compilation and Installation + + +&install.compile.documentation; + + + + + +&documentation.index; + +
    + + + + + + + + diff --git a/doc/kformula/index_smear.png b/doc/kformula/index_smear.png new file mode 100644 index 000000000..b557b7db7 Binary files /dev/null and b/doc/kformula/index_smear.png differ diff --git a/doc/kformula/kfontinst1.png b/doc/kformula/kfontinst1.png new file mode 100644 index 000000000..a81486bc9 Binary files /dev/null and b/doc/kformula/kfontinst1.png differ diff --git a/doc/kformula/kfontinst2.png b/doc/kformula/kfontinst2.png new file mode 100644 index 000000000..be40a39f2 Binary files /dev/null and b/doc/kformula/kfontinst2.png differ diff --git a/doc/kformula/kfontinst3.png b/doc/kformula/kfontinst3.png new file mode 100644 index 000000000..42e643641 Binary files /dev/null and b/doc/kformula/kfontinst3.png differ diff --git a/doc/kformula/kfontinst4.png b/doc/kformula/kfontinst4.png new file mode 100644 index 000000000..6f3c42e7a Binary files /dev/null and b/doc/kformula/kfontinst4.png differ diff --git a/doc/kformula/kfontinst5.png b/doc/kformula/kfontinst5.png new file mode 100644 index 000000000..ec5cb4a5d Binary files /dev/null and b/doc/kformula/kfontinst5.png differ diff --git a/doc/kformula/kfontinst6.png b/doc/kformula/kfontinst6.png new file mode 100644 index 000000000..377d088ef Binary files /dev/null and b/doc/kformula/kfontinst6.png differ diff --git a/doc/kformula/lower-index.png b/doc/kformula/lower-index.png new file mode 100644 index 000000000..04ce92f4d Binary files /dev/null and b/doc/kformula/lower-index.png differ diff --git a/doc/kformula/matrix-view.png b/doc/kformula/matrix-view.png new file mode 100644 index 000000000..c1ea56a94 Binary files /dev/null and b/doc/kformula/matrix-view.png differ diff --git a/doc/kformula/matrix.png b/doc/kformula/matrix.png new file mode 100644 index 000000000..58247413d Binary files /dev/null and b/doc/kformula/matrix.png differ diff --git a/doc/kformula/negative_thin_space.png b/doc/kformula/negative_thin_space.png new file mode 100644 index 000000000..765079f85 Binary files /dev/null and b/doc/kformula/negative_thin_space.png differ diff --git a/doc/kformula/path-integral.png b/doc/kformula/path-integral.png new file mode 100644 index 000000000..cc21d087d Binary files /dev/null and b/doc/kformula/path-integral.png differ diff --git a/doc/kformula/rk-edit0.png b/doc/kformula/rk-edit0.png new file mode 100644 index 000000000..5faaf35da Binary files /dev/null and b/doc/kformula/rk-edit0.png differ diff --git a/doc/kformula/rk-edit1.png b/doc/kformula/rk-edit1.png new file mode 100644 index 000000000..e8785d05f Binary files /dev/null and b/doc/kformula/rk-edit1.png differ diff --git a/doc/kformula/rk-edit2.png b/doc/kformula/rk-edit2.png new file mode 100644 index 000000000..9366015a5 Binary files /dev/null and b/doc/kformula/rk-edit2.png differ diff --git a/doc/kformula/scilab-edit.png b/doc/kformula/scilab-edit.png new file mode 100644 index 000000000..79c5aa695 Binary files /dev/null and b/doc/kformula/scilab-edit.png differ diff --git a/doc/kformula/scilab.png b/doc/kformula/scilab.png new file mode 100644 index 000000000..7bb27190f Binary files /dev/null and b/doc/kformula/scilab.png differ diff --git a/doc/kformula/shortcut0.png b/doc/kformula/shortcut0.png new file mode 100644 index 000000000..f538419e5 Binary files /dev/null and b/doc/kformula/shortcut0.png differ diff --git a/doc/kformula/shortcut1.png b/doc/kformula/shortcut1.png new file mode 100644 index 000000000..525bc92f4 Binary files /dev/null and b/doc/kformula/shortcut1.png differ diff --git a/doc/kformula/sin.png b/doc/kformula/sin.png new file mode 100644 index 000000000..b495d8743 Binary files /dev/null and b/doc/kformula/sin.png differ diff --git a/doc/kformula/toolbars.png b/doc/kformula/toolbars.png new file mode 100644 index 000000000..7d3f97981 Binary files /dev/null and b/doc/kformula/toolbars.png differ diff --git a/doc/kformula/upper-index.png b/doc/kformula/upper-index.png new file mode 100644 index 000000000..3147a8a29 Binary files /dev/null and b/doc/kformula/upper-index.png differ diff --git a/doc/kivio/Makefile.am b/doc/kivio/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kivio/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kivio/credits.docbook b/doc/kivio/credits.docbook new file mode 100644 index 000000000..1a85a4e68 --- /dev/null +++ b/doc/kivio/credits.docbook @@ -0,0 +1,64 @@ + + + +Ben +Lamb + +
    +kde@zurgy.org +
    +
    +
    + +
    +
    + +Credits and License + + +&kivio; + + + +Program copyright 2000-2003 The &kivio; Team + + + +Current maintainer is Peter Simonsonn psn@linux.se. + + + +Contributors + + +Ian Reinhart Geiser geiseri@kde.org + + + +Laurent Montel montel@kde.org + + + +Frauke Oster frauke@frsv.de + + + +Dave Marotti lndshark@verticaladdiction.net + + + +The Kompany.com - "Where Open Source is at Home" info@thekompany.com + + + +Current documentation is maintained by Ben Lamb +kde@zurgy.org + + + + + +&underFDL; +&underGPL; + +
    diff --git a/doc/kivio/index.docbook b/doc/kivio/index.docbook new file mode 100644 index 000000000..02300cedb --- /dev/null +++ b/doc/kivio/index.docbook @@ -0,0 +1,64 @@ + + + + + + + + + +]> + + + + +The &kivio; Handbook + + + + +Ben +Lamb + +
    +kde@zurgy.org +
    +
    +
    + + +
    + +2006-01-30 +1.5.0 + + +20032000 +Ben Lamb + + + +&FDLNotice; + + +&kivio; is the &koffice; flowchart and diagram creation tool. + + + + +KDE +Kivio +KOffice +Flowchart +Diagram + + +
    + +&introduction; +&usage; +&working; +&credits; + +
    diff --git a/doc/kivio/introduction.docbook b/doc/kivio/introduction.docbook new file mode 100644 index 000000000..0fac69144 --- /dev/null +++ b/doc/kivio/introduction.docbook @@ -0,0 +1,33 @@ + + + +Ben +Lamb + +
    +kde@zurgy.org +
    +
    +
    + +
    +
    +Introduction + + +What is &kivio;? + +&kivio; is the &koffice; flowchart and diagram creation tool. It allows you to create accurate scale diagrams by arranging pre-drawn shapes and stencils on a page. The stencils might represent stages of a process, office furniture or components on an electronic circuit. &kivio; comes with a large collection of different stencils which are grouped into collections, known as stencil sets, by subject area. + + + +About this Document +This document describes the features of &kivio; and how to use them. There are often several ways to perform a particular task. Where possible the appropriate menu option is described as this is the easiest to explain without the aid of screenshots. Users are encouraged to explore the menus and to try right-clicking on stencils to reveal shortcut menus. + + + +Contributing to &kivio; +&kivio; is a volunteer project. Your contributions are welcome. If you find a bug whilst using the software please report it by selecting HelpReport Bug.... +Contributions to the documentation, stencils, translations into other languages and the code itself are welcome. Please see the &koffice; website for more information about how to contribute. + +
    diff --git a/doc/kivio/usage.docbook b/doc/kivio/usage.docbook new file mode 100644 index 000000000..7714ef436 --- /dev/null +++ b/doc/kivio/usage.docbook @@ -0,0 +1,203 @@ + + + +Ben +Lamb + +
    +kde@zurgy.org +
    +
    +
    + +
    +
    + +Basic Usage + + +Starting &kivio; +Like other &koffice; applications, on startup &kivio; presents a startup dialog. The dialog offers a choice of creating a new document, opening a saved document or choosing a document from a list of recently saved files. +If you're new to &kivio; begin by creating an empty document by double-clicking on the Empty Document template. +&kivio;'s main window contains a view of the current document. The page outline and margins are shown, as is a grid. Surrounding this view are horizontal and vertical rules. By default a tools toolbar is placed on the left-hand side and beneath the document view is a page selector. Beneath that is the status bar which shows the current position of the mouse pointer as a location on the page. +At the top of the window are the two main toolbars. These contain buttons for the most commonly used features of &kivio;. + + + +Using Stencils +Diagrams are created by placing different pre-drawn shapes and stencils on the page. Stencils can represent many different things and &kivio; comes with a wide selection. For ease of reference they are grouped into collections known as stencil sets. To use a stencil set select ToolsAdd Stencil Set. The stencil sets have been sub-divided into several groups; a sub-menu lists these. The shapes in the stencil set are shown on the left-hand side of the document view. +Stencils are grouped into stencil sets for organizational purposes only; it is perfectly okay to add several stencil sets to a document and &kivio; allows you to mix and match stencils from different sets freely. +To place a stencil onto the document simply drag it from the stencil area to the page. + + +Selecting Stencils + +&kivio; identifies the stencil currently being edited by displaying eight green squares on the corners and edges of a square around the stencil. Stencils shown in this manner are described as being selected. The green rectangles are known as handles. +To change the currently selected stencil move the mouse pointer over the stencil you wish to select and press the &LMB;. +To select all the stencils on the current page select EditSelect All. +To deselect all stencils select EditDeselect. + + + + +Moving Stencils + +To move a stencil to another position on the page, select the stencil. Note the pointer will change to a hand icon. Hold down the &LMB; and move the mouse to the new position. Release the mouse button to place the stencil at the new position. + + + +Resizing a Stencil +Select the stencil, and then move the mouse pointer over one of the handles. Note the mouse pointer change. Hold down the &LMB; and move the mouse. The coordinates of the stencil will be adjusted continuously as the mouse is moved. When you are happy with the new size release the mouse button to give the stencil its new final size. + + + +Undoing a Mistake +If at any time you are unhappy with a change you have made to the document you can select EditUndo to revert the change. There is also an icon on the toolbar. +If you undo an action and decide that was a mistake, select EditRedo to restore the change. &kivio; stores multiple actions to undo/redo several changes. + + + +Limitations of the Stencils +Note that stencils cannot currently be rotated. + + + +Labeling Stencils +A lot of stencils in the Flowcharting Collections, Geographic Collections, Hardware Collections, Miscellaneous Collections and UML Collections can contain text to describe their function. To add text to a stencil move the mouse pointer over the stencil and double-click it or open the context menu with the &RMB; and select Edit Text.... A dialog box will appear prompting for some text. Enter some text and click OK. The text should be shown inside the stencil. +The item Edit Text... in the menu is disabled, if a stencil cannot be labeled. +The font, size, alignment and style of the text can be adjusted by selecting FormatText.... Alternatively use the buttons on the Format toolbar. +The adjustments will only affect the currently selected stencil. + + + +Selecting Several Stencils +There are two ways to select multiple stencils in &kivio;. + + +Click once inside the first stencil you wish to select. + Hold down &Ctrl; as you click inside subsequent stencils. + All the stencils will be shown with handles around them. + + +Move the mouse pointer to a blank area of the document near the stencils you want to select. +Hold down the &LMB; and move the mouse to the other side of the stencils you want to select, drawing a rectangle around them. +The rectangle must completely encompass the stencils for them to be selected. + + + + + + +Adjusting the Fill Color and Line Color +Stencils can be filled with a solid color and the color of the outline can be changed. Select a stencil then select FormatStencils & Connectors.... + + + + +Adjusting the Line Thickness +The width of a stencil's border can be adjusted by selecting FormatStencils & Connectors.... The line width can be entered in centimeters or increased/decreased using the arrows of the spin box. Or use the Line Width button on the Format toolbar. Select a width from the drop down box or select Custom... to open enter the width in the spin box. + + + +Connecting Shapes Together +&kivio;'s connector tool allows lines to be drawn between shapes. The lines remain connected to the shapes even when the shapes are moved to new positions on the page. +To draw a connector select ToolsStraight Connector or ToolsPolyline Connector. +The Polyline Connector tool is also available from the Tools toolbar; by default shown on the top side of the window. Click on this tool to begin using it; the mouse pointer will change shape. +Notice that all stencils have little blue crosses around their edges. These crosses mark points where connectors can be attached. +To connect two stencils move to one of the connection points on the first stencil, hold down the &LMB; and drag a line to one of the connection points on the second stencil. The green square at the end of the line will change to red when it is over a connection point indicating that the line is attached to a stencil. +When you have finished using the connector tool, click on the Arrow tool to regain normal selection functionality. +A stencil can have multiple connectors attached to it, even at the same connection point. +Various properties of the connector can be adjusted including line thickness and color, this is done in the same way as for stencils. +Straight Connectors may also be labeled with text. To add text to a straight connector open the context menu with the &RMB; and select Edit Text.... Enter the text in the dialog that appears. The text will be shown with a green handle next to it. Use this to modify the position of the text. +Arrowheads can be added to either end of a connector. Select the connector and then select FormatArrowheads.... +Limitations: Connectors do not currently reroute around stencils, you need to adjust them manually. Text is always displayed horizontally; rotated text is not currently possible. + + + +Grouping Stencils +Several stencils may be semi-permanently grouped together. Once this has been done any changes made to one stencil will affect the others in the group. +To make a group select the stencils and select FormatGroup Selection. +The procedure can be reversed by selecting a group of stencils and select FormatUngroup. + + + +Overlaying Stencils +Stencils can be positioned on top of one another. A stencil drawn on top of another stencil will obscure the stencil underneath it. To adjust the drawing order select one of the stencils and select either FormatBring to Front or FormatSend to Back. +Send to Back will cause the stencil to be obscured by any stencil which overlaps it. Bring to Front will cause the stencil to obscure any stencil which it overlaps. + + + +Locking Stencils +A stencil's properties may be locked to prevent accidental changes. To alter a stencil's protection use the protection palette. This can be displayed by selecting ViewPalettesShow Protection. Select the stencil or stencils you wish to protect and then tick the properties you want to protect on the protection palette. +The protections available are: Width, Height, Aspect ratio, X position, Y position and Deletion. Deletion prevents a stencil from being deleted from the document. + + + +Stencil Geometry +For accurately specifying the dimensions of a stencil use the Geometry palette. To display the palette select ViewPalettesShow Geometry. The palette contains four spin boxes for specifying the horizontal (X:) and vertical (Y:) position of the stencil and the Width: and Height:. + +Although the measurements are displayed in centmeters it is possible to enter other units into the textbox. For example, entering 2.5 mm will be converted into centimeter. Points (pt) and inches (in) are also accepted. + + + + + + +Viewing the Document + + +Zooming In and Out +To adjust the zoom level select ViewZoom Level. This submenu contains a list of percentages from 33% to 500%; selecting one of these magnify the document by that percentage. +There is also a list of zoom levels in a spin box on the Edit toolbar, by default shown at the top of the screen. +A second method of controlling the magnification is to use the zoom tool. This is available on the Tools toolbar. This tool can be used in two ways. Clicking on the document with the zoom tool active will increase the magnification. Holding down the &Shift; key whilst clicking will decrease the magnification, &ie; zoom out. +Alternatively, holding down the &LMB; and dragging out a box then releasing the mouse button will increase the magnification so that that portion of the document fills the available space. + + + +Panning the Document +The Pan Document tool lets you move the document around, adjusting the portion that is visible. This is very useful when working at high magnifications where the entire document is not completely visible. To pan a document select Pan Document from the Tools toolbar or ToolsPan Document in the menu. Once activated the mouse pointer turns into a hand. To move the document move the mouse over the currently visible portion, hold down the &LMB; and drag. + + + +The Overview +The Overview palette provides a quick way of adjusting the zoom level and moving around the document. To enable it select ViewPalettesOverview. +A miniature representation of the document itself is shown underneath. A red rectangle indicates the portion that is currently visible. Clicking anywhere on this representation pans the view to that area. The rectangle can also be dragged. +At the bottom of the palette there is a slider and two buttons to zoom 25% in or out. + + + +Using Palettes +All palettes have a handle on the top side which enables them to be moved around and positioned on any edge of the main view. They can also float anywhere on the screen. To hide or show a palette select it from ViewPalettes. + + + +Multiple Views +It is possible to have multiple views of the same document displayed simultaneously. +Select New View from the View menu and a new &kivio; window showing the same document will appear. This is very useful for multiple monitor setups. +The additional windows can be closed and &kivio; will only prompt you to save the document when the last window is closed. All windows pertaining to a particular document can be closed simultaneously by selecting ViewClose All Views. + + + +Split Views +It is also possible to split the window into two or more portions which can be used to view two areas of a document at once. +To split a window select ViewSplit View. The orientation of the split can be changed from horizontal to vertical using ViewSplitter Orientation. To restore the window to its original state select ViewRemove View. + + + + + +Customizing the Display +The View menu contains options for toggling the display of page margins, rulers, guides and the grid. + + + + +
    diff --git a/doc/kivio/working.docbook b/doc/kivio/working.docbook new file mode 100644 index 000000000..809b8aebd --- /dev/null +++ b/doc/kivio/working.docbook @@ -0,0 +1,212 @@ + + + +Ben +Lamb + +
    +kde@zurgy.org +
    +
    +
    + +
    +
    + +Working with &kivio; + + +Opening a Document +To open a previously saved document select FileOpen..., a standard &kde; file dialog box will appear. +Recently used documents are listed under FileOpen Recent. + + + +Saving a Document +To save the current document select FileSave or FileSave As... to give an existing file a different name. +It is possible to save the document in a format that can be opened by earlier versions of &kivio;. Select the version you require from the Filter: combo box in the save file dialog. + + + +Printing +The document can be printed by selecting FilePrint.... The standard &kde; printing dialog appears. A preview of the printed output can be obtained by selecting FilePrint Preview.... + + + +Importing/Exporting Documents +The Import... menu option on the File menu currently loads a &kivio; or &XML; document into a new &kivio; application. +The Export... menu option on the File menu currently perform the same functions as File Save As.... These options let you save a document under a different name or into an other format. + + + +Documents with Multiple Pages +A &kivio; document can contain several pages of diagrams. + + +Adding Pages +To add additional pages to a document select PageInsert Page or click with the &RMB; on the page tab and select Insert Page from the context menu. The selector beneath the document view shows tabs for all the pages in the document that have not been hidden. + + + +Removing Pages +Unwanted pages can be removed by selecting PageRemove Page or click with the &RMB; on the page tab and select Remove Page from the context menu. + + + +Renaming Pages +The names given to each page can be adjusted by double-clicking on the page name on the page selector or by clicking with the &RMB; on the page tab and select Rename Page... from the context menu. A dialog box will appear allowing the name to be edited. + + + +Working with Pages +The order of the pages can be adjusted by dragging the tabs on the page selector bar. +The arrow buttons on the page selector bar are for scrolling through the page tabs, they do not cycle through the pages themselves. +If you have a lot of pages in a document and you do not want to see them all on the page selector you can hide pages by selecting PageHide Page. This will remove the currently selected page from the page selector bar. +To reveal a hidden page select PageShow Page... and choose the page you want to see from the list box. + + + + + +Exporting a Page +Individual pages can be exported as bitmap graphics files. To export the current page select File Export... or File Save As.... A standard &kde; file dialog box appears. The export format is determined by the name extension you give the file, it must end with one of the extensions listed below. +The following formats are supported: + + +PNG Image (.png) +JPEG Image (.jpg) +BMP Image (.bmp) +Encapsulated Postscript Image (.eps) +Portable Bitmap (.pbm) +PCX Image (.pcx) +Portable Pixmap Image (.ppm) +SGI Image (RGB) (.rgb) +X PixMap Image (.xpm) +JPEG 2000 Image (.jp2) +Krita Document (.kra) +Adobe Illustrator Document (.ai) +TIFF Image (.tiff) +ILM EXR Image (.exr) +Karbon14 Document (.karbon) +GIMP Native Image Format (.xcf) +Scalable Vector Graphics (.svg) +&Windows; MetaFile (.wmf) + + +You have to confirm the export, because this may result in some loss of formatting. Click the button Save and the Export to Image dialog is displayed. In this dialog you can set some export options: Page: range, the Area to export:, the Custom size (in pixels): and the Margin: of the page. + + + +The Grid +&kivio; displays a regularly spaced grid over the document to aid stencil positioning. The visibility of the grid can be toggled by selecting ViewShow Grid. +Objects edges are snapped to the nearest point on the grid regardless of whether it is visible. To toggle this behavior select ViewSnap Grid. +To customize the grid select SettingsConfigure &kivio;... and click on the Grid on the icon list. +This dialog box will let you adjust the color the grid is drawn in, the horizontal and vertical spacing and the snap distance. +Tip: It is possible to have a non-square grid by specifying different horizontal and vertical spacings. + + + +Freestanding Text +The text tool can be used to add text to a document that is not associated with any object. This is useful for noting general information about a drawing. +To add freestanding text make sure no object is selected by selecting EditDeselect , then activate the text tool by selecting ToolsText Tool. The mouse pointer will change to indicate the text tool is activated. +Drag a box to contain the text. A dialog box will appear prompting for the text, enter some text and click OK. The formatting of the text can be adjusted by selecting FormatText... or by using the toolbars. + + + +Page Layout +The page size, margins and orientation, portrait or landscape, can be adjusted using the Page Size & Margins dialog box. This is accessible by selecting FormatPage Layout.... + + + +Using Guides +Guides are lines used to help you position stencils. Not only can you use guides as a visual reference when aligning items but, optionally, &kivio; will snap stencils to guides. This means that as soon as the edge of a stencil is within a certain distance to a guide it will immediately move to the guide's position. + + +Adding Guides +To add a guide move the mouse pointer over either the horizontal or vertical ruler, depending on the type of guide you require. Hold down the &LMB; and drag the mouse over the document and release the mouse button where you want to position the guide. As you drag the mouse the guide will move accordingly. +Or use ViewAdd Guide Line... to open a dialog to select the Orientation and the Position of the guide. + + + +Repositioning Guides +Once a guide is in place you can reposition it by moving the mouse over it, holding down the &LMB; and dragging. Release the mouse button when the guide is in its new position. + + + +Visibility and Snapping +To hide guides select ViewGuide Lines, this toggles the visibility. +By default stencil edges are snapped to the nearest guide, to toggle this behavior select ViewSnap Grid. + + + + + +Layers +&kivio; allows complex diagrams to be split into multiple layers. The visibility of layers can be turned on and off. This functionality is useful if you have a basic diagram, for example a floorplan, and need to create several versions of it for different audiences. The information for each audience can be placed in a different layer. +Each page of the document has its own set of layers. + + +The Layer Palette +To adjust the current page's layers select ViewPalettesShow Layers . The layer palette allows layers to be created, deleted and renamed. It can also be used to adjust layer visibility, drawing order and select the current layer. +&kivio; has the concept of the currently active layer which is the one affected by any editing actions. By default a page contains only one layer which is the active layer. + + + +Adding Layers +Using the Layers palette you can add new layers by clicking the New Layer button, the first from the left. Layers can be deleted by clicking the second button, Remove Layer. &kivio; numbers the layers consecutively, to rename a layer select it in the list and click Rename Layer. + + + +Layer Settings +Layers are drawn in the order they are listed. The drawing occurs from the top down so objects in the layer at the bottom of the list are drawn on top of objects in all the other layers. The order of the list can be changed by selecting a layer and using the Move Layer Up and Move Layer Down buttons to change its position. +Each layer is listed with four small icons next to its name. From left +to right they represent: + + +Visibility (shown as a small eye) +Clicking on the icon will toggle the layer's visibility. + + + +Printable (shown as a small printer) +Toggles if the layer should be printed with the document or +not. You might use a non-printing layer to keep notes to yourself, or as a +scrapbook to hold images you're not ready to use yet. + + + +Editable (shown as a small pencil) +Toggles if you can edit a layer or not. You might want to +mark some layers non-editable while you work on others, to prevent +inadvertant changes. + + + +Connectable (shown as a small connector) +You can permit connecting of items that lie on different +layers with this icon. + + + + + + + +Arranging Stencils + + +The Align Tool +The Align tool rearranges a group of stencils so that they are aligned on one edge or on an invisible centerline. To use the tool select several stencils, then select FormatAlign & Distribute.... If the stencils are arranged in a horizontal row you the choice of aligning along the top or bottom edges or the centerline. For stencils that are arranged in a vertical row the choice is left or right edge or the centerline. + + + +The Distribute Tool +The Distribute tool arranges a group of stencils so that there is an even amount of spacing between each stencil. +First select the stencils you want to rearrange, then select FormatAlign & Distribute... and click on the Distribute tab in the tabbed window that appears. +You can choose whether the items should be spaced so that there is equal spacing between two edges, for example, the distance between the lefthand edge of each stencil should be the same. Or, whether the gap between each item should be identical. Choose the Spacing option if you desire this. +The second choice is whether the spacing should use the entire extent of the page or just the extent of the selection. If the latter is chosen the stencils will not occupy any more space than they did originally. +The option to use the extent of the page takes the page margins into consideration. + + + +
    diff --git a/doc/koffice.desktop b/doc/koffice.desktop new file mode 100644 index 000000000..fcc5f617b --- /dev/null +++ b/doc/koffice.desktop @@ -0,0 +1,8 @@ +[Desktop Entry] +Type=Application +Name=KOffice +Name[sv]=Koffice +Name[tr]=Koffice +NoDisplay=true +DocPath=koffice/index.html +Categories=Qt;KDE;Office; diff --git a/doc/koffice/Makefile.am b/doc/koffice/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/koffice/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/koffice/index.docbook b/doc/koffice/index.docbook new file mode 100644 index 000000000..4c194a7f8 --- /dev/null +++ b/doc/koffice/index.docbook @@ -0,0 +1,855 @@ + + + + + +]> + + + + + +&koffice; +A General Introduction + + +Raphael +Langerhorst +
    raphael.langerhorst@kdemail.net
    +
    + +Jost +Schenck +
    jost@schenck.de
    +
    + +
    + +2005-10-27 +1.5.0 + + + +&koffice; is an integrated office suite for the K Desktop Environment +(&kde;). + + + + +KDE +KOffice + + +
    + + + +Introduction + +&koffice; components + + +&koffice; is an integrated office suite for the K Desktop Environment +(&kde;). &koffice; currently consists of the following components: + + + +&kword; (a frames-based wordprocessor) +&kspread; (a spreadsheet application) +&kpresenter; (screen and slide presentations) +&kivio; (a flowchart application) +Karbon14 (a vector drawing application) +&krita; (a pixel based drawing application) +&kugar; (a tool for generating business quality reports) +Kexi (an integrated environment for managing data) +&kchart; (a charts/graphs generation application) +&kformula; (an editor for mathematical formulae) + + + +Because these components are based on the KParts component model, &koffice; +components are designed to work very well with each other. Any &koffice; +component can be embedded in another &koffice; document. For instance, you +can insert a spreadsheet which you created in &kspread; directly into a &kword; +document. In this way, complex, compound documents can be created using +&koffice;. + + + +A plugin mechanism makes it easy to extend the functionality of +&koffice;. You will find many plugins in some of the components +and can learn how to write plugins yourself. There is also a section +of this manual dedicated to developing plugins that should get you +started. + + + +This manual only covers the general features of &koffice;, those that +are common to most or all components in the suite. For detailed information +about the different components, have a look at the respective manual. + + + + + +Overview of &koffice; features + +Integration + +&koffice; provides a framework that all components build on. Through +this framework high integration is achieved. It is possible to develop +your own component that integrates as well. The technology of this is +described in more depth in the chapter on +KParts. + + + +Lightweight + +Despite offering so many components, &koffice; is very lightweight, fast and +has a rather low memory footprint. This is also achieved because &koffice; builds +on &kde;, which is already a very powerful application development framework. + + +A goal of &koffice; is also to not overload the user interface with features +that are hardly needed. This results in a lean and mean user interface that +lets you do your work efficiently. + + +Being lightweight can at times also mean that that very particular special +functionality you need is not there. In this case you can always add the +functionality yourself by extending &koffice;. &koffice; really doesn't +want to get bloated by adding large chunks of features that only very +few users might need. Such features can always be made available through +additional plugins or scripts, thus keeping &koffice; itself lightweight. + + + +Completeness + +&koffice; offers a wide range of components, covering most of the home +and business office needs. Additional features can always be implemented +through scripts, plugins or even whole components based on the &koffice; +framework. + + + +OASIS OpenDocument Format + +It is a major importance for any office suite to adhere to established +standards. Especially on the file format level to allow seamless document +exchange with other office suites. This also avoids vendor lock-in, which +is especially important for companies and also for individuals. + + +For this reason &koffice; has adapted the OASIS OpenDocument format +as native file format. + + + +KDE Features + +Since &koffice; builds on &kde; all the features you would expect from a +&kde; application are also available in &koffice;. This includes DCOP, KParts, +Desktop Integration, Configurability and so on. All this makes the look and +feel of &koffice; very familiar and really integrates &koffice; into the +desktop environment, thus allowing seamless workflows. + + + + + + + +&koffice; Technology + + +KParts - the building blocks of &koffice; + + + + + +Each &koffice; application is designed to fulfill very specific needs. +For example, &kspread; is a program for manipulating spreadsheets, while +&kword; is a program for word processing. By focusing on a specific +area, each program aims for perfection in exactly this area. However, +depending on what you do with &koffice;, you'll often want to take +advantage of functionality provided by different applications, but in +the same document. + + + +Suppose that you are preparing a document in &kword; and want to +illustrate some point using a table. While &kword; provides its own +functionality for the insertion of tables, this may not be enough for +your needs. For example, you may want to use certain currency data +formats or to do calculations using spreadsheet formulae. Now, some +&kword; programmer certainly could try to implement +this functionality. However, &kword; would never be as good as &kspread; +in this field; and if it tried to implement all the functionality you +might possibly need, it would end up becoming unreasonably complex and +the source code would become impossible to maintain. + + + +The alternative to this is KParts. Its philosophy is simple: let every +application do what it does best. + + + + + +Compound documents with KParts + + +With KParts, your documents can use all +functionality offered by all &koffice; +applications. You can take advantage of this by inserting so-called +parts into your document. Every one of those parts is +essentially another document, that is, a document within a +document. + + + +In the example mentioned above, you would simply insert a &kspread; part +into your &kword; document. Then, whenever you edit your table, +&kspread; would take control in the background. Control would return to +&kword; when you stop working on the table and start working on text +again. The only change you would notice is that the toolbars and menus, +while editing the table, reflect the functionality of &kspread; instead +of that of &kword;. This ability to include the functionality of one +application in another is called embedding. + + + + + + +Using KParts in your document + + +If you have never worked with compound documents, you may find them +confusing at first. The following step-by-step instructions show you +that using KParts is just as easy as working with a single application. + + + +Inserting a &kspread; part into a &kword; application + +Start &kword;. You can do that either from the panel or by typing +kword at the command line. + + + + +Start a new, blank document. You may want to type some sample text. + + + + +Select Insert Object Frame + Spreadsheets. You'll notice that the mouse cursor has +changed to a cross. This form of the cursor indicates that you are supposed +to select an area. + + + + +Press the &LMB; mouse button where you want the upper left corner of +your table to be, hold it and drag it to the lower right corner. Release +the button. Now a dialog appears that gives you the possibility to +insert an existing document or to create a new one. Create a blank worksheet. +That's it--you're done. + + + + + +Easy, isn't it? You should now see a table frame in your &kword; +document. Now, doubleclick inside the table to see what happens. You'll +notice that: + + + + + +Your menubars and toolbars have changed. They now reflect those of +&kspread;. + + + + +Your table frame now contains the elements of a &kspread; view, with +scrollbars, a tab bar for the selection of tables, &etc; + + + + + +Try editing the table. You'll see that it's not different from using +&kspread;. In fact you are using &kspread;. + + + +Now click somewhere into your &kword; document, outside of the table +area. The menubars and toolbars should change back to those of +&kword;, the elements of the &kspread; view should disappear. Your table +stays and still reflects all of the changes you've applied to it. + + + +KParts are easy to use. Try inserting other parts or even parts in +parts. + + + + + + + + + +Configuring &koffice; and Your System + + +While &koffice; should work quite nice out of the box, there may well be +some things to optimize to get the best out of &koffice;. This chapter +shows you what you might want to do to achieve the best results with +your new office suite and make it suite your needs. &koffice; is +highly configurable, even down to detailed toolbar and menu layout. + + + +Optimizing Font Output + +Fonts are a difficult topic on X Windows. In this section we'll cover +some problems that are frequently reported by people using +&koffice;. Some problems are not just &koffice;s fault, but depend on +your system configuration, which is why you may need to modify system +configuration files in order to solve them. If you don't have access to +the root account on your system, please ask your system operator about +this and point him or her to this manual. As the topic of fonts is too +complex to cover all of it here, you may want to consult the Font +HOWTO from which I've taken the following information. You will +find more details there. + + + +How to Get Nicely Scaled Fonts on Screen + + +STUFF + + + + +How to Get Correct Printout + + While &koffice; automatically can handle all X11 fonts +on screen, printout can pose a problem: on most +systems, printing is done via +ghostscript. Now, while &koffice; knows the +font names used by X Windows, it does normally +not know the font names used by +ghostscript. &koffice; tries to guess these +names, which unfortunately doesn't work all of the time. + + +This problem can be solved, although this is not that easy. Actually, +maybe you are using a distribution which has done most work for you +already (so if you have no reason to complain about printout you can +skip this section). What you have to do is to tell +ghostscript how to translate the (guessed) +font names &koffice; uses to its own font names. This can be done by +adding lines to a file called Fontmap. An alias +line in Fontmap looks like the following +example: + + +An alias in the <application>ghostscript</application> Fontmap + +/Algerian-Roman /Algerian ; + + + + +Please note that a space before the ';' is mandatory. In this example, +Algerian-Roman is the name &koffice; uses for Algerian. You'll have to +add such lines for the fonts &koffice; doesn't display correctly. To +make this task easier, Donovan Rebbechi has written a perl script you +can find at http://pegasus.rutgers.edu/~elflord/font_howto/kwdfont. +Assuming that you have a fontfile +/usr/share/ghostscript/fonts/fontfile.ttf you'll +enter kwdfont +/usr/share/ghostscript/fonts/fontfile.ttf +to get the appropriate aliases. The script should mork in most cases. As +mentioned, you should have a look at the Font +HOWTO for more accurate and in-depth information. + + + + + + +Customizing the &koffice; &GUI; + + +While &koffice; comes out of the box with a &GUI; (graphical user interface) +that should suit most people's needs, there are good reasons why you may +want to change the way the programs look. + + + +My mother, for example, is a bit afraid of buttons and menu entries she +doesn't understand. To tailor &koffice; to her needs, I reduced the +&GUI; to a bare minimum of functionality. As she only needs to write +letters and use certain templates, there is no need for much more +functionality than saving, loading, printing, &etc; + + + Thanks to the action concept of &Qt; and &kde;, +you can freely customize &koffice; menubars and tool +bars. Unfortunately, at the moment, there are no easy-to-use dialogs +to do this. &koffice; stores its &GUI; configuration in &XML; files +and you'll have to edit those. Hopefully, this situation will change +in the future; for now, you'll need some basic knowledge of how an +&XML; document works (or HTML, which is a subset of +&XML;). [The action concept needs to be discussed in +more detail -- kt.] + + +Normally, each &koffice; application has at least two of those &XML; +files: one describing the &GUI; of the shell (basically, that's what you +see if there is no document open) and one describing the &GUI; of the +respective part (that's what you see normally). For example, for +&kword;, these two &XML; files are named +kword_shell.rc and kword.rc. + + + +Here's a simple example of such an rc-file. + + + +An example of a simple rc-file + +<!DOCTYPE QConfig ><qconfig> +<menubar> +<menu name="Edit"><text>Edit</text> +<action name="edit_cut"/> +<action name="edit_copy"/> +<action name="edit_paste"/> +<separator/> +<action name="edit_find"/> +</menu> +<menu name="Insert"><text>Insert</text> +<action name="insert_picture"/> +<action name="insert_clipart"/> +<menu name="Variable"><text>Variable</text> +<action name="insert_var_datefix"/> +<action name="insert_var_datevar"/> +</menu> +</menu> +</menubar> +<toolbars> +<toolbar name="edit_toolbar" position="right"> +<action name="edit_cut"/> +<action name="edit_copy"/> +<action name="edit_paste"/> +</toolbar> +</toolbars> +</qconfig> + + + + + + + + +How to get more information + + +Other &koffice; manuals + + +For detailed information on the different &koffice; applications, please +consult their respective manuals. + + + + + + + + +Links + + +The following links should be useful if you're looking for more information +about &kde; or &koffice;. + + + + +The &koffice; +homepage. Here you can find information on how to get and +install &koffice;, news about &koffice; development, screenshots &etc; + + + +The KDE Homepage. KDE is the most advanced and +absolutely free desktop environment for unix-like operating systems. +&koffice; makes use of the &kde; libraries. + + +Trolltech. The creators +of the C++-toolkit &Qt;. &kde; and &koffice; make use of &Qt;. + + + + + + + + +Programming &koffice; + + +Introduction + +If you want to do &koffice; development, the following resources might +be of interest: + + + + At http://developer.kde.org you'll +find many documents about programming with &Qt; and &kde;. Here you can find +the online version of the complete &kde; library documentation. + + +In the &koffice; sources you'll find an example application in the +example folder. + + + + + + + + + +Copyright and Licensing + + +&koffice; is the result of the joint effort of many developers. Each source file +of &koffice; is copyrighted by the people who wrote this particular file and +their names can be found at the start of each source file with the license that applies to +that source file. The names of the core developers can be found at + +http://www.koffice.org/people.php. + + + +This manual is copyright by Jost Schenck. It can be distributed +freely, as long as this copyright notice is included. You may change +it as long as you send me the changes or commit them to &kde; +CVS. I'll not be liable for anything resulting +from the use of this manual. + + + +The other &koffice; manuals are copyrighted by their respective authors. + + + +&underFDL; +&underGPL; + + + + +Installation + + +System Requirements + + +In order to install and use &koffice; you must have: + + + + +A functioning &UNIX; system (for example, &Linux; or BSD) +with a configured &X-Window; (for example, XFree86 or X.Org). + + +The &Qt; 3.3 libraries from Trolltech. See +www.trolltech.com +for more information. + + +The K Desktop Environment 3.3 (&kde; 3.3) or newer. &koffice; cannot be compiled +with earlier versions of &kde;. Information on obtaining and installing +&kde; can be found at: &kde-http; + + +Permission to install software on your computer. If you are on a +stand-alone system, this should not be a problem. However, if you are +using a networked computer, check with your administrator first. + + + + +Please note that, while you need the &kde; 3.3 (or newer) libraries +on your system, you can still use &koffice; in a different desktop +environment (for example, XFCE or GNOME). + + + +If you plan on compiling &koffice; from +source code you will also need: + + + + +automake 1.6.1 or later. This can be downloaded from: +ftp://ftp.gnu.org/pub/gnu/automake/ + + +autoconf 2.53 or later. This can be downloaded from: +ftp://ftp.gnu.org/pub/gnu/autoconf/ + + +A C++ compiler which supports exceptions, preferably a recent version of GCC. +(See http://gcc.gnu.org +for info about getting and installing it.) + + +Troll Tech's &Qt; 3.3 development packages. If these packages are not installed on +your system and they are not included in the distribution of your operating +system, you should probably have to compile &Qt; from source. +These sources can be obtained from + +http://www.trolltech.com/download/index.html. + + + + +Once you have determined that your system meets these requirements, +you should decide whether you want to compile the source code +or install from pre-compiled binary packages. + + + +If you want to obtain the most current binary version of &koffice;, +you can find more information by following this link: +Getting Binary Packages. + + + +If pre-compiled binaries are not available for your system, you can download +the source code and compile it yourself. Instructions on where to obtain the +current source code (and what to do with the source code once you have it) +can be found by following this link: +Getting the source code. + + + Please see the &koffice; homepage for further +details. That is where you can always find the most up-to-date +information on both source and binary distributions! + + + + + +Getting Binary Packages + + +You can download the most current binaries from: + + + + +http://koffice.kde.org/releases/1.4.0-release.php + + + +or from one of many mirror sites. The current list of mirror sites +can be found at: + + + +http://www.kde.org/mirrors.html + + + It is important that you use a binary package which is +compatible with your system. If you use the &Linux; operating system +and are unable to find a binary package at the &koffice; web site or +one of its mirrors, you may be able to obtain one from the website of +your distribution. + + + + + +From Binary Packages + + +To install &koffice; from precompiled binaries, you should: + + + + +Ensure your computer has all of the required software installed +and in working condition (excluding &koffice; of course). You can find +the system requirements by following this link: System Requirements. +Download the &koffice; binary (or binaries) into a temporary +folder. +If the filename ends in .rpm (&RedHat; Package Management file), +&koffice; can be installed with the following command: +$rpmfilename + +If the filename ends in .deb (Debian Package file), &koffice; can be installed with the following command: +$ dpkgfilename + +If the filename ends in .tar.gz +or .tgz (a tarball file), +&koffice; can be installed with the following commands: + +$ cd / +$ tar filename + +In these examples filename should be replaced by the +complete name of the package including the full path if +you are not in the directory in which you saved. + + +That's all. &koffice; should now be installed on your system. + + + + If you have a graphical front-end for package management, +such as &kpackage; or GnoRPM, installed on +your system, you may find that more convenient to use than a command +line. Consult the program's documentation to find out how to install +with it. + + + + + +Getting Source Code + + +You can download the current source code from: +http://koffice.kde.org/ +or from one of many mirror sites. The current list of mirror sites +can be found at: + + + +http://www.kde.org/mirrors.html + + + + + + +From Source Code + + +If you want to build &koffice; from source code, you should: + + + + +Ensure your computer has all the required software installed and +in working condition (excluding &koffice; of course). You can find +the system requirements by following this link: +System Requirements. + + +Download the &koffice; source file into a temporary folder. + + +If the filename ends in .src.rpm +(&RedHat; Package Management file), the source code for &koffice; can +be installed with: +$ rpm filename + +If the filename ends in .src.tar.gz or .src.tgz (a tarball file), +the source code for &koffice; can be installed with: +$ tar filename + +The source code for &koffice; should now be installed on +your system. + + + + + + +&documentation.index; +
    + diff --git a/doc/koshell/Makefile.am b/doc/koshell/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/koshell/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/koshell/index.docbook b/doc/koshell/index.docbook new file mode 100644 index 000000000..dc43b5d9f --- /dev/null +++ b/doc/koshell/index.docbook @@ -0,0 +1,507 @@ + + + + + +]> + + + + +The &koshell; Handbook + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    + + +2005-2006 +Anne-Marie Mahfouf + + +&FDLNotice; + + + +2006-01-30 +1.5.0 + + + + + +&koshell; is the &koffice; Workspace where you can work with each component of the &koffice; productivity suite at the same time. &koshell; helps you organize your work in a friendly environment. + + + + + +KDE +KOffice +workspace +KWord +KSpread +KPresenter +KChart +KPlato +Kexi +Krita +Kivio +Kugar +KFormula +Karbon14 + + +
    + + +Introduction + +&koshell; is a framework in which you can work with several &koffice; applications in the same window. Being based on a true component framework &koshell; provides exactly the +same functionality as the stand-alone applications, and adds more +features, by making available all components in the same window. + + +&koshell; is part of the &koffice; productivity suite for the K Desktop +Environment. Other applications in &koffice; include: + + +&kword; (A full featured WYSIWYG (What You See Is What You Get) +Word-processor/Desktop Publishing Program.) +&kspread; (A spreadsheet application.) +&kpresenter; (A presentation creator.) +Kexi (An integrated environment for databases.) +&kivio; (A flowchart creator.) +Karbon14 (A vector drawing program.) +&krita; (A pixel based drawing program.) +&kchart; (A chart and graph creator.) +&kformula; (A formula editor.) +&kugar; (A report generation tool.) + + +See the individual application manuals for details on how to use them. These manuals apply to +running the applications as components inside &koshell; just as well as running them stand-alone. + + + + + +The &koshell; Main Window + + +General + +&koshell; consists in a friendly workspace to allow you to work on several &koffice; applications at the same time. In the &koshell; main window you can see a side pane on the left showing the icons of the available &koffice; components and the main view on the right which contains the main window of the active component and the usual menubar and toolbar. + + +Here's a screenshot of &koshell; when you start it for the first time + + + + + + &koshell; screenshot + + + + + +Here you can see &koshell; as it is the first time you run it. &koshell; always starts empty. You can then choose different actions. You can use the side pane on the left to open the programs as if they are standalone applications. You can also open any supported document via the FileOpen + menu and the corresponding &koffice; application will open with the document loaded. + + + +You can also import any supported document using the FileImport + menu and as with the Open action, the adequate &koffice; application will be used to load your document. + + + + + +Side Pane + + +&koshell;'s Side Pane + + + +&koshell;'s Side Pane + +
    + + + +The side pane allows you to open a new &koffice; component as if it was the stand-alone application. In most components, you are asked what document you want to open, a template, an empty document or an existing document. The main window of the component is then shown and the menubar, toolbars and statusbar in &koshell; are +adapted to reflect the functionality of the active component. + + +You can change the size of the icons in the side pane. +Right-clicking on the side pane will give you the option to use Large, +Normal, or Small icons, as well as the option to use text only +instead of icons. + +If you dislike the sidebar, you can simply hide it by dragging the +splitter to the left. + + + + + +Main View + +The view on the right which takes up most of the area of the &koshell; +main window shows the active component. This exactly corresponds to the main +window the component uses when run as a stand-alone application. + + +&koshell;'s Main View + + + +&koshell;'s Main View + + + + +When a component is loaded, the component own menus are merged with the &koshell; menus and the component toolbars are added on the workspace. + +Each new component is opened in a new tab. Using the &RMB; on each tab title, you can save the document in that tab or close that tab. The small button on the right bottom with a red cross also allows you to close the current tab. + +A special action common to all components is the + FileNew action in &koshell; menubar. It opens the Insert Object dialog which starts the &koffice; component as if it was a stand-alone application. + + +&koshell; Insert Object dialog + + + +&koshell; Insert Object dialog + + + + + + + + + +Command Reference + + +Menus and shortcut keys + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N + +File +New + +Open the Insert Object dialog which lists all possible new documents you can open. + + + + + +&Ctrl;O + +File +Open... + +Open a supported document by choosing the corresponding &koffice; application. + + + + +File +Open Recent + +Display a selection of recently saved documents you can open. + + + + + +&Ctrl;S + +File +Save + +Save the current document. + + + + +File +Save As... + +Save the current document with a name you provide. + + + + +File +Reload + +Reload the current document. + + + + +File +Import... + +Import a supported document. + + + + +File +Export... + +Export the current document. + + + + +File +Mail... + +Invokes &kmail; so you can email the file. +The file is already attached to the email. + + + + +File +Save All + +Saves all open documents in &koffice; Workspace. + + + + + + +&Ctrl;P + +File +Print... + +Print the current document. + + + + +File +Print Preview... + +View the current document as it will be printed. + + + + + +File +Document Information + +View or enter information about the current document and +author. + + + + + + +&Ctrl;W + +File +Close + +Close the current document but leave &koshell; running. + + + + + + +&Ctrl;Q + +File +Quit + +Quits &koshell;. + + + + + + + +The <guimenu>Settings</guimenu> Menu + + + + +Settings +Hide/Show Toolbar + +Toggle the Main Toolbar. + + + + + +Settings +Configure Shortcuts... + +Configure the shortcuts. + + + + + +Settings +Configure Toolbars... + +Configure the items you want to put in the toolbar. + + + + + + + + +The <guimenu>Help</guimenu> Menu +&help.menu.documentation; + + + + + +Under The Hood + +&koshell; makes extensive use of several &kde; key technologies, most +notably KParts and &DCOP;. + +The &GUI; integration of the components is done by plugins +providing KParts versions of the applications. This only needs a thin +additional layer on top of the already existing code of the +stand-alone applications. Because they are based on the KParts component model, &koffice; programs +are designed to work very well with each other. Any &koffice; component +can be embedded in another &koffice; document. + +For communication between the components &DCOP; is used. This +has the nice characteristic that it is completely transparent to +whether the application is run stand-alone or embedded as KPart into +&koshell;. + + + + + +Credits and License + + +&koshell; + + +Program copyright 2001-2005 The &koffice; Workspace Team + + +Original authors: + +Sven Lüppken +sven@kde.org +Torben Weis +weis@kde.org +David Faure +faure@kde.org + + + + +Documentation copyright 2005 Anne-Marie Mahfouf annma@kde.org + + + + +&underFDL; +&underGPL; + + + + +Installation + + +How to obtain &koshell; + +&install.intro.documentation; + + + + +Requirements + + +&koshell; is part of &koffice; +on The &koshell; home +page +You must have &koffice; installed. &koshell; will not work without the rest of +&koffice; + + + + + +Compilation and installation + +&install.compile.documentation; + + + + +&documentation.index; + + + + diff --git a/doc/koshell/koshell1.png b/doc/koshell/koshell1.png new file mode 100644 index 000000000..164b9b5c7 Binary files /dev/null and b/doc/koshell/koshell1.png differ diff --git a/doc/koshell/main-view.png b/doc/koshell/main-view.png new file mode 100644 index 000000000..19d9e5818 Binary files /dev/null and b/doc/koshell/main-view.png differ diff --git a/doc/koshell/new-dialog.png b/doc/koshell/new-dialog.png new file mode 100644 index 000000000..515cb8baf Binary files /dev/null and b/doc/koshell/new-dialog.png differ diff --git a/doc/koshell/side-pane.png b/doc/koshell/side-pane.png new file mode 100644 index 000000000..b196ea8b1 Binary files /dev/null and b/doc/koshell/side-pane.png differ diff --git a/doc/kplato/Makefile.am b/doc/kplato/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kplato/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kplato/commands.docbook b/doc/kplato/commands.docbook new file mode 100644 index 000000000..94847b1b6 --- /dev/null +++ b/doc/kplato/commands.docbook @@ -0,0 +1,566 @@ + + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    +
    +Command Reference + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N + +File +New + +Create a new document. + + + + + +&Ctrl;O + +File +Open... + +Open an existing document. + + + + +File +Open Recent + +Open an existing document by selecting it +from a combo box of recently used files. + + + + + +&Ctrl;S + +File +Save + +Save the document. + + + + +File +Save As... + +Save the document with a new name or format. + + + + + +File +Reload + +Reloads the document. + + + + + +File +Import... + +Import other documents. + + + + + +File +Export... + +Save a document to any supported format. +The document does not become the exported file. + + + + + +File +Mail... + +Send the file as an email attachment. + + + + + + +&Ctrl;P + +File +Print... + +Print the document. + + + + +File +Print Preview... + +View the document as it will be printed. + + + + + +File +Document Information + +View or enter information about the document and +author. + + + + + + +&Ctrl;W + +File +Close + +Close the current document but leave &kplato; running. + + + + + + +&Ctrl;Q + +File +Quit + +Quit &kplato;. + + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + + + +&Ctrl;Z + +Edit +Undo + +Undo the last action. + + + + + +&Ctrl;&Shift;Z + +Edit +Redo + +Redo the last undone action. + + + + + +Edit +Delete Task + +Delete the currently highlighted task. + + + + + +Edit +Indent Task + +Indent the currently highlighted task. + + + + + +Edit +Unindent Task + +Unindent the currently highlighted task. + + + + + +Edit +Move Up + +Move up the currently highlighted task. + + + + + +Edit +Move Down + +Move down the currently highlighted task. + + + + + + + + +The <guimenu>View</guimenu> Menu + + + + + +View +Expected + + - + + + + + +View +Optimistic + + - + + + + + +View +Pessimistic + + - + + + + + +View +Gantt + +View Gantt + + + + + +View +Resources + +Toggle on and off the resources names in the +Gantt view. + + + + + +View +Task Name + +Toggle on and off the tasks names in the +Gantt view. + + + + + +View +Task Links + +Toggle on and off the task links in the +Gantt view. + + + + + +View +Progress + +Toggle on and off the progress in the +Gantt view. + + + + + +View +Float + + - + + + + + +View +Critical Path + +Highlight the critical path in red. + + + + + +View +Critical Tasks + +Highlight the critical tasks in red. + + + + + +View +Resources + +View the resources instead of the Gantt or +the accounts. + + + + + +View +Accounts + +View the accounts instead of the Gantt or +the resources. + + + + + + + + + +The <guimenu>Insert</guimenu> Menu + + + + + +Insert +Task... + +Display the task settings dialog which allows +to define a new task after the current highlighted task. + + + + + +Insert +Sub-Task... + +Display the task settings dialog which allows +to define and insert a new sub-task of the current highlighted task. + + + + + +Insert +Milestone... + +Display the task settings dialog which allows +to define and insert a new sub-task of the current highlighted task. + + + + + + + + +The <guimenu>Project</guimenu> Menu + + + + +Project +Edit Main Project... + +Display the project settings dialog. + + + + + +Project +Edit Standard Worktime... + +Display the standard worktime dialog. + + + + + +Project +Edit Calendar... + +Display the calendar settings dialog. + + + + + +Project +Edit Accounts... + +Display the accounts settings dialog. + + + + + +Project +Edit Resources... + +Display the resources dialog where you can add +new resources groups and new resources names and properties. + + + + + +Project +Calculate + +Calculate Expected, Optimistic and Pessimistic. + + + + + + + +The <guimenu>Tools</guimenu> Menu + + + + +Tools +Generate WBS Code + + - + + + + + +Tools +Define WBS Pattern... + + - + + + + + + + +The <guimenu>Settings</guimenu> Menu + + + + +Settings +Toolbars + +Show or hide the toolbars: File, Report, +View and Project. + + + + + +Settings +Configure Shortcuts... + +Configure the keyboard shortcuts used by &kplato;. + + + + + + +Settings +Configure Toolbars... + +Configure the items you want to put in +the toolbars. + + + + + +Settings +Configure &kplato;... + +Display the &kplato; settings dialog. + + + + + + + + +The <guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + + +
    + + diff --git a/doc/kplato/configure-wbs.png b/doc/kplato/configure-wbs.png new file mode 100644 index 000000000..c50b9c0fb Binary files /dev/null and b/doc/kplato/configure-wbs.png differ diff --git a/doc/kplato/configure1.png b/doc/kplato/configure1.png new file mode 100644 index 000000000..747847fee Binary files /dev/null and b/doc/kplato/configure1.png differ diff --git a/doc/kplato/configure2.1.png b/doc/kplato/configure2.1.png new file mode 100644 index 000000000..067465192 Binary files /dev/null and b/doc/kplato/configure2.1.png differ diff --git a/doc/kplato/configure2.png b/doc/kplato/configure2.png new file mode 100644 index 000000000..0d693c3df Binary files /dev/null and b/doc/kplato/configure2.png differ diff --git a/doc/kplato/definitions.docbook b/doc/kplato/definitions.docbook new file mode 100644 index 000000000..fb2e2cf79 --- /dev/null +++ b/doc/kplato/definitions.docbook @@ -0,0 +1,228 @@ + + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +Raphael +Langerhorst + +
    raphael.langerhorst@kdemail.net
    +
    +
    + +
    +
    +Definitions + + +Gantt charts +A Gantt chart is a popular type of bar chart, that aims to show the timing +of tasks or activities as they occur over time. Although the Gantt chart did not +initially indicate the relationships between tasks this has become more +common in current usage as both timing and interdependencies between tasks can +be identified. + + +In project management, a Gantt chart can show when the project terminal elements +start and finish, summary elements (shown) or terminal element dependencies (not +shown). A terminal element is defined as the smallest task tracked as part of +the project effort. The tasks are displayed on a page as bars. The page is laid +out such that time increases as you move across the page. A task's start +time/date is indicated by the point on the page the bar starts, and it's +duration is indicated by the length of the bar. + + +Since the initial introduction of Gantt charts, they have become an industry +standard as a key project management tool for representing the phases, tasks and +activities that are scheduled as part of a project Work Breakdown Structure +(WBS) or timeline of tasks. + + +The initial format of the chart was developed by Henry L. Gantt (1861-1919) in +1910 (see Work, Wages and Profit by H. L. Gantt, published by The +Engineering Magazine, NY, 1910). + + + + +Work Breakdown Structure (WBS) + +In project management, a work breakdown structure (WBS) is an exhaustive, +hierarchical (from general to specific) tree structure of deliverables and tasks +that need to be performed to complete a project. + + +The purpose of a WBS is to identify terminal elements (the actual items to be +done in a project). Therefore, WBS serves as the basis for much of project +planning. + +A useful rule of thumb is that any project can be broken down into +between 10 and 20 tasks. + + +Work breakdown structure is a very common project management tool. Many United +States government statements of work require work breakdown structures. + +See the section to learn how to +configure your WBS. + + + + +Float + +Float in project management is the amount of time that a terminal element in a +project network can be delayed by, without causing a delay to: + +subsequent terminal elements (free float) +project completion date (total float). + +Float is sometimes also called slack. + + + + +Task + +A task is a part of a project that needs to be accomplished within a defined +period of time. Tasks can be linked together to create Dependencies. + + +Tasks take place over a period of time and generally consume resources. + + +A task is termed critical when it has zero or negative float. + + +In &kplato;, each task has a task ID, a name and a responsible person. +The timing, the cost and the assigned resources can also be set +in the Task Settingsdialog. + +A subtask is any node in the WBS tree that has a task as its +parent. + + + + +Resource + +A resource is an item required to complete a task. Resources can be +people, equipment, facilities, funding or anything else needed to perform the +work of a project. Resources can have a limited time availability (&ie; an +employee that works 8 hours a day, 5 days a week). + +The availability is +defined by calendars. + + +In &kplato; resources are either persons (work) or machines/devices (material). + + + + +Calendars + +A calendar defines at what time a resource +is available. + + +Calendars can be either a regular working week or special working times +that can be individually defined for each day. This allows for very subtle +control over the availability of resources. + + +Every resource is usually connected to a +calendar. + + +In &kplato; you can even use hierarchical calendars. + + + + +Milestone + +A milestone is a scheduled event signifying the completion of a major +deliverable or a set of related deliverables (usually marking the end of a +period). A milestone is an activity with zero duration and no effort &ie; there +is no work associated with a milestone. It is a flag in the workplan to signify +some other work has completed. + + +Usually a milestone is used as a project checkpoint to validate how the project +is progressing and revalidate work. Milestones are also used as high-level +snapshots for management to validate the progress of the project. In many cases +there is a decision to be made at a milestone. + + + + +Critical path +A path is a series of connected tasks. In project management, a +critical path is the sequence of project network terminal elements with the +longest overall duration, determining the shortest time to complete the project. + + +The duration of the critical path determines the duration of the entire project. +Any delay of a terminal element on the critical path directly impacts the +planned project completion date (i.e. there is no float on the critical path). +For example, if a task on the critical path is delayed by one day, then the +entire project will be delayed by one day (unless another task on the +critical path can be accelerated by one day). + + +A project can have several, parallel critical paths. An additional parallel path +through the network with the total duration just shorter than the critical path +is called a sub-critical path. + + +Originally, the critical path method considered only logical dependencies among +terminal elements. A related concept is the critical chain, which adds resource +dependencies. + + +The critical path method was invented by the DuPont corporation. + + + + +Scheduling + +Scheduling is the process of creating a project schedule based on the project +data like tasks, +resources and +calendars. The result can be viewed in a chart, +like a gantt chart. &kplato; can also generate +reports for a project. + + +There are usually various scheduling modes, like optimistic, expected and +pessimistic scheduling. When creating a task the additional estimation +percentage +for optimistic and pessimistic scheduling can be set. These settings are then +used for the various scheduling modes. + + +When scheduling a project with &kplato;, you can choose between optimistic, +expected and pessimistic scheduling. + + + +
    + + diff --git a/doc/kplato/edit-accounts.png b/doc/kplato/edit-accounts.png new file mode 100644 index 000000000..7de6f3670 Binary files /dev/null and b/doc/kplato/edit-accounts.png differ diff --git a/doc/kplato/edit-accounts1.png b/doc/kplato/edit-accounts1.png new file mode 100644 index 000000000..804474d1d Binary files /dev/null and b/doc/kplato/edit-accounts1.png differ diff --git a/doc/kplato/edit-calendar.png b/doc/kplato/edit-calendar.png new file mode 100644 index 000000000..41f37158b Binary files /dev/null and b/doc/kplato/edit-calendar.png differ diff --git a/doc/kplato/edit-calendar1.png b/doc/kplato/edit-calendar1.png new file mode 100644 index 000000000..abe7acaa5 Binary files /dev/null and b/doc/kplato/edit-calendar1.png differ diff --git a/doc/kplato/edit-calendar2.png b/doc/kplato/edit-calendar2.png new file mode 100644 index 000000000..9c0ed3abf Binary files /dev/null and b/doc/kplato/edit-calendar2.png differ diff --git a/doc/kplato/edit-resources.png b/doc/kplato/edit-resources.png new file mode 100644 index 000000000..e8662dc4a Binary files /dev/null and b/doc/kplato/edit-resources.png differ diff --git a/doc/kplato/edit-resources1.png b/doc/kplato/edit-resources1.png new file mode 100644 index 000000000..c7428ba54 Binary files /dev/null and b/doc/kplato/edit-resources1.png differ diff --git a/doc/kplato/edit-worktime.png b/doc/kplato/edit-worktime.png new file mode 100644 index 000000000..b898cf388 Binary files /dev/null and b/doc/kplato/edit-worktime.png differ diff --git a/doc/kplato/index.docbook b/doc/kplato/index.docbook new file mode 100644 index 000000000..e9204839a --- /dev/null +++ b/doc/kplato/index.docbook @@ -0,0 +1,131 @@ + + + + + + + + + + + +]> + + + + +The &kplato; Handbook + + + +Raphael + +Langerhorst + +
    raphael.langerhorst@kdemail.net
    +
    +
    + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    + +&FDLNotice; + + + +2006-02-11 +0.5.0 + + + + + +&kplato; is a project planning and management application for &kde;. + + + + + +KDE +KPlato +Project +Management +gantt + + +
    + + Introduction + +&kplato; as included in &koffice; 1.5 is a technology preview +release and it is not advised to use &kplato; in critical +production scenarios. Do so at your own risk. In this first public release we +focus on planning and scheduling of projects. + + +&kplato; is a project management application and a planning tool. +As an integrated component of &koffice;, &kplato; can +be used within larger documents of other &koffice; components. + + + Features + +Features include: +Resource management, +Hierarchical calendars, +Tasks with dependencies and subtasks. + + +Chart for visualization: +Gantt + + + +Project scheduling +Pessimistic, +Expected, +Optimistic. + + +Work breakdown structure (WBS). +Critical path and resources. +Embedding into other KOffice applications. + + + +&definitions; +&mainwindow; +&wbs; +&options; +&commands; + +License + +&underFDL; + + + +&documentation.index; +
    + + + diff --git a/doc/kplato/mainwindow.docbook b/doc/kplato/mainwindow.docbook new file mode 100644 index 000000000..7b48ec207 --- /dev/null +++ b/doc/kplato/mainwindow.docbook @@ -0,0 +1,53 @@ + + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    +
    +&kplato; Main window + +Here is the default &kplato; main window when you load an existing +project. + + + +Here's a screenshot of &kplato; + + + + + + &kplato; main window + + + + +At the top there is the menubar (1). All &kplato; functions are +available from the menus, which are described in detail in . + +Below the menubar are located the toolbars (2) and (3). You can show or +hide them using the +Settings +Toolbars menu. You can also configure +the toolbars (add or remove actions) using the +Settings +Configure Toolbars... dialog. + +(3) is the view toolbar. It allows you to quickly switch between +different views: Gantt, Resources or Accounts. +(4) is the main view. In the Gantt view currently shown on +the screenshot, you have 2 panes, one with the tasks names and one with +the Gantt chart. +(5) is the resource pane which you can see in the Gantt and Resources +views but not in the Account view. It is not shown per default and you +can drag the separation bar to display it. + +
    diff --git a/doc/kplato/mainwindow1.png b/doc/kplato/mainwindow1.png new file mode 100644 index 000000000..99a98a6cc Binary files /dev/null and b/doc/kplato/mainwindow1.png differ diff --git a/doc/kplato/options.docbook b/doc/kplato/options.docbook new file mode 100644 index 000000000..86354a2d4 --- /dev/null +++ b/doc/kplato/options.docbook @@ -0,0 +1,366 @@ + + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    +
    +Configuring &kplato; + + +The <guilabel>Project Settings</guilabel> Dialog + +This dialog allows you to set some properties for your current project. +You can access this dialog using the +Project +Edit Main Project... menu. + + +The Project Settings dialog + + + + +The Project Settings dialog + + + + + +ID: +Enter a number. It sets the project +identification and must be unique. + + + + +Name: +Enter the name of your project. + + + +Leader: +Enter the name of the project leader. Clicking +the Choose... button will bring your +contact list from KAddressBook and you can choose a name here. + + + +Scheduling +Here you define when the project will start or +end. Choose either a start date or an end date. + + +Start Date: +If a start date is set, the project is scheduled forward +from this time. When the project has been calculated, end time shows when the +project is planned to end. + + + +End Date: +If a end date is set, the project is scheduled backwards +from this time. When the project has been calculated, start time shows when the +project must start in order to finish in time. + + + + + + +Project notes and summary: +You can write here various notes associated +with the project or/and a project summary. + + + +Clicking the OK button will apply your changes and +close the dialog and clicking the Cancel button will +cancel any change you just made. + + + + +The <guilabel>Standard Worktime</guilabel> Dialog +This dialog allows you to set the worktime in terms of hours. +You can access this dialog using the +Project +Edit Standard Worktime... menu. + + +The Standard Worktime dialog + + + + +The Standard Worktime dialog + + + +These values are used when you estimate the effort needed to +complete a task. Defaults are the numbers of hours worked in a normal +day/week/month and year. + + + +Hours per year: +Set the hours worked per year. + + +Hours per month: +Set the hours worked per month. + + +Hours per week: +Set the hours worked per week. + + +Hours per day: +Set the hours worked per day. + + + +Clicking the OK button will apply your changes and +close the dialog and clicking the Cancel button will +cancel any change you just made. + + + + +The <guilabel>Calendar's Settings</guilabel> Dialog +This dialog allows you to set a calendar for your current project. +You can access this dialog using the +Project +Edit Calendar... menu. + + +The Calendar's Settings dialog + + + + +The Calendar's Settings dialog + + +You can have several calendars for your current project. First add a name +for your first calendar using the Add button. The +calendar view becomes active with the current day marked in a square +when you click on the calendar name. + + +Working with a calendar + + + + +Working with a calendar + + + +You can set Working or Non-working days. Click on the days you want +as Working days for example for your project and choose Working instead +of Undefined. Set then the work interval by choosing the start and end +times and click the Add interval button to add the +working time. Click the Apply button to validate your +choice. + + +Working and non-working days + + + + +Working and non-working days + + + +Here you can see the working days in blue and the non-working day +in red. + +Clicking the OK button will apply your changes and +close the dialog and clicking the Cancel button will +cancel any change you just made. + + + + +The <guilabel>Edit Accounts</guilabel> Dialog +Accounts are used to evaluate the project cost. This dialog allows you to +set up the various accounts used in your current project. +You can access this dialog using the +Project +Edit Accounts... menu. + + +The Edit Accounts dialog + + + + +The Edit Accounts dialog + + + +To create an account, click the New button. +You can then enter the account name which you validate by using the Enter +key. You can add a short description of this account by double-clicking +in the description field. +You can create sub-accounts of your main account or a new account. Remove +any highlighted account using the Remove button. +You can also set a default account by choosing the account name in +the drop-down list. + + +Creating accounts + + + + +Creating accounts + + + +Clicking the OK button will apply your changes and +close the dialog and clicking the Cancel button will +cancel any change you just made. + + + + +The <guilabel>Resources</guilabel> Dialog +This dialog allows you to set the resources for your current project. +You can access this dialog using the +Project +Edit Resources... menu. + + +The Resources dialog + + + + +The Resources dialog + + + +You need first to define a resource group by clicking the +New button in the resource group area. Click on +this group name and add a new resource by clicking the +New button in the resource area. This will display +the Resource Settings dialog. + + +The Resources Settings dialog + + + + +The Resources Settings dialog + + + +Clicking the OK button will apply your changes and +close the dialog and clicking the Cancel button will +cancel any change you just made. + + + + +The <guilabel>Configure &kplato;...</guilabel> Dialog + +This dialog allows you to set default options globally in &kplato;. You +can access this dialog using the +Settings +Configure &kplato;... menu. + +On any widget in this dialog you can get a What's This +help with &Shift;F1 or using the +Help icon. + + + +<guilabel>Task Defaults</guilabel> + +This set the options that will be used per default each time you add a +new task. + + + +Task Defaults + + + + +Task Defaults + + + + + +Responsible: +Insert the name of the person responsible for this task. +This is not limited to persons available in a resource group but can be +anyone. +Clicking the Choose... button will allow you to +insert a person from your address book. + +Addresses + + + + +Addresses + + + + + + +Timing + + + + +Schedule: +Choose the scheduling constraint you would +like as default. Depending on this constraint, the date fields +become available if they need to be filled. These +settings affect the actual scheduling of the task. + + +Estimate: +Estimates the predictions of the quantitative +results. The estimation can be either effort based or duration based. If it is +effort based, the final duration will depend on the resources assigned to the +task. For duration based estimation, the assigned resources don't affect the +fixed duration of the task, but only the costs. + + + + + + + +Note: +Write here a note that you would like to be +displayed as default on each new task. + + + +Clicking the Defaults button will reset the +dialog to its defaults, while clicking Apply will apply +your changes but leave the dialog open. Clicking the OK +button will apply your changes and close the dialog and +Cancel will cancel any change you just made. + + + + +
    \ No newline at end of file diff --git a/doc/kplato/project-settings.png b/doc/kplato/project-settings.png new file mode 100644 index 000000000..1beb2a96e Binary files /dev/null and b/doc/kplato/project-settings.png differ diff --git a/doc/kplato/wbs.docbook b/doc/kplato/wbs.docbook new file mode 100644 index 000000000..0581c772b --- /dev/null +++ b/doc/kplato/wbs.docbook @@ -0,0 +1,139 @@ + + + + +Anne-Marie +Mahfouf + +
    annma@kde.org
    +
    +
    + +
    +
    +Configuring the Work Breakdown Structure (WBS) + +The Work Breakdown Structure introduces +numbering for all tasks in the +project, according to the task structure. The tasks are numbered in a fashion +that reflects the structure of the project. +The WBS is defined as a tree structure. + + + +The WBS + + + + + + The WBS + + + + +You can configure the way you want the WBS to look in your project. To do +so, you can use the +ToolsDefine WBS Pattern... + menu. This displays the WBS Definition Dialog. + + + +The WBS Definition Dialog + + +WBS Definition Dialog + + + + + + WBS Definition Dialog + + + + + + +Code +Default is Number but you can set the WBS +code to be Roman Numbers or Letters, either upper case or +lower case. + + +Separator +The default separator is a dot and can be set +to anything else you want. The separator defines the way the +tree will look. On the screenshot above, the separator is the +dot. + + + +Instead of having the same code for all levels (for example 3.2.1) +you can define a different code for each level. For this you can check +Use Levels and then you define each level code and +separator. + +For example if you want your tree to be 1:II-B you will set +level 0 to Number and separator :, level 1 will be Roman upper case and +separator - and level 2 will be Letter upper case. + +This is illustrated on the next screenshot. + + +WBS levels definition + + + + + + WBS levels definition + + + + +To set a new level, choose the level number in the box near the +Add Level button then click the Add +Level button. Then choose the Code for the level and the +separator. + + +Add a level + + + + + + Add a level + + + + +To remove a level, choose the level number in the first column of the +list and click on it. The level row is then highlighted and the level number +changes to bold. Then click the Remove button. This is +demonstrated on the screenshot with Level 2. + + +Remove a level + + + + + + Remove a level + + + + + + +<guilabel>Generate WBS Code</guilabel> +The WBS code is auto-generated; simply choose Generate WBS +Code from the Tools menu to generate the +WBS code for the project. +After you changed the WBS definition you will want to generate the +new WBS. + + +
    \ No newline at end of file diff --git a/doc/kplato/wbs.png b/doc/kplato/wbs.png new file mode 100644 index 000000000..f597935b6 Binary files /dev/null and b/doc/kplato/wbs.png differ diff --git a/doc/kplato/wbs1.png b/doc/kplato/wbs1.png new file mode 100644 index 000000000..24503a853 Binary files /dev/null and b/doc/kplato/wbs1.png differ diff --git a/doc/kplato/wbs2.png b/doc/kplato/wbs2.png new file mode 100644 index 000000000..daf133636 Binary files /dev/null and b/doc/kplato/wbs2.png differ diff --git a/doc/kplato/wbs3.png b/doc/kplato/wbs3.png new file mode 100644 index 000000000..7758ab869 Binary files /dev/null and b/doc/kplato/wbs3.png differ diff --git a/doc/kpresenter/Makefile.am b/doc/kpresenter/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kpresenter/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kpresenter/a11y.docbook b/doc/kpresenter/a11y.docbook new file mode 100644 index 000000000..66f687e2d --- /dev/null +++ b/doc/kpresenter/a11y.docbook @@ -0,0 +1,321 @@ + + + + +Gary +Cramblitt + + + + + +For Users with Disabilities +This section of the documentation discusses accessibility features in &kpresenter; +for users with disabilities. Some of these features apply to &kde; as a whole and are controlled from +&kcontrolcenter;. Some apply to all &koffice; applications, +and some are specific to &kpresenter;. + + +Installing the <command>kdeaccessibility</command> Module +kdeaccessibility + +Most of the features described in this chapter are enabled by installing the +kdeaccessibility module. +The kdeaccessibility module is part of the &kde; project +http://www.kde.org. The kdeaccessibility +package can be obtained from &kde-ftp;, the +main ftp site of the &kde; project. + + +Many distributions offer precompiled binaries on their ftp sites. Please check your distribution's web sites for more information. + +More information about &kde; accessibility can be obtained by +visiting http://accessibility.kde.org/. + + + + +Visual Impairments +Visual Impairments + +&kpresenter; is not usable by totally blind users. It is hoped that +a general screen reader for the blind will be available in future versions of &kde;. + + + +Theming +Theming +For low-sighted or light alergic users, several features are available from +K-Button&kcontrolcenter;. +Under Appearance & ThemesTheme Manager +, you may select from several themes. If you are light alergic, the +HighContrastDark or HighContrastLight themes +may be helpful. If you have difficulty reading small fonts or seeing small icons, the +HighContrastDark-Big or HighContrastLight-Big +themes will increase the size of text, buttons, and icons. You may also customize +background, colors, fonts, and icons from the same screen. A set of monochrome icons +is available. + + +If you choose one of the Big themes, you may discover that +some screens are too large to fit your monitor. Purchasing a larger monitor will be helpful. +You can drag the portions of the screen not visible into the visable area by +holding down the &Alt; key and dragging with the mouse anywhere +within the screen. If you have trouble operating a mouse, you can also move screens by pressing +&Alt;F3. In +the dropdown Windows Operations Menu, choose +Move. +Move the screen with the arrow keys and press &Esc;. + + + + + +KMagnifier +magnifier +The kdeaccessibility module includes a screen magnifier +application called KMagnifier. +If it is installed, you may run it from +K-ButtonUtilities +AccessibilityScreen Magnifier. + + + + +Text-to-Speech +Text-to-Speech +TTS +The kdeaccessibility module includes a Text-to-Speech +component called KTTS. If KTTS is installed, you can configure &kpresenter; to +speak the text that is under the mouse pointer or speak the text of each +screen widget as it receives focus. Before using this feature, first configure +KTTS. See The KTTS Handbook for details. +To turn on the TTS feature in &kpresenter;, +select SettingsConfigure +&kpresenter;... from the menubar. +This will display a dialog box. +Clicking TTS will allow you to change +the following. + + + + + + + + + +Speak widget under mouse pointer +When checked, &kpresenter; will speak the text of each widget +as the mouse pointer moves over the widget. + + + +Speak widget with focus +When checked, &kpresenter; will speak the text of each widget +as it receives focus. + + + +Speak tool tips +When checked, &kpresenter; will speak the popup tool tip +for each widget in addition to the text of the widget. + + + +Speak Whats This +When checked, &kpresenter; will speak the Whats This help +for each widget in addition to the text of the widget. + + + +Say whether disabled +When checked, &kpresenter; will speak the word "disabled" +if the widget is currently disabled (grayed). + + + +Speak accelerators +When checked, &kpresenter; will speak the accelerator +of the widget in addition to the text of the widget. +Accelerators are the underlined letters you see in the text of the +widget. For example, in the main menu, the +Quit menu item +has the "Q" underlined. You can choose it by pressing Q. +To speak the accelerator, check this option and enter the +word you want to speak before the accelerator in the +Prefaced by the word box. In this +example shown above, &kpresenter; will speak "Accelerator Q". + + + +Polling interval +This option determines how often &kpresenter; will +check for a change in the widget under the mouse pointer or +a new focused widget. You should leave this option on the +default setting. + + + + + +If the TTS option does not appear +on this screen, you do not have the KTTS component installed +in your system. + + +Not all widgets are spoken. For example, +the items on the main menubar are not spoken. + + + + + + + +Motor Impairments and Mouseless Operation +Motor Impairments +Mouseless Operation + + +KMouseTool +If you can operate a mouse, but have trouble clicking, the +KMouseTool application may help. Run it from +K-ButtonUtilities +KMouseTool (Automatik Mouse Click). + + + + +XAccess Features +XAccess +Sticky Keys +Slow Keys +Bounce Keys + +The &kcontrolcenter; offers several keyboard features collectively called XAccess. +They include: + + +Sticky Keys +This feature permits operation of meta keys, such as +&Alt;, &Ctrl;, and &Shift; without having to hold the keys down. It is useful +when you can only use one finger or one hand to operate the keyboard. +With Sticky Keys on, press and release a &Alt;, &Ctrl;, or &Shift; key, then +press another key. The result is as if you pressed both keys at once. +Press the &Alt;, &Ctrl;, or &Shift; key again to turn off the sticky key. +Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityModifier Keys. + + + +Slow Keys +This feature is useful if you have hand tremors or difficulty +accurately pressing keys. It prevents +inadvertent key presses by requiring that a key be held down for a minimum +time before it is accepted. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityKeyboard Filters . + + + +Bounce Keys +This feature is also useful if you have hand tremors. It prevents +inadvertent repeated key presses by preventing another keystroke for +a certain amount of time. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityKeyboard Filters. + + + + + + + +Mouse Emulation +Mouse Emulation +Mouse Emulation permits you to move and click the mouse using the keyboard. +Press &Alt;F12 to activate it. Use the arrow keys +to move the mouse pointer to the desired location, and press spacebar +to "click" the mouse. Unfortunately, you cannot use Mouse Emulation to perform +&RMB; clicks or dragging. + + + + +Mouse Navigation +Mouse Navigation +This feature permits you to emulate the mouse using the numeric keypad +of your keyboard. To activate it, go to +K-Button&kcontrolcenter; +PeripheralsMouse +Mouse Navigation. +Check the Move pointer with keyboard (using the num pad) box. When you do this, the other settings will become enabled, and you can customize the keyboard pointer behavior further, if required. + The various keys on the number pad move in the direction you would expect. Note that you can move diagonally as well as up, down, left and right. The 5 key emulates a click to a pointer button, typically &LMB;. You change which button is emulated by using the / key (which makes it &LMB;), +* key (which makes it middle mouse button) and - (which makes it &RMB;). + Using the + emulates a doubleclick to the selected pointer button. You can use the +0 key to emulate holding down the selected pointer button (for easy dragging), +and then use the . to emulate releasing the selected pointer button. + + + + + + + + + + + +Keyboard shortcuts + +Use the Menu key to pop up the context +menu. On most keyboards, the Menu key is on the righthand +side of the keyboard between the &Windows; and &Ctrl; +keys. It has a menu icon on it. + + + + + +Resizing panels + +You can move the sizing bar between the outline panel and the +slide panel, and between the slide panel and the notes panel +by pressing F8. A sizing icon appears +overtop the sizing bar. Pressing F8 again moves from one +sizing bar to the next. After the last sizing bar, pressing F8 +hides the sizing icon. Use the arrow keys to move the bar up or down, or left or right. +Press &Esc; when finished sizing. + + + + + +Setting focus to widgets + +Normally, one can use the and &Shift; +to move focus from one widget to the next in any application. However, when focus is +in the slide panel of &kpresenter;, pressing does not move the focus. +You can set focus to any widget that can receive focus by +pressing &Alt;F8. A small lettered box appears +overtop each widget on the screen that can receive focus. + + + + + + + + +Press the letter to move focus to the corresponding widget. Press +&Alt;F8 again or &Esc; +to abandon moving the focus. + + + + + + + diff --git a/doc/kpresenter/autocorrection1.png b/doc/kpresenter/autocorrection1.png new file mode 100644 index 000000000..8de3dcf9b Binary files /dev/null and b/doc/kpresenter/autocorrection1.png differ diff --git a/doc/kpresenter/autocorrection2.png b/doc/kpresenter/autocorrection2.png new file mode 100644 index 000000000..d8227294f Binary files /dev/null and b/doc/kpresenter/autocorrection2.png differ diff --git a/doc/kpresenter/autocorrection3.png b/doc/kpresenter/autocorrection3.png new file mode 100644 index 000000000..6ea8c51d1 Binary files /dev/null and b/doc/kpresenter/autocorrection3.png differ diff --git a/doc/kpresenter/autocorrection4.png b/doc/kpresenter/autocorrection4.png new file mode 100644 index 000000000..a9e07fc5a Binary files /dev/null and b/doc/kpresenter/autocorrection4.png differ diff --git a/doc/kpresenter/barstyle1.png b/doc/kpresenter/barstyle1.png new file mode 100644 index 000000000..47747f59d Binary files /dev/null and b/doc/kpresenter/barstyle1.png differ diff --git a/doc/kpresenter/barstyle3.png b/doc/kpresenter/barstyle3.png new file mode 100644 index 000000000..19db52389 Binary files /dev/null and b/doc/kpresenter/barstyle3.png differ diff --git a/doc/kpresenter/barstyle4.png b/doc/kpresenter/barstyle4.png new file mode 100644 index 000000000..53dfacdf2 Binary files /dev/null and b/doc/kpresenter/barstyle4.png differ diff --git a/doc/kpresenter/barstyle5.png b/doc/kpresenter/barstyle5.png new file mode 100644 index 000000000..d27f23fa3 Binary files /dev/null and b/doc/kpresenter/barstyle5.png differ diff --git a/doc/kpresenter/barstyle6.png b/doc/kpresenter/barstyle6.png new file mode 100644 index 000000000..11145c3cb Binary files /dev/null and b/doc/kpresenter/barstyle6.png differ diff --git a/doc/kpresenter/barstyle7.png b/doc/kpresenter/barstyle7.png new file mode 100644 index 000000000..0f4a95934 Binary files /dev/null and b/doc/kpresenter/barstyle7.png differ diff --git a/doc/kpresenter/break.png b/doc/kpresenter/break.png new file mode 100644 index 000000000..02d888980 Binary files /dev/null and b/doc/kpresenter/break.png differ diff --git a/doc/kpresenter/changeformat.png b/doc/kpresenter/changeformat.png new file mode 100644 index 000000000..074f95e96 Binary files /dev/null and b/doc/kpresenter/changeformat.png differ diff --git a/doc/kpresenter/completion.png b/doc/kpresenter/completion.png new file mode 100644 index 000000000..6d9b7bf35 Binary files /dev/null and b/doc/kpresenter/completion.png differ diff --git a/doc/kpresenter/configure1.png b/doc/kpresenter/configure1.png new file mode 100644 index 000000000..500977084 Binary files /dev/null and b/doc/kpresenter/configure1.png differ diff --git a/doc/kpresenter/configure2.png b/doc/kpresenter/configure2.png new file mode 100644 index 000000000..520282c08 Binary files /dev/null and b/doc/kpresenter/configure2.png differ diff --git a/doc/kpresenter/configure3.png b/doc/kpresenter/configure3.png new file mode 100644 index 000000000..53e747817 Binary files /dev/null and b/doc/kpresenter/configure3.png differ diff --git a/doc/kpresenter/configure4.png b/doc/kpresenter/configure4.png new file mode 100644 index 000000000..21e07ac28 Binary files /dev/null and b/doc/kpresenter/configure4.png differ diff --git a/doc/kpresenter/configure4a.png b/doc/kpresenter/configure4a.png new file mode 100644 index 000000000..01e85f555 Binary files /dev/null and b/doc/kpresenter/configure4a.png differ diff --git a/doc/kpresenter/configure4a1.png b/doc/kpresenter/configure4a1.png new file mode 100644 index 000000000..8c09e4b29 Binary files /dev/null and b/doc/kpresenter/configure4a1.png differ diff --git a/doc/kpresenter/configure4b.png b/doc/kpresenter/configure4b.png new file mode 100644 index 000000000..72bbecc42 Binary files /dev/null and b/doc/kpresenter/configure4b.png differ diff --git a/doc/kpresenter/configure4c.png b/doc/kpresenter/configure4c.png new file mode 100644 index 000000000..eb76fdefa Binary files /dev/null and b/doc/kpresenter/configure4c.png differ diff --git a/doc/kpresenter/configure5.png b/doc/kpresenter/configure5.png new file mode 100644 index 000000000..dcc4d93f1 Binary files /dev/null and b/doc/kpresenter/configure5.png differ diff --git a/doc/kpresenter/configure6.png b/doc/kpresenter/configure6.png new file mode 100644 index 000000000..ccf339f28 Binary files /dev/null and b/doc/kpresenter/configure6.png differ diff --git a/doc/kpresenter/configure6b.png b/doc/kpresenter/configure6b.png new file mode 100644 index 000000000..8d5843860 Binary files /dev/null and b/doc/kpresenter/configure6b.png differ diff --git a/doc/kpresenter/configure6c.png b/doc/kpresenter/configure6c.png new file mode 100644 index 000000000..af3745087 Binary files /dev/null and b/doc/kpresenter/configure6c.png differ diff --git a/doc/kpresenter/configure6d.png b/doc/kpresenter/configure6d.png new file mode 100644 index 000000000..b843ee13f Binary files /dev/null and b/doc/kpresenter/configure6d.png differ diff --git a/doc/kpresenter/configure6e.png b/doc/kpresenter/configure6e.png new file mode 100644 index 000000000..cf306af8d Binary files /dev/null and b/doc/kpresenter/configure6e.png differ diff --git a/doc/kpresenter/configure7.png b/doc/kpresenter/configure7.png new file mode 100644 index 000000000..178d9ca02 Binary files /dev/null and b/doc/kpresenter/configure7.png differ diff --git a/doc/kpresenter/faq.docbook b/doc/kpresenter/faq.docbook new file mode 100644 index 000000000..29ab9b051 --- /dev/null +++ b/doc/kpresenter/faq.docbook @@ -0,0 +1,53 @@ + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +
    +
    +Questions and Answers +&kpresenter; 1.6 + +Things you might like but &kpresenter; does not yet do (and what +to do about it) + + + +Powerpoint Files. &kpresenter; does +attempt to import &Microsoft; Powerpoint +files but it does not always work perfectly. It depends on the +Powerpoint file version and what is in the +file. You can always import pictures for the background image and +re-type any text. It's not the ideal solution, re-doing the entire +presentation. However, just bear in mind that +Powerpoint does not even attempt to read +&kpresenter; files. + +Taking notes or minutes. One piece of software allows you to +make notes during the meeting and puts them into a word +processor. If you are speaking, someone else should be taking notes. If +you really must do this sort of thing, take a note pad and pencil. + + + +
    diff --git a/doc/kpresenter/great-presentations.docbook b/doc/kpresenter/great-presentations.docbook new file mode 100644 index 000000000..82d4bcdcc --- /dev/null +++ b/doc/kpresenter/great-presentations.docbook @@ -0,0 +1,145 @@ + + + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +
    +
    +General Hints and Tips for Great Presentations + +Okay, you've decided to use &kpresenter; for your +presentation. Before you start making transparencies or animated slide +shows, go and find a piece of paper and sit down at a desk away from +the computer. It doesn't matter whether you are doing a teaching +session or trying to convince the boss that your plan, policy or idea +should be adopted, you need to figure out what you are trying to +say. Write down all the subjects you need to cover, try to get them in +the order you think will make sense. Don't put any details in yet, +just decide on headings and the structure of your talk. + +Under each heading make a note of what facts you need to +cover. You are trying to build a convincing argument. Consider +grouping your facts into things must be included, things that should +be included and things that it would be nice to cover if you had +plenty of time. + +Once you have written down all the things you need to say, +consider the time available to do it in. Ten minutes seems ages when +you start, but it is very difficult to actually get much across in so +short a time. Get your sheet of paper and a clock with a second +hand. Practise your presentation over and over again. This has many +benefits. Firstly, you get the timing right. If someone says you have +ten minutes, never go over the allowed time. Secondly, when you +actually do it in front of a live audience, it will not be the first +time you have done that presentation. Third, you get the words right +in your own head. You will find ways of saying things about the +subject. If you've heard yourself do this presentation several times, +you will know what you are going to say next and how you are going to +say it. + +&kpresenter; does not produce Speaker's Notes at the time of +writing, but I am happy to just use ordinary slides. Produce some +slides for yourself, printed on plain paper, and some for use with the +Overhead Projector. Make the text on your slides nice and big, you +need to be able to read it at a distance. I use 14 or 16 point text, +experiment to find a size that you can read easily. I never write out +a script. + +If you are using an Overhead projector, learn how to use it +beforehand. Make sure that the bulb works, that the spare bulb is +still okay. Clean the lens and display plates. If you are not used to +working with projectors, practice. Ensure that the projection screen +itself is clean. It's probably best, when timing yourself, to allow +for five seconds (count one thousand and one, one thousand and +two....) to change each slide. That way you know you don't +have to rush. If you need to point at something on a slide, you can +use a pointer and point at the display screen, find a laser pointer or +put a pencil on the transparency itself. Be warned, these tend to roll +out of place when you nudge the table. + +Consider where you are going to stand. You cannot stand in +front of your display, so off to one side is probably your best option +if you want your audience to be able to see. I often project a picture +onto a wipeboard and draw over the top of it. If you are using a PC +with a digital projector you can draw over the top of your slides with +&kpresenter;'s pen tool. Remember, drawing freehand with a mouse is a +skill that needs practice. If you are using an Overhead projector, you +can use transparent overlay slides and a pen over the top of your +computer generated ones. + +When you are doing the presentation do not accidently look into +the light, it's easy to do. If you are not going to use the machine +for a few minutes, turn it off. Practise to get where you are going +to stand sorted out. Check the room you intend to use for electrical +sockets and learn how the blinds work and where the light switches +are. Good preparation not only makes you less likely to make mistakes +(inanimate things can be a nightmare in front of an audience) but also +gives you confidence. Always have a Plan B ready if +something refuses to work. Have a paper copy of your slides with +you. You can photocopy and distribute these to your audience if the +equipment fails. + +I have not said much about the content yet. At present all you +have is a piece of paper with everything you want to say on it. Before +you make anything, ask youself if their understanding of what you are +saying is going to improved by showing them a picture. Bad +presentations consist of a series of slides full of text. The +presenter then reads the slide to the audience (who have already read +it as they can read faster than someone can say it aloud). Try to +avoid writing anything on the slide, except a title and a number. Draw +a picture of what you need to say, then explain the picture to +them. That way they do not get ahead of you (they can read faster than +you can speak, remember?) and you look like you know it. You do not +know it, you are using the picture as a series of prompts. A slide +should support what you are saying, not duplicate it. A slide should +be the focus of the audience's attention, not a distraction. + +An example. I teach Railway staff how to respond to accidents. I +wanted to use a slide to discuss how you can move dangerous loads from +a derailed or damaged rail vehicle to a road vehicle after an +accident. The slide I made had a simple drawing of tank wagon, the +kind used for carrying gases or oils. On the side I wrote +Lethal Chemical Company so that I do not have to +explain it. I wanted to make several important points. First, you must +get any overhead electric wires turned off before you do anything if +they are within a certain distance. I drew one of the supporting +structures and drew an arrow with the safety distance on it. Then I +wanted to say that you must not transfer the wagon's contents in +darkness or thunderstorms. I drew a moon and a lightning bolt above +the vehicle. You must get specialist advice, so I drew a sheet of +paper and wrote the word Plan near the vehicle. You +also have to ensure that the vehicle does not move when the weight +inside is removed. I drew little red wedges by the wheels. Everything +I need to talk about is on this drawing. All I have to do is look at +the drawing and it tells me what I need to cover. When I have covered +all the things in the drawing, I have finished on that +subject. + +In general, only use a slide or picture if it shows something +that adds to what you are saying. Finally, relax and try not to rush +through it all. Talk to them, not at them and remember that a +presentation is about whatever message you are trying to get +across. &kpresenter; is a useful tool. It can help you to get that +message over, but it cannot do the job for you. + +
    diff --git a/doc/kpresenter/guides.docbook b/doc/kpresenter/guides.docbook new file mode 100644 index 000000000..9055bb435 --- /dev/null +++ b/doc/kpresenter/guides.docbook @@ -0,0 +1,556 @@ + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +Brad +Hards + +
    bradh@frogmouth.net
    +
    +
    + +Danny +Allen + +
    danny@dannyallen.co.uk
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + + +
    +
    +Detailed Guides + +This chapter describes how to perform some common tasks in +&kpresenter;. + + +Create a <acronym>HTML</acronym> Slideshow + +Turn an existing presentation into standard HTML +pages with accompanying navigation aids. + + + +First, either make a new presentation, or open an existing one. Then, +click on FileCreate HTML +Slideshow... + + +File menu option to Create HTML +Slideshow... + + + + +File menu option to Create HTML +Slideshow... + + + + + +A dialog box asks if you want to use a previously saved +configuration: + + +Previous configuration dialog + + + + +Previous configuration dialog + + + +Click No if this is the first time that you have +used this feature, or if you want to alter specific options. The +Yes option allows you to use details that you have +previously entered for your HTML slideshow, so that you can +quickly create the slideshow without needing to adjust the options. + + + +You will then get a dialog box asking for a few details: + + +Fill in the details for your HTML +slideshow + + + + +Fill in the details for your HTML +slideshow + + + +Fill in each field (the dialog takes the informations from &kcontrol; if they exist) and ensure that the path details are correct, as this +is where &kpresenter; will save your new HTML files +and pictures. Click on the Next when you are +done. + +If the path you select at this stage does not exist, &kpresenter; will +ask if you would like to create it. + + +Now you can configure the specific HTML options: + + +Fill in additional details for your HTML +slideshow + + + + +Fill in additional details for your HTML +slideshow + + + +Here, the encoding and format details can be changed, along with +the zoom level of the slides. For example, if you originally designed your +slides to display full screen on a 1280 x 1024 resolution screen, you could +scale the slides to 50% to enable them to be easily viewed in a much smaller web +browser window. + +In most cases, the defaults will be fine, and you can safely press the +Next to continue to the next page. + + + +Now you can customize the colors of the web pages: + + +Setting up the display style for your HTML +slideshow + + + + +Setting up the display style for your +HTML +slideshow + + + +When &kpresenter; creates the web pages for you, the text colors +for the navigation aids will follow whatever you set here. To change any of +these colors, click the colored bar next to the corresponding text label. The +colors used in your actual slides will be unchanged. + +Choose colors that are complementary to the contents of your +presentation. + + +The Next button presents a dialog box +that allows you to change the name used on the HTML page for +each slide: + + +Setting the slide names + + + + +Setting the slide names + + + + + + +If your presentation was intended to be displayed in an unattended manner +(&ie; automatic advance to next slide, &etc;), you can also make your +HTML +presentation counterpart exhibit the same behavior: + + +Unattended presentations + + + + + +Unattended presentations + + + +Here, you can force the slide to advance to the next after a specified +amount of time, and also make the presentation return to the start once it +reaches the end. + + + +Now it is time to actually produce your HTML +presentation, the progress of +which is shown in this dialog box: + + +Saving your configuration + + + + + +Saving your configuration + + + +Finally, you can save the configuration you have just used before you +close the dialog box by pressing the Save +Configuration... button. + + + +What we now have are the newly-produced html/ +and pics/ folders, +created where we earlier set the path: + + +The newly created HTML slideshow +folders + + + + +The newly created HTML slideshow +folders + + + + + +There is also an index.html file to launch +your web slideshow. + +You can see how it works by using your file manager or web +browser to open the index.html file. Click where prompted, +and the first slide of your presentation is displayed. It will now behave as a +&kpresenter; slideshow. + +Each click on the arrow icons take you to the next or previous slide. +To get back to the start of the slideshow click on the slide icon. + +To share your presentation with the world, transfer the +newly-produced files to a network-accessible location (&ie; webspace), +remembering to keep the directory structure intact. + + + +Exporting &kpresenter; presentations to a <trademark>Memory +Stick</trademark> + +Some Sony projectors have the ability to run a presentation directly +from a Memory Stick, without needing to connect a +computer up to the projector. &kpresenter; can export presentations to the +format required by these projectors, and this tutorial will show you how to +export your presentation. + + + +Each exported slideshow consists of a series of image files (one for +each slide in the original presentation, plus two title slides) and an +index file. They are created in a fairly complex directory structure +that allows more than one presentation to be stored on a single memory +stick. A simple example is shown below, consisting of two +presentations. + + + + + + +Memory Stick directory +structure + + + + + + + +If the presentation that you want to export is not already open, go to +FileOpen... and select the +presentation that you want to export. + + + + + +Now, select the File menu and choose Create +Memory Stick Slideshow.... + + + +The &kpresenter; Create Memory Stick +Slideshow... menu selection. + + + + +The &kpresenter; Create Memory Stick +Slideshow... menu selection. + + + + + + +This will bring up the Create Memory Stick +Slideshow dialog. + + +The &kpresenter; Create Memory Stick +Slideshow dialog. + + + + +The &kpresenter; Create Memory Stick +Slideshow dialog. + + + + +The Path is the directory in which your presentation will +be exported to as directories (DCIM and +MSSONY, see the directory structure +diagram above) will be created. If you are able to, you may wish to export +directly +to the Memory Stick, in which case you would enter the +location of the medium here. + + + +The Title is used for both the name of the index +file, and as a text label on the title slide. Note that this title +does not affect the titles on any of the normal presentation slides - +the title slide is visible using the Sony projector setup prior to +starting the actual presentation display. + + +Select the Set Colors option to expand the +dialog: + + +The &kpresenter; Create Memory Stick +Slideshow dialog (extended). + + + + +The &kpresenter; Create Memory Stick +Slideshow dialog (extended). + + + + +These two color selectors are only used for the title slide. It +can be useful to change the title slides to make the presentations +easier to identify when working on the projector, though it is perfectly safe to +leave them as default. + + + +You can then press the OK button to proceed with the +actual export process. + + + + + + +Your presentation will now be exported into the correct format, with the +following dialog informing you of the progress of this process: + + + +The &kpresenter; Create Memory Stick +Slideshow progress dialog. + + + + +The &kpresenter; Create Memory Stick +Slideshow progress dialog. + + + + +When the export is complete, you can select the +Done button, and the dialog will close. + + + + + +If you did not export the slideshow directly onto a Memory +Stick, you will need to copy the correct files onto the +Memory +Stick before you can utilise the projector. As noted above, +you need to copy over the correct directories and files starting at +DCIM and MSSONY into the +"root", or / of the Memory Stick. It +is +critical that the directory structure is maintained, and you may +find it easier to copy the whole of DCIM and +MSSONY directories. + + + +If necessary, you can safely rename the index file (which is +Slideshow.SPP by default), however you cannot +rename the slide images, nor can you change the name of these directories, +as these are encoded into the index file. + + + + + + + + +Creating &kpresenter; Templates + +It is very easy to add new templates to &kpresenter;'s library. + +If you have made a presentation in a style that you would like to use +again, you can save it as a template. + +This tutorial will show how we can make a new template and save +it. + + + +Open &kpresenter; and create a new document. + + + +To add a little sparkle to the blank slide, we can change the slide +background - do this by either going to Format > +Slide Background..., or by selecting the same item +from the &RMB; menu: + + +The &kpresenter; Slide Background +dialog. + + + + +The &kpresenter; Slide Background +dialog. + + + +We want the background to look attractive, so let's add a background +gradient by using the drop-down menu, and then selecting the gradient colors by +clicking the colored boxes. Of course, you may choose to use an image as a +background by clicking the Picture tab: feel free to +experiment, but keep it beautiful! + + +Choosing a slide background + + + + +Choosing a slide background + + + + + +The page should now have the background you desire. Create a text box, and +type a heading for your slide: + + +Adding a Heading to the new template + + + + +Adding a Heading to the new template + + + +When you are happy with your template, go to File +Template Manager: + + +FileTemplate +Manager + + + + +FileTemplate +Manager + + + +This dialog box allows you to select where you would like your template to +be saved: + + +Saving the new template + + + + +Saving the new template + + + +I highly recommend that you save the template in the Screen +Presentations group. You may call it whatever you wish, in this case, +my template is named Tutorial_Template. Once you are +happy with the settings, press OK to add your custom +template to the template collection. + + + +You can now close the document you have been working on (there is no need +to save it). The next time you are presented with the startup +dialog, your very own template will be available to select! + + +Your new template in the &kpresenter; startup +dialog. + + + + +Your new template in the &kpresenter; +startup dialog. + + + + + + + +
    diff --git a/doc/kpresenter/htmlshow1.png b/doc/kpresenter/htmlshow1.png new file mode 100644 index 000000000..a9f8a4e8a Binary files /dev/null and b/doc/kpresenter/htmlshow1.png differ diff --git a/doc/kpresenter/htmlshow2.png b/doc/kpresenter/htmlshow2.png new file mode 100644 index 000000000..ba52b6ad5 Binary files /dev/null and b/doc/kpresenter/htmlshow2.png differ diff --git a/doc/kpresenter/htmlshow3.png b/doc/kpresenter/htmlshow3.png new file mode 100644 index 000000000..c4876d15e Binary files /dev/null and b/doc/kpresenter/htmlshow3.png differ diff --git a/doc/kpresenter/htmlshow4.png b/doc/kpresenter/htmlshow4.png new file mode 100644 index 000000000..49da99b61 Binary files /dev/null and b/doc/kpresenter/htmlshow4.png differ diff --git a/doc/kpresenter/htmlshow5.png b/doc/kpresenter/htmlshow5.png new file mode 100644 index 000000000..c69ec4318 Binary files /dev/null and b/doc/kpresenter/htmlshow5.png differ diff --git a/doc/kpresenter/htmlshow6.png b/doc/kpresenter/htmlshow6.png new file mode 100644 index 000000000..9db24bc70 Binary files /dev/null and b/doc/kpresenter/htmlshow6.png differ diff --git a/doc/kpresenter/htmlshow7.png b/doc/kpresenter/htmlshow7.png new file mode 100644 index 000000000..d7011cfe8 Binary files /dev/null and b/doc/kpresenter/htmlshow7.png differ diff --git a/doc/kpresenter/htmlshow8.png b/doc/kpresenter/htmlshow8.png new file mode 100644 index 000000000..6fb56df5c Binary files /dev/null and b/doc/kpresenter/htmlshow8.png differ diff --git a/doc/kpresenter/htmlshow9.png b/doc/kpresenter/htmlshow9.png new file mode 100644 index 000000000..39e9270c8 Binary files /dev/null and b/doc/kpresenter/htmlshow9.png differ diff --git a/doc/kpresenter/index.docbook b/doc/kpresenter/index.docbook new file mode 100644 index 000000000..79ac69132 --- /dev/null +++ b/doc/kpresenter/index.docbook @@ -0,0 +1,267 @@ + + + + + + + + + + + + + +]> + + + +The &kpresenter; Handbook + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + + +Gary +Cramblitt + +
    garycramblitt@comcast.net
    +
    +
    + + +
    + +2006-11-22 +1.6 + + +19992000 +Krishna Tateneni + + + +20012002 +Neil Lucock + + + +2005 +Anne-Marie Mahfouf + + + +2006 +Gary Cramblitt + + +&FDLNotice; + + + +&kpresenter; is the presentations program in the &koffice; suite of +productivity applications. + + + + +KDE +KPresenter +KOffice +Graphics +Presentations + + +
    + + +Introduction + + Please check http://docs.kde.org +for updated versions of this document. + + +&kpresenter; is the presentations program in the &koffice; productivity +suite. Using &kpresenter;, you can prepare a set of slides for use in an +on-screen slideshow or for printing. Your slides can include text and +graphics in a variety of formats, and of course, you can embed all sorts +of objects using KParts. + + + +The &koffice; productivity suite consists of a number of applications +which are designed to work together. Overview documentation for +&koffice; is available, as well as manuals for each component of the +suite. The components of &koffice; are: + + + + + +&kword; - a frames based wordprocessor. + + + + +&kspread; - a spreadsheet application. + + + + + +&kpresenter; - a presentations application. + + + + + + +&kformula; - an editor for mathematical formulae. + + + + + +&kchart; - an application to draw charts and diagrams. + + + + + + + +&koffice; is a free (or open-source) software project which is +released under the terms of the &GNU; General Public +License. + + + + +&tutorial; + +&screen; + +&guides; + +&great; + +&menus; + +&options; + +&a11y; + +&faq; + + +Credits and License + + +&kpresenter; + + + +Program copyright 1998-2000 by Reginald Stadlbauer +reggie@kde.org + + + +Current maintainer is Laurent Montel montel@kde.org. + + + + +Contributors + + + +Werner Trobin trobin@kde.org. + + + + + +David Faure dfaure@kde.org + + + + + +Toshitaka Fujioka fujioka@kde.org + + + + + +Lukáš Tinkl lukas@kde.org + + + + + +Thorsten Zachmann t.zachmann@zagge.de + + + + + +Ariya Hidayat ariya@kde.org + + + + + +Percy Leonhardt percy@eris23.de + + + + + +Documentation based on the work copyright 1999-2000 by Krishna +Tateneni. Portions are copyright 2000-2002 Neil Lucock +neil@nlucock.freeserve.co.uk +and 2005 Anne-Marie Mahfouf annemarie.mahfouf@free.fr + + + +&underFDL; +&underGPL; + + + + +Installation + +&install.intro.documentation; + +&install.compile.documentation; + + + +&documentation.index; + +
    + diff --git a/doc/kpresenter/kbd-focus-ext.png b/doc/kpresenter/kbd-focus-ext.png new file mode 100644 index 000000000..1135bb70b Binary files /dev/null and b/doc/kpresenter/kbd-focus-ext.png differ diff --git a/doc/kpresenter/link.png b/doc/kpresenter/link.png new file mode 100644 index 000000000..9c12b06e5 Binary files /dev/null and b/doc/kpresenter/link.png differ diff --git a/doc/kpresenter/menus.docbook b/doc/kpresenter/menus.docbook new file mode 100644 index 000000000..52d29d6eb --- /dev/null +++ b/doc/kpresenter/menus.docbook @@ -0,0 +1,2066 @@ + + + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +
    +
    +The Menu and Toolbar Items + +&kpresenter; presents different types of interfaces for you to interact +with the program. Perhaps the most familiar type of interface is the +menu which appears on the top of the &kpresenter; window. + +Clicking on the menu items gives you a list of commands from which you +can choose the one you want. Many of the commands can also be accessed +directly by holding down &Ctrl; or &Alt; and pressing another key on +your keyboard. In the next section, each of the menu commands is +described in brief. + + +The Toolbars + + +Manipulating the Toolbars + +In addition to the menus, &kpresenter; also has a set of toolbars. Each +toolbar consists of a collection of icons. A toolbar icon often presents +a convenient shortcut to a command that is found in one of the menus. + + +The toolbars + + + + + +The toolbars + + + + +You can move the toolbar around by dragging the handle, shown here in red. Toolbars can +be docked or attached to any side of the &kpresenter; +window. If you like, you can also have the toolbar float in +its own window, separated from the main &kpresenter; window as shown in the +screenshot below: + + +Floating toolbar + + + + + +Floating toolbar + + + + + If you don't like dragging toolbars around, +right click on the handle and a menu pops up as shown +in the screenshot below: + + +Toolbar context menu + + + + + +Toolbar context menu + + + + + +The first few items in the popup menu have to do with the placement of +the toolbar. You can choose any of the four sides of the &kpresenter; +window, or have the toolbar float in a separate +window. Choosing Flat hides the toolbar. +To unflat a hidden toolbar, &LMB; click on its handle. + + + + + +Choosing the next item in the menu, Text Position, leads +to an additional menu which lets you control the appearance of the items +in toolbar. This additional cascading menu is shown in the screenshot +below: + + + +The toolbar modes menu + + + + + +The toolbar modes menu + + + + + +The default view of the toolbar is icons only. In this view, if you +don't know what a particular icon means, you can hold the mouse over the +icon, and after a second or so, a little hint pops up in a highlighted +text box as shown in the screenshot below: + + + +Tooltips + + + + + +Tooltips + + + + + +You can choose to display the toolbar items as text instead of icons, or +even to combine both icons and text. If you want both text and icons, +the cascading menu allows you to select whether the text appears beside +the icons or below them. All four styles of displaying toolbar items are +shown in the screenshot below: + + + +The toolbar styles + + + + + +The toolbar styles + + + + + +The &kpresenter; menus are discussed in the following sections. + + + + + + +<guimenu>File</guimenu> Menu + + + + + + +&Ctrl;N + +File +New + + + + +Begins a new presentation. The +startup dialog will open, allowing you to choose a +template for your presentation. + + + + + + + +&Ctrl;O + +File +Open... + + + +Opens an existing presentation. A standard &kde; file +open dialog will appear, allowing you to choose a file to open. + + + + + + + +File +Open Recent + + + + +Displays a list of recently opened files for you to choose +from. + + + + + + + + +&Ctrl;S + +File +Save + + + + +Saves the currently open presentation. If you have not +previously saved it, you will be asked to name the file. If you have +previously saved the presentation, it will be resaved with the same name. + + + + + + + +File +Save As... + + + + +Saves the currently open presentation with a new name. + + + + + + + +File +Reload + + + +Reload the currently active file. + + + + + + + +File +Import... + + + +Import a presentation that was previously created in +one of several common formats. + + + + + + +File +Export... + + + +Export the currently open presentation to one of several common +formats for use in another application, or for exchange with someone +who does not have access to &kpresenter;. + + + + + + +File +Mail... + + + +Open a new email message in your selected email client with the current &kpresenter; document attached. + + + + + + + +File +Create HTML Slideshow... + + + + +Starts the HTML wizard, which is described in the +section . + + + + + + + +File +Create Memory Stick Slideshow... + + + + +Starts the Memory Stick dialog, which is described in the +section . + + + + + + + +Template Manager + + + +Allows you to save the current slide as a +template. In future the template will be available for you to +use to build slides with. Creating a template is further discussed in +section . + + + + + + +File +Use Current Slide as Default Template + + + +Sets the current slide as your default template. +Especially useful if you have created a template of your own to fit into +corporate style guidelines, or if you just use a particular layout very +often. + + + + + + +&Ctrl;P +File +Print... + + +Prints the presentation. More precisely, it opens the +print settings dialog, where you can adjust the settings before printing +your presentation. + + + + + + +File +Print Preview... + + + +Displays the presentation with a &PostScript; viewer, +exactly as it would look if printed. + + + + + + +File +Document Information + + + +Allows you to enter information about the document. +This includes information about the author, and an abstract on the +documents contents. + + + + + + + +&Ctrl;W +File +Close + + + +Close the current presentation. You will be given an +opportunity to save any changes first. + + + + + + + +&Ctrl;Q +File +Quit + + + +Close &kpresenter;. You will be given an opportunity +to save all changes in all open presentations first. + + + + + + + +<guimenu>Edit</guimenu> Menu + + + + + + + +&Ctrl;Z +Edit +Undo: Last task + + + +Undo the last action you performed. + + + + + + + +&Ctrl;&Shift;Z + +Edit +Redo: Last undone +task + + +Redo the last action you undid. If you have not undone +any actions, or the last undo action is not reversible, this menu item +is disabled. + + + + + + +&Ctrl;X +Edit +Cut + + + +Copy the selected item to the clipboard, and remove it from the +document. + + + + + + + +&Ctrl;C +Edit +Copy + + + +Copy the selected item to the clipboard, while leaving it intact +in your presentation. + + + + + + + +&Ctrl;V +Edit +Paste + + + +Insert the contents of the clipboard into your +presentation. + + + + + + + +&Ctrl;Delete +Edit +Delete + + + +Remove the currently selected item from your +presentation. + + + + + + + +&Ctrl;A +Edit +Select All + + + +Select all the objects and text on the current slide. + + + + + + + + +&Ctrl;&Shift;A + +Edit +Deselect + + + +Deselect any currently selected objects. + + + + + + + +&Ctrl;F +Edit +Find... + + + + +Search for text within the presentation. + + + + + + + + +F3 + +EditFind Next + + + +Find the next occurrence of a piece of text within a presentation. + + + + + + + +&Shift;F3 + +EditFind Previous + + + +Find the previous occurrence of a piece of text within a +presentation. + + + + + + + +&Ctrl;R + +EditReplace... + + + +Replace one or more occurrences of a piece of text in +your presentation with a different piece of text. + + + + + + +Edit +Copy Slide + + + +Copy the current slide to the clipboard. + + + + + + +Edit +Duplicate Slide + + + +Insert an exact copy of the current slide. + + + + + + +Edit +Delete Slide + + +Delete the current page from the presentation. You +will be asked to confirm this action. + + + + + + +Edit +Duplicate Object... + + + +Create a duplicate of the currently selected object. A dialog will +display allowing you to set some options for the duplicate, ⪚ if it +should be rotated, or scaled, or offset to a new position on the +slide. + + + + + + + + +<guimenu>View</guimenu> Menu + + + + + + +View +New View + + +Opens another window with the same presentation loaded +so you can work on more than one slide at a time. + + + + + + + +&Ctrl;&Shift;W +View +Close All Views + + + +Close all views on the presentation. You will be given +a chance to save any changes, or to cancel closing. + + + + + + +View +Split View + + + +Splits the window into two (or more) views on the same +presentation. The default split is horizontal. + + + + + + +View +Remove View + + + +Close only the currently active view. The +presentation, and any other views you have open, remain open, and any +changes you have made remain unsaved. + + + + + + +View +Splitter Orientation + + + +Toggle the split view between +Horizontal (the default) and +Vertical. + + + + + + +View +Show Sidebar + + + +Toggle the display of the sidebar where you can +see an overview of all the slides in your presentation. + + + + + + +View +Show Notebar + + + +Toggle the display of the notebar where you can +see an overview of all the notes in your presentation. + + + + + + +View +Slide Master + + + +Toggle the display of the slide master where you can put objects that you want to appear on each slide in your presentation. + + + + + + +View +Formatting Characters + + + +Show a visual representation of non-printing +characters, such as tabs and paragraph markers. This can be +a useful aid to precisely positioning text. + +This item can be toggled. If enabled, formatting characters are +visible; if disabled, they are not. + + + + + + +View +Guide Lines + + + +When working in &kpresenter; you can drag a guide +line from either the horizontal or vertical ruler onto your +document. This guide-line will not print or display in the finished +presentation, it is simply to help you align objects on screen. If +this item is enabled, these guide lines will be visible. If this is +disabled, they will not be visible. + +Guide lines work across slides, allowing you to align objects the +same way across multiple slides. + +Disabling (hiding) guide lines does not delete them. If you have +created guide lines, and then disabled this item, enabling it again +will retain the guide lines you created. + + + + + + +View +Add Guide Line... + + + + +Opens a dialog to select the Orientation +(Horizontal or Vertical) +and choose a Position: + + + + + + + +View +Show/Hide Grid + + + +If enabled, &kpresenter; will display a grid of dots +representing the intersections of imaginary horizontal and vertical +lines. You can use these dots to precisely position objects on the +slide. + + + + +View +Snap to Grid + +If this is enabled, when dropping or moving objects on the +slide the top left corner of the object will snap or +move, to the nearest grid point. +This does reduce your freedom to freely position objects on the +slide, however it also helps to line up objects precisely. It is +easily disabled or enabled with this menu entry, allowing you the best +of both worlds. + + + + + + +View +Zoom + + + +This submenu allows you to zoom in or out of the +slide. Several predefined zoom levels are available, including +Whole Slide to scale the entire slide so as +to be visible in the size window you have open, and +Width to scale the slide so it fills the +entire width of the window, although you may now have to scroll +vertically. There are also several other scaling choices, from +33% up to +500%. + + + + + + + + +<guimenu>Insert</guimenu> Menu + + + + + + + +&Alt;&Shift;C + +Insert +Special Character... + + + +Insert a special character. This might be a character +you don't have a key for on your keyboard layout, for instance ü +on a US Keyboard. + + + + + + +Insert +Variable + + + +Here you can insert a variable that is filled in with a +value that may be updated as you update the document. + + + + + + +Insert +Link... + + + +Insert a hyperlink to a file, a website, or an email +address. This enables these locations to be linked to directly from within active presentations, with resources being handled as appropriately by other applications installed on your system. + + + + + + +Insert +Comment... + + + +Enter a small note that does not display during the +real presentation. You might use this to comment on a colleague's +text, or to leave a note for yourself about something to do +later. + + + + + + + +F2 +Insert +Slide... + + + + +Add a new page to your presentation. A dialog will open +allowing you to choose a template, and whether to insert the new page +before or after the currently selected page. + + + + + + + +InsertFile... + + + +Insert an already existing presentation. A standard &kde; file +open dialog will appear, allowing you to choose a &kpresenter; Document (.kpr) or a +OASIS OpenDocument Presentation (.odp), which will be inserted after the last slide in your current presentation. + + + + + + +F10 +InsertText + + + +Add a new text object. Click and drag to create a frame where +you wish the text to appear. + + + + + + +Insert +Chart + + + +Insert a chart. Click and drag to define the size of the +chart. Some default data will be displayed. Double click to edit the +data and choose the type of chart to display, using the embedded +&kchart; editor. + + + + + + + + +F5 +InsertTable + + + +Insert a table. Click and drag to define the size of +the table. + +A &kspread; open dialog will display. You may import a +spreadsheet that you have saved in one of many formats, including +plain text files. You may also choose to create a new and empty +table. + +Double clicking on the table will allow you to edit the +contents. + + + + + + +Insert +Object + + + + + +An object is an embeddable file, in one of many formats. + +A common use of this action is to insert scaleable clipart in +vector format. + + + + + + + +&Shift;F5 + +Insert +Picture... + + + +Insert a raster image. These are not as easily +scaleable as vector images or clipart. &kpresenter; +currently understands many formats, including .tiff, .jpg, .png and many more. + + + + + + +Insert +Line + + + +You can insert several types of lines. Line drawing is described +further in the drawing tools section. + + + + + + +Insert +Shape + + + +You can insert several prepared shapes, in vector format. These are +editable just like lines you have drawn yourself. Using the drawing +tools is described in detail in the drawing tools +section. + + + + + + +Insert +Scan Image... + + + +Scan an image with a scanner. This requires you have a +scanner installed. It opens the Acquire Image dialog to allow the use of the scanner. + + + + + + + +<guimenu>Format</guimenu> Menu + + + + + + +Format +Select + + + +If you have been using a tool such as the line drawing tool which does +not allow you to select other objects, you can use this menu item to +return to the normal selection cursor. + + + + + + +Format +Rotate + + + +Changes the cursor to a double headed curved arrow. Click with the &LMB; onto an object +and keep the button pressed.Drag with the cursor to rotate the object on the slide around its center. When you are +happy with the position of the object, release the mousebutton to stop +rotating. + +If you change your mind and wish to cancel the rotation, use +EditUndo + to later undo it. + + + + + + +Format +Zoom + + + +Allow you to zoom in or out in the current slide. You can see the zoom factor in the Edit toolbar, in the zoom indicator. + +The zoom factor indicator + + + + + +The zoom factor indicator + + + +Left clicking on the slide will Zoom In. Right clicking on the current slide will present you a menu to allow you to Zoom In, to Zoom Out, to Zoom Entire Slide, to Zoom Slide Width or Zoom Slide Height, to Zoom Selected Objects or Zoom All Objects which put back all objects in your view. + +This action has the same effect as ViewZoom + on another form. + + + + + + +Format +Properties + + + +Open the Properties dialog for the currently selected object on your slide. + +The Properties dialog + + + + + +The Propertiesdialog + + + +The Properties dialog for an object allows you to manipulate it in a +very detailed manner. You can change several properties for the selected object, like the text color if the object is text or the depth if the object is a picture. + + + + + + +Format +Arrange Objects + + + +This is where you can manipulate the stacking order of +objects on the slide. + +An object that is on top will cover, either partially or fully +depending on its size, all other objects beneath it. Meanwhile an +object on the bottom of the stack may not be visible at all, as it is +covered up by other objects. An object in the middle may be partially +covered by other objects, while partially covering yet more objects +itself. + +You can send the selected object down or up a layer, or directly +to the top or bottom of the stack. + + + + + + + +Format +Align Objects + + + + +In the submenu you can quickly align all the currently +selected objects with a side of the slide, or center them either +vertically or horizontally. + + + + + + + + +&Ctrl;G + +Format +Group Objects + + + +If you are drawing, you might want to make something out of +several objects. Arrange the individual parts where you +want them, select one, then hold down the &Ctrl; key +as you click in the others you want to group together. Click +Group Objects and from then on they act as +if they are just one thing. It glues things together. + + + + + + + + +&Ctrl;&Shift;G + +Format +Ungroup Objects + + + +If you decide that you want to alter an object that is made out +of several pieces, you can unglue it with this tool. Click somewhere +away from the object to deselect it, then click to select one of its +parts. + + + + + + +Format +Shadow Objects... + + + +This puts a colored copy of either text or a drawn object behind +it. You can make nice dropped shadows for logos with +this tool. To enable this item, ensure that you have object(s) +selected (you will see the six small black boxes around the +outline.) You choose the color, select which way the shadow is going to +fall and select a distance. For text it looks nice if you set the +distance to two or three. Click Apply +to see the result of your settings for all selected objects on the slide +without leaving the dialog. + + + + + + +Format +Page Layout... + + +Allows you to set the page details. You can specify the margins, +the orientation, either portrait (higher than wide) or Landscape +(wider than high) formats. There are many templates, such as screen, +A4, US legal. + + + + + + +Format +Enable/Disable Document Header + + + +Toggle the display of the header field on the current slide. Header content can only be added in the master slide but you can choose to display the header only on some slides with this action. + + + + + + +Format +Enable/Disable Document Footer + + + +Toggle the display of the footer field on the current slide. Footer content can only be added in the master slide but you can choose to display the footer only on some slides with this action. + + + + + + +Format +Slide Background... + + + + +Allows you to alter the background to your presentation +slides. Your options are Color/Gradient, (which lets you +set either a plain color or one of many gradients) +or Picture, which gives a dialog box to find the picture +you want. Set the View mode: for this picture +to Scaled, Centered, +or Tiled. + + If you want a plain color, click in the box to select +it. Gradients only work when you have chosen two colors. The picture +option allows you to center the picture, zoom it to cover the entire +slide (if it is smaller than the screen, this is very useful) or tile +it. This is used when you want a small pattern to repeat across the +page. It's probably best used with patterns rather than pictures of +logos. + +You can get rid of a picture by selecting another one or +choosing a color/gradient. + + + + + + + + + +<guimenu>Text</guimenu> Menu + +This menu modifies selected text and provides a few tools familiar from +word processing applications for your convienience for when you are making +presentations with large amounts +of text in them. The Text menu will only effect selected or +highlighted text. + + + + + +Text +Default Format + + + +Restores selected text to the system default font size, style and +formatting. + + + + + + +Text +Font... + + + + +The Select Font dialog contains options for selected +segments of text: + + +The Select Font dialog + + + + + +The Select Font dialog + + + + +With this dialog, you can change the font, style and size of +selected text. The preview box at the bottom +allows you to approximate changes before you make them. + + + + + + + + + +&Ctrl;&Alt;P + + +Text +Paragraph... + + + + +The Paragraph Settings dialog contains settings for +larger blocks of text, such as paragraphs. Using this dialog, you can set +indenting, line spacing, bullet/numbered list and border settings. + + + + + + + +Text +Color... + + + + +Use the Select Color dialog to have precise control +over the color of selected text: + + +The Select Color dialog + + + + + +The Select Color dialog + + + + +Using the color spectrum box on the left, +colors can be precisely defined for use in your document. The +color tone can then be adjusted using the scale to the +right of the spectrum box. The input boxes below the +color spectrum allow color values to be entered, so that exact +colors can be specified. + + +Use the color picker to select colors from elsewhere in your document +(⪚ images). + + + + + + + + + +&Ctrl;&Alt;S + +Text +Style Manager + + + +The Style Manager allows you to create an entire set of +attributes that will be applied to selected text all at once. See Working With Styles + + + + + + +Text +Import Styles... + + + +Here you can import styles that you have defined in another &kpresenter; +document. + + + + + + +Text +Style + + + +Using this submenu, you can apply a style that you have previously defined +to the currently selected text. + + + + + + +Text +Create Style From Selection + + + +Copy the properties of the currently selected text and +save them as a style that you may apply to other text. + + + + + + +Text +Align + + + +Align has a submenu with several options: +Align Left (&Alt;L), +Align Center (&Alt;C), +Align Right (&Alt;R), and +Align Block (&Alt;J) +which is also commonly known as Justify. + +Text is by default left-aligned. + + + + + + + +Text +Type + + + +Using this submenu, you can format the currently selected text as a list, +either of the numbered or bulleted type. If you choose numbered, you can then +select a numbering style, and likewise if you choose bulleted, you can +choose the style of bullets to use. + +To change a list back to plain text, select +None as the style. + + + + + + + +&Ctrl;+ + +Text +Increase Depth + + + + + + +&Ctrl;- + +Text +Decrease Depth + + + +Increase Depth and Decrease +Depth move paragraphs in a list either to the right +(Increase Depth) or back to the left +(Decrease Depth). + + + + + + + +Text +Extend Contents to Object Height + + + +Text +Extend Object to Fit Contents + + + +Extend Contents to Object Height and +Extend Object to Fit Contents help to +resize text within the text box or make the text box fit the text you have typed +or pasted into it. + + + + + + +Text +Insert Slide Number + + + +Insert a dynamically-updated slide number. This page number will +automatically update when slides are added or removed from your presentation to +reflect the correct slide value. + + + + + + +Text +Change Case... + + + +Presents a dialog that provides a variety of different case/capitalization +options for the currently selected text. + +You may choose between several styles of capitalization, +including all lower or uppercase, book style capitalization where each +word except conjunctions has an initial capital letter, and sentence +style capitalization where the first word in a sentence is capitalized. You can +also toggle the case, so that uppercase becomes lowercase, and vice +versa. + + + + + + +Text +Spellcheck + + + +Use this submenu to utilize the spellcheck options. If you enable +Autospellcheck, &kpresenter; will automatically check +text that you enter for spelling errors. + +If you prefer to check spelling explicitly, rather than automatically, you +can also force a Spelling... check here. + + + + + + +Text +Autocorrection + + + +Use this submenu to utilize autocorrection options. If you +Enable Autocorrection, common spelling errors will be +corrected as you type. For example, if you entered Teh, +it would be autocorrected to The. + +If the autocorrection feature is not active, you can also +Apply Autocorrection check here. + + + + + + + + +<guimenu>Slide Show</guimenu> Menu + + + + + + +Slide Show +Configure Slide Show... + + + + +You can set up the properties for the entire slide show here, +including whether to show the duration on screen, which of the slides +in a presentation to include, and several other global settings. + + + + + + + + +Slide Show +Edit Object Effect... + + + +Choose what effect you want to apply for the highlighted object. This is where +you can set the order of appearance, how the object will appear, if you want a sound while the object appears and if you want some disappearance effects too. + + + + + + +Slide Show +Edit Slide Transition... + + + +Apply transition effects to the currently open slide. This is where +you can choose how the transition from one slide to the next +will be handled. + +The transition effects you select here are applied on the +transition from this slide +to the next. + + + + + + + +F12 +Slide Show +Start + + + +Begin the slideshow from the current slide. + + + + + + +Slide Show +Start From First Slide + + + +Begin the slideshow from the first slide. + + + + + + +Slide Show +Custom Slide Show... + + + +Opens a dialog to Add..., Modify..., +Remove and Copy slides and +Test the slide show in full screen mode. + + + + + + +Home +Slide Show +Go to Start + + + +Go directly to the first slide in the slide show. + + + + + + +PageUp +Slide Show +Previous Slide + + + +Go back to the previous slide in the slide show. + + + + + + +PageDown +Slide Show +Next Slide + + + +Go to the next slide in the slide show. + + + + + + +End +Slide Show +Go to End + + + +Go immediately to the final slide in the slide show. + + + + + + + + +<guimenu>Settings</guimenu> Menu + +The Settings menu allows you to customize +&kpresenter;. + + + + + + +Settings +Toolbars + + + +The items in this submenu can be toggled, that is, you can both enable and +disable the display of specific toolbars here. + + + + + + +Settings +Configure Autocorrection... + + + +Autocorrection is &kpresenter;'s ability to correct +common typing errors or expand abbreviations independently of the spell +checking function. There are several common typing errors entered for +you by default such as replacing teh with +the and you can add as many more as you +like. + +The ability to expand abbreviations can save you a lot of typing +time, if you often repeat text whether in the same presentation or in +multiple presentations. + +For instance, if you work for Company with a really really +long name Inc. then you might define an autocorrection entry so +that whenever you type myJob or some other piece +of unique text, it will be replaced with Company with a really +really long name Inc.. + +Autocorrection can be applied automatically as you type, or only +on demand when you choose it from the Text +menu. + +Please see the Configure Autocorrection section for a complete explanation. + + + + + + +Settings +Configure Completion... + + + +Autocompletion allows you to type the first few letters of a commonly used word (often technical or job specific), and tells &kpresenter; to finish typing the word for you. + +Please see the Configure Completion section for a complete explanation. + + + + + + + +Settings +Configure Shortcuts... + + + + +Configure Shortcuts allows you to +assign a keyboard shortcut to actions that &kpresenter; menus or icons +contain. + + +Customize Shortcuts + + + + + +Customizing the shortcuts + + + + +If you try to assign a shortcut that is already used, it will +give you a warning message. Highlight what you want to do (in the +picture, I have chosen to make a keyboard shortcut to About +KDE). + +Click the radio button to the Custom key setting and type the +key you want to use. I assigned Control key and +Y to bring up the About KDE dialog +box. + +The button shows what has been assigned. Click +OK to make the changes, click +Default to restore whatever was assigned as +default, click Cancel to do nothing and leave +the dialog. + + + + + + + +Settings +Configure Toolbars... + + + +Configure Toolbars allows you to add or delete icons on each of +the toolbars. + + +Configuring &kpresenter; toolbars + + + + + +Configuring &kpresenter; toolbars + + + + + + +At the top is a drop down box to enable you to choose which +toolbar you want to modify. In the picture the Format toolbar is +selected. If I want to add the Spelling icon to +that toolbar, I click the entry in the left window. The arrow pointing +right becomes available, if I click the arrow the Spelling +entry is added to the selected toolbar. The left arrow +is available when you click in the right side window. It allows you to +remove an icon from a toolbar. The up and down arrows become active +when an item on the wright side is selected. You can also move the highlight in +the right side window up and down with the keyboard arrow keys. By +clicking on the arrows with the mouse you can change the order of the entries +in the menu. + + + + + + + + +Settings +Configure &kpresenter;... + + + +See the configure &kpresenter; section for a complete explanation of all &kpresenter; settings. + + + + + + + +<guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + + +
    \ No newline at end of file diff --git a/doc/kpresenter/mousenav.png b/doc/kpresenter/mousenav.png new file mode 100644 index 000000000..462c6051f Binary files /dev/null and b/doc/kpresenter/mousenav.png differ diff --git a/doc/kpresenter/msexport1.png b/doc/kpresenter/msexport1.png new file mode 100644 index 000000000..fa3de1e42 Binary files /dev/null and b/doc/kpresenter/msexport1.png differ diff --git a/doc/kpresenter/msexport2.png b/doc/kpresenter/msexport2.png new file mode 100644 index 000000000..27bb44f2b Binary files /dev/null and b/doc/kpresenter/msexport2.png differ diff --git a/doc/kpresenter/msexport2b.png b/doc/kpresenter/msexport2b.png new file mode 100644 index 000000000..a141a9038 Binary files /dev/null and b/doc/kpresenter/msexport2b.png differ diff --git a/doc/kpresenter/msexport3.png b/doc/kpresenter/msexport3.png new file mode 100644 index 000000000..55b03e609 Binary files /dev/null and b/doc/kpresenter/msexport3.png differ diff --git a/doc/kpresenter/msexport4.png b/doc/kpresenter/msexport4.png new file mode 100644 index 000000000..634246107 Binary files /dev/null and b/doc/kpresenter/msexport4.png differ diff --git a/doc/kpresenter/options.docbook b/doc/kpresenter/options.docbook new file mode 100644 index 000000000..39f13e130 --- /dev/null +++ b/doc/kpresenter/options.docbook @@ -0,0 +1,1032 @@ + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +
    +
    +Configuring &kpresenter; + + +The <guilabel>Configure Autocorrection...</guilabel> Dialog +Auto correction is a system for correcting common typing errors, converting abbreviations to their full spelling and adjusting capitalization. As you could guess from its name, this all occurs automatically, while you are editing your document. + + +Enabling/Disabling Autocorrection + +To toggle autocorrection on, select TextAutocorrectionEnable Autocorrection from the menubar. When enabled, autocorrection makes changes to your document as you type. You can determine which changes to make by configuring autocorrection, as explained below. + + +To toggle autocorrection off, select TextAutocorrectionDisable Autocorrection from the menubar. When disabled, autocorrection changes are not made. You can, however, apply autocorrection manually, using the TextAutocorrectionApply Autocorrection menu. + + +To adjust the options for autocorrection, select Settings +Configure Autocorrection... from the menubar. + +A dialog window appears to help you set your options, with four tabs: Simple Autocorrection, Custom Quotes, Advanced Autocorrection and Exceptions. + + + +<guilabel>Simple Autocorrection</guilabel> + + +Simple Autocorrection + + + + +Simple Autocorrection + + + + + +Convert first letter of a sentence automatically to uppercase +When selected, &kpresenter; will automatically capitalize the first letter after a period. You can tell &kpresenter; when not to alter capitalization in certain instances (ie “Sr.” or “Jr.”). For more details, see the section entitled Autocorrection Exceptions. + + + +Convert two uppercase characters to one uppercase and one lowercase character +When selected, &kpresenter; will automatically convert a double capital letter (a common typographical error), into a single capital letter. You can tell &kpresenter; when not to alter capitalization in certain instances. For more details, see the section entitled Autocorrection Exceptions. + + + +Autoformat URLs +When selected, &kpresenter; will scan text for patterns which suggest a certain section of text is a URL and automatically creates a link. + + + +Suppress double spaces +When checked, &kpresenter; will ignore the second space typed. This prevents users from adding double spaces between words or sentences + + + +Remove spaces at the beginning and end of paragraphs +When selected, &kpresenter; will automatically remove spaces at the beginning and/or the end of a line of text. + + + +Automatically do bold and underline formatting +When selected, &kpresenter; will look for words surrounded by asterisks ( * ). It will remove the asterisks and change the font of all words in between the two asterisks to bold face. +&kpresenter; will also look for words surrounded by underscores ( _ ). It will remove the underscores and underline all words in between the two underscores. + + + +Replace 1/2... with ½... +When selected, &kpresenter; will automatically change 1/2, 1/3 and 3/4 to their single character equivalents. + + + +Use autonumbering for numbered paragraphs +If you start a paragraph with a number and a symbol ( 1) for example), &kpresenter; will automatically convert that paragraph to a numbered paragraph. All future paragraphs will be consecutively numbered. + + + +Replace 1st with 1^st... +When selected, &kpresenter; will automatically change 1st to 1st. + + + +Capitalize name of days +Automatically capitalize the days of the week (Sunday, Monday, Tuesday, etc...). + + + +Use list-formatting for bulleted paragraphs +When selected, &kpresenter; will look for lines that begin with - , and automatically convert the paragraph style to a bulleted list. The bullet is selected with the left button below this option. + + + + + + +<guilabel>Custom Quotes</guilabel> + +Select the tab labeled Custom Quotes + + +Custom Quotes + + + + +Custom Quotes + + + + + +Replace double quotes with typographical quotes + +When selected, this option will replace the standard keyboard double +quotes, with typographical quotation marks. If you want to change the +quotation character, click on one of the buttons. Clicking on +Default, restores the default paragraph marks. + + + + +Replace single quotes with typographical quotes + +When selected, this option will replace the standard keyboard single +quotes, with typographical quotation marks. If you want to change the +quotation character, click on one of the buttons. Clicking on +Default, restores the default paragraph marks. + + + + + + +<guilabel>Advanced Autocorrection</guilabel> + +To switch to the Advanced Autocorrection, click on the tab labeled +Advanced Autocorrection. + + +Advanced Autocorrection + + + + +Advanced Autocorrection + + + +This allows you to automatically have &kpresenter; replace one string +of text with another. This can be useful for special symbols, commonly +used abbreviations that you want spelled out, or common typing errors. + +&kpresenter; uses different autocorrection strings depending on the language. +Set the correct language using the combo box labeled +Replacement and exceptions for language:. + +The check box labeled Enable word replacement is used to +toggle on and off the autoreplacement features of &kpresenter;. If there is no mark in the check box, +then &kpresenter; will not perform any autoreplacements from the list in this dialog. + +If there is a mark in the check box labeled Replace text with format +&kpresenter; will not only change the text when it finds a match, but it will change the formatting of the new text. +If there is no mark in this check box, then +&kpresenter; uses the same formatting options for the replaced text as it found in the search text. For more information +on setting the format options for replacement text, see the section on +Changing the format of the autocorrection string. + + +Adding an autocorrection string + +To add an autocorrection string, simply type the text you want &kpresenter; to +check for in the text box labeled +Find:, then enter the text you want &kpresenter; +to substitute in the text box labeled Replace:. + + +If you want to insert symbols or special characters not available on your +keyboard, you can click the +buttons with three periods on them and select a special character from the table provided. + +When these are entered, click Add.... Your text +strings are now added to the table. + + + +Editing an autocorrection string +Changing the text you want to find. +&kpresenter; does not allow you to change the text to search for. +This is to prevent disastrous mistakes. +Instead, you must delete the current autocorrection rule and +add a new text string with the corrected text to find. + +Changing the text you want to replace. +Begin by clicking once on the string you want to edit. It will be +highlighted and the find and replace text will be listed in the text boxes +above. You can alter the replacement text. When you +are done, simply click on the Modify button. + + + + +Deleting an autocorrection string + +Simply click on the string you want to delete. Now click the +Remove button. The string is removed. + + +Be aware that &kpresenter; does not give you a chance to back out once +you have deleted a string. Be sure you have selected the correct string +before you click the Remove +button. + + + + +Changing the format of the autocorrection string +Currently, you must create the autocorrection string before you can format it. +Once the autocorrection string has been created, simply click on it once with the &LMB;. +Now click on the Change Format... button. A small dialog will appear: + + + + + + + +You can use this dialog to select the format of the replaced text. +The left column consists of 13 check boxes. If there is a mark in the check box, then &kpresenter; will change +any replaced text to match the property selected. +If no mark is in the check box, &kpresenter; does not consider that property when replacing text. + + + + +Family: + +Use this combo box to select the font family you want your replacement text to use. + + + + +Size: + +Use this spin box to set the font size you want &kpresenter; to use for your replaced text. + + + + +Color: and Background color: + +Clicking on either of these two buttons allows you to select the font color and/or background color respectively, +you want &kpresenter; to use. + + + + +Bold: and Italic: + +Use these Yes/No radio buttons to determine whether you want &kpresenter; +to change the fonts to boldface or italicized fonts. + + + + +Strikeout: + +You can select None, Single, Double +or Simple Bold to use for the replacement text. + + + + +Underline: + +You can select None, Single, Double, +Simple Bold or Wave to use for the replacement text. + + + + +Vertical alignment: + +You can select Normal, Superscript or +Subscript to determine what font alignment you want &kpresenter; to use. + + + +Shadow: and Word by word: + +Use these Yes/No radio buttons to determine whether you want &kpresenter; +to use shadow text and/or word by word underlining and strikethrough in the replacement text. + + + + +Capitalization: + +You can select Normal, Uppercase, Lowercase, or +Small Caps to determine what capitalization to use for the replacement text. + + + + +Language: + +You can select the language of the text you will use to replace the found text. + + + + +Once you have selected your options, click OK to accept your text options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the initial values prior to making any changes. +Click Clear to remove all marks from the checked options. + + + + +<guilabel>Exceptions</guilabel> + +There are instances where &kpresenter; will make autocorrection changes +that are inappropriate. You can use the fourth tab of this dialog to define +exceptions to the rules previously discussed. +The dialog for exceptions is shown below: + + +Exceptions + + + + +Exceptions + + + +To prevent &kpresenter; from deciding an abbreviation or other text is +the end of a sentence, simply enter the text fragment in the text box below +Do not treat as the end of a sentence:. Then click +Add. +As an example: Adding Jr. to this dialog prevents +Robert Jones Jr. is a friend of the family. +from being changed to: +Robert Jones Jr. Is a friend of the family. +To remove an erroneous entry, simply click once on the wrong entry with the &LMB; +and click on the Remove button. +The second set of boxes performs a similar function to the first except text entered in these boxes will allow two capital letters in a word if it +is entered in this text box. +Simply enter the word in the text box below +Accept two uppercase letters in:. Then click +Add. +As an example: Adding CD to this dialog prevents +CD +from being changed to: +Cd +To remove an erroneous entry, simply click once on the wrong entry with the &LMB; +and click on the Remove button. + + + +Manually applying autocorrection + +If autocorrection is turned off in your document, you can manually enable autocorrection. +To manually apply autocorrection, first configure your options by using the +autocorrection dialogs. +Then select +TextAutocorrectionApply Autocorrection +from the menubar. +&kpresenter; will start at the beginning of the document and apply all selected autocorrection options to the entire document. +When &kpresenter; is finished, it will return you to your document for further editing. +For more information on enabling and disabling autocorrection, +see Enabling/Disabling Autocorrection. + + + + + +The <guilabel>Configure Completion</guilabel> Dialog + +Autocompletion allows you to type the first few letters of a commonly +used word (often technical or job specific), and tells &kpresenter; to +finish typing the word for you. This is often very useful when you have lengthy technical words. + + +Using autocompletion +Using autocompletion could not be easier. Simply type the first few +letters of the word you want &kpresenter; to finish, and press +&Ctrl;E. &kpresenter; will look +through the list of autocompletion words and if it finds a word which begins +with those letters, it will finish entering the remainder of the word. + +Adding words to autocompletion +&kpresenter; maintains a list of words for each user that will be used for autocompletion. +You can add words to this list one of two ways: + +&kpresenter; can automatically add new words to the completion list for later approval. +This is selected using the dialog. +Individual words can be added to the list by using +the dialog. + + + + + +Configuring autocomplete +To configure autocompletion, select +SettingsConfigure Completion... +from the menubar. This will bring up a dialog. + + +Completion Dialog + + + + +Completion Dialog + + + + + +Enable word completion +It is used to toggle autocompletion on and off. + + + +Add + +By clicking this button you can manually add +an individual word to the completion list. + + + + +Remove + +To remove words from the completion list, select the word with the &LMB; +from the list, then click this button. + + + + +Automatically add new words to suggestion list + +This option will add any word equal to or longer than +the Characters needed: to the list of proposed +autocompletion words. +The large listbox in the center of the dialog contains the current +proposed list of autocompletion words. +Not all words listed in the list box will be immediatly affected by +autocompletion when entered into this dialog. + + + + +Show words in tooltip + +If this option is enabled, a tool tip box will appear when you type the +beginning of a word that exists in the completion list. To complete the word, +press the key you set to accept suggestions in the Key to accept +suggestion: drop-down list. + + + + + +Characters needed: + +Use this spinbox/slider combination to prevent &kpresenter; +from automatically adding short words to the completion list. You can select +any value from 5-100 and the words will need to be at least the number of +characters set here to be added in the list. + + + + +Suggest words: + +This spinbox/slider combination can be adjusted to allow more or less +words into the autocompletion list. This option is most important when +Automatically add new words to suggestion list is enabled. +This option keeps the list from becoming too cumbersome. You can select any +value from 1 to 500. + + + + +Append space + +If checked, it adds a single space to the end of a word after +autocompletion, this means it is not necessary to add the space manually for the +next word. + + + + +Key to accept suggestion: + +Set the key you want to use when an autocompleted word is suggested to you +and you want to accept it. You can choose +Enter, Tab, Space, +End or Right. + + + + +Make Default + +A word is not part of autocompletion until the list is +saved to disk. At that moment, &kpresenter; +will use that saved list for all autocompletion, until the list is replaced with +another saved list. +Some of the words in the autocompletion list may not have been saved +yet.To save the current list to disk and have &kpresenter; begin +using this new list for autocompletion, click this button. + + + + +Click OK to save your options. Click +Cancel to abort all changes. Click +Reset to reset to the state after you clicked on the +Make Default button. + + + + + + +The <guilabel>Configure &kpresenter;</guilabel> Dialog + + +<guilabel>Interface</guilabel> + + +Configure Interface + + + + +Configure Interface + + + + + +Show rulers +This is checked by default and both a vertical and horizontal +ruler are shown on &kpresenter;slides. When unchecked, the rulers are not shown +anymore on any slide. + + + +Show status bar +Toggle the statusbar which is shown by default. + + + +Number of recent files: +Set the number of recent files which will be opened using the +FileOpen +Recent menu. Default is to remember 10 filenames. The +maximum you can set is 20 and the minimum is 1. + + + +Text indentation depth: +This setting is used in the Text menu by Increase Depth and Decrease Depth menu items to change the indentation depth. Default is 1 centimeter. + + + + + + +<guilabel>Color</guilabel> + + +Color + + + + +Color + + + + + +Background object color: +It changes the background color of the text box. The Text boxes background is white by default. If you had a dark +background color and you wanted to put some white text over it, you +could color the text box so that you could see what you were +typing. When you have finished, the area around the text would revert +to whatever the background color was. The +Defaults button restores the original +settings. + + + +Grid color: +You can change here the grid color which is black as default. + + + + + + + +<guilabel>Spelling</guilabel> + +This tab defines the spellchecker behavior. + + +Spelling + + + + +Spelling + + + + + +Default language: +You can choose here the language for the spellchecker. The languages listed come from aspell so if you want more spelling support languages, you should install the corresponding aspell-ISO packages. + + + +Enable background spellchecking +If it is checked, it will highlight in red mispelled words according to the dictionary selected above and it will spellcheck words as you type them. This is enabled by default. This option has the same effect as TextSpellcheckAutospellcheck and both are checked/unchecked at the same time. + + + +Skip all uppercase words +If this option is checked, the all uppercase words will not be checked for spelling. This option is also used when you choose the TextSpellcheckSpelling... menu option. +This is useful if the document you are working on uses a large number of acronyms. If this box is left unchecked, most of those acronyms will be incorrectly marked. By placing a mark in this checkbox, &kpresenter; will not mark the acronyms as misspelled. + + + +Skip run-together words +If checked, then concatenated words made of existing words are not spellchecked. This is useful in some languages. This option is also used when you choose the TextSpellcheckSpelling... menu option. +Examples of such words are shutout, +cannot and blackout. + +Checking this box will help prevent &kpresenter; from +flagging website and email addresses for spelling errors. These +addresses often contain words run together. + + + + + +Ignore These Words +You can have here a list of words you want to ignore in all spellchecking. + + + +Add +Write a word in the field then click on the Add button to add it in the list. Once the word is added in the list, even if you click the Cancel button of the configuration dialog, it will stay in the list. + + + +Remove +Highlight a word in the list then click on this button to remove it. + + + + + + +<guilabel>Misc</guilabel> + + +Misc + + + + +Misc + + + + +<guilabel>Misc</guilabel> + +Undo/Redo limit: +Set the number of actions you can undo and redo (how many actions &kpresenter; keeps in its Undo buffer). Default is 30. Maximum is 60 and minimum is 10. Any action that exceeds the number set will be forgotten. + + + +Display links +When you want to include a link in your slide, you will use the InsertLink... menu which allows you to insert URL, mail or file links. If the option Display links is checked, all links will be displayed in a different color. This makes document links visible. This is the default behavior. If the option is unchecked, the link will be the same color as the text color. The links are visible (or not) both in the edited slides and in the slide show. A displayed link: + A non displayed link: + + + + +Underline all links +If this is checked, all links will be underlined. The option is checked per default. If it is not checked, the link will not be underlined. A displayed and underlined link: + + + + +Display comments +Comments are inserted in the text at the cursor using the InsertComment... menu. Comments can only be viewed in editing mode and not in the slide show. If this option is checked (default) then each comment will be shown as a small yellow rectangle. You can then right click on it to edit it, remove it or copy its text. A displayed comment: + + + + + + +Display field code +In editor mode (not in slide show) this option will display all the variable codes. This is very useful to see what variable is displayed. Variables are inserted using the InsertVariable menu. + + + +Print slide notes +If checked, all notes will be printed on paper. The notes will all be printed on a separate last page, from slide one to the last slide and finishing with the Master Page Note. You can see the notes for each slide using the ViewShow Notebar menu. + + + + +<guilabel>Grid</guilabel> + +Horizontal grid size: +Set the space in centimeters between two points on an horizontal line on the grid. Default is 0.5 centimeter. + + + +Vertical grid size: +Set the space in centimeters between two points on a vertical line on the grid. Default is 0.5 centimeter. + + + + + +<guilabel>Document</guilabel> + + +Document + + + + +Document + + + + +<guilabel>Document Defaults</guilabel> + +Default font: +Click on the Choose... button, and a new dialog will appear. Use this dialog to choose the default font. This setting determines the default font used by &kpresenter; until further formatting is done. You can revert any text to this default by selecting TextDefault Format from the menubar. + + + +Global language: +Use this drop down box to determine the default language for the document. This setting is used by the hyphenation and spelling tools. + + + +Automatic hyphenation +Check this box if you want &kpresenter; to automatically hyphenate long words when it determines the word wrap in text frames. This is not set as default. + + + + + +<guilabel>Document Settings</guilabel> + +Create backup file +If checked, this will create a .<name>.odp.autosave.odp in the dir where your file is. This backup file can then be used in case of a problem. The backup file is updated everytime you save your document or everytime there is an autosave. + + + +Autosave (min): +You can use this to adjust how often &kpresenter; saves a temporary file. If you set this value to No autosave, &kpresenter; will not autosave. You can adjust the autosave from 1 minute to 60 minutes. + + + +Starting page number: +You can change here the number for the first page. It is set to 1 per default. +This is helpful if you have split a single document into multiple files. + + + +Tab stop: +Each &kpresenter; document has a default set of tab stops. If you add tab stops to your document, the newly added tab stops override the default tabstops. You can use this text box to define the spacing between default tab stops. +As an example, if you enter 1.5 in this text box, and the unit of measure is in centimeters, then the first default tab stop will be located 1.5 cm to the right of the left margin of the frame. The second default tab stop will be located at 3 cm from the left margin, etc. + + + + +<guilabel>Cursor</guilabel> + +Cursor in protected area +When this box is checked and you click in a protected frame of your document, a cursor appears. When the mark is removed from this check box, and you click in a protected frame, there is no cursor visible. + + + +Direct insert cursor + +When this box is checked then you can select a section of text using your mouse. Move the mouse to a new place in your document and click once with the middle mouse button and a copy of the selected text is copied and pasted to the new location in the document. +When there is no mark in this checkbox, in order to copy text from one section to another, you must select the text, manually copy the text in to the clipboard, then manually paste the text in the new location. + + + + + + +<guilabel>Tools</guilabel> + +This dialog sets the default tools settings. There are 5 tabs in this dialog. + + +<guilabel>Outline</guilabel> + + +The Outline tab + + + + +The Outline tab + + + +This is used in the InsertLine menu. + + + +Color: +Set the color of the line. Clicking on the color will bring the standard KDE Select Color dialog. + + +Style: +Choose the line style from No Outline which will not draw any line to dotted lines and plain line. + + +Width: +Set the width of the line. + + +Arrow Style +Set the styles of the beginning and the end of your line for example you can choose an arrow at the end and a square dot at the beginning. + + +The last field displays a preview of your settings. + + + +<guilabel>Fill</guilabel> + + +The Fill tab + + + + +The Fill tab + + + + + +Type: +You can choose between Single Color, Gradient or Transparent as the type. + + +Style: +Choose the style or the pattern. + + +Color: +Choose the color. White is the default one. Clicking on the color will bring you the standard KDE Select Color dialog. + + +The last field displays a preview of your settings, provided the color is not white! + + + +<guilabel>Rectangle</guilabel> + +This is used in the InsertShapeRectangle menu. + + +The Rectangle tab + + + + +The Rectangle tab + + + +You can choose to keep the same ratio for the two settings below by having the + icon or to separate the two settings by using the + icon. + + +Vertical declination: +Set the vertical declination. + + +Horizontal declination: +Set the horizontal declination. + + +The last field displays a preview of your settings. + + + +<guilabel>Polygon</guilabel> + +This is used in the InsertShapeConvex/Concave Polygon menu. + + +The Polygon tab + + + + +The Polygon tab + + + + + +Type: +You can choose Polygon or Convex/Concave. + + +Corners: +Set here the number of corners of the polygon. + + +Sharpness: +Increase or decrease the sharpness of the polygon. + + +The last field displays a preview of your settings. + + + +<guilabel>Pie</guilabel> + +This is used in the InsertShapePie/Arc/Chord menu. + + +The Pie tab + + + + +The Pie tab + + + + + +Type: +You can choose among three options in the dropdown box: Pie, Arc or Chord. + + +Start position: +Set here the start position. + + +Length: +Set the length of your pie. + + +The last field displays a preview of your settings. + + + + + +<guilabel>Paths</guilabel> + + +Paths + + + + +Paths + + +There are two paths that are set here, the Backup Path and the Picture Path. The Backup Path is the directory where your backup files are saved and the Picture Path is the directory where your pictures are saved. Highlight a path in order to modify it and click on Modify Path.... A small dialog appears and if you uncheck Default path, you will be able either to enter a path yourself or to choose one with the standard KDE file dialog. + + + +TTS + +See the Text-to-Speech section +in the accessibility chapter for further details. + + + + + +
    diff --git a/doc/kpresenter/properties.png b/doc/kpresenter/properties.png new file mode 100644 index 000000000..a1b38c301 Binary files /dev/null and b/doc/kpresenter/properties.png differ diff --git a/doc/kpresenter/screen.docbook b/doc/kpresenter/screen.docbook new file mode 100644 index 000000000..f35d11168 --- /dev/null +++ b/doc/kpresenter/screen.docbook @@ -0,0 +1,44 @@ + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +
    +
    +The &kpresenter; Screen + +Here is the default &kpresenter; Screen Layout. + +At the top there is the menubar. All &kpresenter; functions are +available from the menus, which are described in detail in . + +Below the menubar are the toolbars. There are several +toolbars. You may hide and show toolbars as you prefer. The toolbars +are described in detail in . + + +The Outline and +Preview panes give an overview of your entire +presentation. The Preview pane provides +thumbnails of each slide, and allows you to drag and drop to change +the order. The Outline pane provides a +hierarchal tree of each slide, and also the objects inside the slides. +As well as overview, this allows you to easily select objects which +may be covered by others, or are otherwise difficult to grab directly on +the slide. + +
    diff --git a/doc/kpresenter/settings01.png b/doc/kpresenter/settings01.png new file mode 100644 index 000000000..db91f31c3 Binary files /dev/null and b/doc/kpresenter/settings01.png differ diff --git a/doc/kpresenter/settings03.png b/doc/kpresenter/settings03.png new file mode 100644 index 000000000..85d370e6e Binary files /dev/null and b/doc/kpresenter/settings03.png differ diff --git a/doc/kpresenter/settings04.png b/doc/kpresenter/settings04.png new file mode 100644 index 000000000..6f2883bd2 Binary files /dev/null and b/doc/kpresenter/settings04.png differ diff --git a/doc/kpresenter/template02.png b/doc/kpresenter/template02.png new file mode 100644 index 000000000..8d1ef9769 Binary files /dev/null and b/doc/kpresenter/template02.png differ diff --git a/doc/kpresenter/template03.png b/doc/kpresenter/template03.png new file mode 100644 index 000000000..53efdad53 Binary files /dev/null and b/doc/kpresenter/template03.png differ diff --git a/doc/kpresenter/template04.png b/doc/kpresenter/template04.png new file mode 100644 index 000000000..f0e69a162 Binary files /dev/null and b/doc/kpresenter/template04.png differ diff --git a/doc/kpresenter/template05.png b/doc/kpresenter/template05.png new file mode 100644 index 000000000..4faa5eb2d Binary files /dev/null and b/doc/kpresenter/template05.png differ diff --git a/doc/kpresenter/template06.png b/doc/kpresenter/template06.png new file mode 100644 index 000000000..e92f9f73f Binary files /dev/null and b/doc/kpresenter/template06.png differ diff --git a/doc/kpresenter/template07.png b/doc/kpresenter/template07.png new file mode 100644 index 000000000..4e8b694f0 Binary files /dev/null and b/doc/kpresenter/template07.png differ diff --git a/doc/kpresenter/textmenu1.png b/doc/kpresenter/textmenu1.png new file mode 100644 index 000000000..0ed57be7a Binary files /dev/null and b/doc/kpresenter/textmenu1.png differ diff --git a/doc/kpresenter/textmenu2.png b/doc/kpresenter/textmenu2.png new file mode 100644 index 000000000..7ce121e69 Binary files /dev/null and b/doc/kpresenter/textmenu2.png differ diff --git a/doc/kpresenter/toolsmenu01.png b/doc/kpresenter/toolsmenu01.png new file mode 100644 index 000000000..f1ad76927 Binary files /dev/null and b/doc/kpresenter/toolsmenu01.png differ diff --git a/doc/kpresenter/tts.png b/doc/kpresenter/tts.png new file mode 100644 index 000000000..916f04ca0 Binary files /dev/null and b/doc/kpresenter/tts.png differ diff --git a/doc/kpresenter/tut01.png b/doc/kpresenter/tut01.png new file mode 100644 index 000000000..fc61e1db1 Binary files /dev/null and b/doc/kpresenter/tut01.png differ diff --git a/doc/kpresenter/tut02.png b/doc/kpresenter/tut02.png new file mode 100644 index 000000000..edc1f1c16 Binary files /dev/null and b/doc/kpresenter/tut02.png differ diff --git a/doc/kpresenter/tut03.png b/doc/kpresenter/tut03.png new file mode 100644 index 000000000..6f7f419cf Binary files /dev/null and b/doc/kpresenter/tut03.png differ diff --git a/doc/kpresenter/tut04.png b/doc/kpresenter/tut04.png new file mode 100644 index 000000000..e609be605 Binary files /dev/null and b/doc/kpresenter/tut04.png differ diff --git a/doc/kpresenter/tut05.png b/doc/kpresenter/tut05.png new file mode 100644 index 000000000..962fcf1f4 Binary files /dev/null and b/doc/kpresenter/tut05.png differ diff --git a/doc/kpresenter/tut06.png b/doc/kpresenter/tut06.png new file mode 100644 index 000000000..2fd81c15e Binary files /dev/null and b/doc/kpresenter/tut06.png differ diff --git a/doc/kpresenter/tut07.png b/doc/kpresenter/tut07.png new file mode 100644 index 000000000..0320f122a Binary files /dev/null and b/doc/kpresenter/tut07.png differ diff --git a/doc/kpresenter/tut08.png b/doc/kpresenter/tut08.png new file mode 100644 index 000000000..4e479869a Binary files /dev/null and b/doc/kpresenter/tut08.png differ diff --git a/doc/kpresenter/tut09.png b/doc/kpresenter/tut09.png new file mode 100644 index 000000000..f46e7edf8 Binary files /dev/null and b/doc/kpresenter/tut09.png differ diff --git a/doc/kpresenter/tut10.png b/doc/kpresenter/tut10.png new file mode 100644 index 000000000..345db52a1 Binary files /dev/null and b/doc/kpresenter/tut10.png differ diff --git a/doc/kpresenter/tut11.png b/doc/kpresenter/tut11.png new file mode 100644 index 000000000..bc7df396d Binary files /dev/null and b/doc/kpresenter/tut11.png differ diff --git a/doc/kpresenter/tut12.png b/doc/kpresenter/tut12.png new file mode 100644 index 000000000..440e49d56 Binary files /dev/null and b/doc/kpresenter/tut12.png differ diff --git a/doc/kpresenter/tut13.png b/doc/kpresenter/tut13.png new file mode 100644 index 000000000..991f74932 Binary files /dev/null and b/doc/kpresenter/tut13.png differ diff --git a/doc/kpresenter/tut14.png b/doc/kpresenter/tut14.png new file mode 100644 index 000000000..54ee8257c Binary files /dev/null and b/doc/kpresenter/tut14.png differ diff --git a/doc/kpresenter/tut15.png b/doc/kpresenter/tut15.png new file mode 100644 index 000000000..1954661f5 Binary files /dev/null and b/doc/kpresenter/tut15.png differ diff --git a/doc/kpresenter/tut16.png b/doc/kpresenter/tut16.png new file mode 100644 index 000000000..1f289c11b Binary files /dev/null and b/doc/kpresenter/tut16.png differ diff --git a/doc/kpresenter/tut17.png b/doc/kpresenter/tut17.png new file mode 100644 index 000000000..c36b2af83 Binary files /dev/null and b/doc/kpresenter/tut17.png differ diff --git a/doc/kpresenter/tut18.png b/doc/kpresenter/tut18.png new file mode 100644 index 000000000..87a7fda68 Binary files /dev/null and b/doc/kpresenter/tut18.png differ diff --git a/doc/kpresenter/tut19.png b/doc/kpresenter/tut19.png new file mode 100644 index 000000000..4d469987b Binary files /dev/null and b/doc/kpresenter/tut19.png differ diff --git a/doc/kpresenter/tut20.png b/doc/kpresenter/tut20.png new file mode 100644 index 000000000..0a9c8c01b Binary files /dev/null and b/doc/kpresenter/tut20.png differ diff --git a/doc/kpresenter/tut21.png b/doc/kpresenter/tut21.png new file mode 100644 index 000000000..c1d736f24 Binary files /dev/null and b/doc/kpresenter/tut21.png differ diff --git a/doc/kpresenter/tut22.png b/doc/kpresenter/tut22.png new file mode 100644 index 000000000..b96c2f570 Binary files /dev/null and b/doc/kpresenter/tut22.png differ diff --git a/doc/kpresenter/tut23.png b/doc/kpresenter/tut23.png new file mode 100644 index 000000000..9da71f832 Binary files /dev/null and b/doc/kpresenter/tut23.png differ diff --git a/doc/kpresenter/tut24.png b/doc/kpresenter/tut24.png new file mode 100644 index 000000000..d7d20eabb Binary files /dev/null and b/doc/kpresenter/tut24.png differ diff --git a/doc/kpresenter/tut25.png b/doc/kpresenter/tut25.png new file mode 100644 index 000000000..4454bcfee Binary files /dev/null and b/doc/kpresenter/tut25.png differ diff --git a/doc/kpresenter/tut26.png b/doc/kpresenter/tut26.png new file mode 100644 index 000000000..302216b53 Binary files /dev/null and b/doc/kpresenter/tut26.png differ diff --git a/doc/kpresenter/tutorial.docbook b/doc/kpresenter/tutorial.docbook new file mode 100644 index 000000000..a0aa1be2e --- /dev/null +++ b/doc/kpresenter/tutorial.docbook @@ -0,0 +1,510 @@ + + + + + + +Neil +Lucock + +
    neil@nlucock.freeserve.co.uk
    +
    +
    + +Krishna +Tateneni + +
    tateneni@pluto.njcc.com
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +
    +
    +A Step-By-Step Tutorial + + +In this chapter, &kpresenter; is introduced using a simple tutorial. We +shall walk through the most basic steps that are involved in creating a +presentation, and adding some basic effects. + + + +Start a new document + + +When you start &kpresenter;, the usual &koffice; startup dialog appears. + + + +The &koffice; +startup dialog + + + +The &koffice; startup dialog + + + + +Select Screen on the left then select the template labeled +Title (highlighted in blue in the screenshot above) by +clicking on it. You can check Always use this template to +make it the default template. + + + +Now click Use This Template. This brings up the slide +editor window, where you can view and edit the slides (and objects contained in +them) in your document. At the moment, we just have one slide, with one +object on it, which is a text box. + + + +The slide editor + + +The slide editor + + + + +Double-click the text box. The cursor changes to a vertical bar to show +that you can now type some text and the background of the edited area +becomes grey. + + + +The text insertion cursor + + + +The text insertion cursor + + + + +Go ahead, type some text! + + + +Adding text + + + +Adding text + + + + +Click away from the text to de-select the text box when you are done +typing. + + + + + +Add a new page + + +Let's now add a new slide to our document. To do so, click the +Insert menu, and then click on +Slide.... + + + +Inserting a slide from the menu + + + +Inserting a slide from the menu + + + + +This brings up the Insert Slide dialog. + + + +The Insert Slide dialog + + + +The Insert Slide +dialog + + + + +Select Use different template and click OK to add a +new page after page 1. + + + +The Create Document dialog comes up so that we can decide +what the new slide should look like. This time, select Screen on the left and double click on the +One Column template (highlighted in blue.) + + + +Choosing a template for the new page + + +Choosing a template for the new +page + + + + +The new slide now appears in the editing window. To change between pages +of your presentation, you can select slides in the pane to the left +(highlighted in blue for this screenshot). + + + +The slides list + + +The slides list + + + + +The newly inserted slide has two text boxes. There is one for a title, +and another to contain a bulleted list of items. + + + +The new slide + + +The new slide + + + + +Double-click and type a title. Then double-click on the second text +box with the bullet. Type some text and end the paragraph by pressing the +Enter or Return key. As you type new +paragraphs, bullets automatically appear in front of them. + + + +Adding text to the second slide + + +Adding text to the second slide + + + + +You can de-select the text box by clicking away from it. + + + + + +Insert a picture + + +Let's go back to the first slide now. Use the list of slides on the left +of your screen. + + + +In this section, we'll liven our presentation up a bit by adding a nice +logo to the title page. To do so, the first step is to click on the +Insert menu item, and then on +Picture.... + + + +Using the menu to add an image + + +Using the menu to add an image + + + + +This brings up a file selection dialog. To learn about this or other +standard &kde; dialog boxes in detail, please consult the &kde; +documentation. You can browse by clicking on folder +icons or by using the browser style buttons on the +toolbar (highlighted in red.) Clicking the up arrow +takes you up one folder level. + + + +Find the file named koffice-logo.png, which may be +in a different folder than the one shown in the screenshot below. You +can also choose any other graphic file if you like! Select the file, and +click OK. + + + +Choosing a picture to add + + +Choosing a picture to add + + + + +Click with the &LMB; where you want to place the loge in it's original size or +draw a rectangle with the left mouse cursor to specify the position and size for the logo. +There are selection handles (little squares) visible around the border of the graphic. + + + +The newly added image + + +The newly added image + + + + +Place the mouse cursor anywhere in the middle of the logo, and drag it +to the middle of the title page. Then use the selection handles to resize +it correctly. + + + +Dragging and resizing the image + + +Dragging and resizing the image + + + + +That's it. Now you have a picture on the title page! + + + + + +Insert a &koffice; object +Let's insert another &koffice; object under the picture, for example +a chart. + + +Every &koffice; supported document can be embedded in a &kpresenter; slide. +Let's choose a chart from &kchart;. To do so, the first step is to click on the +Insert menu item, and then +on Object. + + + +The Insert Object menu + + +The Insert Object menu + + + + +A list of the &koffice; available components appears as submenu. +Select Chart and then outline with your mouse the area you +want to put your chart in on the &kpresenter; slide. + + + +Select the area where to put the chart + + +Select the area where to put the chart + + + + + + +Once you release the mouse button, a blank chart is added on the slide. Whenever +you work in the chart, the toolbars and menubar in &kpresenter; main window are +replaced by those from &kchart;. + + + +&kchart; menus and toolbars embedded + + +&kchart; menus and toolbars embedded + + + +While you are in the chart, clicking with the &RMB; will bring the +&kchart; settings menu which allows you to modify the parameters of the chart. +Please see the &kchart; user manual to get more information on how to use +&kchart;. + +Click anywhere with the &LMB; outside the chart to go back to +&kpresenter; slide. + +A single click on the chart will allow you to drag it to change its +location and also to drag the borders to make it bigger as with any other +&kpresenter; object. Double click on the chart to get into &kchart; mode and +modify any of the chart property. + + + + +Add a shadow to the title text + + +Let's continue enhancing our title page by adding a shadow +behind the title. Right click anywhere on the +title text. This achieves two things: the text box containing the title +is selected, and a menu pops up. + + + +Select the Shadow Objects... option in the popup menu. + + + +The context menu + + +The context menu + + + + +The Shadow dialog pops up. The distance between the +shadow and the text is currently 0 so the shadow cannot be seen (this +part of the dialog box is highlighted in red.) + + + +The Shadow dialog + + +The Shadow +dialog + + + + +Increase the distance value to 3. The effect of changing the distance +can be seen in the preview window. Now click OK. + + + +Adding a shadow to the title + + +Adding a shadow to the title + + + + +Now the title has a shadow! + + + +The new shadowed title + + +The new shadowed title + + + + + + +Change the color of the title text + + +Let's finish by changing the color of the title text from black to +blue. To do so, select the title text by double-clicking the text box and select the text. + + + +Open the Select Color dialog by clicking on the dark blue A +icon on the right side of the Text toolbar (this icon has +a Color... tooltip) or choose the Text menu and then click on +Color... and change the color to blue. + + +The color palette + + +The color palette + + + + +Click OK in the Select Color dialog. Changing the color of +the selected text to blue changes its appearance. The exact color that +highlighted text turns depends on your system color scheme. + + + +Highlighted text + + +Highlighted text + + + + +Now click away from the text to de-select it. + + + +The finished title + + +The finished title + + + + +Now that there are two slides, why not try a slide show! To start the +slide show, press the play button (the blue double arrow) on +the Slide Show toolbar. The first slide should appear on your screen. + + + +The first slide + + +The first slide + + + + +To advance from the first slide to the next, just click anywhere on the +screen, or use the Page Down key. + + + +The second slide + + +The second slide + + + + +To exit the slide show, right click, and then +select the End option from the +popup menu. + + + + +
    diff --git a/doc/kpresenter/zoomfactor.png b/doc/kpresenter/zoomfactor.png new file mode 100644 index 000000000..499738905 Binary files /dev/null and b/doc/kpresenter/zoomfactor.png differ diff --git a/doc/krita/Makefile.am b/doc/krita/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/krita/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/krita/README.SCREENSHOTS b/doc/krita/README.SCREENSHOTS new file mode 100644 index 000000000..bc1d55bd0 --- /dev/null +++ b/doc/krita/README.SCREENSHOTS @@ -0,0 +1,7 @@ +Note for translators: + +The file "mountains.png" is the original photo used for creating the screenshots +in the Dialogs section. + + +- ASK \ No newline at end of file diff --git a/doc/krita/commands-dialogs.docbook b/doc/krita/commands-dialogs.docbook new file mode 100644 index 000000000..758a4924c --- /dev/null +++ b/doc/krita/commands-dialogs.docbook @@ -0,0 +1,1411 @@ + +Dialogs + + +This section describes &krita;'s dialog windows. + + + +Dialogs for working with images + + +The <guilabel>Color Range</guilabel> dialog + + + +The Color Range dialog + + + + + +The Color Range dialog + + + + + + + +You can create a selection based on the color values of pixels here. In the +dropdown box, choose which color range you want to select. Pixels will be +selected according to their color value on this scale (⪚ a fully yellow +pixel would score maximally on the yellow scale and on the red and green scales). +If you check the Invert box, the selection becomes inverted: +pixels will become selected if they have a lower value in the specified range instead. +You can choose whether the current selection should be +added to or subtracted from the color range selection by clicking the +respective option: Add to current selection or +Subtract from current selection. Choose +Select to actually perform the selection or +Deselect to remove these pixels from the selection. + + + + + +The <guilabel>Convert Image Type</guilabel> dialog + + + +The Convert Image Type dialog + + + + + +The Convert Image Type dialog + + + + + + + +This dialog allows you to convert your image from one color space to another. +The Target color space and Destination ICM +profile are used to set to which colorspace and profile the image +will be converted. You can influence how this conversion is done with the +Rendering Intent option. + + +With Perceptual conversion, the source color space is +mapped linearly to the destination color space. If the destination color space +accepts a lesser color range than the source, shifts may occur +because the range is compressed. Relative colorimetric +conversion converts every color to the closest color in the destination color +space. This may mean that a certain color range is mapped to one color in the +destination color space. Saturation means that fully +saturated colors will remain fully saturated, even if this means that the +actual color is changed. With Absolute colorimetric +conversion, the same approach is used as with Relative +colorimetric, but the white point of the color space (the value +designating the color white) is not changed to match the new color space, +which may result in unwanted changes to near colors. + + + + + +The <guilabel>Image Properties</guilabel> dialog + + + +The Image Properties dialog + + + + + +The Image Properties dialog + + + + + + + +In this dialog you can change a couple of image properties. First of all, the +Name of the image. If you did not set a name earlier +(that can also be done when creating the image), it will have a default name +like Image1. Then, you can set its size (determined by the +Width and Height in pixels and +the Resolution in dots per inch) and the color profile to +be used (Profile). Finally, you can fill in the +Description field with any information you want to add to +the image. + + + + + +The <guilabel>Image Size</guilabel> dialog + + + +The Image Size dialog + + + + + +The Image Size dialog + + + + + + + +This dialog lets you resize your image. In the top part, you can choose the +way the image is resized. If you choose Resize, the size +of the image is changed, but its layers (which contain the actual contents) +will not be modified. So, when you double the height and width of the image, +your original image will occupy the top-left quarter part of your new image. +On decreasing the size of your image, the image layers will stretch out over +the image borders, unless you choose Crop layers on image +resize, which will crop all layers to the new image size. + +With Scale, the image layers will be resized with the +image. So increasing the image size will actually enlarge the contents, and +similar for decreasing. + +Under Pixel dimensions, you can set which new size you +want the image to have. The original size is given as a reference. The new +size can be set both as pixels or as a percentage, with 100% being the +original size. If you select Constrain proportions, the +new width and height will always be set to the same percentage. For example, +if you have an image of 200 x 100 pixels, and set the width to 20 pixels, the +height will automatically be changed to 10. With this checkbox unselected, you +can also resize the image non-proportionally. + +The Filter: dropdown box can be used to select a +different algorithm for determining the colors of the pixels in the newly +resized image that did not correspond to a pixel in the old image (the +calculated corresponding location in the old image was located in between +pixels). BSpline uses a 4 x 4 pixel grid and results into a quite high +blurring. Bell is quite fast while resulting in a reasonably smooth image. +Box is the fastest method, but yields the least appealing result. Hermite +keeps the image quite sharp, while smoothing it as well, and is reasonably +fast. Lanczos3 results in sharp images, but is very slow. Mitchell (the +default) is not very fast, but often yields a good intermediate result. +Triangle/Bilinear uses the 2 x 2 pixel grid around the calculated location +resulting in relatively sharp lines. + + + + + +The <guilabel>Rotate Image</guilabel> dialog + + + +The Rotate Image dialog + + + + + +The Rotate Image dialog + + + + + + + +With this dialog, you can rotate the image. The top part of the dialog shows +the result of the rotation in the form of a change in dimension (if any). +Under Direction you can choose between +rotating clockwise and counter-clockwise. Under Angle, +you can set the amount of rotation. 90, 180 and 270 degrees can be selected +using the respective option button, other amounts need to be specified with +the Custom spin box. + + + + + +The <guilabel>Separate Image</guilabel> dialog + + + +The Separate Image dialog + + + + + +The Separate Image dialog + + + + + + + +With this dialog, you can separate (part of) your image. Every color component +(channel) will be put into a separate layer or image. At the top of the +dialog, the current color model is shown. Below that, a couple of options can +be set. + + +Under Source, you can choose what part of the image to +separate. The two options are Current layer, which +(obviously) only uses the currently selected layer and Flatten all +layers before separation, which uses the entire image. + + +Under Output, you can choose where the result of the +separation should be written to: either to a couple of layers, or to a couple +of images. + + +Under Alpha Options, you can choose what should be done +with the alpha channel of the selected layer(s). It can be copied to each new +channel, be discarded, or separated on its own. + + +The two options at the bottom of the dialog, finally, determine whether the +source should be downscaled to 8 bit colors (if it contains more), and whether +the output should be in color (default is to separate the channels to grayscale +values). + + + + +The <guilabel>Shear Image</guilabel> dialog + + + +The Shear Image dialog + + + + + +The Shear Image dialog + + + + + + + +This dialog allows you to shear your image. By shearing, the bounding +rectangle of your image is transformed into a parallellogram. One pixel +row/column is kept in place, the next one is shifted by a certain amount, the +next one by the same amount relative to the previous one, etcetera. +The X and Y shearing angles can be set using the two spin boxes. + + + + + +The <guilabel>Substrate</guilabel> dialog + + + +The Substrate dialog + + + + + +The Substrate dialog + + + + + + + +(This dialog is still to be described.) + + + + + + + +Dialogs for working with layers + + +The <guilabel>Convert Layer Type</guilabel> dialog + + + +The Convert Layer Type dialog + + + + + +The Convert Layer Type dialog + + + + + + + +This dialog is exactly the same as the Convert Image +Type dialog, which converts an entire image instead of a +single layer. See the description there for details. + + + + + +The <guilabel>Drop Shadow</guilabel> dialog + + + +The Drop Shadow dialog + + + + + +The Drop Shadow dialog + + + + + + + +With this dialog, you can add a drop shadow effect to the current layer. +Select the X and Y offsets (displacements) of the shadow relative to the +original layer with the two topmost spin boxes. The Blur +radius spinbox determines the radius in which the shadow will be +blurred (to achieve a smooth transition at the shadow border). If you want +a special color for the shadow, you can choose one with the +Color field. The Opacity slider and +spinbox can be used to make the shadow more or less transparent. Disable the +Allow resizing checkbox if you don't want the layer to be +resized in order to give it a shadow. + + + + + +The <guilabel>Histogram</guilabel> dialog + + + +The Histogram dialog + + + + + +The Histogram dialog + + + + + + + +This dialog shows a histogram for the current layer. With the +Method: settings, you can choose what kind of histogram +to show. You can change the channel(s) to show with the +Channels: listbox, and the scale on which it should be +drawn with the Linear and +Logarithmic radio buttons. Under the preview, there are +buttons available to zoom in to, and move over, the histogram. These are +activated for 16-bit colorspace layers. + + + + + +The <guilabel>Layer Properties</guilabel> dialog + + + +The Layer Properties dialog + + + + + +The Layer Properties dialog + + + + + + + +This dialog is in essence the same as the New Layer dialog, with the difference that +you cannot change its colorspace or profile anymore. These properties are +shown, though, to keep the information complete. + + + + +The <guilabel>Layer Size</guilabel> dialog + + + +The Layer Size dialog + + + + + +The Layer Size dialog + + + + + + + +This dialog allows you to resize the current layer. +Under Pixel dimensions, you can set which new size you +want the layer to have. The original size is given as a reference. The new +size can be set both as pixels or as a percentage, with 100% being the +original size. If you select Constrain proportions, the +new width and height will always be set to the same percentage. For example, +if you have a layer of 200 x 100 pixels, and set the width to 20 pixels, the +height will automatically be changed to 10. With this checkbox unselected, you +can also resize the layer non-proportionally. The Filter: +dropdown list can be used to select a different algorithm for resizing the +layer. + + + + + +The <guilabel>New Adjustment Layer</guilabel> dialog + + + +The New Adjustment Layer dialog + + + + + +The New Adjustment Layer dialog + + + + + + + +In this dialog, you can select the type of adjustment layer to add to the +image. In the left-hand list, you can see the available adjustment layers, +each with a preview. When you select one, the Preview +will change to show a correctly scaled preview of what the result of the +adjustment layer is going to be. + +You can then choose to show either the original image or the preview of the +adjustment layer with the radio buttons below the preview window. The buttons +next to these allow you to zoom in, zoom out, and refresh the preview, +respectively. The Autoupdate checkbox determines if the +preview window should update automatically after you made a change. + +The various options available for the filter that is used to create the +adjustment layer, are shown at the bottom of the dialog. See the section on +filters of this chapter for +descriptions. + + + + + +The <guilabel>New Layer</guilabel> dialog + + + +The New Layer dialog + + + + + +The New Layer dialog + + + + + + + +You can add a new layer to your image with this dialog. If you want a +descriptive name for your layer, you can fill one in at +Name:. You can select the desired colorspace for the new +layer from the Colorspace: list, and the specific +color profile for that colorspace at Profile:. +You can preset the layer's Opacity (you can change it later with the slider in +the Layer box), and choose the mode with which the layer should be composited +onto the final image. + + + + + +The <guilabel>Rotate Layer</guilabel> dialog + + + +The Rotate Layer dialog + + + + + +The Rotate Layer dialog + + + + + + + +This dialog, similar to the Rotate Image +dialog, allows you to rotate the current layer. You can choose the +direction in which to rotate and the amount to rotate the layer by. + + + + + +The <guilabel>Shear Layer</guilabel> dialog + + + +The Shear Layer dialog + + + + + +The Shear Layer dialog + + + + + + + +This dialog works the same as the Shear Image +dialog, except that it operates on the current layer instead of on the +entire image. + + + + + + + +Dialogs for working with filters + + +All filter dialogs consist of a filter-specific part, at the left, and a +generic part, at the right. The generic part contains a preview window, which +you can configure using the controls below it. Choose +Preview or Original depending on +whether you want the preview window to show the preview of the filter effect +or the original image. The four buttons at the bottom right allow you to zoom +in and zoom out, set the zooming factor to 100% (this shows the image at its +original size), and refresh the preview, respectively. Furthermore, the option +Autoupdate determines if the preview window is updated +automatically. If you uncheck this checkbox, you will have to refresh the +preview yourself. + + + +The <guilabel>Blur</guilabel> dialog + + + +The Blur dialog + + + + + +The Blur dialog + + + + + + + +This dialog allows you to customize the way your image is blurred. The +Half-width and Half-height spinboxes +determine the size of the areas of your image that are consecutively blurred. +With the Strength spinbox you can set the strength with which the +blurring should be applied, and with the Angle spinbox +you can add a rotation to the area. The Shape setting, +finally, allows you to choose between circular and rectangular areas + + + + + + +The <guilabel>Brightness / Contrast</guilabel> dialog + + + +The Brightness / Contrast dialog + + + + + +The Brightness / Contrast dialog + + + + + + + +With this dialog, you can customize the brightness and contrast of your image. + +The curve diagram has a histogram-like background that shows you the abundance +of various brightness levels. The curve itself (initially a diagonal line from +bottom left to top right) determines to which new brightness level (on the +vertical axis) pixels with a certain original level (on the horizontal axis) are +to be mapped. For example, the default diagonal line from bottom left to top +right sets every original pixel to its own brightness value, meaning no +change. A horizontal line means that all pixels will get the same brightness. +This means minimal contrast, the brightness itself is indicated by the height +at which the line is placed. + +You can click on a handle (red circle) to select it (a selected handle is +indicated by a filled circle) and drag it around to change the shape of the +curve. The curve will be drawn smoothly through the handles (always +strictly from left to right). If you click on the curve, a handle is added to +it at that position. Clicking somewhere else in the image will also add a +handle at that point. You can press Delete to delete the +currently selected handle. + + + + + +The <guilabel>Bumpmap</guilabel> dialog + + + +The Bumpmap dialog + + + + + +The Bumpmap dialog + + + + + + + +You can apply a bumpmap effect and customize it using this dialog. One layer +is used as bumpmap layer: it is read as grayscale image and the gray values of +its pixels are used to to distort the other layer for creating the depth +illusion. High grey values, &ie; more white, mean a larger height, small +values, &ie; near black, mean a smaller height — or a larger depth, the +height can get below sealevel. A light source, shining +from above on the image that lies on the ground, +is simulated to determine the depth and direction of the shadows. + +The first option in this dialog offers you the selection of the +Bumpmap layer. + +Under Type, you can select what kind of bumpmap to be +applied. There are three types, Linear (a normal +application of the bumpmap), Spherical (focusing on the +extremes, that is, the shadow and highlight values) and +Sinusoidal (focusing on the midtone values). + +Then, there are three options to modify the bumpmap apart from its +algorithmical application. With Compensate for darkening, +the image is restored to about its original average lightness if using the +bumpmap filter would make it darker. The Invert bumpmap +option creates an inverted bumpmap (high and low are reversed). With +Tile bumpmap, a bumpmap layer that is smaller than the +layer it is applied to, will be tiled (repeatedly) to cover the entire layer. + +Under Settings, you can select the mathematical +parameters for the bumpmap. First of all, Azimuth (the +angle of the light source in the X-Y plane), Elevation +(the height of the simulated light source above the surface in degrees, with 0 +degrees being on the ground and 90 degrees being vertically above the image), +and Depth (the maximal vertical distortion of the image). + +Then, there are the X offset and Y +offset, with which you can displace the bumpmap layer relative to +the destination layer, Water level (the depth seen as +neutral), and Ambient light, which determines the +relative amount of ambient (environmental) light. + + + + + +The <guilabel>Color Adjustment</guilabel> dialog + + + +The Color Adjustment dialog + + + + + +The Color Adjustment dialog + + + + + + + +This dialog allows you to customize the Color Adjustment filter. You can use +the curve (see the section on Brightness / +Contrast for a description on the curve) to determine the mapping +from old to new color levels, for each of the channels separately. + + + + + +The <guilabel>Color to Alpha</guilabel> dialog + + + +The Color to Alpha dialog + + + + + +The Color to Alpha dialog + + + + + + + +With this dialog, you can make parts of the image having a certain color +transparent (officially alpha-transparent). You can select the +color you want to remove from the image (replacing it with transparency) with +the Color swatch, and how much a color may differ from +the selected one before it is considered not to match, with the +Threshold spinbox. Setting a threshold of zero (0) +ensures that only pixels with the exact matching color will be made +transparent, higher thresholds will make other colors match as well. + + + + +The <guilabel>Color Transfer</guilabel> dialog + + + +The Color Transfer dialog + + + + + +The Color Transfer dialog + + + + + + + +This dialog lets you copy the colors from one image (the Reference +Image) to the current one. The colors in both images are compared +and each color in the one you are working with, will be replaced by the +nearest one in the reference image. + + + + + + + +The <guilabel>Custom Convolution</guilabel> dialog + + + +The Custom Convolution dialog + + + + + +The Custom Convolution dialog + + + + + + + +With this filter, you can apply a customized distortion effect to your image. +The nine spinboxes at the top left determine the distortion. Each pixel is +assigned a new value based on these values: the old color values of the pixel +inself and the eight surrounding pixels are each multiplied by the values in +the respective spinboxes, these results are added, and the final result is the +new color value for the pixel. Before being applied, this final result can be +multiplied with a certain Factor: or a certain +Offset: can be added to it. + +In the example screenshot, each pixel is assigned a new value based on its +own (the 1 in the center), to which are added the values of the pixels to its +top right and directly below it (each with a factor of 1, &ie; the actual +value, since multiplying by one has no effect), and from which are subtracted +the values of the pixels to its bottom right and directly above it (added with +a factor of -1, so subtracted by a factor of 1). + + + + + +The <guilabel>Emboss</guilabel> dialog + + + +The Emboss dialog + + + + + +The Emboss dialog + + + + + + + +This dialog contains just one option, the Depth: slider +and spinbox which determines the depth of the embossing effect. + + + + + +The <guilabel>Filters Gallery</guilabel> dialog + + + +The Filters Gallery dialog + + + + + +The Filters Gallery dialog + + + + + + + +This dialog can be used to get a quick overview of what the various available +filters do. The filters are in turn applied to the current image and the +results are put in the left list box as thumbnails. If you select one, its +options become available in the Configuration section. +See the description of the respective filter for details. + + + + + +The <guilabel>Gaussian Noise Reduction</guilabel> dialog + + + +The Gaussian Noise Reduction dialog + + + + + +The Gaussian Noise Reduction dialog + + + + + + + +This dialog allows you to customize a Gaussian noise reduction. The +Threshold setting is a measure for how much noise should +be removed (&ie; how quickly a lonely pixel should be made +equal to its surroundings), while the Window Size setting +determines the radius of the area considered when changing pixels. + + + + + +The <guilabel>Lens Correction</guilabel> dialog + + + +The Lens Correction dialog + + + + + +The Lens Correction dialog + + + + + + + +With this dialog, you can fix an image which is distorted due to common lens +anomalies. You can specify a Distortion correction, +indicating how much the image should be corrected if its +concaveness / convexness is not right, for areas near the center and areas +near the edges. If you want an asymmetrical correction, you can specify +different X and Y coordinates for +the center (in percentages of the total width and height, measured from the +top left). + +You can also correct a too light or too dark image with the +Brightness correction spinbox. + + + + + +The <guilabel>Image Restoration</guilabel> dialog + + + +The Image Restoration dialog + + + + + +The Image Restoration dialog + + + + + + + +Using this dialog, you can specify exactly how the image restoration should +be done. This filter tries to increase the quality of an image, for instance +by removing scratches. Various options are available to customize its +behaviour. + +(Unfortunately, these are not described as of yet.) + + + + + +The <guilabel>Oilpaint</guilabel> dialog + + + +The Oilpaint dialog + + + + + +The Oilpaint dialog + + + + + + + +This dialog can configure two parameters for the associated filter. The +Brush size: setting determines the size of the brush that +is used to simulate the oilpaint effect, the Smooth: +setting specifies if the difference in colors between adjacent +swatches may be large (low smoothness) or should be small (high +smoothness). + + + + + +The <guilabel>Pixelize</guilabel> dialog + + + +The Pixelize dialog + + + + + +The Pixelize dialog + + + + + + + +On this dialog, you can adjust two settings. Pixel width: +and Pixel height: indicate the width and height of the +area that should be taken together and averaged to form one new, large +pixel. + + + + + +The <guilabel>Raindrops</guilabel> dialog + + + +The Raindrops dialog + + + + + +The Raindrops dialog + + + + + + + +This filter can be configured using the settings Drop +size: (the average diameter of the raindrops), +Number: (the number of raindrop effects that should be +added to the image), and Fish eyes: (the percentage of +raindrops that should be rendered as fisheye lens effects instead of plain +raindrop effects). + + + + +The <guilabel>Random Noise</guilabel> dialog + + + +The Random Noise dialog + + + + + +The Random Noise dialog + + + + + + + +This filter adds random noise (speckles, or something similar) to your image. +There are two customizable settings: the amount of noise +(Level, as a percentage) and the +Opacity of the noise (should the original color still be +a bit visible or not). + + + + +The <guilabel>Random Pick</guilabel> dialog + + + +The Random Pick dialog + + + + + +The Random Pick dialog + + + + + + + +In this dialog, you can specify parameters for the Random Pick +filter. The Level setting determines how much pixels will +be affected (measured as a percentage), the area which is looked in to take a +new color for a pixel is set with the Size of the window +setting, and the Opacity of the modifications can be set as +well. + + + + + + +The <guilabel>Round Corners</guilabel> dialog + + + +The Round Corners dialog + + + + + +The Round Corners dialog + + + + + + + +This dialog has one setting: the radius of the rounded corners. + + + + + +The <guilabel>Small Tiles</guilabel> dialog + + + +The Small Tiles dialog + + + + + +The Small Tiles dialog + + + + + + + +In this dialog, you can set the amount of subdivisions with the +Number of tiles settings. + + + + + +The <guilabel>Sobel</guilabel> dialog + + + +The Sobel dialog + + + + + +The Sobel dialog + + + + + + + +Here, you can set the parameters for the Sobel edge +detection filter. First of all you can determine which directions to sobel in: +horizontally, vertically, or both. The Keep sign of +result setting does not affect regular images. +Make image opaque determines whether the resulting image +is opaque or transparent. + + + + + +The <guilabel>Unsharp Mask</guilabel> dialog + + + +The Unsharp Mask dialog + + + + + +The Unsharp Mask dialog + + + + + + + +This dialog offers three options for the sharpening filter +Unsharp Mask: the radius (Half-size) +of the mask, the Amount of sharpening that should be +done, and the Threshold level. + + + + + +The <guilabel>Wave</guilabel> dialog + + + +The Wave dialog + + + + + +The Wave dialog + + + + + + + +For both the horizontal and the vertical components of the wave distortion +(note: a vertical wave means that the vertical position is dependent on the +horizontal one, and hence looks like a W), +you can determine four settings here. The Wavelength (a +shorter wavelength means a more erratical wave), the +Shift (which point of the wave should be started at), the +Amplitude (the amount of distortion), and the +Shape (Sinusoidal or rounded, +versus Triangle or pointy). + + + + + +The <guilabel>Wavelet Noise Reduction</guilabel> dialog + + + +The Wavelet Noise Reduction dialog + + + + + +The Wavelet Noise Reduction dialog + + + + + + + +The only setting here, Threshold, indicates how easily pixels +are seen as noise that should be removed and made equal to the surrounding area. + + + + + + + +Miscellaneous dialogs + + +The <guilabel>Add Palette</guilabel> dialog + + + +The Add Palette dialog + + + + + +The Add Palette dialog + + + + + + + +With this dialog, you can add a custom color palette to &krita;. Fill in the +name for your palette in the text field at the top. Then make the palette: use +the button Add New Color... to add a color to the palette +and Remove Selected Color to remove the currently +selected color. Click the button Add to Predefined +Palettes to add your newly created palette to the palette list, or +just choose OK when you're done. + + + + + +The <guilabel>Document Information</guilabel> dialog + + + +The Document Information dialog + + + + + +The Document Information dialog + + + + + + + +This dialog is the same as in other &koffice; programs. You can enter various +information about your document here, which will be saved with the document so +that you can retrieve it later to review or edit. + + + +On the General tab, you can enter the title, subject and +keywords, as well as an abstract. On the bottom of this tab, some statistical +information is displayed. On the Author tab, you can +store information about yourself. The third tab, User-defined +Metadata, allows you to store any other information. + + + + + + + diff --git a/doc/krita/commands-menus.docbook b/doc/krita/commands-menus.docbook new file mode 100644 index 000000000..b3abdcc93 --- /dev/null +++ b/doc/krita/commands-menus.docbook @@ -0,0 +1,2158 @@ + +Menus + + +Some of &krita;'s menus are standard in &kde; or &koffice;, while others are +particular to &krita;. The File menu contains commands for +manipluating files. In the Edit menu, you can find commands +that do things with the current selection. With the commands from the +View menu, you can change the way you look at the image. +The Image menu contains commands that change the entire +image, like converting all layers to another color model or resizing or +scaling the image. The Layer menu is like the +Image menu, but the commands only work on the current +layer. The Select menu contains commands to create and +manipulate selections. The Filter menu contains all the +filters you have installed. These work on the current layer. The +Scripts menu contains entries for working with scripts. +The Settings menu is again common to &koffice; and allows +you to manipulate the toolbars, shortcuts and configuration of &krita;. +Finally, the Help menu gives you access to various +(hopefully helpful) information, such as this handbook. + + + + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N +File +New + +Creates a new document. This displays the +New document dialog, standard across &koffice;, in which +you can choose to start with a blank document of a certain type, or to open a +recently opened document. + + + + +&Ctrl;O +File +Open... + +Opens an existing document. +Because this uses the usual &kde; Open Document +dialog to let you select a file, you can open files via various protocols +(ftp, fish, etcetera). + + + + + +File +Open Recent + +Opens a recently +opened document. Clicking this menu item will show a +submenu with the ten most recently opened documents in which +you can quickly open an image you have been working on lately. + + + + +&Ctrl;S +File +Save + +Saves the document. If you +haven't saved the document before, you will get the Save +Document As dialog, otherwise the document will be saved under +its current name. + + + + +File +Save As... + +Saves the document under a different name. +The default &kde; dialog is used, so saving remotely via ftp +or ssh (fish) is perfectly possible. + + + + +File +Reload + +Reloads the current document +from disk. All changes since you last saved the document +will be lost. + + + + +File +Import... + +Opens an existing document. Unlike +FileOpen, +this does not load the actual document, but only its contents: you receive a +copy of the chosen file as a new document. + + + + + +File +Export... + +Saves the document under a different name. (For +the moment, this is the same as +FileSave +As....) + + + + + +File +Mail... + +Sends the document via email. The default &kde; +mail compose window will be used. + + + + +&Ctrl;P +File +Print... + +Prints the document. You will see the usual +&kde; print dialog appear. + + + + +File +Print Preview... + +Shows a preview of what the printed document +will look like. + + + + +File +Document Information + +Opens the Document +Information dialog. This dialog can be used to add +various information to the image, like title, subject, keywords, author +information, and any other information you want to save with the +image. + + + + +&Ctrl;W +File +Close + +Closes the document. + + + + +&Ctrl;Q +File +Quit + +Quits &krita;. + + + + + + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + + +&Ctrl;Z +Edit +Undo + +Undoes the last action carried out. Actions +(like painting a stroke, filling an area, etcetera) are stored on +a stack. The last action you did will be undone, and the image is +restored to the state before that. Immediately choosing +Undo again will undo the action that was carried +out before the one just undone, etcetera. + + + + +&Ctrl;&Shift;Z +Edit +Redo + +Redoes the last action undone. As described at +Undo, a series of actions can be undone. With +Redo, an action undone is carried out again, and if +more actions have been undone before that, you can redo these in +turn. + + + + +&Ctrl;X +Edit +Cut + +Cuts the selection to the +clipboard. The current selection is put on the &kde; +clipboard, and the selection is cleared. + + + + +&Ctrl;C +Edit +Copy + +Copies the selection to the +clipboard. + + + + +&Ctrl;V +Edit +Paste + +Pastes the contents of the +clipboard. + + + + +Edit +Paste into New Image + +Pastes the contents of the +clipboard as a new image. + + + + +Edit +Clear + +Clears the selection. + + + + +&Alt;&Backspace; +Edit +Fill with Foreground Color + +Fills the selection with the current foreground +color. The current foreground color is shown in the top left color +square of the Colors palette. + + + + +&Backspace; +Edit +Fill with Background Color + +Fills the selection with the current background +color. The current background color is shown in the bottom right color +square in the top left corner of the Colors +palette. + + + + +Edit +Fill with Pattern + +Fills the selection with the current pattern. +The current pattern is shown on the Brush Shapes toolbar, +usually at the top right of the &krita; window. + + + + +Edit +Resources + +Contains options for working with color +palettes. + + + + +Edit +Resources +Add New Palette... + +Opens the Add Palette +dialog. You can create a custom color palette +here. + + + + +Edit +Resources +Edit Palette... + +Opens the Edit Palette +dialog. Choose a color palette to edit from this list. You will then be +given the same dialog as with Add Palette, with the +difference that you edit the chosen color palette instead of adding a new +one. + + + + + + + + + + + +The <guimenu>View</guimenu> Menu + + + + + +&Ctrl;&Shift;F +View +Full Screen Mode + +Switches between normal view +and full screen view. In full screen view, the title +bar is hidden and the actual application window is resized to the entire +screen. + + + + +View +New View + +Opens a new view for the +current document. A new application window is opened +so that you can have two different views of the same document, for example +to work on different areas at the same time, or to look at an area at different +zoom levels simultaneously. Changes you make to the document in one view are +immediately visible in other views. + + + + +&Ctrl;&Shift;W +View +Close All Views + +Closes all views. + + + + +View +Split View + +Splits the current view. The +drawing area will be split into two parts, which can be used +just like two views in different windows. + + + + +View +Remove View + +Unsplits the view. The second +view (the bottom or right one) will be closed and the first one will remain +visible. + + + + +View +Splitter Orientation + +Changes the way the split +view is displayed. + + + + +View +Splitter Orientation +Vertical + +Changes the orientation of +the splitter to vertical. The two split +views will be positioned side by side. + + + + +View +Splitter Orientation +Horizontal + +Changes the orientation of +the splitter to horizontal. The two split views will +be positioned above each other. + + + + +&Ctrl;+ +View +Zoom In + +Zooms in on the view. The view +will be more detailed, but a smaller area will be visible at the +same time. + + + + +&Ctrl;- +View +Zoom Out + +Zooms out of the view. A larger +area will be visible at the same time, but it will be less +detailed. + + + + +&Ctrl;0 +View +Actual Pixels + +Zooms the view to actual pixel +level. (1:1 scale) + + + + +View +Actual Size + +Zooms the view to the actual image +size. + + + + +View +Fit to Page + +Zooms the view so that the image fills the available +workspace. + + + + +&Ctrl;R +View +Show Rulers + +Toggles display of the +rulers on and off. + + + + +View +Show Grid + +Toggles display of the +grid lines on and off. + + + + +View +Grid Spacing + +Contains various options to set the distance between +grid lines. The available spacing options are +1x1, 2x2, +5x5, 10x10, +20x20, and 40x40. + + + + + +View +Show Perspective Grid + +Toggles display of the perspective grid on and off. + + + + + + +View +Clear Perspective Grid + +Clears the perspective grid. (All grid lines +that were created, are deleted.) + + + + + +View +Palettes + +Allows you to toggle the +display of the various palettes on and off. The +default view of &krita; shows all palettes, and the items are listed as Hide +palette therefore. When a certain palette is hidden, +the corresponding menu item changes to Show +palette. + + + + +&Ctrl;&Shift;H +View +Palettes +Hide All Palette Windows + +Hides all palettes. + + + + +View +Palettes +Hide Overview + +Hides the +Overview palette. + + + + +View +Palettes +Hide HSV + +Hides the +HSV palette. + + + + +View +Palettes +Hide RGB + +Hides the +RGB palette. + + + + +View +Palettes +Hide Gray + +Hides the +Gray palette. + + + + +View +Palettes +Hide Palettes + +Hides the +Palettes palette. + + + + +View +Palettes +Hide Layers + +Hides the Layers +palette. + + + + +View +Palettes +Hide Scripts Manager + +Hides the Scripts Manager. + + + + + +View +Palettes +Hide Histogram + +Hides the +Histogram palette. + + + + +View +Palettes +Hide Watercolors + +Hides the Watercolors +palette. + + + + +View +Palettes +Hide Brush, Ellipse, Filter tool, Line, Polygon &etc; + +Hides the palette of the selected +Tool. + + + + +View +Wetness Visualisation + +Toggles indication of the wetness of watercolor paint +on and off. + + + + + + + + + + + +The <guimenu>Image</guimenu> Menu + + + + + +Image +Image Properties + +Opens the Image +Properties dialog, +in which you can change the image name, size, +profile and description. + + + + +Image +Resize Image to Size of Current Layer + +Resizes the image to the +size of the currently active layer. + + + + +Image +Substrate... + +Opens the Substrate dialog. + + + +Image +Rotate + +Rotates the image. + + + + +Image +Rotate +Rotate Image... + +Opens the Rotate Image +dialog. + + + + +Image +Rotate +Rotate Image CW + +Rotates the image 90 degrees +clockwise. + + + + +Image +Rotate +Rotate Image CCW + +Rotates the image 90 degrees counterclockwise +(270 degrees clockwise). + + + + +Image +Rotate +Rotate 180 + +Rotates the image 180 degrees. + + + + +Image +Convert Image Type... + +Opens the Convert All +Layers dialog. This allows you to convert the image +to a different color space. Apart from the color space, the profile and +rendering intent can be specified as well. + + + + +Image +Separate Image... + +Opens the +Separate Image +dialog. You can separate the image into layers for each +individual colorspace component there. + + + + +Image +Change Image Size... + +Opens the +Image Size +dialog . You can resize or scale the image using various +algorithms here. + + + + +Image +Shear Image... + +Opens the Shear Image +dialog. You can shear the image in X or Y directions, +or both. + + + + + + + + + + +The <guimenu>Layer</guimenu> Menu + + + + + + +Layer +New + +Creates a new layer. + + + + +&Ctrl;&Shift;N +Layer +New +Add... + +Opens the +New Layer +dialog. This will create a new empty +layer. You can set the name, opacity, composite mode and +layer type. + + + + +Layer +New +Object Layer + +Creates a new layer for a +given &koffice; object type. + + + + +Layer +New +Object Layer +Scalable Graphics + +Creates a new layer for an +embedded &karbon14; object. + + + + +Layer +New +Object Layer +Text Documents + +Creates a new layer for an +embedded &kword; document. + + + + +Layer +New +Object Layer +Flowchart & Diagram + +Creates a new layer for an embedded +&kivio; object. + + + + +Layer +New +Object Layer +Slide Presentations + +Creates a new layer for an embedded +&kpresenter; object. + + + + +Layer +New +Object Layer +Image Object + +Creates a new layer for an +embedded &krita; object. + + + + +Layer +New +Object Layer +Report Template + +Creates a new layer for an embedded +&kugar; Designer object. + + + + +Layer +New +Object Layer +Chart + +Creates a new layer for an +embedded &kchart; object. + + + + +Layer +New +Object Layer +Formula Editor + +Creates a new layer for an +embedded &kformula; object. + + + + +Layer +New +Object Layer +Report Generator + +Creates a new layer for an +embedded &kugar; object. + + + + +Layer +New +Object Layer +Project Management + +Creates a new layer for an +embedded KPlato object. + + + + +Layer +New +Object Layer +Spreadsheets + +Creates a new layer for an +embedded &kspread; document. + + + + +Layer +New +Adjustment Layer + +Opens the New Adjustment +Layerdialog. + + + + +Layer +New +Insert Image as Layer... + +Opens the Import Image +dialog. You can browse and select an image file, +which will be inserted in a new layer. + + + + +&Ctrl;&Shift;J +Layer +New +Cut Selection to New Layer + +Cuts the current selection +and inserts it as a new layer. + + + + +&Ctrl;J +Layer +New +Copy Selection to New Layer + +Copies the current selection +and inserts it as a new layer. + + + + +Layer +Remove + +Removes the current layer +and its contents. + + + + +Layer +Duplicate + +Duplicates the current +layer. + + + + +Layer +Hide/Show + +Toggles the visibility of +the current layer in the image editing window. + + + + +Layer +Mask + +Contains actions for working with layer masks. + + + + +Layer +Mask +Create Mask + + + + + + +Layer +Mask +Mask From Selection + + + + + + +Layer +Mask +Mask To Selection + + + + + + +Layer +Mask +Apply Mask + + + + + + +Layer +Mask +Remove Mask + + + + + + +Layer +Mask +Edit Mask + + + + + + +Layer +Mask +Show Mask + + + + + + +&Ctrl;] +Layer +Raise + +Moves the current layer one +level upward. + + + + +&Ctrl;[ +Layer +Lower + +Moves the current layer one +level downward. + + + + +&Ctrl;&Shift;] +Layer +To Top + +Moves the current layer to the +top. + + + + +&Ctrl;&Shift;[ +Layer +To Bottom + +Moves the current layer to +the bottom. + + + + +Layer +Save Layer as Image... + +Opens the Export Layer +dialog. The current layer will be saved to the +chosen file. + + + + +Layer +Flip on X Axis + +Flips the current layer +horizontally. + + + + +Layer +Flip on Y Axis + +Flips the current layer +vertically. + + + + +Layer +Properties + +Opens the Layer +Properties dialog. You can change the name, +colorspace, opacity, composite mode and position of the current layer +here. + + + + +&Ctrl;E +Layer +Merge with Layer Below + +Merges the current layer +with the one below it. + + + + +&Ctrl;&Shift;E +Layer +Flatten Image + +Merges all visible layers. + + + + +Layer +Rotate + +Rotates the current layer. + + + + +Layer +Rotate +Rotate Layer... + +Opens the Rotate Layer +dialog. + + + + +Layer +Rotate +Rotate CW + +Rotates the current layer 90 degrees +clockwise. + + + + +Layer +Rotate +Rotate CCW + +Rotates the current layer 90 degrees counterclockwise +(270 degrees clockwise). + + + + +Layer +Rotate +Rotate 180 + +Rotates the current layer by +180 degrees. + + + + +Layer +Histogram... + +Opens the Histogram +dialog, in which you can see histograms for the current +layer. + + + + +Layer +Convert Layer Type... + +Opens the +Convert +Current Layer dialog. You can +set various options with respect to the colorspace and +rendering intent. + + + + +Layer +Scale Layer... + +Opens the Layer +Size dialog. You can choose the new +dimensions and the resize filter to use. + + + + +Layer +Layer Effects + +Contains commands to add effects to the current layer. + + + + + +Layer +Layer Effects +Add Drop Shadow... + +Opens the Drop Shadow +dialog. This dialog can be used to add a drop shadow beneath +the current layer. + + + + +Layer +Shear Layer... + +Opens the Shear Layer +dialog. You can select the X and Y angles to shear +by. + + + + + + + + + + + +The <guimenu>Select</guimenu> Menu + + + + + +&Ctrl;A +Select +Select All + +Selects the entire +current layer. + + + + +&Ctrl;&Shift;A +Select +Deselect + +Unselects everything. + + + + +&Ctrl;&Shift;D +Select +Reselect + +Reselects the previous +unselected areas. + + + + +&Ctrl;I +Select +Invert + +Inverts the selection. +(Everything that is selected will be unselected and vice +versa.) + + + + +&Alt;&Ctrl;D +Select +Feather... + +Feathers the selection. (Adds +a soft border around it.) + + + + +Select +Similar + + + + + + +&Ctrl;H +Select +Hide Selection + +Hides the selection. The selection is still +active, but it is not made visible anymore. + + + + +Select +Grow Selection... + +Grows the selection. + + + + +Select +Shrink Selection... + +Shrinks the selection. + + + + +Select +Border Selection... + +Borders the selection. + + + + +Select +Color Range... + +Opens the Color Range +dialog. + + + + + + + + + + + +The <guimenu>Filter</guimenu> Menu + +See the Filters chapter for more +information on filters. + + + + +&Ctrl;&Shift;J +Filter +Apply Filter Again + +Repeats the last filter +action. + + + + +Filter +Adjust + +Contains various options for changing the +colors in your image. + + + + +Filter +Adjust +Auto Contrast + +Automatically changes the image to obtain as much +contrast as possible. + + + + +Filter +Adjust +Brightness/Contrast... + +Opens the +Brightness/Contrast +dialog. You can set the +brightness and contrast ratio of your image here. + + + + +Filter +Adjust +Desaturate + +Desaturates the image. This +will effectively convert the current image to grayscale, but all subsequent +painting is done with usual colors. + + + + +Filter +Adjust +Invert + +Inverts the image or +selection. (Black becomes white, blue becomes yellow, +etcetera.) + + + + +Filter +Adjust +Color Adjustment... + +Opens the Color Adjustment +dialog. You can adjust the colorspace components +of the current image there (for example, in an RGB image, you can change the +contribution of red, green, and blue to the total image). + + + + +Filter +Artistic + +Contains various filters for +artistic actions. + + + + + + +Filter +Artistic +Oilpaint... + +Opens the Oilpaint +dialog to add +an oilpaint effect to the selection or image. + + + + +Filter +Artistic +Pixelize... + +Opens the Pixelize +dialog to pixelize the image. (A block of pixels is +changed so that they all become the same, averaged color.) + + + + +Filter +Artistic +Raindrops... + +Opens the Raindrops +dialog to add a raindrops effect to the selection or +image. + + + + +Filter +Artistic +Dry the Paint + +Dries wet paint. + + + + +Filter +Blur + +Contains various blur filters. + + + + +Filter +Blur +Gaussian Blur + +Performs a slight blur on the image or +selection. + + + + +Filter +Colors + +Contains filters that change the image colors. + + + + +Filter +Colors +Color to Alpha + + + + + + +Filter +Colors +Color Transfer + +Opens the Color Transfer dialog +to give the image a new look. + + + + +Filter +Colors +Maximize Channel + +Adjusts the colors of each pixel by removing color +channels that are less abundant. + + + + +Filter +Colors +Minimize Channel + +Adjusts the colors of each pixel by removing color +channels that are abundant. + + + + +Filter +Edge Detection + +Contains edge detecting filters. + + + + +Filter +Edge Detection +Bottom Edge Detection + +Performs edge detection with the bottom sides of image +parts as references. + + + + +Filter +Edge Detection +Left Edge Detection + +Performs edge detection with the left sides of image +parts as references. + + + + +Filter +Edge Detection +Right Edge Detection + +Performs edge detection with the right sides of image +parts as references. + + + + +Filter +Edge Detection +Sobel... + +Opens the Sobel +dialog. + + + + +Filter +Edge Detection +Top Edge Detection + +Performs edge detection with the top sides of image +parts as references. + + + + +Filter +Enhance + +Contains image enhancing +filters. + + + + +Filter +Enhance +CImg Image Restoration... + +Opens the Image +Restoration dialog. + + + + +Filter +Enhance +Custom Convolution... + +Opens the Custom +Convolution dialog. + + + + +Filter +Enhance +Gaussian Noise Reduction... + + + + + + +Filter +Enhance +Mean Removal + +Sharpens the image or selection by aggravating color +borders. + + + + +Filter +Enhance +Sharpen + +Sharpens the image or selection. + + + + +Filter +Enhance +Unsharp Mask + +Applies an unsharp mask to the image or +selection. + + + + +Filter +Enhance +Wavelet Noise Reducer + +Reduces noise in the image or +selection. + + + + +Filter +Emboss + +Contains emboss filters. + + + + +Filter +Emboss +Emboss Horizontal & Vertical + +Embosses the image or selection on the two main +directions. + + + + +Filter +Emboss +Emboss with Variable Depth... + +Opens the Emboss +dialog. + + + + +Filter +Emboss +Emboss in All Directions + +Embosses the image or +selection. + + + + +Filter +Emboss +Emboss Horizontal Only + +Embosses the image or selection on the horizontal axis +only. + + + + +Filter +Emboss +Emboss Laplascian + +Embosses the image or selection using the Laplace +technique. + + + + +Filter +Emboss +Emboss Vertical Only + +Embosses the image or selection on the vertical axis +only. + + + + +Filter +Map + +Contains map filters. + + + + +Filter +Map +Bumpmap... + +Opens the Bumpmap +dialog. + + + + +Filter +Map +Round Corners... + +Opens the Round +Corners dialog to round off the corners of the image or +selection. + + + + +Filter +Map +Small Tiles... + +Shrinks the image or selection and then tiles +it. + + + + +Filter +Other + +Contains miscellaneous filters. + + + + +Filter +Other +Lens Correction... + +Opens the Lens Correction +dialog to correct for lens anomalies. + + + + +Filter +Other +Random Noise... + +Opens the Random Noise dialog to add +random noise to the image. + + + + +Filter +Other +Random Pick... + +Opens the Random Pick dialog to +distort the image. + + + + +Filter +Other +Wave... + +Opens the Wave dialog to distort the +image + + + + + +Filter +Filters Gallery + +Opens the +Filters +Gallery dialog. This +shows previews of the various filters and allows for easy +comparison. + + + + + + + + + + + +The <guimenu>Scripts</guimenu> Menu + + + + + +Scripts +Execute Script File + +Executes a script file. + + + + +Scripts +Script Manager + +Opens the Script Manager dialog. + + + + + + + + + + + +The <guimenu>Settings</guimenu> Menu + + + + + +Settings +Toolbars + +Contains options to display or hide the various +toolbars. + + + + +Settings +Toolbars +File + +Displays or hides the File +toolbar. + + + + +Settings +Toolbars +Edit + +Displays or hides the Edit +toolbar. + + + + +Settings +Toolbars +Navigation + +Displays or hides the Navigation +toolbar. + + + + +Settings +Toolbars +&krita; + +Displays or hides the +&krita; toolbar. + + + + +Settings +Toolbars +Brushes and Stuff + +Displays or hides the +Brushes and Stuff toolbar. + + + + +Settings +Configure Shortcuts... + +Opens the Configure Shortcuts + dialog. This dialog is common to most &kde; applications +and allows you to configure shortcuts for all actions &krita; has to +offer. + + + + +Settings +Configure Toolbars... + +Opens the Configure Toolbars +dialog. This dialog is common to most &kde; applications +and allows you to configure &krita;'s toolbars. + + + + +Settings +Configure &krita;... + +Opens the +Preferences +dialog. You can configure &krita; here to match your personal +preferences. + + + + + + + + + + + +The <guimenu>Help</guimenu> Menu +&help.menu.documentation; + + + diff --git a/doc/krita/commands-palettes.docbook b/doc/krita/commands-palettes.docbook new file mode 100644 index 000000000..3661be608 --- /dev/null +++ b/doc/krita/commands-palettes.docbook @@ -0,0 +1,769 @@ + +Palettes + + +This section describes &krita;'s palettes. The palettes are usually found at +the right hand side of &krita;'s main window. There are three palettes which +help you in customizing your images: + + + +The <guilabel>Control box</guilabel> palette +The Control box contains three tabs. You can get an +overview of the image, view a color histogram, and modify options for the +current tool. + + +<guilabel>Overview</guilabel> + + + +The Overview tab + + + + + +The Overview tab + + + + + +This tab offers you two settings. With the spinbox, slider, and +1:1 button at the bottom, you can set the zoom level +for the document. The Exposure slider and textbox can be +used to choose the exposure level for OpenEXR images. Furthermore, the +X and Y labels indicate the current +pointer position, with (0,0) being the top left corner of the canvas. + + + +<guilabel>Histogram</guilabel> + + + +The Histogram tab + + + + + +The Histogram tab + + + + + +This tab displays a color histogram showing the distribution of +colors over the image. The histogram is split up in red, green and blue +levels. + + + +<guilabel>Tool</guilabel> + +Actually, there is no tab named like this, since the tab name changes to +reflect the name of the currently selected tool. This tab shows the +customization options available for the tools that have them. + + +<guilabel>Brush</guilabel> + + +The Tool tab for Brush + + + + + +The Tool tab for Brush + + + + + +There are three options available on this tab. + +The Opacity slider and spin box are used to set the +opacity when drawing (opacity is the opposite of transparency, i.e. 100% +opaque is 0% transparent, and vice versa). + +In the Mode drop down box, you can choose a drawing +mode. This changes the actual effect that results from drawing on the image +(for example, only changing the saturation or lightness). + +With the Paint direct option, you can determine whether +you want to paint directly on the current layer, or on a temporary layer which +is then composited onto the actual layer. This makes a difference especially +when using relative low opacity values. + + + +<guilabel>Line</guilabel> + + +The Tool tab for Line + + + + + +The Tool tab for Line + + + + + +See Brush +for the description of Opacity and +Mode. The ? button shows a tip about +the usage of modifier keys. + + + +<guilabel>Rectangle</guilabel> + + +The Tool tab for Rectangle + + + + + +The Tool tab for Rectangle + + + + + +See Brush for a description of Opacity and +Mode. + +The Fill drop down box is used to specify whether the +inside of the rectangle should be filled. You can choose between three fill +options: the current foreground color, background color or pattern is +used. + + + +<guilabel>Bezier</guilabel> +See Brush for the +description of Mode and Opacity. + + + + +<guilabel>Ellipse</guilabel> +The same options as for Rectangle are +available here. + + + +<guilabel>Polygon</guilabel> +The same options as for Rectangle are +available here. + + + +<guilabel>Polyline</guilabel> +The same options as for Line +are available here. + + + +<guilabel>Star</guilabel> + + +The Tool tab for Star + + + + + +The Tool tab for Star + + + + + +The options for Rectangle are +available here, as well as two options specific to this tool. + +The Vertices drop down box is used to set the amount +of vertices (points) in the star. + +The Ratio setting defines the shape of the +star. A ratio of 0% will create a star with no inner area (when drawing the +star, the two lines that make up a star point, overlap). Increasing the ratio +will slowly make the star more outlined (the two lines are pulled +apart). A star with a ratio of 100% is a regular polygon. + + + + +<guilabel>Duplicate</guilabel> + + +The Tool tab for Duplicate + + + + + +The Tool tab for Duplicate + + + + + +The same options as for Line +are available here. In addition, there are three other options. + +With the Healing and +Healing radius options, you can specify that the +duplication should not copy the colors, but only the structure +of the source area. + +If you enable the Correct the perspective option, the +duplicate tool will follow your perspective grid. + + + + +<guilabel>Paint with Filters</guilabel> + + +The Tool tab for Paint with Filters + + + + + +The Tool tab for Paint with Filters + + + + + +Depending on the filter, you can set different options here. The +options you can set are the same as those available in the +normal settings dialog for the chosen filter. See the +Filters section in the Dialogs +chapter for more information. + + +<guilabel>Transform</guilabel> + + +The Tool tab for Transform + + + + + +The Tool tab for Transform + + + + + + +You can choose which transformation algorithm to use in the +Filter drop down box. + + + +<guilabel>Crop</guilabel> + + +The Tool tab for Crop + + + + + +The Tool tab for Crop + + + + + +Set the corner coordinates of the area that should remain with the +four spin boxes X, Y, +Width and Height. You can also +fill in Ratio to determine the Y/X ratio. Check one of +the checkboxes to have the respective value remain constant while changing the +size of the area. The drop down box can be used to select whether the entire +image or only the current layer should be cropped. Clicking the +Crop button has the same effect as double-clicking +outside the area in the image. + + + +<guilabel>Contiguous Fill</guilabel> + + +The Tool tab for Contiguous Fill + + + + + +The Tool tab for Contiguous Fill + + + + + +The same options as for Brush +are available here, as are a couple of other options. + +The setting in the Threshold slider and spin box +determines how near the color of a point should be to the color of the +starting point of the fill, in order for the fill to spread out over the +former point. A higher threshold will therefore fill areas that have less +similar colors, a lower threshold limits the spread. + +If you check the Fill entire selection checkbox, the +entire selection will be filled instead of only the neighboring area. + +Checking the Limit to current layer checkbox changes the +behavior of the fill: the extent to which the fill is done, is determined from +the current layer only instead of the entire image. + +By checking the Use pattern checkbox you can choose to +fill with the currently selected pattern instead of with the foreground color. + + + + +<guilabel>Gradient</guilabel> + + +The Tool tab for Gradient + + + + + +The Tool tab for Gradient + + + + + +The same options as for Brush +are available here, as are a couple of other options. + +The Shape drop down box can be used to select the gradient +type: Linear, Bi-Linear, Radial, +Square, Conical and Conical Symmetric. + +The Repeat option determines whether the gradient is +repeated if it does not fill the entire image. With None, the colors on the +ends of the gradient are used to fill the remaining space. With Forwards, the +gradient is normally repeated (connecting the back end of one occurrence with +the front end of the next). With Alternating, the gradient is repeated with +every second occurrence being drawn from back to front (linking front to front +and back to back). + +Check the Reverse checkbox to have the gradient drawn +reversed (from back to front). + +The final setting is Anti-alias threshold, which +determines how smooth the gradient will become. + + + + +<guilabel>Text</guilabel> + + +The Tool tab for Text + + + + + +The Tool tab for Text + + + + + +The same options as for Brush +are available here. Furthermore there is an option Font, +which shows the font that will be used for the text. Click the +... button to change the font. + + + + +<guilabel>Color Picker</guilabel> + + +The Tool tab for Color Picker + + + + + +The Tool tab for Color Picker + + + + + +The first option is a dropdown box in which you can choose which +layer to pick the color from. If you choose a specific layer, +the color of the point in that layer will be retrieved. With Sample +All Visible Layers, the topmost visible layer which is not +transparent at that point is used. + +If the Update current color checkbox is checked, then the +current foreground color (when clicking with the &LMB;) or background color +(when clicking with the &RMB;) is set to the picked color. + +The checkbox Add to palette and the accompanying +dropdown box determine whether the picked color should be added to an existing +palette. Check the checkbox, and choose the desired palette from the list, if +you want to do so. + +The checkbox Show colors as percentages switches the +range of color values displayed from the normal range (e.g. 0 to +255) to a scaled value between 0% and 100%. + +With the Sample radius option, you can choose the area +size to use when picking the color. A radius of one just picks one pixel, +larger radii will make the picker average over the colors of the circle-shaped +area with the chosen radius that is centered around the chosen pixel. + + + + +<guilabel>Select</guilabel> tools + + +The Tool tab for Select tools + + + + + +The Tool tab for Select tools + + + + + +The Paint Selection, Erase Selection, +Select Rectangular, Select Elliptical, Select Polygonal and Select Outline tools have one option: +the Action to perform. You can choose between Add to, or +Subtract from the selection. + + + +<guilabel>Select Contiguous Area</guilabel> + + +The Tool tab for Select Contiguous + + + + + +The Tool tab for Select Contiguous + + + + + +The Action is the same as discussed with the +Select +operations. + +The slider and spin box at Fuzziness determine how near +colors must be to the color at the clicked point to be added to the selection. + +When the Sample merged checkbox is checked, the +bounds of the selection are determined by looking at the entire image instead +of at the current layer. + + + + +<guilabel>Similar Select</guilabel> +The Action and Fuzziness +options are the same as with Select +contiguous. + + + +<guilabel>Select Magnetic</guilabel> + + +The Tool tab for Select Magnetic + + + + + +The Tool tab for Select Magnetic + + + + + +The Action option is the same as with the other +Select tools. + + +The Distance option determines the maximal distance at +which boundaries to attach to, are searched for. The To +Selection button has the same effect as double-clicking the &LMB;: +the selection is finished. + + + + + + + + +The <guilabel>Colors</guilabel> palette +In this palette you can choose the foreground and background colors +that should be used for painting. You can choose these in five different +ways. Each of these has its own tab on this palette. + +You can choose which color to set by clicking the corresponding +buttons at the top left. The topmost color is the foreground color, the +bottom one is the background color. You can click the double-headed arrow +to swap the colors: foreground color becomes background color and vice +versa. You can reset the colors to the default (foreground black, background +white) by clicking the small black/white icon. + + + +<guilabel>HSV</guilabel> + + +The HSV tab + + + + + +The HSV tab + + + + + +On this tab, you can select a color via the Hue / Saturation / Value +system. + +The hue determines the major color and starts at red with 0, then increases +along the color spectrum (that is, along the line yellow, green, +blue, violet) to a maximum of 359. This is represented in the circle on the tab +as the angle component (starting at the top, rotate along the circle +in clockwise direction to increase the hue). + +The saturation determines the pureness of the color. A saturation of 255 +yields the pure color, while a saturation of 0 yields a gray. This is the +radius component of the color circle on the tab: the center corresponds to +no saturation, the circle boundary corresponds to fully saturated. + +The value determines the lightness of the color. This darkens or lightens the +color, as can be set using the vertical slider on the tab. A value of 0 gives +black, a value of 255 gives the pure color. + + + + +<guilabel>RGB</guilabel> + + +The RGB tab + + + + + +The RGB tab + + + + + +On this tab, colors can be selected using their Red / Green / Blue +components. + +You can set red, green and blue components on a scale of 0 to 255. At 0 that +color component is absent, at 255 it is used at maximum intensity. The sliders +will change color to give you a hint about which color you will produce by +altering the corresponding value. + + + + +<guilabel>Gray</guilabel> + + +The Gray tab + + + + + +The Gray tab + + + + + +On this tab, you can choose a gray value (indicated with a K for Key, +the usual designation for black). +The gray value can be chosen on a scale from 0 (pure white) to 255 +(pure black). + + + +<guilabel>Palettes</guilabel> + + +The Palettes tab + + + + + +The Palettes tab + + + + + +On this tab, you can select a color from one of several predefined +color palettes. +You can choose which color palette to pick from in the drop down +box at the top. + + + +<guilabel>Watercolors</guilabel> + + +The Watercolors tab + + + + + +The Watercolors tab + + + + + +This tab offers you a selection of watercolors for painting with wet +paint. + +You can set two options to modify the painting behaviour: Paint +strength influences how much paint you will apply to the canvas, +and Wetness determines how wet the paint is when it is +applied. You can dry the paint later. + + + + + + +The <guilabel>Layers</guilabel> palette +This palette offers two tabs. + + +<guilabel>Layers</guilabel> + + +The Layers tab + + + + + +The Layers tab + + + + + +This tab offers you access to various operations on layers. + +On the top left, you can select what blending mode should be used for the +selected layer. These are the same possibilities as you can choose from for +drawing modes. + +The slider/textbox at the top right determines the opacity of the selected +layer. 0% opacity corresponds to 100% transparency, and vice versa. + +The list shows all layers and their names, and offers various controls for each +layer. The eye icon toggles whether the layer is visible or not. The link icon +is used to link layers together. The lock icon determines if the layer is +locked or not. Locked layers cannot be edited. + +Below the layer list, there are some other controls. You can create a new +layer, move the current layer up or down, show the layer's properties and +delete it. + + +There are some more handy tricks you can do with the mouse within the list. +Right-click on the layer list and select New Folder to +create a new layer folder, which you can use to group layers in. You can also +drag and drop layers to change their order. To do so, click on the bottom part +of the list item representing the layer, drag the mouse, and release the mouse +button at the desired position. If you click at the top part of the list item +instead, you will get a text field so that you can rename the layer. + + + + +<guilabel>Scripts Manager</guilabel> + + +The Script Manager tab + + + + + +The Script Manager tab + + + + + +This tab is a smaller version of the Script +Manager dialog. See the description over there for more +information. + + + + + + diff --git a/doc/krita/commands-toolbars.docbook b/doc/krita/commands-toolbars.docbook new file mode 100644 index 000000000..05ddea55d --- /dev/null +++ b/doc/krita/commands-toolbars.docbook @@ -0,0 +1,752 @@ + +Toolbars + +This section describes &krita;'s toolbars. By default, the +Krita toolbar is located to the left of the drawing area, +while the others can be found at the top, below the menu bar. + +You can customize your toolbars by choosing +SettingsConfigure +Toolbars... or by clicking with the &RMB; on a +toolbar and choosing Configure Toolbars.... + + +The <guilabel>File</guilabel> Toolbar + + + +The File toolbar + + + + + +The File toolbar + + + + + + +This toolbar contains actions for working with files. In &krita;'s +default, there are five buttons on this toolbar: New, +Open, Save, Print +Preview, and Print. + +These actions all correspond to entries in the File menu. + + + + +The <guilabel>Edit</guilabel> Toolbar + + + +The Edit toolbar + + + + + +The Edit toolbar + + + + + + +This toolbar contains editing actions. With default settings this +toolbar offers four buttons: Undo, +Redo, Cut, and +Copy. + +These actions all correspond to entries in the Edit menu. + + + +The <guilabel>Navigation</guilabel> Toolbar + + + +The Navigation toolbar + + + + + +The Navigation toolbar + + + + + + +This toolbar offers easy access to navigation actions. The two +default actions available are Zoom In and +Zoom Out. With Zoom In, the zoom +level is increased. You will see less, but in higher detail. With +Zoom Out, the zoom level is decreased, so that you see +more at less detail. + + + + +The <guilabel>Krita</guilabel> Toolbar + + + +The Krita toolbar + + + + + +The Krita toolbar + + + + + + + +This toolbar contains painting operations and tools, as well as editing and +selecting tools. The available actions and some controls are listed below. You +can change the behaviour of most tools (and with that, usually the resulting +effect) by setting their options. + + + + + + Brush + +With this tool you can paint freely. Click the &LMB; to paint a +single instance of the currently selected brush, or hold the &LMB; and drag +your mouse around to paint. The mouse movements you make are directly used for +painting. + + + + Line + +This tool is used to draw lines. Click the &LMB; to indicate the first +endpoint, keep the button pressed, drag to the second endpoint and release the +button. + +Use &Shift; while holding the mouse button to restrict drawing to only +horizontal or vertical lines. You can press &Alt; while still keeping the &LMB; +down to move the line to a different location. + + + + Rectangle + +This tool can be used to paint rectangles. Click and hold the &LMB; to indicate +one corner of the rectangle, drag to the opposite corner, and release the +button. + +If you hold &Shift; while drawing, a square will be drawn instead of a +rectangle. Holding &Ctrl; will change the way the rectangle is constructed. +Normally, the first mouse click indicates one corner and the second click the +opposite. With &Ctrl;, the initial mouse position indicates the center of the +rectangle, and the final mouse position indicates a corner. +You can press &Alt; while still keeping the &LMB; down to move the rectangle to +a different location. + +You can change between the corner/corner and center/corner drawing +methods as often as you want by pressing or releasing &Ctrl;, provided that you +keep the &LMB; pressed. With &Ctrl; pressed, mouse movements will affect all +four corners of the rectangle (relative to the center), without &Ctrl;, one +of the corners is unaffected. + + + + Ellipse + +Use this tool to paint an ellipse. The currently selected brush is used for +drawing the ellipse outline. Click and hold the &LMB; to indicate one corner of +the bounding rectangle of the ellipse, then move your mouse to +the opposite corner. &krita; will show a preview of the ellipse using a thin +line. Release the button to draw the ellipse. + +If you hold &Shift; while drawing, a circle will be drawn instead of an +ellipse. Holding &Ctrl; will change the way the ellipse is constructed: instead +of two corners, the initial mouse position indicates the ellipse center, and the +final mouse position indicates one of the corners of the bounding rectangle. +You can press &Alt; while still keeping the &LMB; down to move the ellipse to a +different location. + +You can change between the corner/corner and center/corner drawing +methods as often as you want by pressing or releasing &Ctrl;, provided that you +keep the &LMB; pressed. With &Ctrl; pressed, mouse movements will +affect all four corners of the bounding rectangle (relative to the center), +without &Ctrl;, the corner opposite to the one you are moving remains still. + + + + Polygon + +With this tool you can draw polygons. Click the &LMB; to indicate the +starting point and successive vertices, then double-click or press &Enter; to +connect the last vertex to the starting point. + + + + Polyline + +Polylines are drawn like polygons, with the difference that the double-click +indicating the end of the polyline does not connect the last vertex to the +first one. + + + + Star + +This tool creates star-shaped objects. Press the &LMB; to indicate the center, +and drag the mouse to change the size and rotation of the star. + +You can press &Alt; while still keeping the &LMB; down to move the star to a +different location. + + + + Bezier + +You can draw Bezier curves by using this tool. Click the &LMB; to indicate the +starting point of the curve, then click again for consecutive control points +of the curve. + + + +Drawing a Bezier curve + + + + + +Drawing a Bezier curve + + + + + + +&krita; will show a blue line with two handles when you add a control point. +You can drag these handles to change the direction of the curve in that point. + + + +Modifying a Bezier curve + + + + + +Modifying a Bezier curve + + + + + + +You can click on a previously inserted control point to modify it. With an intermediate +control point (&ie; a point that is not the starting point and not the ending +point), you can move the direction handles seperately to have the curve enter +and leave the point in different directions. After editing a point, you can +just click on the canvas to continue adding points to the curve. + + +Pressing Delete will remove the currently selected control +point from the curve. Double-click the &LMB; on any point of the curve or +press &Enter; to finish drawing, or press &Esc; to cancel the entire curve. +You can use &Ctrl; while keeping the &LMB; pressed to move the entire curve to +a different position. + + + +A finished Bezier curve + + + + + +A finished Bezier curve + + + + + + + + Duplicate + +You can use this tool to duplicate parts of an image. Press &Shift; and click +with the &LMB; on the location you want to duplicate from. &krita; will +indicate this location by an outline of your current brush. Then click with +the &LMB; to designate the location where you want to duplicate to, and drag +with the mouse. You will then duplicate whatever is at the source location to +the current (destination) location. + +While you are painting the duplicate, both your cursor in the destination +location and the brush outline in the source location will move, in order to +give you visual feedback. + +You can also use this tool to correct colors in a part of the image: use the +Healing option for that. + + + + Paint with +filters + +This tool allows you to pick a filter and draw with it. The image below shows +the effect of using a large circular brush and painting with, from left to +right, the Maximize Channel, Minimize Channel, Invert, and Desaturate filters. + + + +Painting with filters + + + + + +Painting with filters + + + + + + + + Crop + +With this tool you can crop a layer or an image to a certain rectangular area. +Click and drag with the &LMB; to define an area. This area is designated by an +outline with 8 handles. You can then use the handles to change the size of the +area which the image or layer is to be cropped to. You can also click and drag +inside the area to move the outline in its entirety. + +Double-click outside the area (i.e. on a part of the image that is to be removed) +to confirm the cropping operation. + + + + Move + +With this tool, you can move the current layer or selection by dragging the +mouse. + + + + Transform + +With this tool you can quickly transform the current selection or layer. +Handles will appear at the corners and sides, with which you can resize the +selection or layer. You can perform rotations by moving the mouse above or to +the left of the handles and dragging it. You can also click anywhere inside +the selection or layer and move it by dragging the mouse. + + + + Perspective Transform + +This tool allows you to change the perspective of an image. Designate the area +which should become the new image by clicking at its top-left, top-right, +bottom-right and bottom-left corners. The area given by these four corners +will then be transformed so that the given corners become the corners of the +actual image. + + + + Contiguous Fill + +Use this tool to fill a contiguous area of one color with the current +foreground color or a pattern. Simply click to fill up the area. + + + + Gradient + +This tool fills the current layer or selection with the currently selected +gradient. Click the &LMB;, hold it, and drag the mouse to define two endpoints. +The gradient will be drawn along this line. If the line does not extend to the +border of the selection or layer, the color at the corresponding endpoint of +the gradient will be used to fill up the rest of the area at that side. + + + + Text + +With this tool you can add simple text to your image. Click the &LMB; on the +location at which you want have the text. Then enter the desired text in the +dialog window that appears. The text will be horizontally centered on, and +the top of the text will be at the same height as, the chosen location. + + + + Color Picker + +With this tool you can find the color values of a point. Click the &LMB; +somewhere in the image to see color information about that point in the +Control box. + + + + Pan + +This tool can be used to navigate through your image. Click and hold the &LMB; +and move the mouse to scroll in a certain direction. + + + + Zoom + +Use this tool to zoom in and out. Click the &LMB; to increase the zoom by +a factor 2 (e.g. 1:1 to 2:1), click the &RMB; to decrease the zoom by a factor +2 (e.g. 1:1 to 1:2). + + + + Perspective Grid + +You can create and edit a perspective grid with this tool. Click the &LMB; and +drag the mouse to indicate the first two corners of the grid, then click for +the third and fourth corners. The outline of the grid is now shown and you can +edit it if you are not completely happy. When you switch to a different tool, +the perspective grid will be subdivided and shown as thin gray lines. + +If you only see three corners instead of four, you probably +clicked instead of dragging initially. In this case you can still click the +handle of your now combined first and second corners and drag it to get four +separate corners. + +Clicking the Perspective Grid tool again later will allow +you to modify the grid. You can hide or remove the grid by choosing the +Hide Perspective Grid or Clear +Perspective Grid options from the View menu. + + + + Paint Selection + +This tool can be used to select custom areas. The currently selected brush is +used to select areas: instead of painting on the image, the area is selected. +For more information on selections, see the Selections chapter. + + + + + Erase Selection + +This tool works almost the same as the Paint Selection +tool, but a selection, if it exists at the mouse location, is removed instead +of created. + + + + + Select Rectangular + +You can use this tool to select rectangular areas. Operation is similar to the +Rectangle tool, and &Shift;, &Ctrl; and &Alt; can be used +like when painting rectangles. + + + + + Select Elliptical + +You can use this tool to select elliptical areas. Operation is similar to the +Ellipse tool, and &Shift;, &Ctrl; and &Alt; can be used +like when painting ellipses. + + + + Select +Polygonal + +You can use this tool to select polygonal areas. Operation is similar to the +Polygon tool, and &Shift;, &Ctrl; and &Alt; can be used +like when painting polygons. + + + + Select +Outline + +You can use this tool to select custom outlined areas. Click the &LMB; and drag +with your mouse, like when painting with the Brush tool, +to define the outline. When you release the mouse button, the outline will be +finished with a straight line between the current position and the start +position. + + + + + Select Contiguous + +With this tool you can select contiguous areas of a color. Click with the +&LMB; to select an area. + + + + + Select Similar + +With this tool you can select multiple areas with the same color. Detection is +done the same as with the contiguous fill, but the areas do not need to be +adjacent. + + + + Magnetic Selection + +With this tool you can easily select a visually distinct area. Click with the +&LMB; and move the mouse around the area that you want to select. If the area +has a well enough defined boundary, the selection will be drawn nicely around +it. You will see a number of control points appear, which connect the various +parts of the selection boundary. + +If you want more control over the area that is selected, press &Ctrl; to +switch to manual mode. You will now have to click for each control point. +In manual mode, you can also move control points by clicking on them with the +&LMB; and dragging with the mouse. + +When you want to return to automatic mode, simply press &Ctrl; again. You can +switch between these two modes as often as you like. + + + + Select Bezier + +With this tool you can select an area by drawing a Bezier outline. See the +description of the Bezier tool for details. + + + + + + + +The <guilabel>Brushes and Stuff</guilabel> Toolbar + + + +The Brushes and Stuff toolbar + + + + + +The Brushes and Stuff toolbar + + + + + + +This toolbar contains dropdown palettes in which you +can choose brush shapes, gradients, and fill patterns. It also contains a +dropdown box for painter's tools, and a tablet pressure setting. + + +<guilabel>Brush Shapes</guilabel> + + + +The Brush Shapes palette + + + + + +The Brush Shapes palette + + + + + + +In the Brush Shapes palette, you can choose +which brush to paint with. This brush is used for painting operations +like Freehand, Rectangle, +Ellipse, etcetera. You can choose a predefined +brush (in the Predefined Brushes tab, shown above), or +customize or create one. + + + +The Brush Shapes palette with the Autobrush tab + + + + + +The Brush Shapes palette with the Autobrush tab + + + + + + +The Autobrush tab allows you to create a customized +rectangular or ellipsoid brush. You can set its height and width using +the Size spin boxes. The link icon controls whether +the height and width are forced to be the same or not. If a connected link +picture is shown, changing one value will automatically change the other one +as well. A disconnected link indicates that both values can be set +independently. The fuzziness of the brush can be set with the +Fade spin boxes. Again, horizontal and vertical values can +be allowed to differ or not, depending on the state of the link button. + + + +The Brush Shapes palette with the Custom Brush tab + + + + + +The Brush Shapes palette with the Custom Brush tab + + + + + + +The Custom Brush tab of this palette lets you +use the current image as a brush. With the Add to +Predefined Brushes button, you can save it for later use. + + + + +Gradients + + + +The Gradients palette + + + + + +The Gradients palette + + + + + + +In the Gradients palette, you can choose a gradient +to paint with using the Gradient tool. Clicking once on a gradient in the +palette will show a larger preview. Click it again to make it the current +gradient. +You can create your own gradients with the Custom +Gradient button. + + + + +Patterns + + + +The Patterns palette + + + + + +The Patterns palette + + + + + + +The Patterns palette allows you to choose a pattern +for operations like Pattern fill. Click a pattern to see a preview at +actual size, then click it again to select it. + + + +The Patterns palette with the Custom Pattern tab selected + + + + + +The Patterns palette with the Custom Pattern tab selected + + + + + + +You can also create a custom pattern, as is shown above. + + + + +Painter's tools + +With the Painter's tools dropdown box, you can +select the tool your painting operation should simulate. For example, you can +paint with a normal brush, an airbrush, or a filter. + + + + +Pressure variation + +This setting allows you to change &krita;'s behaviour when you use a +tablet to paint with. When you change the pressure on the tablet, you can +choose between changing the line width (size), the +opacity, and the darkness. + + + + + + diff --git a/doc/krita/commands.docbook b/doc/krita/commands.docbook new file mode 100644 index 000000000..13ab46b05 --- /dev/null +++ b/doc/krita/commands.docbook @@ -0,0 +1,14 @@ + +Command Reference + + +This chapter explains &krita;'s user interface in detail. Each of the menus, +toolbars, palettes, and dialogs will be discussed. + + +&commands-menus; +&commands-toolbars; +&commands-palettes; +&commands-dialogs; + + diff --git a/doc/krita/createdocument.png b/doc/krita/createdocument.png new file mode 100644 index 000000000..5188e232e Binary files /dev/null and b/doc/krita/createdocument.png differ diff --git a/doc/krita/credits.docbook b/doc/krita/credits.docbook new file mode 100644 index 000000000..9059e1478 --- /dev/null +++ b/doc/krita/credits.docbook @@ -0,0 +1,63 @@ + + +Credits and License + + +&krita; + + +Program copyright © 1999-2006 The &krita; Team + + + +Contributors: + + +Adrian Page +Adrian.Page@tesco.net +Andrew Richards +physajr@phys.canterbury.ac.nz +Bart Coppens kde@bartcoppens.be +Boudewijn Rempt +boud@valdyas.org (current maintainer) +Carsten Pfeiffer +pfeiffer@kde.org +Casper Boemann cbr@boemann.dk +Cyrille Berger cyb@lepi.org +Danny Allen +dannya40uk@yahoo.co.uk +Dirk Schoenberger +dirk.schoenberger@sz-online.de +Gábor Lehel +illissius@gmail.com +John Califf +jcaliff@compuzone.net +Matthias Elter elter@kde.org +Melchior Franz melchior@kde.org +Michael Koch koch@kde.org +Michael Thaler +michael.thaler@ph.tum.de +Patrick Julien +freak@codepimps.org +Roger Larsson +roger.larsson@norran.net +Sven Langkamp +longamp@reallygood.de + + + + +Documentation copyright © 2005-2006 Boudewijn Rempt +boud@valdyas.org, Sander Koning +sanderkoning@kde.nl +with contributions from Casper Boemann, Bart Coppens, Cyrille Berger, Burkhard +Lueck, and Anne-Marie Mahfouf. + + + +&underFDL; +&underGPL; + + + + diff --git a/doc/krita/crocusses-autocontrast.png b/doc/krita/crocusses-autocontrast.png new file mode 100644 index 000000000..e03b36357 Binary files /dev/null and b/doc/krita/crocusses-autocontrast.png differ diff --git a/doc/krita/crocusses-blur.png b/doc/krita/crocusses-blur.png new file mode 100644 index 000000000..b6aa67da1 Binary files /dev/null and b/doc/krita/crocusses-blur.png differ diff --git a/doc/krita/crocusses-brightnesscontrast.png b/doc/krita/crocusses-brightnesscontrast.png new file mode 100644 index 000000000..f09808fe1 Binary files /dev/null and b/doc/krita/crocusses-brightnesscontrast.png differ diff --git a/doc/krita/crocusses-bumpmap.png b/doc/krita/crocusses-bumpmap.png new file mode 100644 index 000000000..ed3d01752 Binary files /dev/null and b/doc/krita/crocusses-bumpmap.png differ diff --git a/doc/krita/crocusses-coloradjustment.png b/doc/krita/crocusses-coloradjustment.png new file mode 100644 index 000000000..4e30ad203 Binary files /dev/null and b/doc/krita/crocusses-coloradjustment.png differ diff --git a/doc/krita/crocusses-colortoalpha.png b/doc/krita/crocusses-colortoalpha.png new file mode 100644 index 000000000..f3f805a15 Binary files /dev/null and b/doc/krita/crocusses-colortoalpha.png differ diff --git a/doc/krita/crocusses-colortransfer.png b/doc/krita/crocusses-colortransfer.png new file mode 100644 index 000000000..cae7c1a91 Binary files /dev/null and b/doc/krita/crocusses-colortransfer.png differ diff --git a/doc/krita/crocusses-customconvolution.png b/doc/krita/crocusses-customconvolution.png new file mode 100644 index 000000000..406c42292 Binary files /dev/null and b/doc/krita/crocusses-customconvolution.png differ diff --git a/doc/krita/crocusses-desaturate.png b/doc/krita/crocusses-desaturate.png new file mode 100644 index 000000000..5d91e28f8 Binary files /dev/null and b/doc/krita/crocusses-desaturate.png differ diff --git a/doc/krita/crocusses-edgebottom.png b/doc/krita/crocusses-edgebottom.png new file mode 100644 index 000000000..7438f8abd Binary files /dev/null and b/doc/krita/crocusses-edgebottom.png differ diff --git a/doc/krita/crocusses-edgeleft.png b/doc/krita/crocusses-edgeleft.png new file mode 100644 index 000000000..2b31536be Binary files /dev/null and b/doc/krita/crocusses-edgeleft.png differ diff --git a/doc/krita/crocusses-edgeright.png b/doc/krita/crocusses-edgeright.png new file mode 100644 index 000000000..996b6de83 Binary files /dev/null and b/doc/krita/crocusses-edgeright.png differ diff --git a/doc/krita/crocusses-embossall.png b/doc/krita/crocusses-embossall.png new file mode 100644 index 000000000..dcdd6f55d Binary files /dev/null and b/doc/krita/crocusses-embossall.png differ diff --git a/doc/krita/crocusses-embosshorvert.png b/doc/krita/crocusses-embosshorvert.png new file mode 100644 index 000000000..b3eb0d37f Binary files /dev/null and b/doc/krita/crocusses-embosshorvert.png differ diff --git a/doc/krita/crocusses-embossvariable.png b/doc/krita/crocusses-embossvariable.png new file mode 100644 index 000000000..526e45f31 Binary files /dev/null and b/doc/krita/crocusses-embossvariable.png differ diff --git a/doc/krita/crocusses-gaussianblur.png b/doc/krita/crocusses-gaussianblur.png new file mode 100644 index 000000000..df58f7f14 Binary files /dev/null and b/doc/krita/crocusses-gaussianblur.png differ diff --git a/doc/krita/crocusses-gaussiannoise.png b/doc/krita/crocusses-gaussiannoise.png new file mode 100644 index 000000000..3de2a4e98 Binary files /dev/null and b/doc/krita/crocusses-gaussiannoise.png differ diff --git a/doc/krita/crocusses-invert.png b/doc/krita/crocusses-invert.png new file mode 100644 index 000000000..9f3d50466 Binary files /dev/null and b/doc/krita/crocusses-invert.png differ diff --git a/doc/krita/crocusses-lenscorrection.png b/doc/krita/crocusses-lenscorrection.png new file mode 100644 index 000000000..4ac1da9af Binary files /dev/null and b/doc/krita/crocusses-lenscorrection.png differ diff --git a/doc/krita/crocusses-maximizechannel.png b/doc/krita/crocusses-maximizechannel.png new file mode 100644 index 000000000..a3f3a3f21 Binary files /dev/null and b/doc/krita/crocusses-maximizechannel.png differ diff --git a/doc/krita/crocusses-meanremoval.png b/doc/krita/crocusses-meanremoval.png new file mode 100644 index 000000000..d867e95a0 Binary files /dev/null and b/doc/krita/crocusses-meanremoval.png differ diff --git a/doc/krita/crocusses-minimizechannel.png b/doc/krita/crocusses-minimizechannel.png new file mode 100644 index 000000000..cfe00f211 Binary files /dev/null and b/doc/krita/crocusses-minimizechannel.png differ diff --git a/doc/krita/crocusses-oilpaint.png b/doc/krita/crocusses-oilpaint.png new file mode 100644 index 000000000..6edf1d24a Binary files /dev/null and b/doc/krita/crocusses-oilpaint.png differ diff --git a/doc/krita/crocusses-pixelize.png b/doc/krita/crocusses-pixelize.png new file mode 100644 index 000000000..bce9291ce Binary files /dev/null and b/doc/krita/crocusses-pixelize.png differ diff --git a/doc/krita/crocusses-raindrops.png b/doc/krita/crocusses-raindrops.png new file mode 100644 index 000000000..322f674a7 Binary files /dev/null and b/doc/krita/crocusses-raindrops.png differ diff --git a/doc/krita/crocusses-randomnoise.png b/doc/krita/crocusses-randomnoise.png new file mode 100644 index 000000000..e43979f57 Binary files /dev/null and b/doc/krita/crocusses-randomnoise.png differ diff --git a/doc/krita/crocusses-randompick.png b/doc/krita/crocusses-randompick.png new file mode 100644 index 000000000..2b35f9d54 Binary files /dev/null and b/doc/krita/crocusses-randompick.png differ diff --git a/doc/krita/crocusses-roundcorners.png b/doc/krita/crocusses-roundcorners.png new file mode 100644 index 000000000..12f386462 Binary files /dev/null and b/doc/krita/crocusses-roundcorners.png differ diff --git a/doc/krita/crocusses-sharpen.png b/doc/krita/crocusses-sharpen.png new file mode 100644 index 000000000..25014c6cd Binary files /dev/null and b/doc/krita/crocusses-sharpen.png differ diff --git a/doc/krita/crocusses-smalltiles.png b/doc/krita/crocusses-smalltiles.png new file mode 100644 index 000000000..0916036b5 Binary files /dev/null and b/doc/krita/crocusses-smalltiles.png differ diff --git a/doc/krita/crocusses-sobel.png b/doc/krita/crocusses-sobel.png new file mode 100644 index 000000000..a59c98f37 Binary files /dev/null and b/doc/krita/crocusses-sobel.png differ diff --git a/doc/krita/crocusses-topedge.png b/doc/krita/crocusses-topedge.png new file mode 100644 index 000000000..291da428f Binary files /dev/null and b/doc/krita/crocusses-topedge.png differ diff --git a/doc/krita/crocusses-unsharpmask.png b/doc/krita/crocusses-unsharpmask.png new file mode 100644 index 000000000..31b60d26e Binary files /dev/null and b/doc/krita/crocusses-unsharpmask.png differ diff --git a/doc/krita/crocusses-wave.png b/doc/krita/crocusses-wave.png new file mode 100644 index 000000000..107c53a6d Binary files /dev/null and b/doc/krita/crocusses-wave.png differ diff --git a/doc/krita/crocusses-waveletnoise.png b/doc/krita/crocusses-waveletnoise.png new file mode 100644 index 000000000..e3b25b420 Binary files /dev/null and b/doc/krita/crocusses-waveletnoise.png differ diff --git a/doc/krita/crocusses.png b/doc/krita/crocusses.png new file mode 100644 index 000000000..837da62d2 Binary files /dev/null and b/doc/krita/crocusses.png differ diff --git a/doc/krita/developers-plugins.docbook b/doc/krita/developers-plugins.docbook new file mode 100644 index 000000000..58dd345e8 --- /dev/null +++ b/doc/krita/developers-plugins.docbook @@ -0,0 +1,1553 @@ + +Developing &krita; Plugins + + +Introduction + + +&krita; is infinitely extensible with plugins. Tools, filters, large +chunks of the user interface and even colorspaces are plugins. In fact, +&krita; recognizes these six types of plugins: + + + +colorspaces — these define the channels that constitute +a single pixel +tools — anything that is done with a mouse or tablet +input device +paint operations — pluggable painting effects for +tools +image filters — change all pixels, or just the selected +pixels in a layer +viewplugins — extend Krita’s user interface with new +dialog boxes, palettes and operations +import/export filters — read and write all kinds of +image formats + + + +&krita; itself consists of three layered libraries and a directory with some +common support classes: kritacolor, kritaimage and kritaui. Within +&krita;, objects can by identified by a KisID, that is +the combination of a unique untranslated string (used when saving, for +instance) and a translated string for GUI purposes. + +A word on compatibility: &krita; is still in development. From &krita; 1.5 to +1.6 not many API changes are expected, but there may be some. From &krita; 1.6 +to 2.0 we will move from &Qt;3 to &Qt;4, from &kde;3 to &kde;4, from +automake to cmake: many changes are to +be expected. If you develop a plugin for &krita; and choose to do so in +&krita;’s subversion repository, chances are excellent that we’ll help you +porting. These changes may also render parts of this document out of date. +Always check with the latest API documentation or the header files installed +on your system. + + + +KritaColor + + +The first library is kritacolor. This library loads the colorspace plugins. + +A colorspace plugin should implement the KisColorSpace +abstract class or, if the basic capabilities of the new colorspace will be +implemented by lcms (), extend KisAbstractColorSpace. The kritacolor +library could be used from other applications and does not depend on +&koffice;. + + + + +KritaImage + + +The libkritaimage library loads the filter and paintop plugins and is +responsible for working with image data: changing pixels, compositing and +painting. Brushes, palettes, gradients and patterns are also loaded by +libkritaimage. It is our stated goal to make libkritaimage independent of +&koffice;, but we currently share the gradient loading code with &koffice;. + +It is not easy at the moment to add new types of resources such as brushes, +palettes, gradients or patterns to &krita;. (Adding new brushes, palettes, +gradients and patterns is easy, of course.) &krita; follows the guidelines of +the Create project () for these. +Adding support for Photoshop's brush file format needs libkritaimage hacking; +adding more gimp brush data files not. + +KritaImage loads the following types of plugins: + + + +&krita; filters must extend and implement the abstract class +KisFilter, +KisFilterConfiguration and possibly +KisFilterConfigurationWidget. +An example of a filter is Unsharp Mask. +Paint operations or paintops are the set of operations +painting tools suchs as freehand or circle have access to. Examples of +paintops are pen, airbrush or eraser. Paintops should extend the +KisPaintop base class. Examples of new paintops could +be a chalk brush, an oilpaint brush or a complex programmable +brush. + + + + + +KritaUI + + +The libkritaui library loads the tool and viewplugins. This library is a +&koffice; Part, but also contains a number of widgets that are useful for +graphics applications. Maybe we will have to split this library in kritapart +and kritaui in the 2.0 release. For now, script writers are not given access +to this library and plugin writers are only allowed to use this library when +writing tools or viewplugins. KritaUI loads the +following types of plugins: + + + +Tools are derived from KisTool or one +of the specialized tool base classes such as +KisToolPaint, KisToolNonPaint or +KisToolFreehand. A new tool could be a foreground +object selection tool. Painting tools (and that includes tools that paint on +the selection) can use any paintop to determine the way pixels are +changed. +Viewplugins are ordinary KParts that use +kxmlgui to insinuate themselves into &krita;'s user +interface. Menu options, dialogs, toolbars — any kind of user interface +extension can be a viewplugin. In fact, important functionality like &krita;'s +scripting support is written as a viewplugin. + + + + + +Import/Export filters + + +Import/Export filters are &koffice; filters, subclasses of +KoFilter. Filters read and write image data in any of +the myriad image formats in existence. And example of a new &krita; +import/export filter could be a PDF filter. Filters are loaded by the +&koffice; libraries. + + + + + + + +Creating plugins + + +Plugins are written in C++ and can use all of &kde; and &Qt; and the &krita; +developer API. Only viewplugins should use the &koffice; API. Don’t worry: +&krita;’s API’s are quite clear and rather extensively documented (for free +software) and coding your first filter is really easy. + +If you do not want to use C++, you can write scripts in Python or Ruby; that +is a different thing altogether, though, and you cannot currently write tools, +colorspaces, paintops or import/export filters as scripts. + +&krita; plugins use &kde;'s parts mechanism for loading, so the parts +documentation at is relevant here, too. + +Your distribution should have either installed the relevant header files with +&krita; itself, or might have split the header files into either a &koffice; +dev or a &krita; dev package. You can find the API documentation for &krita;'s +public API at . + + + +Automake (and CMake) + + +&kde; 3.x and thus &koffice; 1.5 and 1.6 use automake; +&kde; 4.0 and &koffice; 2.0 use cmake. This tutorial +describes the automake way of creating plugins. + + +Plugins are &kde; modules and should be tagged as such in their +Makefile.am. Filters, tools, paintops, colorspaces and +import/export filters need .desktop files; +viewplugins need a KXMLGui +pluginname.rc file in addition. The easiest way to get +started is to checkout the krita-plugins project from the &koffice; Subversion +repository and use it as the basis for your own project. We intend to prepare +a skeleton &krita; plugin pack for KDevelop, but haven’t had the time to do +so yet. + + + +<filename>Makefile.am</filename> + + +Let's look at the skeleton for a plugin module. First, the +Makefile.am. This is what &kde; uses to generate the +makefile that builds your plugin: + + +kde_services_DATA = kritaLIBRARYNAME.desktop + +INCLUDES = $(all_includes) + +kritaLIBRARYNAME_la_SOURCES = sourcefile1.cc sourcefile2.cc + +kde_module_LTLIBRARIES = kritaLIBRARYNAME.la +noinst_HEADERS = header1.h header2.h + +kritaLIBRARYNAME_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kritaLIBRARY_la_LIBADD = -lkritacommon + +kritaextensioncolorsfilters_la_METASOURCES = AUTO + + +This is the makefile for a filter plugin. Replace +LIBRARYNAME with the name of your work, and you are +set. + +If your plugin is a viewplugin, you will likely also install a .rc file with entries for menubars and toolbars. +Likewise, you may need to install cursors and icons. That is all done through +the ordinary &kde; Makefile.am magic incantantions: + + +kritarcdir = $(kde_datadir)/krita/kritaplugins +kritarc_DATA = LIBRARYNAME.rc +EXTRA_DIST = $(kritarc_DATA) + +kritapics_DATA = \ + bla.png \ + bla_cursor.png +kritapicsdir = $(kde_datadir)/krita/pics + + + + + + +Desktop files + + +The .desktop file announces the type of plugin: + + +[Desktop Entry] +Encoding=UTF-8 +Icon= +Name=User-visible Name +ServiceTypes=Krita/Filter +Type=Service +X-KDE-Library=kritaLIBRARYNAME +X-KDE-Version=2 + + +Possible ServiceTypes are: + + + +Krita/Filter +Krita/Paintop +Krita/ViewPlugin +Krita/Tool +Krita/ColorSpace + + + +File import and export filters use the generic &koffice; filter framework and +need to be discussed separately. + + + + +Boilerplate + + +You also need a bit of boilerplate code that is called by the &kde; part +framework to instantiate the plugin — a header file and an implementation file. + +A header file: + +#ifndef TOOL_STAR_H_ +#define TOOL_STAR_H_ + +#include <kparts/plugin.h> + +/** +* A module that provides a star tool. +*/ +class ToolStar : public KParts::Plugin +{ + Q_OBJECT +public: + ToolStar(QObject *parent, const char *name, const QStringList &); + virtual ~ToolStar(); + +}; + +#endif // TOOL_STAR_H_ + + + + +And an implementation file: + +#include <kinstance.h> +#include <kgenericfactory.h> + +#include <kis_tool_registry.h> + +#include "tool_star.h" +#include "kis_tool_star.h" + + +typedef KGenericFactory<ToolStar> ToolStarFactory; +K_EXPORT_COMPONENT_FACTORY( kritatoolstar, ToolStarFactory( "krita" ) ) + + +ToolStar::ToolStar(QObject *parent, const char *name, const QStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(ToolStarFactory::instance()); + if ( parent->inherits("KisToolRegistry") ) + { + KisToolRegistry * r = dynamic_cast<KisToolRegistry*>( parent ); + r -> add(new KisToolStarFactory()); + } + +} + +ToolStar::~ToolStar() +{ +} + +#include "tool_star.moc" + + + + + +Registries + + +Tools are loaded by the tool registry and register themselves with the tool +registry. Plugins like tools, filters and paintops are loaded only once: view +plugins are loaded for every view that is created. Note that we register +factories, generally speaking. For instance, with tools a new instance of a +tool is created for every pointer (mouse, stylus, eraser) for every few. And a +new paintop is created whenever a tool gets a mouse-down event. + + + +Filters call the filter registry: + + if (parent->inherits("KisFilterRegistry")) { + KisFilterRegistry * manager = dynamic_cast<KisFilterRegistry *>(parent); + manager->add(new KisFilterInvert()); + } + + +Paintops the paintop registry: + + if ( parent->inherits("KisPaintOpRegistry") ) { + KisPaintOpRegistry * r = dynamic_cast<KisPaintOpRegistry*>(parent); + r -> add ( new KisSmearyOpFactory ); + } + + +Colorspaces the colorspace registry (with some complications): + + if ( parent->inherits("KisColorSpaceFactoryRegistry") ) { + KisColorSpaceFactoryRegistry * f = dynamic_cast<isColorSpaceFactoryRegistry*>(parent); + + KisProfile *defProfile = new KisProfile(cmsCreate_sRGBProfile()); + f->addProfile(defProfile); + + KisColorSpaceFactory * csFactory = new KisRgbColorSpaceFactory(); + f->add(csFactory); + + KisColorSpace * colorSpaceRGBA = new KisRgbColorSpace(f, 0); + KisHistogramProducerFactoryRegistry::instance() -> add( + new KisBasicHistogramProducerFactory<KisBasicU8HistogramProducer> + (KisID("RGB8HISTO", i18n("RGB8 Histogram")), colorSpaceRGBA) ); + } + + +View plugins do not have to register themselves, and they get access to a +KisView object: + + if ( parent->inherits("KisView") ) + { + setInstance(ShearImageFactory::instance()); + setXMLFile(locate("data","kritaplugins/shearimage.rc"), true); + + (void) new KAction(i18n("&Shear Image..."), 0, 0, this, SLOT(slotShearImage()), actionCollection(), "shearimage"); + (void) new KAction(i18n("&Shear Layer..."), 0, 0, this, SLOT(slotShearLayer()), actionCollection(), "shearlayer"); + + m_view = (KisView*) parent; + } + + +Remember that this means that a view plugin will be created for every view the +user creates: splitting a view means loading all view plugins again. + + + + +Plugin versioning + + +&krita; 1.5 loads plugins with X-KDE-Version=2 set in the +.desktop file. &krita; 1.6 plugins will +probably be binary incompatible with 1.5 plugins and will need the version +number 3. &krita; 2.0 plugins will need the version number 3. Yes, this is not +entirely logical. + + + + + + + +Colorspaces + + +Colorspaces implement the KisColorSpace pure virtual +class. There are two types of colorspaces: those that can use +lcms for transformations between colorspaces, and those +that are too weird for lcms to handle. Examples of the +first are cmyk, rgb, yuv. An example of the latter is watercolor or wet & +sticky. Colorspaces that use lcms can be derived from +KisAbstractColorSpace, or of one of the base classes +that are specialized for a certain number of bits per channel. + +Implementing a colorspace is pretty easy. The general principle is that +colorspaces work on a simple array of bytes. The interpretation of these bytes +is up to the colorspace. For instance, a pixel in 16-bit GrayA consists of +four bytes: two bytes for the gray value and two bytes for the alpha value. +You are free to use a struct to work with the memory layout of a pixel in your +colorspace implementation, but that representation is not exported. The only +way the rest of &krita; can know what channels and types of channels your +colorspace pixels consist of is through the +KisChannelInfo class. + +Filters and paintops make use of the rich set of methods offered by +KisColorSpace to do their work. In many cases, the +default implementation in KisAbstractColorSpace will +work, but more slowly than a custom implementation in your own colorspace +because KisAbstractColorSpace will convert all pixels +to 16-bit L*a*b and back. + + + +<classname>KisChannelInfo</classname> + + +(http://websvn.kde.org/trunk/koffice/krita/kritacolor/kis_channelinfo.h) + + +This class defines the channels that make up a single pixel in a particular +colorspace. A channel has the following important characteristics: + + +a name for display in the user interface +a position: the byte where the bytes representing this channel +start in the pixel. +a type: color, alpha, substance or substrate. Color is plain +color, alpha is see-throughishness, substance is a representation of amount of +pigment or things like that, substrate is the representation of the canvas. +(Note that this may be refactored at the drop of a hat.) +a valuetype: byte, short, integer, float — or +other. +size: the number of bytes this channel takes +color: a QColor representation of this +channel for user interface visualization, for instance in +histograms. +an abbreviaton for use in the GUI when there’s not much +space + + + + +<classname>KisCompositeOp</classname> + + +As per original Porter-Duff, there are many ways of combining pixels to get a +new color. The KisCompositeOp class defines most of +them: this set is not easily extensible except by hacking the kritacolor +library. + +A colorspace plugin can support any subset of these possible composition +operations, but the set must always include "OVER" (same as "NORMAL") and +"COPY". The rest are more or less optional, although more is better, of +course. + + + + +<classname>KisColorSpace</classname> + + +The methods in the KisColorSpace pure virtual classs +can be divided into a number of groups: conversion, identification and +manipulation. + +All classes must be able to convert a pixel from and to 8 bit RGB (i.e., a +QColor), and preferably also to and from 16 bit L*a*b. +Additionally, there is a method to convert to any colorspace from the current +colorspace. + +Colorspaces are described by the KisChannelInfo vector, +number of channels, number of bytes in a single pixel, whether it supports +High Dynamic Range images and more. + +Manipulation is for instance the combining of two pixels in a new +pixel: bitBlt, darkening or convolving of pixels. + +Please consult the API documentation for a full description of all methods you +need to implement in a colorspace. + +KisAbstractColorSpace implements many of the virtual +methods of KisColorSpace using functions from the +lcms library. On top of +KisAbstractColorSpace there are base colorspace classes +for 8 and 16 bit integer and 16 and 32 bit float colorspaces that define +common operations to move between bit depths. + + + + + + +Filters + + +Filters are plugins that examine the pixels in a layer and them make changes +to them. Although &krita; uses an efficient tiled memory backend to store +pixels, filter writers do not have to bother with that. When writing a filter +plugin for the &Java; imaging API, Photoshop or The Gimp, you need to take care +of tile edges and cobble tiles together: &krita; hides that +implementation detail. + +Note that it is theoretically easy to replace the current tile +image data storage backend with another backend, but that backens are not true +plugins at the moment, for performance reasons. + +&krita; uses iterators to read and write pixel values. Alternatively, you can +read a block of pixels into a memory buffer, mess with it and then write it +back as a block. But that is not necessarily more efficient, it may even be +slower than using the iterators; it may just be more convenient. See the API +documentation. + +&krita; images are composed of layers, of which there are currently four +kinds: paint layers, group layers, adjustment layers (that contain a filter +that is applied dynamically to layers below the adjustment layer) and part +layers. Filters always operate on paint layers. Paint layers contain paint +devices, of the class KisPaintDevice. A paint device in +its turn gives access to the actual pixels. + +PaintDevices are generally passed around wrapped in +shared pointers. A shared pointer keeps track of in how many places the paint +device is currently used and deletes the paint device when it is no longer +used anywhere. You recognize the shared pointer version of a paint device +through its SP suffix. Just remember that you never have to +explicitly delete a KisPaintDeviceSP. + +Let's examine a very simple filter, one that inverts every pixel. The code for +this filter is in the koffice/krita/plugins/filters/example directory. +The main method is + +KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, + KisFilterConfiguration* /*config*/, const QRect& rect). + +The function gets passed two paint devices, a configuration object (which is +not used in this simple filter) and a rect. The +rect describes the area of the +paint device which the filter should act on. This area is described by +integers, which means no sub-pixel accuracy. + +The src paint device is for reading from, the +dst paint device for writing to. These parameters may point +to the same actual paint device, or be two different paint devices. (Note: +this may change to only one paint device in the future.) + +Now, let's look at the code line by line: + + +void KisFilterInvert::process(KisPaintDeviceSP src, KisPaintDeviceSP dst, + KisFilterConfiguration* /*config*/, const QRect& rect) +{ + Q_ASSERT(src != 0); + Q_ASSERT(dst != 0); + + KisRectIteratorPixel srcIt = src->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), false); + KisRectIteratorPixel dstIt = dst->createRectIterator(rect.x(), rect.y(), rect.width(), rect.height(), true ); + + int pixelsProcessed = 0; + setProgressTotalSteps(rect.width() * rect.height()); + + KisColorSpace * cs = src->colorSpace(); + Q_INT32 psize = cs->pixelSize(); + + while( ! srcIt.isDone() ) + { + if(srcIt.isSelected()) + { + memcpy(dstIt.rawData(), srcIt.oldRawData(), psize); + + cs->invertColor( dstIt.rawData(), 1); + } + setProgress(++pixelsProcessed); + ++srcIt; + ++dstIt; + } + setProgressDone(); // Must be called even if you don't really support progression +} + + + + +This creates an iterator to read the existing pixels. Krita has three +types of iterators: horizontal, vertical and rectangular. The rect iterator +takes the most efficient path through the image data, but does not guarantee +anything about the location of the next pixel it returns. That means that you +cannot be sure that the pixel you will retrieve next will be adjacent to the +pixel you just got. The horizontal and vertical line iterators do guarantee +the location of the pixels they return. + + +(2) We create the destination iterator with the write +setting to true. This means that if the destination paint +device is smaller than the rect we write, it will automatically be enlarged to +fit every pixel we iterate over. Note that we have got a potential bug here: +if dst and src are not the same device, +then it is quite possible that the pixels returned by the iterators do not +correspond. For every position in the iterator, src may be, +for example, at 165,200, while dst could be at 20,8 — +and therefore the copy we perform below may distort the image... + + +Want to know if a pixel is selected? That is easy — use the +isSelected method. But selectedness is not a binary +property of a pixel, a pixel can be half selected, barely selected or almost +completely selected. That value you can also got from the iterator. Selections +are actually a mask paint device with a range between 0 and 255, where 0 is +completely unselected and 255 completely selected. The iterator has two +methods: isSelected() and +selectedNess(). The first returns true if a pixel is +selected to any extent (i.e., the mask value is greater than 1), the other +returns the maskvalue. + + +As noted above, this memcpy is a big bad bug... +rawData() returns the array of bytes which is the +current state of the pixel; oldRawData() returns the +array of bytes as it was before we created the iterator. However, we may be +copying the wrong pixel here. In actual practice, that will not happen too +often, unless dst already exists and is not aligned with +src. + + +But this is correct: instead of figuring out which byte represents which +channel, we use a function supplied by all colorspaces to invert the current +pixel. The colorspaces have a lot of pixel operations you can make use of. + + + + +This is not all there is to creating a filter. Filters have two other +important components: a configuration object and a configuration widget. The +two interact closely. The configuration widget creates a configuration object, +but can also be filled from a pre-existing configuration object. Configuration +objects can represtent themselves as XML and can be created from XML. That is +what makes adjustment layers possible. + + + +Iterators + + +There are three types of iterators: + + + +Horizontal lines +Vertical lines +Rectangular iterors + + + +The horizontal and vertical line iterators have a method to move the iterator +to the next row or column: nextRow() and +nextCol(). Using these is much faster than creating a +new iterator for every line or column. + +Iterators are thread-safe in &krita;, so it is possible to divide the work +over multiple threads. However, future versions of &krita; will use the +supportsThreading() method to determine whether your +filter can be applied to chunks of the image (&ie;, all pixels modified +independently, instead of changed by some value determined from an examination +of all pixels in the image) and automatically thread the execution your +filter. + + + + +<classname>KisFilterConfiguration</classname> + + +KisFilterConfiguration is a structure that is used to +save filter settings to disk, for instance for adjustment layers. The +scripting plugin uses the property map that’s at the back of +KisFilterConfigaration to make it possible to script +filters. Filters can provide a custom widget that &krita; will show in the +filters gallery, the filter preview dialog or the tool option tab of the +paint-with-filters tool. + + +An example, taken from the oilpaint effect filter: + + +class KisOilPaintFilterConfiguration : public KisFilterConfiguration +{ + +public: + + KisOilPaintFilterConfiguration(Q_UINT32 brushSize, Q_UINT32 smooth) + : KisFilterConfiguration( "oilpaint", 1 ) + { + setProperty("brushSize", brushSize); + setProperty("smooth", smooth); + }; +public: + + inline Q_UINT32 brushSize() { return getInt("brushSize"); }; + inline Q_UINT32 smooth() {return getInt("smooth"); }; + +}; + + + + +<classname>KisFilterConfigurationWidget</classname> + + +Most filters can be tweaked by the user. You can create a configuration widget +that Krita will use where-ever your filter is used. An example: + + + + +The Oilpaint dialog + + + + + +The Oilpaint dialog + + + + + + + +Note that only the left-hand side of this dialog is your responsibility: +&krita; takes care of the rest. There are three ways of going about creating +an option widget: + + + +Use &Qt; Designer to create a widget base, and subclass it for +your filter +Use one of the simple widgets that show a number of sliders +for lists of integers, doubles or bools. These are useful if, like the above +screenshot, your filter can be configured by a number of integers, doubles or +bools. See the API dox for KisMultiIntegerFilterWidget, +KisMultiDoubleFilterWidget and +KisMultiBoolFilterWidget. +Hand-code a widget. This is not recommended, and if you do so +and want your filter to become part of &krita;’s official release, then I’ll ask +you to replate your hand-coded widget with a &Qt; Designer +widget. + + + +The oilpaint filter uses the multi integer widget: + + + +KisFilterConfigWidget * KisOilPaintFilter::createConfigurationWidget(QWidget* parent, KisPaintDeviceSP /*dev*/) +{ + vKisIntegerWidgetParam param; + param.push_back( KisIntegerWidgetParam( 1, 5, 1, i18n("Brush size"), "brushSize" ) ); + param.push_back( KisIntegerWidgetParam( 10, 255, 30, i18n("Smooth"), "smooth" ) ); + return new KisMultiIntegerFilterWidget(parent, id().id().ascii(), id().id().ascii(), param ); +} + +KisFilterConfiguration* KisOilPaintFilter::configuration(QWidget* nwidget) +{ + KisMultiIntegerFilterWidget* widget = (KisMultiIntegerFilterWidget*) nwidget; + if( widget == 0 ) + { + return new KisOilPaintFilterConfiguration( 1, 30); + } else { + return new KisOilPaintFilterConfiguration( widget->valueAt( 0 ), widget->valueAt( 1 ) ); + } +} + +std::list<KisFilterConfiguration*> KisOilPaintFilter::listOfExamplesConfiguration(KisPaintDeviceSP ) +{ + std::list<KisFilterConfiguration*> list; + list.insert(list.begin(), new KisOilPaintFilterConfiguration( 1, 30)); + return list; +} + + + +You can see how it works: fill a vector with your integer parameters and +create the widget. The configuration() method +inspects the widget and creates the right filter configuration object, in this +case, of course, KisOilPaintFilterConfiguration. The +listOfExamplesConfiguration method (which should be +renamed to correct English...) returns a list with example configuration +objects for the filters gallery dialog. + + + + +Filters conclusion + + +There’s more to coding interesting filters, of course, but with this +explanation, the API documentation and access to our source code, you should +be able to get started. Don’t hesitate to contact the &krita; developers on +IRC or on the mailing list. + + + + + + +Tools + + +Tools appear in &krita;’s toolbox. This means that there is limited space for +new tools — think carefully whether a paint operation isn’t enough for +your purposes. Tools can use the mouse/tablet and keyboard in complex ways, +which paint operations cannot. This is the reason that Duplicate is a tool, +but airbrush a paint operation. + +Be careful with static data in your tool: a new instance of your tool is +created for every input device: mouse, stylus, eraser, airbrush — whatever. +Tools come divided into logical groups: + + +shape drawing tools (circle, rect) +freehand drawing tools (brush) +transform tools that mess up the geometry of a +layer +fill tools (like bucket fill or gradient) +view tools (that don’t change pixels, but alter the way you +view the canvas, such as zoom) +select tools (that change the selection +mask) + + + +The tool interface is described in the API documentation for +KisTool. There are three subclasses: +KisToolPaint, KisToolNonPaint +and KisToolShape (which is actually a subclass of +KisToolPaint) that specialize +KisTool for painting tasks (i.e., changing pixels) , +non-painting tasks and shape painting tasks. + +A tool has an option widget, just like filters. Currently, the option widgets +are shown in a tab in a dock window. We may change that to a strip under the +main menu (which then replaces the toolbar) for &krita; 2.0, but for now, +design your option widget to fit in a tab. As always, it’s best to use &Qt; +Designer for the design of the option widget. + +A good example of a tool is the star tool: + + + +kis_tool_star.cc Makefile.am tool_star_cursor.png wdg_tool_star.ui +kis_tool_star.h Makefile.in tool_star.h +kritatoolstar.desktop tool_star.cc tool_star.png + + + +As you see, you need two images: one for the cursor and one for the toolbox. +tool_star.cc is just the plugin loader, similar to what +we have seen above. The real meat is in the implementation: + + + +KisToolStar::KisToolStar() + : KisToolShape(i18n("Star")), + m_dragging (false), + m_currentImage (0) +{ + setName("tool_star"); + setCursor(KisCursor::load("tool_star_cursor.png", 6, 6)); + m_innerOuterRatio=40; + m_vertices=5; +} + + + +The constructor sets the internal name — which is not translated +— and the call to the superclass sets the visible name. We also load the +cursor image and set a number of variables. + + + +void KisToolStar::update (KisCanvasSubject *subject) +{ + KisToolShape::update (subject); + if (m_subject) + m_currentImage = m_subject->currentImg(); +} + + + +The update() method is called when the tool is +selected. This is not a KisTool method, but a +KisCanvasObserver method. Canvas observers are notified +whenever something changes in the view, which can be useful for tools. + +The following methods (buttonPress, +move and buttonRelease) are +called by &krita; when the input device (mouse, stylus, eraser etc.) is +pressed down, moved or released. Note that you also get move events if the +mouse button isn’t pressed. The events are not the regular &Qt; events, but +synthetic &krita; events because we make use of low-level trickery to get +enough events to draw a smooth line. By default, toolkits like &Qt; (and GTK) +drop events if they are too busy to handle them, and we want them all. + + + +void KisToolStar::buttonPress(KisButtonPressEvent *event) +{ + if (m_currentImage && event->button() == LeftButton) { + m_dragging = true; + m_dragStart = event->pos(); + m_dragEnd = event->pos(); + m_vertices = m_optWidget->verticesSpinBox->value(); + m_innerOuterRatio = m_optWidget->ratioSpinBox->value(); + } +} + +void KisToolStar::move(KisMoveEvent *event) +{ + if (m_dragging) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + // move (alt) or resize star + if (event->state() & Qt::AltButton) { + KisPoint trans = event->pos() - m_dragEnd; + m_dragStart += trans; + m_dragEnd += trans; + } else { + m_dragEnd = event->pos(); + } + // draw new lines on canvas + draw(m_dragStart, m_dragEnd); + } +} + +void KisToolStar::buttonRelease(KisButtonReleaseEvent *event) +{ + if (!m_subject || !m_currentImage) + return; + + if (m_dragging && event->button() == LeftButton) { + // erase old lines on canvas + draw(m_dragStart, m_dragEnd); + m_dragging = false; + + if (m_dragStart == m_dragEnd) + return; + + if (!m_currentImage) + return; + + if (!m_currentImage->activeDevice()) + return; + + KisPaintDeviceSP device = m_currentImage->activeDevice ();; + KisPainter painter (device); + if (m_currentImage->undo()) painter.beginTransaction (i18n("Star")); + + painter.setPaintColor(m_subject->fgColor()); + painter.setBackgroundColor(m_subject->bgColor()); + painter.setFillStyle(fillStyle()); + painter.setBrush(m_subject->currentBrush()); + painter.setPattern(m_subject->currentPattern()); + painter.setOpacity(m_opacity); + painter.setCompositeOp(m_compositeOp); + KisPaintOp * op = + KisPaintOpRegistry::instance()->paintOp(m_subject->currentPaintop(), m_subject->currentPaintopSettings(), &painter); + painter.setPaintOp(op); // Painter takes ownership + + vKisPoint coord = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y()); + + painter.paintPolygon(coord); + + device->setDirty( painter.dirtyRect() ); + notifyModified(); + + if (m_currentImage->undo()) { + m_currentImage->undoAdapter()->addCommand(painter.endTransaction()); + } + } +} + + + +The draw() method is an internal method of +KisToolStar and draws the outline of the star. We call +this from the move() method to give the user feedback +of the size and shape of their star. Note that we use the +Qt::NotROP raster operation, which means that calling +draw() a second time with the same start and end +point the previously drawn star will be deleted. + + + +void KisToolStar::draw(const KisPoint& start, const KisPoint& end ) +{ + if (!m_subject || !m_currentImage) + return; + + KisCanvasController *controller = m_subject->canvasController(); + KisCanvas *canvas = controller->kiscanvas(); + KisCanvasPainter p (canvas); + QPen pen(Qt::SolidLine); + + KisPoint startPos; + KisPoint endPos; + startPos = controller->windowToView(start); + endPos = controller->windowToView(end); + + p.setRasterOp(Qt::NotROP); + + vKisPoint points = starCoordinates(m_vertices, startPos.x(), startPos.y(), endPos.x(), endPos.y()); + + for (uint i = 0; i < points.count() - 1; i++) { + p.drawLine(points[i].floorQPoint(), points[i + 1].floorQPoint()); + } + p.drawLine(points[points.count() - 1].floorQPoint(), points[0].floorQPoint()); + + p.end (); +} + + + +The setup() method is essential: here we create the +action that will be plugged into the toolbox so users can actually select the +tool. We also assign a shortcut key. Note that there’s some hackery going on: +remember that we create an instance of the tool for every input device. This +also means that we call setup() for every input +device and that means that an action with the same name is added several times +to the action collection. However, everything seems to work, so why worry? + + + +void KisToolStar::setup(KActionCollection *collection) +{ + m_action = static_cast<KRadioAction *>(collection->action(name())); + + if (m_action == 0) { + KShortcut shortcut(Qt::Key_Plus); + shortcut.append(KShortcut(Qt::Key_F9)); + m_action = new KRadioAction(i18n("&Star"), + "tool_star", + shortcut, + this, + SLOT(activate()), + collection, + name()); + Q_CHECK_PTR(m_action); + + m_action->setToolTip(i18n("Draw a star")); + m_action->setExclusiveGroup("tools"); + m_ownAction = true; + } +} + + + +The starCoordinates() method contains some funky math +— but is not too interesting for the discussion of how to create a tool +plugins. + + + +KisPoint KisToolStar::starCoordinates(int N, double mx, double my, double x, double y) +{ + double R=0, r=0; + Q_INT32 n=0; + double angle; + + vKisPoint starCoordinatesArray(2*N); + + // the radius of the outer edges + R=sqrt((x-mx)*(x-mx)+(y-my)*(y-my)); + + // the radius of the inner edges + r=R*m_innerOuterRatio/100.0; + + // the angle + angle=-atan2((x-mx),(y-my)); + + //set outer edges + for(n=0;n<N;n++){ + starCoordinatesArray[2*n] = KisPoint(mx+R*cos(n * 2.0 * M_PI / N + angle),my+R*sin(n *2.0 * M_PI / N+angle)); + } + + //set inner edges + for(n=0;n<N;n++){ + starCoordinatesArray[2*n+1] = KisPoint(mx+r*cos((n + 0.5) * 2.0 * M_PI / N + angle),my+r*sin((n +0.5) * 2.0 * M_PI / N + angle)); + } + + return starCoordinatesArray; +} + + + +The createOptionWidget() method is called to create +the option widget that &krita; will show in the tab. Since there is a tool per +input device per view, the state of a tool can be kept in the tool. This +method is only called once: the option widget is stored and retrieved the next +time the tool is activated. + + + +QWidget* KisToolStar::createOptionWidget(QWidget* parent) +{ + QWidget *widget = KisToolShape::createOptionWidget(parent); + + m_optWidget = new WdgToolStar(widget); + Q_CHECK_PTR(m_optWidget); + + m_optWidget->ratioSpinBox->setValue(m_innerOuterRatio); + + QGridLayout *optionLayout = new QGridLayout(widget, 1, 1); + super::addOptionWidgetLayout(optionLayout); + + optionLayout->addWidget(m_optWidget, 0, 0); + + return widget; +} + + + +Tool Conclusions + + +Tools are relatively simple plugins to create. You need to combine the +KisTool and KisCanvasObserver +interfaces in order to effectively create a tool. + + + + + + + +Paint operations + + +PaintOps are one of the more innovative types of plugins in Krita (together +with pluggable colorspaces). A paint operation defines how tools change the +pixels they touch. Airbrush, aliased pencil or antialiased pixel brush: these +are all paint operations. But you could — with a lot of work — +create a paintop that reads Corel Painter XML brush definitions and uses those +to determine how painting is done. + +Paint operations are instantiated when a paint tool receives a +mouseDown event and are deleted when the mouseUp event is +received by a paint tool. In between, the paintop can keep track of previous +positions and other data, such as pressure levels if the user uses a tablet. + +The basic operation of a paint operation is to change pixels at the cursor +position of a paint tool. That can be done only once, or the paint op can +demand to be run at regular intervals, using a timer. The first would be +useful for a pencil-type paint op, the second, of course, for an +airbrush-type paintop. + +Paintops can have a small configuration widget which is placed in a toolbar. +Thus, paintop configuration widgets need to have a horizontal layout of +widgets that are not higher than a toolbar button. Otherwise, &krita; will +look very funny. + +Let’s look at a simple paintop plugin, one that shows a little bit of +programmatic intelligence. First, in the header file, there’s a factory +defined. This factory creates a paintop when the active tool needs one: + + + +public: + KisSmearyOpFactory() {} + virtual ~KisSmearyOpFactory() {} + + virtual KisPaintOp * createOp(const KisPaintOpSettings *settings, KisPainter * painter); + virtual KisID id() { return KisID("paintSmeary", i18n("Smeary Brush")); } + virtual bool userVisible(KisColorSpace * ) { return false; } + virtual QString pixmap() { return ""; } + +}; + + + +The factory also contains the KisID with the public and +private name for the paintop — make sure your paintop’s private name +does not clash with another paintop! — and may optionally return a +pixmap. &krita; can then show the pixmap together with the name for visual +identifcation of your paintop. For instance, a painter’s knife paintop would +have the image of such an implement. + +The implementation of a paintop is very straightforward: + + + +KisSmearyOp::KisSmearyOp(KisPainter * painter) + : KisPaintOp(painter) +{ +} + +KisSmearyOp::~KisSmearyOp() +{ +} +void KisSmearyOp::paintAt(const KisPoint &pos, const KisPaintInformation& info) +{ + + + +The paintAt() method really is where it’s at, with +paintops. This method receives two parameters: the current position (which is +in floats, not in whole pixels) and a +KisPaintInformation object. which contains the +pressure, x and y tilt, and movement vector, and may in the future be extended +with other information. + + + + if (!m_painter->device()) return; + + KisBrush *brush = m_painter->brush(); + + + +A KisBrush is the representation of a Gimp brush file: +that is a mask, either a single mask or a series of masks. Actually, we don’t +use the brush here, except to determine the hotspot under the +cursor. + + + + Q_ASSERT(brush); + + if (!brush) return; + + if (! brush->canPaintFor(info) ) + return; + + KisPaintDeviceSP device = m_painter->device(); + KisColorSpace * colorSpace = device->colorSpace(); + KisColor kc = m_painter->paintColor(); + kc.convertTo(colorSpace); + + KisPoint hotSpot = brush->hotSpot(info); + KisPoint pt = pos - hotSpot; + + // Split the coordinates into integer plus fractional parts. The integer + // is where the dab will be positioned and the fractional part determines + // the sub-pixel positioning. + Q_INT32 x, y; + double xFraction, yFraction; + + splitCoordinate(pt.x(), &x, &xFraction); + splitCoordinate(pt.y(), &y, &yFraction); + + KisPaintDeviceSP dab = new KisPaintDevice(colorSpace, "smeary dab"); + Q_CHECK_PTR(dab); + + + +We don’t change the pixels of a paint device directly: instead we create a +small paint device, a dab, and composite that onto the current paint device. + + + + m_painter->setPressure(info.pressure); + + + +As the comments say, the next bit code does some programmatic work to create +the actual dab. In this case, we draw a number of lines. When I am done with +this paintop, the length, position and thickness of the lines will be +dependent on pressure and paint load, and we’ll have create a stiff, smeary +oilpaint brush. But I haven’t had time to finish this yet. + + + + // Compute the position of the tufts. The tufts are arranged in a line + // perpendicular to the motion of the brush, i.e, the straight line between + // the current position and the previous position. + // The tufts are spread out through the pressure + + KisPoint previousPoint = info.movement.toKisPoint(); + KisVector2D brushVector(-previousPoint.y(), previousPoint.x()); + KisVector2D currentPointVector = KisVector2D(pos); + brushVector.normalize(); + + KisVector2D vl, vr; + + for (int i = 0; i < (NUMBER_OF_TUFTS / 2); ++i) { + // Compute the positions on the new vector. + vl = currentPointVector + i * brushVector; + KisPoint pl = vl.toKisPoint(); + dab->setPixel(pl.roundX(), pl.roundY(), kc); + + vr = currentPointVector - i * brushVector; + KisPoint pr = vr.toKisPoint(); + dab->setPixel(pr.roundX(), pr.roundY(), kc); + } + + vr = vr - vl; + vr.normalize(); + + + +Finally we blt the dab onto the original paint device and tell the painter +that we’ve dirtied a small rectangle of the paint device. + + + + if (m_source->hasSelection()) { + m_painter->bltSelection(x - 32, y - 32, m_painter->compositeOp(), dab.data(), + m_source->selection(), m_painter->opacity(), x - 32, y -32, 64, 64); + } + else { + m_painter->bitBlt(x - 32, y - 32, m_painter->compositeOp(), dab.data(), m_painter->opacity(), x - 32, y -32, 64, 64); + } + + m_painter->addDirtyRect(QRect(x -32, y -32, 64, 64)); +} + + +KisPaintOp * KisSmearyOpFactory::createOp(const KisPaintOpSettings */*settings*/, KisPainter * painter) +{ + KisPaintOp * op = new KisSmearyOp(painter); + Q_CHECK_PTR(op); + return op; +} + + + +That’s all: paintops are easy and fun! + + + + + +View plugins + + +View plugins are the weirdest of the bunch: a view plugin is an ordinary KPart +that can provide a bit of user interface and some functionality. For instance, +the histogram tab is a view plugin, as is the rotate dialog. + + + + + +Import/Export filters + + +&krita; works with the ordinary &koffice; file filter architecture. There is a +tutorial, a bit old, but still useful, at: . It is probably best +to cooperate with the &krita; team when developing file filters and do the +development in the &koffice; filter tree. Note that you can test your filters +without running &krita; using the koconverter utility. + +Filters have two sides: importing and exporting. These are usually two +different plugins that may share some code. + +The important Makefile.am entries are: + + + +service_DATA = krita_XXX_import.desktop krita_XXX_export.desktop +servicedir = $(kde_servicesdir) +kdelnk_DATA = krita_XXX.desktop +kdelnkdir = $(kde_appsdir)/Office +libkritaXXXimport_la_SOURCES = XXXimport.cpp +libkritaXXXexport_la_SOURCES = XXXexport.cpp +METASOURCES = AUTO + + + +Whether you are building an import filter or an export filter, your work always +boils down to implementing the following function: + + + +virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + + + +It is the settings in the .desktop files +that determine which way a filter converts: + +Import: + + + +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-xcf-gimp +X-KDE-Weight=1 +X-KDE-Library=libkritaXXXimport +ServiceTypes=KOfficeFilter + + + +Export: + + + +X-KDE-Export=image/x-xcf-gimp +X-KDE-Import=application/x-krita +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Weight=1 +X-KDE-Library=libkritaXXXexport + + + +And yes, the mimetype chosen for the example is a hint. Please, pretty please, +implement an xcf filter? + + + +Import + + +The big problem with import filters is of course your code to read the data on +disk. The boilerplate for calling that code is fairly simple: + + +Note: we really, really should find a way to enable &krita; to keep +a file open and only read data on a as-needed basis, instead of copying the +entire contents to the internal paint device representation. But that would +mean datamanager backends that know about tiff files and so on, and is not +currently implemented. It would be ideal if some file filters could implement +a class provisionally named KisFileDataManager, create +an object of that instance with the current file and pass that to KisDoc. But +&krita; handles storage per layer, not per document, so this would be a hard +refactor to do. + + +KoFilter::ConversionStatus XXXImport::convert(const QCString&, const QCString& to) +{ + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast<KisDoc*>(m_chain -> outputDocument()); + KisView * view = static_cast<KisView*>(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc -> prepareForImport(); + + if (!filename.isEmpty()) { + + KURL url(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisImageXXXConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + + + +This is supposed to be an importfilter, so +if it is not called to convert to a &krita; image, then something is +wrong. +The filter chain already has created an +output document for us. We need to cast it to KisDocM, +because &krita; documents need special treatment. It would not, actually, be +all that bad an idea to check whether the result of the cast is not 0, because +if it is, importing will fail. +If we call this filter from the GUI, we try +to get the view. If there is a view, the conversion code can try to update the +progressbar. +The filter has the filename for our input +file for us. +KisDoc needs to be +prepared for import. Certain settings are initialized and undo is disabled. +Otherwise you could undo the adding of layers performed by the import filter +and that is weird behaviour. +I have chosed to implement the actual +importing code in a separate class that I instantiate here. You can also put +all your code right in this method, but that would be a bit +messy. +My importer returns a statuscode that I +can then use to set the status of the import filter. &koffice; takes care of +showing error messages. +If creating the +KisImage has succeeded we set the document's current +image to our newly created image. Then we are done: return +KoFilter::OK;. + + + + + + + diff --git a/doc/krita/developers-scripting.docbook b/doc/krita/developers-scripting.docbook new file mode 100644 index 000000000..b4ee3a53c --- /dev/null +++ b/doc/krita/developers-scripting.docbook @@ -0,0 +1,534 @@ + +Scripting + + +In &krita;, you can write scripts in Ruby or Python (the availability of the +interpreters might depend on what your distributions or the administrator of +your machine did install). Here you will find a description of the scripting +API. + +Some examples are distributed with &krita;, and you might find them in +/usr/share/apps/krita/scripts (or +/opt/kde/share/apps/krita/scripts). + + + +Variables in the <classname>Krosskritacore</classname> module + + +KritaDocument returns a +Document object +KritaScript returns a +ScriptProgress object + + + +You can retrieve an object using the get function of the +Krosskritacore module, in Ruby you will have to write something like that: + +doc = Krosskritacore::get("KritaDocument") +script = Krosskritacore::get("KritaScript") + + + + + + +Functions in the <classname>Krosskritacore</classname> module + + +Function: getBrush +This function returns a Brush taken from the list of +&krita; resources. It takes one argument: the name of the brush. +For example (in Ruby): + +Krosskritacore::getBrush("Circle (05)") + + +Function: getFilter +This function returns a Filter taken from the list of +&krita; resources. It takes one argument: the name of the filter. +For example (in Ruby): + +Krosskritacore::getFilter("invert") + + +Function: getPattern +This function returns a Pattern taken from the list of +&krita; resources. It takes one argument: the name of the pattern. +For example (in Ruby): + +Krosskritacore::getPattern("Bricks") + + +Function: loadBrush +This function loads a Brush and then returns it. +It takes one argument: the filename of the brush. + +Function: loadPattern +This function loads a Pattern and then returns it. +It takes one argument: the filename of the pattern. + +Function: newCircleBrush +This function returns a Brush with a circular shape. It +takes at least two arguments: width and height. It can take two other +arguments: width of the shading, and height of the shading. If the shading +is not specified, no shading will be used. +For example (in Ruby): + +Krosskritacore::newCircleBrush(10,20) # create a plain circle +Krosskritacore::newCircleBrush(10,20,5,10) # create a gradient + + +Function: newHSVColor +This function returns a new Color with the given HSV +triplet. It takes three arguments: hue component (0 to 255), saturation +component (0 to 255), value component (0 to 255). + +For example (in Ruby): + +Krosskritacore::newHSVColor(255,125,0) + + +Function: newImage +This function returns a new Image. It takes four arguments: +width, height, colorspace id, name of the image. And in return you get an +Image object. +For example (in Ruby): + +Krosskritacore::newImage(10,20, "RGBA", "kikoo") + + +Function: newRectBrush +This function returns a Brush with a rectangular shape. +It takes at least two arguments: width and height. It can take two other +arguments: width of the shading and height of the shading. If the shading is +not specified, no shading will be used. +For example (in Ruby): + + Krosskritacore::newRectBrush(10,20) # create a plain rectangle + Krosskritacore::newRectBrush(10,20,5,10) # create a gradient + + +Function: newRGBColor +This function returns a new Color with the given RGB +triplet. It takes three arguments: red component (0 to 255), blue component (0 to +255), green component (0 to 255). +For example (in Ruby): + +Krosskritacore::newRGBColor(255,0,0) # create a red color +Krosskritacore::newRGBColor(255,255,255) # create a white color + + + + + +Descriptions and function lists for various objects in +<classname>Krosskritacore</classname> + + +Object: PaintLayer + + +Function: beginPainting + +Function: convertToColorspace +Convert the image to a colorspace. This function takes one argument: the name +of the destination colorspace. +For example (in Ruby): + +image.convertToColorspace("CMYK") + + +Function: createHistogram +This function creates a Histogram for this layer. It takes two arguments: +the type of the histogram ("RGB8HISTO"), and 0 if the histogram is linear, or +1 if it is logarithmic. + +Function: createHLineIterator +Create an iterator over a layer, it will iterate on a row. This function takes three arguments: +x (start in the row), y (vertical +position of the row), width of the row. + +Function: createPainter +This function creates a Painter which will allow you to +paint on the layer. + +Function: createRectIterator +Create an iterator over a layer, it will iterate on a rectangular area. This +function takes four arguments: x, y, +width of the rectangle, height of the rectangle. + +Function: createVLineIterator +Create an iterator over a layer, it will iterate on a column. This function +takes three arguments: x (horizontal position of the +column), y (start in the column), height of the column. + +Function: endPainting +This function closes the current undo entry and adds it to the history. + +Function: fastWaveletTransformation +Returns the fast wavelet transformation of the layer. + +Function: fastWaveletUntransformation +Untransforms a fast wavelet into this layer. It takes one argument: a wavelet +object. +For example (in Ruby): + +wavelet = layer.fastWaveletTransformation() +layer.fastWaveletUntransformation(wavelet) + + +Function: getHeight +Return the height of the layer. + +Function: getWidth +Return the width of the layer. + + + +Object: Filter + + +Function: getFilterConfiguration +This function returns the FilterConfiguration +associated with this filter. + +Function: process +This function will apply the filter. It takes at least one argument: the +source layer. You can also use these four aguments: x, +y, width, height. +(x,y,width,height) +defines the rectangular area on which the filter +will be computed. If the rectangle is not defined, then the filter will be +applied on the entire source layer. +For example (in Ruby) + +doc = Krosskritacore::get("KritaDocument") +image = doc.getImage() +layer = image.getActivePaintLayer() +width = layer.getWidth() +height = layer.getHeight() +filter = Krosskritacore::getFilter("invert") +filter.process(layer, layer) +filter.process(layer, layer, 10, 10, 20, 20 ) + + + +Object: FilterConfiguration + + +Function: getProperty +This function returns the value of a parameter of the associated +Filter. It takes one argument: the name of the +parameter. + +Function: setProperty +This function defines a parameter of the associated +Filter. It takes two arguments: the name of the +parameter and the value, whose type depends on the +Filter. + + + +Object: Histogram + +This class allows you to access the histogram of a +PaintLayer. +Example (in Ruby): + + doc = krosskritacore::get("KritaDocument") + image = doc.getImage() + layer = image.getActiveLayer() + histo = layer.createHistogram("RGB8HISTO",0) + min = layer.getMin() * 255 + max = layer.getMax() * 255 + for i in min..max + print layer.getValue(i) + print "\n" + end + + + + +Function: getChannel +Return the selected channel. + +Function: getCount +This function returns the number of pixels used by the histogram. + +Function: getHighest +This function returns the highest value of the histogram. + +Function: getLowest +This function returns the lowest value of the histogram. + +Function: getMax +This function returns the maximum bound of the histogram (values at greater +position than the maximum are null). The value is in the range 0.0 – 1.0. + +Function: getMean +This function returns the mean of the histogram. + +Function: getMin +This function returns the minimum bound of the histogram (values at smaller +position than the minimum are null). The value is in the range 0.0 – 1.0. + +Function: getNumberOfBins +Return the number of bins of this histogram. + +Function: getTotal +This function returns the sum of all values of the histogram. + +Function: getValue +Return the value of a bin of the histogram. This function takes one argument: +index, in the range [0..255]. + +Function: setChannel +Select the channel of the layer on which to get the result of the histogram. +This function takes one argument: the channel number. + + + +Object: ScriptProgress +ScriptProgress is used to manage the progress bar +of the status bar in &krita;. +For example (in Ruby): + +script = Krosskritacore::get("KritaScript") +script.setProgressTotalSteps(1000) +script.setProgressStage("progressive", 0) +for i in 1..900 + script.incProgress() +end +script.setProgressStage("brutal", 1000) + + + +Function: incProgress +This function increments the progress by one step. + +Function: setProgress +This function sets the value of the progress. It takes one argument: +the value of the progress. + +Function: setProgressStage +This function sets the value of the progress and displays the text. + +Function: setProgressTotalSteps +This function set the number of steps that the script will require. It takes +one argument: the maximum value of the progress + + + +Object: Wavelet +This object holds the coefficients of a wavelet transformation of a +PaintLayer. + + +Function: getDepth +Returns the depth of the layer. + +Function: getNCoeff +Returns the value of the Nth coefficient. The function takes one argument: the +index of the coefficient. + +Function: getNumCoeffs +Returns the number of coefficients in this wavelet (= size * size * depth). + +Function: getSize +Returns the size of the wavelet (size = width = height). + +Function: getXYCoeff +Returns the value of a coefficient. The function takes two arguments: +x and y. + +Function: setNCoeff +Set the value of the Nth coefficient. The function takes two arguments: the +index of the coefficient and the new value of the coefficient. + +Function: setXYCoeff +Set the value of a coefficient. The function takes three arguments: +x, y, and the new value of the +coefficient. + + + +Object: Painter + + +Function: convolve +This function applies a convolution kernel to an image. It takes at least three arguments: +a list of kernels (all lists need to have the same size), +factor, and offset. + +The value of a pixel will be given by the following function: K * P / factor + offset, +where K is the kernel and P is the neighbourhood. + +It can take the following optional arguments: borderOp +(control how to convolve the pixels on the border of an image: 0 = use the +default color, 1 = use the pixel on the opposite side of the image, 2 = use +the border pixel, 3 = avoid border pixels), channel (1 for +color, 2 for alpha, 3 for both), x, y, +width, height. + +Function: setFillThreshold +Sets the fill threshold. It takes one argument: the threshold. + +Function: fillColor +Starts filling with a color. It takes two arguments: x and +y. + +Function: fillPattern +Starts filling with a pattern. It takes two arguments: x +and y. + +Function: paintPolyline +This function will paint a polyline. It takes two arguments: a list of x +positions, and a list of y positions. + +Function: paintLine +This function will paint a line. It takes five arguments: +x1, y1, x2, +y2, and pressure. + + +Function: paintBezierCurve +This function will paint a Bezier curve. It takes ten arguments: +x1, y1, p1, +cx1, cy1, cx2, +cx2, x2, y2, +p2, where (x1,y1) is +the start position, p1 is the pressure at the start, +(x2,y2) is the end position, +p2 is the pressure at the end. +(cx1,cy1) and +(cx2,cy2) are the positions of the +control points. + +Function: paintEllipse +This function will paint an ellipse. It takes five arguments: +x1, y1, x2, +y2, pressure, where +(x1,y1) and +(x2,y2) are the positions of the two +centers. + +Function: paintPolygon +This function will paint a polygon. It takes two arguments: a list of x +positions and a list of y positions. + +Function: paintRect +This function will paint a rectangle. It takes five arguments: +x, y, width +height, pressure. + +Function: paintAt +This function will paint at a given position. +It takes three arguments: x, y, +pressure. + +Function: setPaintColor +This function sets the paint color (also called foreground color). It takes +one argument: a Color. + +Function: setBackgroundColor +This function sets the background color. It takes one argument: a +Color. + +Function: setPattern +This function sets the pattern used for filling. It takes one argument: a +Pattern object. + +Function: setBrush +This function sets the brush used for painting. It takes one argument: a +Brush object. + +Function: setPaintOp +This function defines the paint operation. It takes one argument: the name of +the paint operation. + +Function: setDuplicateOffset +This function defines the duplicate offset. It takes two arguments: the +horizontal offset and the vertical offset. + +Function: setOpacity +This function set the opacity of the painting. It takes one argument: the +opacity, in the range 0 to 255. + +Function: setStrokeStyle +This function sets the style of the stroke. It takes one argument: 0 for none, +or 1 for brush. + +Function: setFillStyle +This function sets the fill style of the Painter. +It takes one argument: 0 for none, 1 for fill with foreground color, 2 for +fill with background color, 3 for fill with pattern. + + + +Object: Iterator +This object allows you to change pixel values one by one. +The name of some functions depends on the colorspace, for instance, if the +colorspace of the layer is RGB, you will have setR, +setG and setB, and for +CMYK: setC, setM, +setY and setK. In the documentation +below we will assume that the colorspace is called ABC, with three channels: +A, B and C. + + +Functions: setA, +setB, setC +Those functions take one argument: the new value of one of the channels of +this pixel. + +Function: setABC +Set the value of all channels. This function takes one argument: an array with +the new values for all channels. + +Functions: getA, +getB, getC +Return the value of one of the channels of this pixel. + +Function: getABC +Return an array with the values of all channels. + +Function: darken +Darken a pixel. This function takes at least one argument: +shade (amount used to darken all color channels). This +function can take the following optional argument: +compensation (to limit the darkening). + +Function: invertColor +Invert the color of a pixel. + +Function: next +Increment the position, go to the next pixel. + +Function: isDone +Return true if the iterator is at the end (no more pixels are +available). + + + + + + + +Resources + + +Here are hints or partial lists of resources for &krita;. + +For Brush and Pattern: You can get +the name and the associated brush or pattern from the selector in &krita;'s +toolbar. + +A list of ids for colorspaces in &krita;: LABA, RGBA, RGBA16, RGBAF32, +RGBAF16HALF, LMSAF32, GRAYA, GRAYA16, CMYK, CMYKA16. + + + + + diff --git a/doc/krita/developers.docbook b/doc/krita/developers.docbook new file mode 100644 index 000000000..275495309 --- /dev/null +++ b/doc/krita/developers.docbook @@ -0,0 +1,13 @@ + +Developer's information + + +This chapter contains information for developers or other enthousiasts who +want to get more out of &krita;. + + +&developers-scripting; +&developers-plugins; + + + diff --git a/doc/krita/dialogs-addpalette.png b/doc/krita/dialogs-addpalette.png new file mode 100644 index 000000000..378ba4db9 Binary files /dev/null and b/doc/krita/dialogs-addpalette.png differ diff --git a/doc/krita/dialogs-blur.png b/doc/krita/dialogs-blur.png new file mode 100644 index 000000000..d41f58446 Binary files /dev/null and b/doc/krita/dialogs-blur.png differ diff --git a/doc/krita/dialogs-brightnesscontrast.png b/doc/krita/dialogs-brightnesscontrast.png new file mode 100644 index 000000000..4dd8673d0 Binary files /dev/null and b/doc/krita/dialogs-brightnesscontrast.png differ diff --git a/doc/krita/dialogs-bumpmap.png b/doc/krita/dialogs-bumpmap.png new file mode 100644 index 000000000..5a778befa Binary files /dev/null and b/doc/krita/dialogs-bumpmap.png differ diff --git a/doc/krita/dialogs-coloradjustment.png b/doc/krita/dialogs-coloradjustment.png new file mode 100644 index 000000000..8d6dcc295 Binary files /dev/null and b/doc/krita/dialogs-coloradjustment.png differ diff --git a/doc/krita/dialogs-colorrange.png b/doc/krita/dialogs-colorrange.png new file mode 100644 index 000000000..d72961a1b Binary files /dev/null and b/doc/krita/dialogs-colorrange.png differ diff --git a/doc/krita/dialogs-colortoalpha.png b/doc/krita/dialogs-colortoalpha.png new file mode 100644 index 000000000..c51d3878f Binary files /dev/null and b/doc/krita/dialogs-colortoalpha.png differ diff --git a/doc/krita/dialogs-colortransfer.png b/doc/krita/dialogs-colortransfer.png new file mode 100644 index 000000000..ccdfe92b8 Binary files /dev/null and b/doc/krita/dialogs-colortransfer.png differ diff --git a/doc/krita/dialogs-convertimagetype.png b/doc/krita/dialogs-convertimagetype.png new file mode 100644 index 000000000..54ec4e934 Binary files /dev/null and b/doc/krita/dialogs-convertimagetype.png differ diff --git a/doc/krita/dialogs-convertlayertype.png b/doc/krita/dialogs-convertlayertype.png new file mode 100644 index 000000000..748ef1f97 Binary files /dev/null and b/doc/krita/dialogs-convertlayertype.png differ diff --git a/doc/krita/dialogs-cubism.png b/doc/krita/dialogs-cubism.png new file mode 100644 index 000000000..302a40175 Binary files /dev/null and b/doc/krita/dialogs-cubism.png differ diff --git a/doc/krita/dialogs-customconvolution.png b/doc/krita/dialogs-customconvolution.png new file mode 100644 index 000000000..c3036a05d Binary files /dev/null and b/doc/krita/dialogs-customconvolution.png differ diff --git a/doc/krita/dialogs-documentinformation.png b/doc/krita/dialogs-documentinformation.png new file mode 100644 index 000000000..0df47cdd8 Binary files /dev/null and b/doc/krita/dialogs-documentinformation.png differ diff --git a/doc/krita/dialogs-dropshadow.png b/doc/krita/dialogs-dropshadow.png new file mode 100644 index 000000000..5539c24c0 Binary files /dev/null and b/doc/krita/dialogs-dropshadow.png differ diff --git a/doc/krita/dialogs-emboss.png b/doc/krita/dialogs-emboss.png new file mode 100644 index 000000000..cd1ddfff5 Binary files /dev/null and b/doc/krita/dialogs-emboss.png differ diff --git a/doc/krita/dialogs-filtersgallery.png b/doc/krita/dialogs-filtersgallery.png new file mode 100644 index 000000000..309942657 Binary files /dev/null and b/doc/krita/dialogs-filtersgallery.png differ diff --git a/doc/krita/dialogs-gaussiannoise.png b/doc/krita/dialogs-gaussiannoise.png new file mode 100644 index 000000000..5630a2aad Binary files /dev/null and b/doc/krita/dialogs-gaussiannoise.png differ diff --git a/doc/krita/dialogs-histogram.png b/doc/krita/dialogs-histogram.png new file mode 100644 index 000000000..1f91c1e4d Binary files /dev/null and b/doc/krita/dialogs-histogram.png differ diff --git a/doc/krita/dialogs-imageproperties.png b/doc/krita/dialogs-imageproperties.png new file mode 100644 index 000000000..1d100a2dc Binary files /dev/null and b/doc/krita/dialogs-imageproperties.png differ diff --git a/doc/krita/dialogs-imagerestoration.png b/doc/krita/dialogs-imagerestoration.png new file mode 100644 index 000000000..0f5f82863 Binary files /dev/null and b/doc/krita/dialogs-imagerestoration.png differ diff --git a/doc/krita/dialogs-imagesize.png b/doc/krita/dialogs-imagesize.png new file mode 100644 index 000000000..7db26de91 Binary files /dev/null and b/doc/krita/dialogs-imagesize.png differ diff --git a/doc/krita/dialogs-layerproperties.png b/doc/krita/dialogs-layerproperties.png new file mode 100644 index 000000000..1c0852d28 Binary files /dev/null and b/doc/krita/dialogs-layerproperties.png differ diff --git a/doc/krita/dialogs-layersize.png b/doc/krita/dialogs-layersize.png new file mode 100644 index 000000000..2b7bfaa7b Binary files /dev/null and b/doc/krita/dialogs-layersize.png differ diff --git a/doc/krita/dialogs-lenscorrection.png b/doc/krita/dialogs-lenscorrection.png new file mode 100644 index 000000000..39449f4b2 Binary files /dev/null and b/doc/krita/dialogs-lenscorrection.png differ diff --git a/doc/krita/dialogs-newadjustmentlayer.png b/doc/krita/dialogs-newadjustmentlayer.png new file mode 100644 index 000000000..cb55622b2 Binary files /dev/null and b/doc/krita/dialogs-newadjustmentlayer.png differ diff --git a/doc/krita/dialogs-newlayer.png b/doc/krita/dialogs-newlayer.png new file mode 100644 index 000000000..07b9b7c85 Binary files /dev/null and b/doc/krita/dialogs-newlayer.png differ diff --git a/doc/krita/dialogs-oilpaint.png b/doc/krita/dialogs-oilpaint.png new file mode 100644 index 000000000..c25e49ff3 Binary files /dev/null and b/doc/krita/dialogs-oilpaint.png differ diff --git a/doc/krita/dialogs-pixelize.png b/doc/krita/dialogs-pixelize.png new file mode 100644 index 000000000..87e5d72c1 Binary files /dev/null and b/doc/krita/dialogs-pixelize.png differ diff --git a/doc/krita/dialogs-raindrops.png b/doc/krita/dialogs-raindrops.png new file mode 100644 index 000000000..8fef6e225 Binary files /dev/null and b/doc/krita/dialogs-raindrops.png differ diff --git a/doc/krita/dialogs-randomnoise.png b/doc/krita/dialogs-randomnoise.png new file mode 100644 index 000000000..40cffc10f Binary files /dev/null and b/doc/krita/dialogs-randomnoise.png differ diff --git a/doc/krita/dialogs-randompick.png b/doc/krita/dialogs-randompick.png new file mode 100644 index 000000000..dd71fe139 Binary files /dev/null and b/doc/krita/dialogs-randompick.png differ diff --git a/doc/krita/dialogs-rotateimage.png b/doc/krita/dialogs-rotateimage.png new file mode 100644 index 000000000..569a157d4 Binary files /dev/null and b/doc/krita/dialogs-rotateimage.png differ diff --git a/doc/krita/dialogs-rotatelayer.png b/doc/krita/dialogs-rotatelayer.png new file mode 100644 index 000000000..8b06e26fc Binary files /dev/null and b/doc/krita/dialogs-rotatelayer.png differ diff --git a/doc/krita/dialogs-roundcorners.png b/doc/krita/dialogs-roundcorners.png new file mode 100644 index 000000000..07d3c1d1b Binary files /dev/null and b/doc/krita/dialogs-roundcorners.png differ diff --git a/doc/krita/dialogs-separateimage.png b/doc/krita/dialogs-separateimage.png new file mode 100644 index 000000000..ae2457504 Binary files /dev/null and b/doc/krita/dialogs-separateimage.png differ diff --git a/doc/krita/dialogs-shearimage.png b/doc/krita/dialogs-shearimage.png new file mode 100644 index 000000000..0b7c4676d Binary files /dev/null and b/doc/krita/dialogs-shearimage.png differ diff --git a/doc/krita/dialogs-shearlayer.png b/doc/krita/dialogs-shearlayer.png new file mode 100644 index 000000000..1b4fb94b5 Binary files /dev/null and b/doc/krita/dialogs-shearlayer.png differ diff --git a/doc/krita/dialogs-smalltiles.png b/doc/krita/dialogs-smalltiles.png new file mode 100644 index 000000000..d7640ec55 Binary files /dev/null and b/doc/krita/dialogs-smalltiles.png differ diff --git a/doc/krita/dialogs-sobel.png b/doc/krita/dialogs-sobel.png new file mode 100644 index 000000000..5ce7b6a62 Binary files /dev/null and b/doc/krita/dialogs-sobel.png differ diff --git a/doc/krita/dialogs-substrate.png b/doc/krita/dialogs-substrate.png new file mode 100644 index 000000000..2c9fe0698 Binary files /dev/null and b/doc/krita/dialogs-substrate.png differ diff --git a/doc/krita/dialogs-unsharpmask.png b/doc/krita/dialogs-unsharpmask.png new file mode 100644 index 000000000..b26332f9b Binary files /dev/null and b/doc/krita/dialogs-unsharpmask.png differ diff --git a/doc/krita/dialogs-wave.png b/doc/krita/dialogs-wave.png new file mode 100644 index 000000000..929a20c5b Binary files /dev/null and b/doc/krita/dialogs-wave.png differ diff --git a/doc/krita/dialogs-waveletnoise.png b/doc/krita/dialogs-waveletnoise.png new file mode 100644 index 000000000..90b735ec2 Binary files /dev/null and b/doc/krita/dialogs-waveletnoise.png differ diff --git a/doc/krita/faq.docbook b/doc/krita/faq.docbook new file mode 100644 index 000000000..91ac0b1e2 --- /dev/null +++ b/doc/krita/faq.docbook @@ -0,0 +1,51 @@ + +Questions and Answers + + +Sometimes, stuff does not work as one would like. &krita; can crash — not all +that often, these days, but still. So you might need some help. The first thing +to do is trying to determine what was going on, exactly. Try to reproduce the +problem and write down what you did before the problem occurred. + +Then you can create a bug report: go to the Help menu and select +Report Bug. That way, we know exactly which version of +&krita; you are using. Please try to make reasonably sure that your problem has +not been reported already! Also, please try to be as complete as possible in +describing your problem. + +You can also, if it is just that you cannot figure out how to do something +that you can do using Photoshop (or any other drawing program) using &krita;, +or if you have some other question, e-mail the &krita; developers at our +mailing list kimageshop@kde.org, or e-mail the program or +documentation maintainer directly at boud@valdyas.org or +sanderkoning@kde.nl, respectively. + + + + +&reporting.bugs; +&updating.documentation; + + + + + diff --git a/doc/krita/index.docbook b/doc/krita/index.docbook new file mode 100644 index 000000000..b5ef3c1b5 --- /dev/null +++ b/doc/krita/index.docbook @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + +The &krita; Handbook + + + + +Boudewijn +Rempt + +boud@valdyas.org + + + +Casper +Boemann + +cbr@boemann.dk + + + +Cyrille +Berger + +cberger@cberger.net + + + +Sander +Koning + +sanderkoning@kde.nl + + + + + +2005-2006 +Boudewijn Rempt +Casper Boemann +Cyrille Berger +Sander Koning + + +&FDLNotice; + + + +2006-09-13 +1.6 + + + + + +&krita; is part of the &koffice; package. &krita; is a photo retouching, image +editing application, but above all, a paint application that will allow you to +create original art on your computer as if you were working with paint and +brushes, pencils, pen and ink — or, at least, it will one day. We are +continually working on extending &krita; and making it better in every respect. + + + + +KDE +koffice +Krita +image manipulation +graphics +painting + + + + +&introduction; +&tutorial; +&images; +&views; +&layers; +&selections; +&filters; +&colorspaces; +&commands; +&settings; +&developers; +&faq; +&credits; +&installation; + +&documentation.index; + + + diff --git a/doc/krita/installation.docbook b/doc/krita/installation.docbook new file mode 100644 index 000000000..83158a747 --- /dev/null +++ b/doc/krita/installation.docbook @@ -0,0 +1,73 @@ + +Installation + + +How to obtain &krita; + + + +&install.intro.documentation; + + + + +Requirements + + + + +&krita; depends on the following libraries, apart from what &koffice; needs +itself: + + +Image +Magick — X11 Image Processing and Display +Package +Little CMS +— A free color management system in 100K +OpenEXR + + + + +You can find a list of changes in the ChangeLog file or on +&krita;'s website. + + + + +Compilation and Installation + + + + + +&install.compile.documentation; + + + + + + + diff --git a/doc/krita/introduction.docbook b/doc/krita/introduction.docbook new file mode 100644 index 000000000..7441f80df --- /dev/null +++ b/doc/krita/introduction.docbook @@ -0,0 +1,153 @@ + +Introduction + + +What is &krita;? + +&krita;, part of &koffice;, can do everything you want with images — or +it will be able to one day. Everything from photo retouching, image editing, +and last but not least creating original art on your computer as if you were +working with real paint and brushes, pencils, pen and ink. Every day +&krita; becomes a little better, a little more useful. We are working on it, +anyway. We, that is, Adrian, Bart, Boudewijn, Casper, Cyrille, Michael and Sven. +It could be you, too — whether you would like to help with some artwork +for the user interface, cool ideas for the todo, helpful bug reports, usability +reviews or even actual code, you will not be snubbed by us. + + +&krita; is as much yours as it is ours. It should be fun, innovative, and +experimental — first and foremost a pleasure to use and to hack on. + + + + +Key features + +The most important features &krita; currently has to offer, are: + + +Plugins: Krita is extensible through plugins. There are tools, +colorspaces, paint operations, filters and kpart-based user interface plugins. + + +Scriptable: &krita; is scriptable in Python and Ruby using +Kross, the cross language scripting engine that originated in Kexi. The +scripting is compatible with PyQt/KDE and Korundum for adding GUI +items, such as dialog boxes. + +Color models: &krita; uses lcms for a dependable color +workflow using icc profiles for importing, exporting, selecting paint colors, +printing, cutting and pasting. 8, 16, and 32 bit colorspaces are available +(RGB, CMYK, L*a*b*, ...) and colors can be selected from a color wheel, rgb or +grayscale sliders or with a palette. + +Editing and viewing: Unlimited undo and redo are available. +You can cut, copy and paste between lagers and images, with conversion through +icc profiles if this is necessary. OpenGL is supported for display. The view +can be made fullscreen and can be split. Rulers are available, the +image can be zoomed, and for maximizing the workspace all palette windows can +be hidden in one go. Also a histogram palette is available. + +Images and layers: Layers and entire images can be mirrored, +sheared, rotated and scaled, converted between colorspaces, and layers in +different colorspaces can be merged. An image can be separated into colorspace +channels. + +Layers: Layers can be added, removed, grouped, locked, made +(in)visible, and re-ordered. Adjustment layers (layers which perform a filter +function) can be added as well. A layer can be saved as a separate image and +its colorspace can be changed. + +Tools: Through the innovative paintOp plugin system, all +painting tools (brush, ellipse, line, etc.) can paint aliased, anti-aliased, +erase, airbrush and more. + +Filters: &krita; can multithread the operation of some +filters. Filters can be previewed in the filter gallery. Available filters +include color adjustment, sharpen or blur, emboss, raindrops, and +more. + +Brushes: The GIMP brush shapes can be used, both colored and +grayscale brushes and pipe brushes. Custom brushes can be created, even from +entire layers or images. Colored brushes can also be used as +masks. + + + + +Color management + +One of the most distinguishing features in &krita; is its color management. +If you put two screens side to side, you will notice that there is often a lot +of difference in the way they display colors. Even white, especially white, is +often not the same thing at all. On one screen it can be a dirty yellow, on +another screen a sickly bluish. Very seldom is it a creamy milk-white. The same +holds, unfortunately, for scanners, printers and digital cameras. So, if you +want to see the right colors on screen and on paper, being the colors that you +saw when taking your snapshot, you will have to compensate. + +&krita; can do this for you: in &krita;, a color is (almost) never just a set of +numbers, one for each color channel; it is a set of numbers with information +attached. And that extra information is contained in a profile: your image has a +profile, your scanner has a profile, your camera should have a profile and your +screen has a profile. When passing information from your image to your screen, +the profiles are checked and the correct color is computed. This may cause a +little slowness, now and then, but the result is that you can work with colors, +instead of almost meaningless RGB triplets. + +Available colorspaces are: 8 bit/channel RGB, CMYK, grayscale and wet +watercolors, 16 bit/channel RGB, CMYK, grayscale and L*a*b*, half +RGB, and 32 bit float RGB (HDR) and LMS. + + + + +Image formats + +&krita; currently supports the following image formats, both for importing and +exporting, apart from its own: PNG, TIFF, JPEG, Dicom, XCF, PSD, GIF, BMP, +XPM, Targa, RGB, and OpenEXR. Additionally, &krita; can import +ICO files. PSD (the Photoshop file format) is only supported up to version 6, +from version 7 on, the Photoshop file format is closed. + +Embedded icc profiles and exif information are preserved on export to +supporting file formats. &krita;'s native file format stores icc and exif +information. + + + + + + +About this manual + +We are assuming you have got a good working knowledge of &kde; and of your +operating system. The first chapter will give you a quick tour of &krita;'s +cool features; the other chapters will expand on that information. + + +This manual is not complete. The invitation to join us and help out extends to +the manual, too! + + +Should you have any questions, comments or suggestions, please contact the +documentation maintainer at sanderkoning@kde.nl. + + + + +About the application maintainer + +Hi! I'm Boudewijn Rempt — the current maintainer of &krita;. I was +educated as a linguist, retrained as a database developer, work as a Java +hacker, study theology and I have always liked to paint and sketch a little. +Conspiciously absent in my life have been two important things for a developer +of an image app: mathematics and experience with graphic design. That means that +I am probably not the best person to explain the niceties of using an image +editor or a paint application to you. If you catch me in an error, please don't +hesitate to mail me: boud@valdyas.org. + + + + + diff --git a/doc/krita/mainscreen.png b/doc/krita/mainscreen.png new file mode 100644 index 000000000..f0f775a7f Binary files /dev/null and b/doc/krita/mainscreen.png differ diff --git a/doc/krita/mountains-burn.png b/doc/krita/mountains-burn.png new file mode 100644 index 000000000..679e0ebda Binary files /dev/null and b/doc/krita/mountains-burn.png differ diff --git a/doc/krita/mountains-color.png b/doc/krita/mountains-color.png new file mode 100644 index 000000000..0766e86f9 Binary files /dev/null and b/doc/krita/mountains-color.png differ diff --git a/doc/krita/mountains-darken.png b/doc/krita/mountains-darken.png new file mode 100644 index 000000000..9f15fe4c5 Binary files /dev/null and b/doc/krita/mountains-darken.png differ diff --git a/doc/krita/mountains-divide.png b/doc/krita/mountains-divide.png new file mode 100644 index 000000000..1471b2dc9 Binary files /dev/null and b/doc/krita/mountains-divide.png differ diff --git a/doc/krita/mountains-dodge.png b/doc/krita/mountains-dodge.png new file mode 100644 index 000000000..4904225f9 Binary files /dev/null and b/doc/krita/mountains-dodge.png differ diff --git a/doc/krita/mountains-hue.png b/doc/krita/mountains-hue.png new file mode 100644 index 000000000..82be57dcc Binary files /dev/null and b/doc/krita/mountains-hue.png differ diff --git a/doc/krita/mountains-lighten.png b/doc/krita/mountains-lighten.png new file mode 100644 index 000000000..d8e5a85a6 Binary files /dev/null and b/doc/krita/mountains-lighten.png differ diff --git a/doc/krita/mountains-multiply.png b/doc/krita/mountains-multiply.png new file mode 100644 index 000000000..e734cfc51 Binary files /dev/null and b/doc/krita/mountains-multiply.png differ diff --git a/doc/krita/mountains-normal.png b/doc/krita/mountains-normal.png new file mode 100644 index 000000000..244bc6ff5 Binary files /dev/null and b/doc/krita/mountains-normal.png differ diff --git a/doc/krita/mountains-original.png b/doc/krita/mountains-original.png new file mode 100644 index 000000000..7bd1dea92 Binary files /dev/null and b/doc/krita/mountains-original.png differ diff --git a/doc/krita/mountains-overlay.png b/doc/krita/mountains-overlay.png new file mode 100644 index 000000000..bf6cf10f8 Binary files /dev/null and b/doc/krita/mountains-overlay.png differ diff --git a/doc/krita/mountains-saturation.png b/doc/krita/mountains-saturation.png new file mode 100644 index 000000000..c114891cf Binary files /dev/null and b/doc/krita/mountains-saturation.png differ diff --git a/doc/krita/mountains-screen.png b/doc/krita/mountains-screen.png new file mode 100644 index 000000000..2600fbcdb Binary files /dev/null and b/doc/krita/mountains-screen.png differ diff --git a/doc/krita/mountains-value.png b/doc/krita/mountains-value.png new file mode 100644 index 000000000..097aa5d1d Binary files /dev/null and b/doc/krita/mountains-value.png differ diff --git a/doc/krita/mountains.png b/doc/krita/mountains.png new file mode 100644 index 000000000..b97ed9ea9 Binary files /dev/null and b/doc/krita/mountains.png differ diff --git a/doc/krita/newimage.png b/doc/krita/newimage.png new file mode 100644 index 000000000..804f927ca Binary files /dev/null and b/doc/krita/newimage.png differ diff --git a/doc/krita/palettes-colors-gray.png b/doc/krita/palettes-colors-gray.png new file mode 100644 index 000000000..9c7d2fab8 Binary files /dev/null and b/doc/krita/palettes-colors-gray.png differ diff --git a/doc/krita/palettes-colors-hsv.png b/doc/krita/palettes-colors-hsv.png new file mode 100644 index 000000000..78da99c95 Binary files /dev/null and b/doc/krita/palettes-colors-hsv.png differ diff --git a/doc/krita/palettes-colors-palettes.png b/doc/krita/palettes-colors-palettes.png new file mode 100644 index 000000000..4c71dce09 Binary files /dev/null and b/doc/krita/palettes-colors-palettes.png differ diff --git a/doc/krita/palettes-colors-rgb.png b/doc/krita/palettes-colors-rgb.png new file mode 100644 index 000000000..55f1ff4f1 Binary files /dev/null and b/doc/krita/palettes-colors-rgb.png differ diff --git a/doc/krita/palettes-colors-watercolors.png b/doc/krita/palettes-colors-watercolors.png new file mode 100644 index 000000000..722bf0ffb Binary files /dev/null and b/doc/krita/palettes-colors-watercolors.png differ diff --git a/doc/krita/palettes-controlbox-bezier.png b/doc/krita/palettes-controlbox-bezier.png new file mode 100644 index 000000000..b31e87b24 Binary files /dev/null and b/doc/krita/palettes-controlbox-bezier.png differ diff --git a/doc/krita/palettes-controlbox-brush.png b/doc/krita/palettes-controlbox-brush.png new file mode 100644 index 000000000..b3a62f383 Binary files /dev/null and b/doc/krita/palettes-controlbox-brush.png differ diff --git a/doc/krita/palettes-controlbox-colorpicker.png b/doc/krita/palettes-controlbox-colorpicker.png new file mode 100644 index 000000000..02d19266d Binary files /dev/null and b/doc/krita/palettes-controlbox-colorpicker.png differ diff --git a/doc/krita/palettes-controlbox-contiguousfill.png b/doc/krita/palettes-controlbox-contiguousfill.png new file mode 100644 index 000000000..97eb56cf5 Binary files /dev/null and b/doc/krita/palettes-controlbox-contiguousfill.png differ diff --git a/doc/krita/palettes-controlbox-crop.png b/doc/krita/palettes-controlbox-crop.png new file mode 100644 index 000000000..c8338b778 Binary files /dev/null and b/doc/krita/palettes-controlbox-crop.png differ diff --git a/doc/krita/palettes-controlbox-duplicate.png b/doc/krita/palettes-controlbox-duplicate.png new file mode 100644 index 000000000..6b7f0277d Binary files /dev/null and b/doc/krita/palettes-controlbox-duplicate.png differ diff --git a/doc/krita/palettes-controlbox-ellipse.png b/doc/krita/palettes-controlbox-ellipse.png new file mode 100644 index 000000000..b057604c4 Binary files /dev/null and b/doc/krita/palettes-controlbox-ellipse.png differ diff --git a/doc/krita/palettes-controlbox-fill.png b/doc/krita/palettes-controlbox-fill.png new file mode 100644 index 000000000..3aed56341 Binary files /dev/null and b/doc/krita/palettes-controlbox-fill.png differ diff --git a/doc/krita/palettes-controlbox-gradient.png b/doc/krita/palettes-controlbox-gradient.png new file mode 100644 index 000000000..e18a83259 Binary files /dev/null and b/doc/krita/palettes-controlbox-gradient.png differ diff --git a/doc/krita/palettes-controlbox-histogram.png b/doc/krita/palettes-controlbox-histogram.png new file mode 100644 index 000000000..9c2c2b657 Binary files /dev/null and b/doc/krita/palettes-controlbox-histogram.png differ diff --git a/doc/krita/palettes-controlbox-line.png b/doc/krita/palettes-controlbox-line.png new file mode 100644 index 000000000..36900c634 Binary files /dev/null and b/doc/krita/palettes-controlbox-line.png differ diff --git a/doc/krita/palettes-controlbox-overview.png b/doc/krita/palettes-controlbox-overview.png new file mode 100644 index 000000000..9bab43360 Binary files /dev/null and b/doc/krita/palettes-controlbox-overview.png differ diff --git a/doc/krita/palettes-controlbox-paintwithfilters.png b/doc/krita/palettes-controlbox-paintwithfilters.png new file mode 100644 index 000000000..da712402b Binary files /dev/null and b/doc/krita/palettes-controlbox-paintwithfilters.png differ diff --git a/doc/krita/palettes-controlbox-polygon.png b/doc/krita/palettes-controlbox-polygon.png new file mode 100644 index 000000000..113474206 Binary files /dev/null and b/doc/krita/palettes-controlbox-polygon.png differ diff --git a/doc/krita/palettes-controlbox-polyline.png b/doc/krita/palettes-controlbox-polyline.png new file mode 100644 index 000000000..36900c634 Binary files /dev/null and b/doc/krita/palettes-controlbox-polyline.png differ diff --git a/doc/krita/palettes-controlbox-rectangle.png b/doc/krita/palettes-controlbox-rectangle.png new file mode 100644 index 000000000..b057604c4 Binary files /dev/null and b/doc/krita/palettes-controlbox-rectangle.png differ diff --git a/doc/krita/palettes-controlbox-select.png b/doc/krita/palettes-controlbox-select.png new file mode 100644 index 000000000..59cd04ea9 Binary files /dev/null and b/doc/krita/palettes-controlbox-select.png differ diff --git a/doc/krita/palettes-controlbox-selectcontiguous.png b/doc/krita/palettes-controlbox-selectcontiguous.png new file mode 100644 index 000000000..26c3d4d91 Binary files /dev/null and b/doc/krita/palettes-controlbox-selectcontiguous.png differ diff --git a/doc/krita/palettes-controlbox-selectmagnetic.png b/doc/krita/palettes-controlbox-selectmagnetic.png new file mode 100644 index 000000000..798434f8d Binary files /dev/null and b/doc/krita/palettes-controlbox-selectmagnetic.png differ diff --git a/doc/krita/palettes-controlbox-selectsimilar.png b/doc/krita/palettes-controlbox-selectsimilar.png new file mode 100644 index 000000000..6043a28ec Binary files /dev/null and b/doc/krita/palettes-controlbox-selectsimilar.png differ diff --git a/doc/krita/palettes-controlbox-star.png b/doc/krita/palettes-controlbox-star.png new file mode 100644 index 000000000..e963b2d5c Binary files /dev/null and b/doc/krita/palettes-controlbox-star.png differ diff --git a/doc/krita/palettes-controlbox-text.png b/doc/krita/palettes-controlbox-text.png new file mode 100644 index 000000000..42043596e Binary files /dev/null and b/doc/krita/palettes-controlbox-text.png differ diff --git a/doc/krita/palettes-controlbox-transform.png b/doc/krita/palettes-controlbox-transform.png new file mode 100644 index 000000000..4c4c95d7c Binary files /dev/null and b/doc/krita/palettes-controlbox-transform.png differ diff --git a/doc/krita/palettes-layers-layers.png b/doc/krita/palettes-layers-layers.png new file mode 100644 index 000000000..4ca4ff8e7 Binary files /dev/null and b/doc/krita/palettes-layers-layers.png differ diff --git a/doc/krita/palettes-layers-scriptsmanager.png b/doc/krita/palettes-layers-scriptsmanager.png new file mode 100644 index 000000000..b0092993d Binary files /dev/null and b/doc/krita/palettes-layers-scriptsmanager.png differ diff --git a/doc/krita/preferences-color.png b/doc/krita/preferences-color.png new file mode 100644 index 000000000..9db8e687e Binary files /dev/null and b/doc/krita/preferences-color.png differ diff --git a/doc/krita/preferences-display.png b/doc/krita/preferences-display.png new file mode 100644 index 000000000..b7d245f5b Binary files /dev/null and b/doc/krita/preferences-display.png differ diff --git a/doc/krita/preferences-general.png b/doc/krita/preferences-general.png new file mode 100644 index 000000000..f83225292 Binary files /dev/null and b/doc/krita/preferences-general.png differ diff --git a/doc/krita/preferences-grid.png b/doc/krita/preferences-grid.png new file mode 100644 index 000000000..6bb9ed957 Binary files /dev/null and b/doc/krita/preferences-grid.png differ diff --git a/doc/krita/preferences-performance.png b/doc/krita/preferences-performance.png new file mode 100644 index 000000000..2884030b3 Binary files /dev/null and b/doc/krita/preferences-performance.png differ diff --git a/doc/krita/preferences-sidebar.png b/doc/krita/preferences-sidebar.png new file mode 100644 index 000000000..a7fcff980 Binary files /dev/null and b/doc/krita/preferences-sidebar.png differ diff --git a/doc/krita/preferences-tablet.png b/doc/krita/preferences-tablet.png new file mode 100644 index 000000000..6ec6f8c09 Binary files /dev/null and b/doc/krita/preferences-tablet.png differ diff --git a/doc/krita/settings.docbook b/doc/krita/settings.docbook new file mode 100644 index 000000000..fd72d68da --- /dev/null +++ b/doc/krita/settings.docbook @@ -0,0 +1,229 @@ + + +Settings + +This chapter describes the various settings that affect the way &krita; +functions and looks. + + +The <guilabel>Preferences</guilabel> dialog + + +A number of options to configure &krita; are available via the +Preferences dialog, which is available via +SettingsConfigure +&krita;.... The dialog is divided into several +sections, which you can open via the sidebar at the left, shown below. + + + + +The available Preferences sections + + + + + +The available Preferences sections + + + + + + + +The <guilabel>General</guilabel> section + + + +The General section + + + + + +The General section + + + + + + + +This section offers three options. First of all, the setting in the +Cursor shape: dropdown box determines what the drawing +cursor looks like. You can choose between a cursor resembling the actual tool +you are working with, a normal cursor, a crosshair, and a brush-shaped cursor. +Then you can select the Palette Behavior. You can set +here when palettes may be docked (set aside at a window +border): always (Allow docking), never +(Allow only floating), or when there is enough space +(Allow docking only on large screens). The last option is +Palette font size: which determines the text size used in +the palettes. Set this to a larger value if you have trouble reading the text, +with the side effect that the palettes will take more space. + + + + + +The <guilabel>Display</guilabel> section + + + +The Display section + + + + + +The Display section + + + + + + + +This section contains just one option. If your graphics card and driver have +OpenGL support, you can enable it here to make drawing faster (the +processor of yor graphics card will take over part of the calculations). Be +warned, though: there are a few cases where enabling OpenGL is known to +introduce erratic behavior. + + + + + +The <guilabel>Color Management</guilabel> section + + + +The Color Management section + + + + + +The Color Management section + + + + + + + +Here you can set various options related to colorspaces in rendering, editing +and printing of images. The topmost option can be used to set the default +color model for creating new images (useful if you usually want to create CMYK +images, for instance). Use the Display options to let +&krita; know what color profile your monitor uses, and how rendering should be +done. Under Printing, you can set the color model and +profile for your printer. The next option determines what &krita; should do +when you paste an image into it that was copied from another application. If +Use Blackpoint compensation is checked, whenever a +colorspace conversion is needed, the black points of the source and +destination colorspaces are matched. + + + + + +The <guilabel>Performance</guilabel> section + + + +The Performance section + + + + + +The Performance section + + + + + + + +Two options are available here. The Maximum number of tiles kept in +memory setting indicates how many tiles (image subparts) &krita; +will keep in memory. The default setting should be reasonable, if you are low +or very high on memory, you may want to decrease or increase this option, +respectively. The Swappiness: option determines how eager +&krita; will be to swap to disk. + + + + + +The <guilabel>Tablet</guilabel> section + + + +The Tablet section + + + + + +The Tablet section + + + + + + + +If you have a tablet device attached, you can enable it and set its pressure +sensitivity in this section. + +You need to activate the tablet devices you want to use with &krita;. There +are three supported devices: the cursor, the eraser and the stylus. You can +activate them using the tablet sections. Only use the configuration options of +a device if you use a non-Wacom tablet, and if the behavior of the tablet is +unexpected, like moving when you press on the tablet for instance. In this +situation, you can use the dialog to make sure you have a correct interaction: +values (position, pressure, tilt...) are sent from the tablet to the computer +in a given order, it might happen that some tablets do not use the default +order. You can set this in the configuration options of a device. + + + + + +The <guilabel>Grid</guilabel> section + + + +The Grid section + + + + + +The Grid section + + + + + + + +In this section, you can fine-tune &krita;'s grid. The line styles for the +grid can be set in the Styles option set. +Colors allows you to choose the line colors for the grid. +The horizontal and vertical spacing between the main lines can be set under +Spacing, as well as the amount of subdivisions (in how +many smaller parts a grid section is subdivided). Furthermore you can set the +Offset: usually the grid is painted starting at the top +left corner, if you want the first main grid lines not to start there, you can +enter an offset (displacement) here. + + + + + + + diff --git a/doc/krita/tool-bezier-example.png b/doc/krita/tool-bezier-example.png new file mode 100644 index 000000000..818774a71 Binary files /dev/null and b/doc/krita/tool-bezier-example.png differ diff --git a/doc/krita/tool-bezier-example2.png b/doc/krita/tool-bezier-example2.png new file mode 100644 index 000000000..07a4eb65e Binary files /dev/null and b/doc/krita/tool-bezier-example2.png differ diff --git a/doc/krita/tool-bezier-example3.png b/doc/krita/tool-bezier-example3.png new file mode 100644 index 000000000..6ff03222c Binary files /dev/null and b/doc/krita/tool-bezier-example3.png differ diff --git a/doc/krita/tool-bezier.png b/doc/krita/tool-bezier.png new file mode 100644 index 000000000..84e3d75bf Binary files /dev/null and b/doc/krita/tool-bezier.png differ diff --git a/doc/krita/tool-brush.png b/doc/krita/tool-brush.png new file mode 100644 index 000000000..f2f917c5b Binary files /dev/null and b/doc/krita/tool-brush.png differ diff --git a/doc/krita/tool-colorpicker.png b/doc/krita/tool-colorpicker.png new file mode 100644 index 000000000..285e04f65 Binary files /dev/null and b/doc/krita/tool-colorpicker.png differ diff --git a/doc/krita/tool-contiguousfill.png b/doc/krita/tool-contiguousfill.png new file mode 100644 index 000000000..a2c087f9d Binary files /dev/null and b/doc/krita/tool-contiguousfill.png differ diff --git a/doc/krita/tool-crop.png b/doc/krita/tool-crop.png new file mode 100644 index 000000000..05e80ae1f Binary files /dev/null and b/doc/krita/tool-crop.png differ diff --git a/doc/krita/tool-duplicate.png b/doc/krita/tool-duplicate.png new file mode 100644 index 000000000..604e42106 Binary files /dev/null and b/doc/krita/tool-duplicate.png differ diff --git a/doc/krita/tool-ellipse.png b/doc/krita/tool-ellipse.png new file mode 100644 index 000000000..77fdda70f Binary files /dev/null and b/doc/krita/tool-ellipse.png differ diff --git a/doc/krita/tool-eraseselection.png b/doc/krita/tool-eraseselection.png new file mode 100644 index 000000000..3ad47747f Binary files /dev/null and b/doc/krita/tool-eraseselection.png differ diff --git a/doc/krita/tool-gradient.png b/doc/krita/tool-gradient.png new file mode 100644 index 000000000..4c110075a Binary files /dev/null and b/doc/krita/tool-gradient.png differ diff --git a/doc/krita/tool-line.png b/doc/krita/tool-line.png new file mode 100644 index 000000000..60dfa84df Binary files /dev/null and b/doc/krita/tool-line.png differ diff --git a/doc/krita/tool-move.png b/doc/krita/tool-move.png new file mode 100644 index 000000000..cf019e7ac Binary files /dev/null and b/doc/krita/tool-move.png differ diff --git a/doc/krita/tool-paintselection.png b/doc/krita/tool-paintselection.png new file mode 100644 index 000000000..83ae74e4f Binary files /dev/null and b/doc/krita/tool-paintselection.png differ diff --git a/doc/krita/tool-paintwithfilters-example.png b/doc/krita/tool-paintwithfilters-example.png new file mode 100644 index 000000000..15c8e1c8b Binary files /dev/null and b/doc/krita/tool-paintwithfilters-example.png differ diff --git a/doc/krita/tool-paintwithfilters.png b/doc/krita/tool-paintwithfilters.png new file mode 100644 index 000000000..dc8815aef Binary files /dev/null and b/doc/krita/tool-paintwithfilters.png differ diff --git a/doc/krita/tool-pan.png b/doc/krita/tool-pan.png new file mode 100644 index 000000000..1470a1672 Binary files /dev/null and b/doc/krita/tool-pan.png differ diff --git a/doc/krita/tool-perspectivegrid.png b/doc/krita/tool-perspectivegrid.png new file mode 100644 index 000000000..f2815380a Binary files /dev/null and b/doc/krita/tool-perspectivegrid.png differ diff --git a/doc/krita/tool-perspectivetransform.png b/doc/krita/tool-perspectivetransform.png new file mode 100644 index 000000000..fbcbf59d9 Binary files /dev/null and b/doc/krita/tool-perspectivetransform.png differ diff --git a/doc/krita/tool-polygon.png b/doc/krita/tool-polygon.png new file mode 100644 index 000000000..98f4d711c Binary files /dev/null and b/doc/krita/tool-polygon.png differ diff --git a/doc/krita/tool-polyline.png b/doc/krita/tool-polyline.png new file mode 100644 index 000000000..5a688216e Binary files /dev/null and b/doc/krita/tool-polyline.png differ diff --git a/doc/krita/tool-rectangle.png b/doc/krita/tool-rectangle.png new file mode 100644 index 000000000..27c9dfd1b Binary files /dev/null and b/doc/krita/tool-rectangle.png differ diff --git a/doc/krita/tool-selectbezier.png b/doc/krita/tool-selectbezier.png new file mode 100644 index 000000000..4604f957e Binary files /dev/null and b/doc/krita/tool-selectbezier.png differ diff --git a/doc/krita/tool-selectcontiguous.png b/doc/krita/tool-selectcontiguous.png new file mode 100644 index 000000000..07339ef12 Binary files /dev/null and b/doc/krita/tool-selectcontiguous.png differ diff --git a/doc/krita/tool-selectelliptical.png b/doc/krita/tool-selectelliptical.png new file mode 100644 index 000000000..5ae5f5041 Binary files /dev/null and b/doc/krita/tool-selectelliptical.png differ diff --git a/doc/krita/tool-selectmagnetic.png b/doc/krita/tool-selectmagnetic.png new file mode 100644 index 000000000..77d3a49d2 Binary files /dev/null and b/doc/krita/tool-selectmagnetic.png differ diff --git a/doc/krita/tool-selectoutline.png b/doc/krita/tool-selectoutline.png new file mode 100644 index 000000000..6258c37f9 Binary files /dev/null and b/doc/krita/tool-selectoutline.png differ diff --git a/doc/krita/tool-selectpolygonal.png b/doc/krita/tool-selectpolygonal.png new file mode 100644 index 000000000..5e390dee7 Binary files /dev/null and b/doc/krita/tool-selectpolygonal.png differ diff --git a/doc/krita/tool-selectrectangular.png b/doc/krita/tool-selectrectangular.png new file mode 100644 index 000000000..1ad6718e5 Binary files /dev/null and b/doc/krita/tool-selectrectangular.png differ diff --git a/doc/krita/tool-selectsimilar.png b/doc/krita/tool-selectsimilar.png new file mode 100644 index 000000000..cfa8b2355 Binary files /dev/null and b/doc/krita/tool-selectsimilar.png differ diff --git a/doc/krita/tool-star.png b/doc/krita/tool-star.png new file mode 100644 index 000000000..7dab32180 Binary files /dev/null and b/doc/krita/tool-star.png differ diff --git a/doc/krita/tool-text.png b/doc/krita/tool-text.png new file mode 100644 index 000000000..da97cda68 Binary files /dev/null and b/doc/krita/tool-text.png differ diff --git a/doc/krita/tool-transform.png b/doc/krita/tool-transform.png new file mode 100644 index 000000000..fded6ebef Binary files /dev/null and b/doc/krita/tool-transform.png differ diff --git a/doc/krita/tool-zoom.png b/doc/krita/tool-zoom.png new file mode 100644 index 000000000..e30f00d9b Binary files /dev/null and b/doc/krita/tool-zoom.png differ diff --git a/doc/krita/toolbar-brushes-brushshapes-autobrush.png b/doc/krita/toolbar-brushes-brushshapes-autobrush.png new file mode 100644 index 000000000..5ea484862 Binary files /dev/null and b/doc/krita/toolbar-brushes-brushshapes-autobrush.png differ diff --git a/doc/krita/toolbar-brushes-brushshapes-custombrush.png b/doc/krita/toolbar-brushes-brushshapes-custombrush.png new file mode 100644 index 000000000..4c89af8de Binary files /dev/null and b/doc/krita/toolbar-brushes-brushshapes-custombrush.png differ diff --git a/doc/krita/toolbar-brushes-brushshapes-predefined.png b/doc/krita/toolbar-brushes-brushshapes-predefined.png new file mode 100644 index 000000000..ddcb7d1b5 Binary files /dev/null and b/doc/krita/toolbar-brushes-brushshapes-predefined.png differ diff --git a/doc/krita/toolbar-brushes-gradients.png b/doc/krita/toolbar-brushes-gradients.png new file mode 100644 index 000000000..f466a81de Binary files /dev/null and b/doc/krita/toolbar-brushes-gradients.png differ diff --git a/doc/krita/toolbar-brushes-patterns-custompattern.png b/doc/krita/toolbar-brushes-patterns-custompattern.png new file mode 100644 index 000000000..90f76a236 Binary files /dev/null and b/doc/krita/toolbar-brushes-patterns-custompattern.png differ diff --git a/doc/krita/toolbar-brushes-patterns.png b/doc/krita/toolbar-brushes-patterns.png new file mode 100644 index 000000000..5e64f461b Binary files /dev/null and b/doc/krita/toolbar-brushes-patterns.png differ diff --git a/doc/krita/toolbar-brushesandstuff.png b/doc/krita/toolbar-brushesandstuff.png new file mode 100644 index 000000000..3915acd8a Binary files /dev/null and b/doc/krita/toolbar-brushesandstuff.png differ diff --git a/doc/krita/toolbar-edit.png b/doc/krita/toolbar-edit.png new file mode 100644 index 000000000..aef82505b Binary files /dev/null and b/doc/krita/toolbar-edit.png differ diff --git a/doc/krita/toolbar-file.png b/doc/krita/toolbar-file.png new file mode 100644 index 000000000..302e5c1c8 Binary files /dev/null and b/doc/krita/toolbar-file.png differ diff --git a/doc/krita/toolbar-krita.png b/doc/krita/toolbar-krita.png new file mode 100644 index 000000000..d1c6c4b98 Binary files /dev/null and b/doc/krita/toolbar-krita.png differ diff --git a/doc/krita/toolbar-navigation.png b/doc/krita/toolbar-navigation.png new file mode 100644 index 000000000..f1dd911c6 Binary files /dev/null and b/doc/krita/toolbar-navigation.png differ diff --git a/doc/krita/toolbar-transformationtools.png b/doc/krita/toolbar-transformationtools.png new file mode 100644 index 000000000..32a8125fe Binary files /dev/null and b/doc/krita/toolbar-transformationtools.png differ diff --git a/doc/krita/toolbars-button-zoomin.png b/doc/krita/toolbars-button-zoomin.png new file mode 100644 index 000000000..bdc0746c8 Binary files /dev/null and b/doc/krita/toolbars-button-zoomin.png differ diff --git a/doc/krita/toolbars-button-zoomout.png b/doc/krita/toolbars-button-zoomout.png new file mode 100644 index 000000000..4d002a6ad Binary files /dev/null and b/doc/krita/toolbars-button-zoomout.png differ diff --git a/doc/krita/tutorial-quick-starts.docbook b/doc/krita/tutorial-quick-starts.docbook new file mode 100644 index 000000000..05f367295 --- /dev/null +++ b/doc/krita/tutorial-quick-starts.docbook @@ -0,0 +1,183 @@ + +Quick start guides + +Crop an area and save it + +Aim: from a picture, crop an area and save that area in a new file + +Open &krita; with the original picture. + + +The original picture + + + + +The original picture + + + +Select the Select Rectangular tool in the +&krita; toolbar. + + +The Select a rectangular area tool + + + + +The Select a rectangular area tool + + + +Select the area you want to make a new picture with. &krita; makes the +outside area grey. + + +The selected area + + + + +The selected area + + + +Then use the +EditCopy +menu item or &Ctrl;C to +copy the selected area. + +Click again on the Edit menu. +Use the Paste into new image item. + + +The Edit menu + + + + +The Edit menu + + + +&krita; opens a new window with the selected area as new image. + + +The new image + + + + +The new image + + + +Save the new image. + + + +Draw a rectangle on your picture + +Aim: draw a coloured rectangle on your picture + +Open &krita; with the original picture. My picture consists of a view of +a toolbar in which I want to point an icon by putting a red rectangle around +it. + + +The original picture + + + + +The original picture + + + +Enable the Brushes and Stuff toolbar using +SettingsToolbars +menu. +Also make sure the palettes are viewed. If not, use the +ViewPalettes +menu. + + +&krita; view + + + + +&krita; view + + + +Click on the Brush Shapes icon in the +Brushes and Stuff toolbar. + + +The Brush Shapes icon + + + + +The Brush Shapes icon + + + +Select which brush shape you want to use among the predefined +brushes. + + +Selecting a brush shape + + + + +Selecting a brush shape + + + +Select the drawing shape on the &krita; toolbar. I choose a +rectangle. + + +Selecting the Rectangle icon + + + + +Selecting the Rectangle icon + + + +In the Colors palette, select the color you want by clicking on one of the +tabs and then choosing the color. + + +Choosing the color + + + + +Choosing the color + + + +Finally draw your shape on your picture and save the new picture! + + +Drawing + + + + +Drawing + + + +Thanks go to Anne-Marie Mahfouf for providing this tutorial. + + + + diff --git a/doc/krita/tutorial-quick-starts1.png b/doc/krita/tutorial-quick-starts1.png new file mode 100644 index 000000000..9db94c657 Binary files /dev/null and b/doc/krita/tutorial-quick-starts1.png differ diff --git a/doc/krita/tutorial-quick-starts10.png b/doc/krita/tutorial-quick-starts10.png new file mode 100644 index 000000000..7df8da5b0 Binary files /dev/null and b/doc/krita/tutorial-quick-starts10.png differ diff --git a/doc/krita/tutorial-quick-starts11.png b/doc/krita/tutorial-quick-starts11.png new file mode 100644 index 000000000..35ea56961 Binary files /dev/null and b/doc/krita/tutorial-quick-starts11.png differ diff --git a/doc/krita/tutorial-quick-starts12.png b/doc/krita/tutorial-quick-starts12.png new file mode 100644 index 000000000..c86471405 Binary files /dev/null and b/doc/krita/tutorial-quick-starts12.png differ diff --git a/doc/krita/tutorial-quick-starts2.png b/doc/krita/tutorial-quick-starts2.png new file mode 100644 index 000000000..450c82a5f Binary files /dev/null and b/doc/krita/tutorial-quick-starts2.png differ diff --git a/doc/krita/tutorial-quick-starts3.png b/doc/krita/tutorial-quick-starts3.png new file mode 100644 index 000000000..e6e65d9e6 Binary files /dev/null and b/doc/krita/tutorial-quick-starts3.png differ diff --git a/doc/krita/tutorial-quick-starts4.png b/doc/krita/tutorial-quick-starts4.png new file mode 100644 index 000000000..0d5f1a207 Binary files /dev/null and b/doc/krita/tutorial-quick-starts4.png differ diff --git a/doc/krita/tutorial-quick-starts5.png b/doc/krita/tutorial-quick-starts5.png new file mode 100644 index 000000000..877d07c60 Binary files /dev/null and b/doc/krita/tutorial-quick-starts5.png differ diff --git a/doc/krita/tutorial-quick-starts6.png b/doc/krita/tutorial-quick-starts6.png new file mode 100644 index 000000000..b1b4173ca Binary files /dev/null and b/doc/krita/tutorial-quick-starts6.png differ diff --git a/doc/krita/tutorial-quick-starts7.png b/doc/krita/tutorial-quick-starts7.png new file mode 100644 index 000000000..42477b57b Binary files /dev/null and b/doc/krita/tutorial-quick-starts7.png differ diff --git a/doc/krita/tutorial-quick-starts8.png b/doc/krita/tutorial-quick-starts8.png new file mode 100644 index 000000000..314467f7a Binary files /dev/null and b/doc/krita/tutorial-quick-starts8.png differ diff --git a/doc/krita/tutorial-quick-starts9.png b/doc/krita/tutorial-quick-starts9.png new file mode 100644 index 000000000..a42b2d51d Binary files /dev/null and b/doc/krita/tutorial-quick-starts9.png differ diff --git a/doc/krita/tutorial-select-layer-1.png b/doc/krita/tutorial-select-layer-1.png new file mode 100644 index 000000000..0ebdfe16e Binary files /dev/null and b/doc/krita/tutorial-select-layer-1.png differ diff --git a/doc/krita/tutorial-select-layer-10.png b/doc/krita/tutorial-select-layer-10.png new file mode 100644 index 000000000..0b8f67509 Binary files /dev/null and b/doc/krita/tutorial-select-layer-10.png differ diff --git a/doc/krita/tutorial-select-layer-11.png b/doc/krita/tutorial-select-layer-11.png new file mode 100644 index 000000000..589f049b0 Binary files /dev/null and b/doc/krita/tutorial-select-layer-11.png differ diff --git a/doc/krita/tutorial-select-layer-12.png b/doc/krita/tutorial-select-layer-12.png new file mode 100644 index 000000000..045ecc55e Binary files /dev/null and b/doc/krita/tutorial-select-layer-12.png differ diff --git a/doc/krita/tutorial-select-layer-13.png b/doc/krita/tutorial-select-layer-13.png new file mode 100644 index 000000000..fb715dfd7 Binary files /dev/null and b/doc/krita/tutorial-select-layer-13.png differ diff --git a/doc/krita/tutorial-select-layer-2.png b/doc/krita/tutorial-select-layer-2.png new file mode 100644 index 000000000..8fc7f9a06 Binary files /dev/null and b/doc/krita/tutorial-select-layer-2.png differ diff --git a/doc/krita/tutorial-select-layer-3.png b/doc/krita/tutorial-select-layer-3.png new file mode 100644 index 000000000..bc1ce8786 Binary files /dev/null and b/doc/krita/tutorial-select-layer-3.png differ diff --git a/doc/krita/tutorial-select-layer-4.png b/doc/krita/tutorial-select-layer-4.png new file mode 100644 index 000000000..37f971d02 Binary files /dev/null and b/doc/krita/tutorial-select-layer-4.png differ diff --git a/doc/krita/tutorial-select-layer-5.png b/doc/krita/tutorial-select-layer-5.png new file mode 100644 index 000000000..77658e0b3 Binary files /dev/null and b/doc/krita/tutorial-select-layer-5.png differ diff --git a/doc/krita/tutorial-select-layer-6.png b/doc/krita/tutorial-select-layer-6.png new file mode 100644 index 000000000..85d78dd5e Binary files /dev/null and b/doc/krita/tutorial-select-layer-6.png differ diff --git a/doc/krita/tutorial-select-layer-7.png b/doc/krita/tutorial-select-layer-7.png new file mode 100644 index 000000000..deca6a10e Binary files /dev/null and b/doc/krita/tutorial-select-layer-7.png differ diff --git a/doc/krita/tutorial-select-layer-8.png b/doc/krita/tutorial-select-layer-8.png new file mode 100644 index 000000000..576a9081a Binary files /dev/null and b/doc/krita/tutorial-select-layer-8.png differ diff --git a/doc/krita/tutorial-select-layer-9.png b/doc/krita/tutorial-select-layer-9.png new file mode 100644 index 000000000..79e846ce6 Binary files /dev/null and b/doc/krita/tutorial-select-layer-9.png differ diff --git a/doc/krita/tutorial-select-layer-sample.png b/doc/krita/tutorial-select-layer-sample.png new file mode 100644 index 000000000..b6294b1b5 Binary files /dev/null and b/doc/krita/tutorial-select-layer-sample.png differ diff --git a/doc/krita/tutorial-select-layer.docbook b/doc/krita/tutorial-select-layer.docbook new file mode 100644 index 000000000..3e60bc887 --- /dev/null +++ b/doc/krita/tutorial-select-layer.docbook @@ -0,0 +1,263 @@ + +A Small selections and layers tutorial + + + +The starting image + + + + + +The starting image + + + + + + +The image above is the image we will work with. Start krita with this +image (in the documentation folder +$KDEDIR/share/doc/HTML/en/krita/tutorial-select-layer-sample.png) +and save it to your Home folder (by choosing Save Image As...). + +Then open it in &krita; — your screen will look a bit like this (we have +zoomed in): + + + +Krita with the starting image + + + + + +The starting image + + + + + + +Now try to select the outline of the head with the Select Outline tool: + + + +The Select Outline tool + + + + + +The Select Outline tool + + + + + + +After you select it, it should look a bit like this picture: + + + +The picture after selecting the head + + + + + +The picture after selecting the head + + + + + + +If you accidently select too much, you can cut that part easily off by switching the tool to Subtract mode: + + + +The Subtract mode + + + + + +The Subtract mode + + + + + + +Now it's time to make the edges of the selection a bit fuzzy. This can be done by applying Feather to the selection. + + + +Feather selection + + + + + +Feather selection + + + + + + +Now cut the selection, using +EditCut. +Delete the current layer with +LayerRemove +Layer. Paste your selection, with +EditPaste. +Now we give ourselves a bit more room to work in by resizing the image a bit. +Use the ImageChange Image +Size... dialog for this. + + + +The Image Size dialog + + + + + +The Image Size dialog + + + + + + +Add a new layer, and place it below the old layer. You do this by selecting +the new layer in the layerbox, and then pressing the little 'down' arrow at the bottom. +Now we are going to select the area around the head with a contiguous select +(the tool has a selection-with-bucketfill icon at the border). + + + +The Select Contiguous tool + + + + + +The Select Contiguous tool + + + + + + +Make sure to select Sample merged in the tool options: + + + +The Sample merged option + + + + + +The Sample merged option + + + + + + +Feather the selection again, and invert it. +Select the Contiguous Fill tool (this is a different tool than +the Contiguous Select tool) and use it on the layer. + + + +The Contiguous Fill tool + + + + + +The Contiguous Fill tool + + + + + + +Deselect with SelectDeselect. +You'll notice some artefacts of the feathering at the sides. You can select them easily with a rectangular selection and then cut them. + + + +The Select Rectangular tool + + + + + +The Select Rectangular tool + + + + + + +Move the shadow layer a bit down and to the right to make it look nice. + + + +Moving the shadow layer + + + + + +Moving the shadow layer + + + + + + +Now you can use the Crop tool to make the image better fit around the head. + + + +The Crop tool + + + + + +The Crop tool + + + + + + +Save the image, and you're done :-) + + + +The resulting image + + + + + +The resulting image + + + + + + +Thanks go to Bart Coppens for providing this tutorial. The original is available at http://www.bartcoppens.be/krita/hackergotchi.html. + + + diff --git a/doc/krita/tutorial-starting.docbook b/doc/krita/tutorial-starting.docbook new file mode 100644 index 000000000..f720a88c0 --- /dev/null +++ b/doc/krita/tutorial-starting.docbook @@ -0,0 +1,117 @@ + +Starting to know &krita; + + +So, let's show you all the niceties. You can start &krita; either on its own +or from the &koffice; shell. In your &kde; menus, &krita; should be placed +either under Graphics or under Office — it depends a bit on who packaged +&koffice; for you. Or do what I do: press +&Alt;F2 (which opens the +minicli), type krita and +press OK. + + + +A little later, you'll be greeted by a dialog: + + + + +The Create Document dialog + + + + + +The Create Document dialog + + + + + + + +This is standard for &koffice;: you can create a new document, choose a +document from among your files or select a document you had opened in an earlier +session. We have got a bunch of templates here, ordered by color model. &krita; +is a very flexible application and can handle many different types of images: +CMYK images for printers, RGB images for +the web, RGB images with high channel depths for +photographers, watercolor images for painters — and more. For now, choose +Custom Document. That will allow +us to see the New Image dialog box: + + + + +The New Image dialog + + + + + +The New Image dialog + + + + + + + +Here you can give your document a name, determine the dimensions and the +resolution. The combination of width/height and resolution determines how big +your image will be on screen or on paper: if your image has a resolution of +100x100 dpi, and your image is 1000x1000 pixels big, then, if everything is +configured correctly, your image will be exactly 10 inches long and 10 inches +wide if you check with a ruler, no matter the resolution of your screen or of +your printer — if shown at 100%. However, life is seldom so well-regulated +that this actually works out. For now, just think pixels, not inches. + + + +The next group of options is a lot more interesting than resolution: &krita; +is an enormously flexible application and you can work with many kinds of +images. For this tutorial, just select RGB (8 +bits/channel). You can also select a profile. For now, we leave this +at the default setting of sRGB built-in - (lcms internal). + + + +In the third option group, you can select the initial canvas color and the +amount of opacity/transparency of this color. Furthermore you can +add a description of the contents. We leave these options at their default +settings as well, so click Create to actually create the new +image. + + + +You will now see the main &krita; screen. + + + + +&krita;'s main screen + + + + + +&krita;'s main screen + + + + + + + +On the left hand side and on the top, there are toolbars which offer you access +to tools for painting, editing, and selecting. +You can find a more detailed description of these toolbars here. The actual painting area is in the +middle. On the right side of your screen, there are various palettes, which you +can read more about in this section. +Finally, there is a menu bar at the top of the screen, as usually. Read more +about it here. + + + diff --git a/doc/krita/tutorial-tablet-1.png b/doc/krita/tutorial-tablet-1.png new file mode 100644 index 000000000..6857e2d67 Binary files /dev/null and b/doc/krita/tutorial-tablet-1.png differ diff --git a/doc/krita/tutorial-tablet-2.png b/doc/krita/tutorial-tablet-2.png new file mode 100644 index 000000000..21f49de70 Binary files /dev/null and b/doc/krita/tutorial-tablet-2.png differ diff --git a/doc/krita/tutorial-tablet-3.png b/doc/krita/tutorial-tablet-3.png new file mode 100644 index 000000000..092fe4abd Binary files /dev/null and b/doc/krita/tutorial-tablet-3.png differ diff --git a/doc/krita/tutorial-tablet.docbook b/doc/krita/tutorial-tablet.docbook new file mode 100644 index 000000000..2e5e6184b --- /dev/null +++ b/doc/krita/tutorial-tablet.docbook @@ -0,0 +1,141 @@ + +Working with tablets + +This tutorial is intended to describe you the first steps with working +with a tablet with &krita;. The tutorial assumes you are using &Linux;. + + +Configuring it + + +As any hardware it nearly works out of the box. &Linux; should recognize it +fine, but you might have to configure the X11 server by hand. The best way to +do this is to follow the instruction on the Wacom &Linux; howto: . + +Then, in &krita;, you need to enable the various tools (in the +Tablet section of the +SettingsConfigure +&krita;... dialog) — you can find more +information in the tablet settings +section. + + + + + +First contact with the tablet + + +There are three devices of your tablet that you can use with &krita;: + + + +the cursor, the mouse that was shipped with the Wacom +tablet +the eraser, the round part on the top of the pen +the stylus, the thin point on the bottom of the pen + + + +By default, when you use the stylus or the cursor on the tablet, the Brush +tool and the pixel brush painting operation will get selected. The eraser +device is associated to the pixel eraser painting operation. +But if you select a different tool or a different painting operation with one +device, &krita; will remember the association when you switch between devices. + + + + + +Outlines of a flower + + +Even if you knew how to draw before you started with a tablet, you will need +to adapt to the tablet. It doesn't feel the same. So I suggest to start with +something simple, like a flower, and to use a picture as a model: + + + + +A flower + + + + + +A flower + + + + + + + +First, you will need to create a new layer for the outline. I advise you to +lock the layer with the picture, it will prevent you from making mistakes. + +Drawing the outline of the flower seems pretty easy, but for your first +experience you will have a great difficulty to precisely follow the line on +the screen while your hand has to move on the tablet. Eventually you will get +something like this: + + + + +The outline of the flower + + + + + +The outline of the flower + + + + + + + + + +Colorization + + +For the colorization, you will need to create a third layer. You will +have to move it below the layer with the outlines, and do not forget to lock +the outline layer. + +It's mostly easier than the outline part, just select the color you want to +use (either with the color selector or with the color picker), then for most +of the work you can use the fill tool: with the mouse, click on the part you +want to fill, as by default the fill tool will take the outline into +consideration. On the following image, the different colors of the heart of +the flower are not seperated by outlines, to do them I just completed the +missing outline with a yellow or brown line to create the separation between +the different colors. + + + + +The colored flower + + + + + +The colored flower + + + + + + + +The resulting image looks and feels like old fashion clipart, mostly because +it lacks shadows and illumination, which are not covered by this tutorial. + + + + + diff --git a/doc/krita/tutorial.docbook b/doc/krita/tutorial.docbook new file mode 100644 index 000000000..078b1886a --- /dev/null +++ b/doc/krita/tutorial.docbook @@ -0,0 +1,14 @@ + +Tutorial + + +The toolbars and palettes shown in these tutorials may not match your +installation of &krita;. Our apologies for this inconvenience. + + +&tutorial-starting; +&tutorial-select-layer; +&tutorial-quick-starts; +&tutorial-tablet; + + diff --git a/doc/krita/using-colorspaces.docbook b/doc/krita/using-colorspaces.docbook new file mode 100644 index 000000000..0222e8d3d --- /dev/null +++ b/doc/krita/using-colorspaces.docbook @@ -0,0 +1,149 @@ + +Colorspaces + + +This chapter gives information on what colorspaces are, which colorspaces +&krita; offers, and what you should keep in mind when using them. + + + +Introduction to colorspaces + + +What is a colorspace? + + +In short, a colorspace is a way to represent colors by specifying a number of +parameters. As parameters, one can choose for example the amounts of red, +green and blue light needed for the color. This results in the commonly known +RGB colorspace. One can visualize this as a three-dimensional space, with each +of the red, green, and blue light components being an axis in the colorspace. +A color then corresponds to a certain point in this colorspace, defined by its +coordinates on the three axes. + + +To be more precise, a colorspace is a combination of a color model (indicating +which axes are present) and a mapping function (indicating which values +correspond to which colors). + + +Not every color can be represented in every colorspace. Some colorspaces +define more, or different, colors than others. The set of colors that can be +represented in a certain colorspace is called its gamut. Because gamuts +can differ widely, it is not guaranteed that images in a certain colorspace +can be converted to another colorspace without having to substitute certain +colors for others, even if they are based on the same color model. + + + + + + + +Available colorspaces + + +&krita; offers colorspaces based on RGB, CMYK, Lab, LMS, YCbCr, and Gray +color models. These are shortly discussed in this section. + + + +The RGB color models + + +The abbreviation RGB stands for Red, Green, Blue, and the color model with +this name refers to the three light components that are emitted in displays +(televisions, computer monitors, etcetera) to create a certain color. This +color model is used by default in virtually any standard painting application. + +When defining a color in the RGB model, its red, green and blue components are +specified. If all components are absent (each component is emitted at 0 +percent intensity, so no light at all), the color is pure black. If all +components are fully present (100 percent intensity), the color is pure white. +If one component is present at full intensity and the other two are absent, +the pure respective color is obtained. + +Two more examples: if both red and green are emitted at 100 percent and blue +is not emitted, pure yellow is obtained. A color with all three components at +the same intensity is a shade of gray. + +There are various colorspaces that implement the RGB model. For example, the +so-called RGB8 colorspace represents each color with 8 bits per component. +Since 8 bits allow for 256 distinct values, the total number of different +colors that can be specified in this colorspace is 256 (red) * 256 (green) * +256 (blue), or about 16.7 million colors. In &krita;, a couple of RGB +colorspaces are available, for example RGB32, which is able to distinguish +between 4.2 billion values per component. + + + + + +The CMYK color model + + +CMYK is the abbreviation for Cyan, Magenta, Yellow, blacK (although officially +the K stands for Key, black is much more commonly used). This color model is +based on ink: a color is specified by the amount of ink needed for a point +to be perceived as having that color. + +Since CMYK colors are used by printers while RGB colors are used on-screen, +one often wants to convert RGB colors to CMYK colors. As this cannot always be +done correctly, printed images may turn out to look quite different than what +is perceived on-screen. + + + + + +The L*a*b* color model + + +This color model uses three parameters for a color: its +luminance or lightness (L*, which lies between 0 for black and +100 for white), its position between absolute red and absolute green (a*, +which is negative for colors closer to green and positive for colors closer to +red), and its position between yellow and blue (b*, which is negative for +colors closer to blue and positive for colors closer to yellow). + + + + + +The LMS color model + + +This model is based on the contribution of actual light wave lengths to the +color. The human eye is sensitive to three types of light waves, distinguished +by their wave lengths: long (L), middle (M) and short (S) waves. The eye's +sensitivity for a certain color on these three wavelengths can be expressed in +L, M and S coordinates. + + + + + +The YCbCr color model + + +The YCbCr model is often used for video systems. The Y parameter indicates the +luminance or lightness of the color (which can be seen as a gray-tone), the Cb +and Cr parameters indicate the chrominance (color tone): Cb places the color +on a scale between blue and yellow, Cr indicates the place of the color +between red and green. + + + + +The Gray color model + + +The Gray color model simply represents colors as shades of gray (with black +and white being the extremes). + + + + + + + diff --git a/doc/krita/using-filters.docbook b/doc/krita/using-filters.docbook new file mode 100644 index 000000000..3dd686c4c --- /dev/null +++ b/doc/krita/using-filters.docbook @@ -0,0 +1,923 @@ + +Filters + + +&krita; comes with a number of filters. These can be used to enhance or +otherwise modify the image, either in whole or in part. Some filters are +applied directly, others are customizable, meaning that you are presented with +a dialog in which you can tune the result to your liking before the filter is +applied. If a selection is active, a filter is applied on the selected part of +the image. If no selection is active, the entire image is modified. + +This chapter describes the available filters in detail. To make comparing the +filters easier, each filter has been applied to the same image and each description +contains a comparison image, showing the result of applying the filter described. +The original image (with thanks to the photographer, Christian Peper) is shown +below at half the original size. The sample images demonstrating the +results of applying the filters, with the original image at the left and the +modified image at the right, are shown at 25% of the original size. + +Some filters yield reasonable results for most images. For +other filters though, quite some tweaking needs to be done before the desired +outcome is achieved. If a filter does not do what you want, it might need +more or less customising. The examples in this chapter are exaggerated to +give a good impression of the filters. You will usually want to have more +gentle modifications. + +Tip: If you want to apply a filter to everything except a certain part of your +image (for example, you want to desaturate your image except for the centre), +select the part you do not want to apply the filter to, use the +SelectInvert +menu option, and then apply the filter. + + +See the Dialogs for working with +filters section for descriptions of the settings available for the +customizable filters. + + + +The original image + + + + + +The original image + + + + + + +The Auto Contrast filter + +The Auto Contrast filter changes the contrast of your image to what should be +the best settings. Usually this works out fine, but in some cases (for example +photos taken under unusual lighting circumstances), the filter will not yield +satisfying results. + + +You can find the Auto Contrast filter in the Filter +Adjust menu. This filter is not customizable. + + +The image with the Auto Contrast filter applied to it + + + + + +The image with the Auto Contrast filter applied to it + + + + + + + +The Blur filter + +You can use the Blur filter to blur your image (give it a fuzzy look). + + +You can find the filter in the Filter +Blur menu. +See the section on the +Blur dialog +for more information on its settings. + + +The image with the Blur filter applied to it + + + + + +The image with the Blur filter applied to it + + + + + + + +The Brightness / Contrast filter + +With this filter, you can adjust the brightness and contrast of your image. + + +You can find the filter in the Filter +Adjust menu. +See the section on the +Brightness / Contrast dialog +for more information on its settings. + + +The image with the Brightness / Contrast filter applied to it + + + + + +The image with the Brightness / Contrast filter applied to it + + + + + + + +The Bumpmap filter + +The Bumpmap filter takes two layers and uses one of these to convert the other +one so that it will give an illusion of depth. The object layer (the layer to be +transformed) is the actual layer that should receive the three-dimensional +looks. The bumpmap layer is a grayscale layer, which is read and used to +determine the height for each point of the object layer. Alternatively, the +same layer can be used as both object layer and bumpmap layer. + + +You can find the filter in the Filter +Map menu. +See the section on the +Bumpmap dialog for more information on its +settings. + + +The image with the Bumpmap filter applied to it + + + + + +The image with the Bumpmap filter applied to it + + + + + + + +The CImg Image Restoration filter + +With this filter, you can perform minor enhancements to your image, for +example removing small scratches or adding a slight blur. The difference +between our sample original image and the result of applying this filter with +standard settings is virtually none. + + +You can find the filter in the Filter +Enhance menu. +See the section on the +Image Restoration dialog +for more information on its settings. + + + + +The Color Adjustment filter + +This filter allows you to change the looks of your image by increasing or +decreasing the abundance of certain colors. + + +You can find the filter in the Filter +Adjust menu. +See the section on the +Color Adjustment dialog +for more information on its settings. + + +The image with the Color Adjustment filter applied to it + + + + + +The image with the Color Adjustment filter applied to it + + + + + + + +The Color to Alpha filter + +This filter changes a color or color range in your image to become +transparent, effectively clearing regions with those colors. + + +You can find the filter in the Filter +Colors menu. +See the section on the +Color to Alpha dialog +for more information on its settings. + + +The image with the Color to Alpha filter applied to it + + + + + +The image with the Color to Alpha filter applied to it + + + + + + + +The Color Transfer filter + +With this filter, you can re-color an image using the colors from another +image. Each color in your current image will be replaced by the most alike +color used in the other image. + + +You can find the filter in the Filter +Colors menu. +See the section on the +Color Transfer dialog +for more information on its settings. + + +The image with the Color Transfer filter applied to it + + + + + +The image with the Color Transfer filter applied to it + + + + + + + +The Custom Convolution filter + +This filter allows you to distort your image by setting a number of +parameters. + + +You can find the filter in the Filter +Enhance menu. +See the section on the +Custom Convolution dialog +for more information on its settings. + + +The image with the Custom Convolution filter applied to it + + + + + +The image with the Custom Convolution filter applied to it + + + + + + + +The Desaturate filter + +This filter converts your image to grayscale by setting the saturation of each +pixel's color to zero. + + +You can find the filter in the Filter +Adjust menu. +This filter is not customizable. + + +The image with the Desaturate filter applied to it + + + + + +The image with the Desaturate filter applied to it + + + + + + + +The Edge Detection filters + +These filters try to detect edges (boundaries) in the picture +and modify the image such that only these edges retain their respective colors, +while the rest of the image is turned gray. Through the use of lighting the +image will then get a three-dimensional look. + +There are four edge detection filters available. Each of these detects edges +from a different side (possibly considering other parts of the image as being +edges) and will therefore obtain a different resulting image. + + +You can find the filters in the Filter +Edge Detection menu. +These filters are not customizable. + + +The image with the Bottom Edge Detection filter applied to +it + + + + + +The image with the Bottom Edge Detection filter applied to it + + + + + + + +The Emboss filters + +Emboss filters work somewhat like edge detection filters, with the difference +that embossed images are entirely gray. Areas in the picture are detected and +are given a certain height level, which is made visible by using +grayscale borders, making the image look like it is three-dimensional. + + +You can find the filters in the Filter +Emboss menu. +Except for the Emboss with Variable Depth filter, these filters are not +customizable. See the section on the +Emboss dialog +for more information on the settings of the Emboss with Variable Depth filter. + + +The image with the Emboss in All Directions filter applied to it + + + + + +The image with the Emboss in All Directions filter applied to it + + + + + +The image with the Emboss with Variable depth filter applied to +it + + + + + +The image with the Emboss with Variable depth filter applied to it + + + + + + + +The Gaussian Blur filter + +This filter makes the image a little fuzzy by blurring it in a pseudo-random +way. A gaussian algorithm is used for finding the extent to which each part of +the image should be blurred. + + +You can find the filter in the Filter +Blur menu. +This filter is not customizable. + + +The image with the Gaussian Blur filter applied to it + + + + + +The image with the Gaussian Blur filter applied to it + + + + + + + +The Gaussian Noise Reduction filter + +With this filter, you can remove noise from your image. + + +You can find the filter in the Filter +Enhance menu. +See the section on the +Gaussian Noise Reduction dialog +for more information on its settings. + + +The image with the Gaussian Noise Reduction filter applied to it + + + + + +The image with the Gaussian Noise Reduction filter applied to it + + + + + + + +The Invert filter + +This filter inverts all colors. The Red, Green and Blue component of each pixel +are taken and subtracted from 255. This means that red becomes cyan, green +becomes purple, and blue becomes yellow. The resulting values form the new +pixel color. + + +You can find the filter in the Filter +Adjust menu. +This filter is not customizable. + + +The image with the Invert filter applied to it + + + + + +The image with the Invert filter applied to it + + + + + + + +The Lens Correction filter + +This filter can fix distortions in your image resulting from for example +pincushion lens effects, and modify some lighting. + + +You can find the filter in the Filter +Other menu. +See the section on the +Lens Correction dialog +for more information on its settings. + + +The image with the Lens Correction filter applied to it + + + + + +The image with the Lens Correction filter applied to it + + + + + + + +The Maximize Channel filter + +This filter gives each pixel in your image a new color: only the color channel +that contributes the most to the color of a pixel is retained (except for +gray pixels, which are kept gray). + + +You can find the filter in the Filter +Colors menu. +This filter is not customizable. + + +The image with the Maximize Channel filter applied to it + + + + + +The image with the Maximize Channel filter applied to it + + + + + + + +The Mean Removal filter + +This filter sharpens the image by changing the colors of neighboring pixels +with approximately the same color, so that small differences are evened out. + + +You can find the filter in the Filter +Enhance menu. +This filter is not customizable. + + +The image with the Mean Removal filter applied to it + + + + + +The image with the Mean Removal filter applied to it + + + + + + + +The Minimize Channel filter + +This filter gives each pixel in your image a new color: the color channel +that contributes the most to the color of a pixel is removed (except for +gray pixels, which are kept gray). + + +You can find the filter in the Filter +Colors menu. +This filter is not customizable. + + +The image with the Minimize Channel filter applied to it + + + + + +The image with the Minimize Channel filter applied to it + + + + + + + +The Oilpaint filter + +An oilpaint effect is given to the image by creating patch-shaped areas in which +the most important color is applied to the entire area. + + +You can find the filter in the Filter +Artistic menu. +See the section on the +Oilpaint dialog +for more information on its settings. + + +The image with the Oilpaint filter applied to it + + + + + +The image with the Oilpaint filter applied to it + + + + + + + +The Pixelize filter + +The image is pixelated by taking a square area and giving it the mean color +value of the pixels it contains. + + +You can find the filter in the Filter +Artistic menu. +See the section on the +Pixelize dialog +for more information on its settings. + + +The image with the Pixelize filter applied to it + + + + + +The image with the Pixelize filter applied to it + + + + + + + +The Raindrops filter + +This filter makes it look like raindrops have fallen on the image by distorting +drop-shaped areas with a lens-like effect as one would see when looking +at the image through a real raindrop. Some raindrops will have a fish-eye lens +effect. + + +You can find the filter in the Filter +Artistic menu. +See the section on the +Raindrops dialog +for more information on its settings. + + +The image with the Raindrops filter applied to it + + + + + +The image with the Raindrops filter applied to it + + + + + + + +The Random Noise filter + +With this filter, random noise can be added to your image. + + +You can find the filter in the Filter +Other menu. +See the section on the +Random Noise dialog +for more information on its settings. + + +The image with the Random Noise filter applied to it + + + + + +The image with the Random Noise filter applied to it + + + + + + + +The Random Pick filter + +This filter distorts the image by interchanging pixels. + + +You can find the filter in the Filter +Other menu. +See the section on the +Random Pick dialog +for more information on its settings. + + +The image with the Random Pick filter applied to it + + + + + +The image with the Random Pick filter applied to it + + + + + + + +The Round Corners filter + +This filter just rounds off the corners of the image. This is done by making +the outside of the rounded corner transparent. + + +You can find the filter in the Filter +Map menu. +See the section on the +Round Corners dialog +for more information on its settings. + + +The image with the Round Corners filter applied to it + + + + + +The image with the Round Corners filter applied to it + + + + + + + +The Sharpen filter + +This filter sharpens the image. + + +You can find the filter in the Filter +Enhance menu. +This filter is not customizable. + + +The image with the Sharpen filter applied to it + + + + + +The image with the Sharpen filter applied to it + + + + + + + +The Small Tiles filter + +The picture is reduced in size and repeated multiple times. + + +You can find the filter in the Filter +Map menu. +See the section on the +Small Tiles dialog +for more information on its settings. + + +The image with the Small Tiles filter applied to it + + + + + +The image with the Small Tiles filter applied to it + + + + + + + +The Sobel filter + +This is a more enhanced edge detection filter. + + +You can find the filter in the Filter +Edge Detection menu. +See the section on the +Sobel dialog +for more information on its settings. + + +The image with the Sobel filter applied to it + + + + + +The image with the Sobel filter applied to it + + + + + + + +The Unsharp Mask filter + +This filter sharpens part of your image. (The name unsharp is +historical: parts would be masked off while the rest would be made less sharp.) + + +You can find the filter in the Filter +Enhance menu. +See the section on the +Unsharp Mask dialog +for more information on its settings. + + +The image with the Unsharp Mask filter applied to it + + + + + +The image with the Unsharp Mask filter applied to it + + + + + + + +The Wave filter + +This filter transforms your image into a wave shape. + + +You can find the filter in the Filter +Other menu. +See the section on the +Wave dialog +for more information on its settings. + + +The image with the Wave filter applied to it + + + + + +The image with the Wave filter applied to it + + + + + + + +The Wavelet Noise Reduction filter + +This filter reduces noise in the image by giving loose pixels a color close to +the surrounding area. This causes small details to be lost, but can enhance the +general view of the image when this is hampered by too many unnecessary details. + + +You can find the filter in the Filter +Enhance menu. +See the section on the +Wavelet Noise Reduction dialog +for more information on its settings. + + +The image with the Wavelet Noise Reduction filter applied to +it + + + + + +The image with the Wavelet Noise Reduction filter applied to it + + + + + + + + diff --git a/doc/krita/using-images.docbook b/doc/krita/using-images.docbook new file mode 100644 index 000000000..e3b1f239a --- /dev/null +++ b/doc/krita/using-images.docbook @@ -0,0 +1,66 @@ + +Images + + +Creating and modifying images is one of &krita;'s core functionalities. While +most of the other chapters in this manual focus on the things you can do when +painting or editing, this chapter shows you what you can do with respect to +the images themselves. + + + +Working with files + + +Unless you are doing some quick sketching, working with &krita; will most +likely involve files. You can open existing images — &krita; can work +with a large number of file formats, see Image formats — +or start &krita; to create a new one. When you are done or if you want to +continue at a later time, you can easily save your work. + + + + +Opening existing files +When you start &krita;, you can open an existing image with +the Open Existing Document button at the lower left of +the opening dialog. You can also use the +FileOpen +menu option (&Ctrl;O). +This will bring up the Open Document dialog in which you +can choose an image to open. The opening dialog and the +File menu also contain a list of the most recently used +files for quick access. + + +Saving your work in progress +With the +FileSave +and FileSave As... +menu options (or their respective shortcuts &Ctrl;S and &Ctrl;&Shift;S), you can save your +work. The former option will save the modifications to the current image, the +latter option will show the Save Document dialog in which +you can give a new file name for the image. If this is the first time you save +the image, Save will ask for a file name as well. + + + +Creating a new image +From the opening dialog (available via the +FileNew +menu option or the &Ctrl;N keys), you can create a +fully custom document or choose one of the image templates. These templates +offer a quick way of creating a new image. See the Starting to know &krita; tutorial. + + + + + + + + diff --git a/doc/krita/using-layers.docbook b/doc/krita/using-layers.docbook new file mode 100644 index 000000000..8cb574f69 --- /dev/null +++ b/doc/krita/using-layers.docbook @@ -0,0 +1,620 @@ + +Layers + + +This chapter gives an overview of how layers work in &krita;. + + + +Background information on layers + + +Extensive use of &krita; will almost require you to have some knowledge of +layers. Using layers, you can work on one part of the image without touching +the rest of it, and most effects are best applied on a layer, instead of on +the whole image. Of course, if you do want to apply an effect to an entire +image, &krita; does offer you that possibility, and there is nothing against +it. + +The idea behind layers is quite simple. As the name suggests, layers lie on +top of each other, and together form the layer stack. The final resulting +image is that what you see when looking through the stack from top to bottom. +This means that usually the upper layers of your image will have more or less +transparency, since you cannot look through a layer which has no transparency. +(&krita; works with opaqueness instead of transparency. A layer that is 100 +percent opaque is 0 percent transparent, and vice versa.) A layer higher in +the stack gets applied later than one lower in the stack. For example, if your +image contains four layers, numbered from 1 (lowest) to 4 (highest), the +effect that layer number 4 adds to the image, is applied to the result from +applying layers 1 through 3. + +Every image you edit in &krita; contains layers. When you create a new image, +the layer box (usually shown at the bottom right of your screen, see this section) will contain +one layer. The painting and editing you do is then applied to that layer. Once +you add more layers, you can choose on which part of the image you want to +work, by selecting the respective layer. All further painting is then applied +to that layer, until you select another one. + +Layers are also an excellent way to check whether adding certain effects (or +applying certain image modifications) come out right. Add a layer which +contains what you want to try out, and show or hide it with the eye icon in +the layer box. You can especially profit from this method if you have multiple +effects to check out: show and hide them in any combination, and decide which +you like best. And since you can move the layers around, you can also +experiment with the order in which the effects are applied. + +See the Selections and layers +tutorial for a small hands-on introduction. + + + + +The layer box + +The layer box is the instrument you will use most to work with layers. It +gives an overview of the layers that are present in your image, and using it +you can manage layers by adding, removing, reordering or modifying them. + +The layer box consists of three parts. The middle part gives an overview of the +layers in the image. At the top, you can set some properties for the current +layer. At the bottom, a couple of layer management options can be found. The +next sections describe these three parts in more detail. + + + +Layer overview + +This part shows you which layers are present in your image. In a tree-like +structure, the layer group hierarchy is shown: layers that are contained within +a layer group are displayed a bit to the right to indicate their belonging to +that group. + +For each layer, a thumbnail preview and its name are shown. The layer name +is preceded by a folder icon if it is a group layer. Furthermore, two +indicators are present: the eye icon shows whether the layer is currently +visible (an open eye indicates that the layer is visible, a closed eye +indicates that it is not), and the lock icon shows whether the layer is +locked. No changes can be made to a locked layer. + +When you click on a layer's eye icon, its visibility is switched from on to +off or vice versa. Clicking on the lock icon enables or disables editing of +that layer. You can click on the name of the current layer to rename it. +Note that to rename a layer, it has to be the current one. You do not need to +activate a layer in order to make it (in)visible or (un)locked via the eye and +lock icons, respectively: these work directly. + +Doubleclick on a layer entry in the list to open the Layer +Properties dialog. This dialog shows a layer's colorspace and +profile. You can also change its name, opacity and composite mode here. + + + + +Layer options + +The top of the layer box contains two controls for setting properties of the +currently selected layer. The list box at the left allows you to quickly set +the layer's composite mode. The spin field and slider at the right can be used +to change the layer's opacity. + +At the bottom of the layer box, there are five buttons. From left to right, +these are as follows. The New Layer icon brings up a +submenu from which you can choose which type of layer you want to add. This +menu can also be opened by clicking with the &RMB; on the layer box. The +Move Layer Down and Move Layer Up +buttons move the current layer one level down and up, respectively, within the +current layer group. If the layer is already the last or first within the +layer group, trying to move it further will move it out of the layer group. +The Layer Properties button opens the Layer +Properties dialog, just as when you would have doubleclicked +on the layer. The Delete Layer button deletes the +current layer. + + + + + + +Working with layers + + +Because layers are quite important when extensively using &krita;, you can +perform a lot of operations on them. These are all available via the Layer menu. Some of +the possibilities: + + + +Add, remove, and duplicate layers; +Create and edit layer masks; +Flip, rotate, scale and shear layers; +Convert layers between colorspaces; +Save layers as images; +View layer histograms. + + + + + +Adjustment Layers + +Adjustment layers are layers that consist of a filter and an optional +selection. The filter effect is applied to the composite image of all +layers under the adjustment layer in the current layer group. The big +thing is, adjustment layers apply these effects non-destructively. The +original image data is not modified. + +Almost all &krita; filters are suitable for use in adjustment +layers -- even filters that would downgrade the image quality. For instance, +the raindrops filter converts to 8-bit RGB before working its magic. If you +would try to use this filter directly on a 16-bit L*a*b* layer, &krita; would +warn you about the conversion to RGB and back again this filter would cause. +Not so with adjustment layers: the original data isn't touched, so applying +the filter is safe. + +What about the colorspace of an adjustment layer then? In order to examine +this issue, you need to know what happens when &krita; renders an adjustment +layer. + + + +Adjustment layers and selections + +If the currently active layer has an active selection, then that selection +will be copied and used as a mask for the adjustment layer. If there is no +active selection, then there will be no mask and the adjustment will apply to +the entire extent of the layers under the adjustment layer in the current +group. There is no way of adding a mask to an existing +adjustment layer. + +If there is a mask in the adjustment layer, you can edit the mask using the +ordinary painting tools and painting operations. + + + + + +A note on projections + + +&krita; composites the layers bottom to top, within each layer group. The +aggregate -- or the projection as it is also called -- is then filtered by +the adjustment layer. If there are layers on top of the adjustment layer, +those are composited onto the projection. &krita; converts all layer data before +compositing, so if the bottom-most layer in an image is grayscale, all layers +are converted to grayscale before compositing -- and that means that the +adjustment layer projection will be grayscale, too. + +With this knowledge you'll understand why &krita; can often offer better +performance working with layers on top of an adjustment layer which is on top +of a complex layer structure: &krita; uses the projection and doesn't even look +anymore at the layers under the adjustment layer. Unless, of course, you +change one of them. + + + + + + +Compositing modes + + +Layers can be composited in various ways, each yielding a different effect. +This section describes the available compositing modes. Each description is +accompanied by an example: on top of an original image (see below), a rainbow +gradient is added. + + + + +The original image + + + + + +The original image + + + + + + + +<guilabel>Normal</guilabel> + + +The Normal mode does nothing special. It adds the layer +to the image, and if no other special effects like opacity are changed, the +underlying layers will only be visible at places where the new layer is +itself transparent. + + + + +The gradient applied with the Normal compositing +mode + + + + + +The gradient applied with the Normal compositing +mode + + + + + + + + + +<guilabel>Multiply</guilabel> + + +The Multiply mode blends the two layers so that the +bottom layer gets colorized by the new layer. The resulting +image is generally quite dark. + + + + +The gradient applied with the Multiply compositing +mode + + + + + +The gradient applied with the Multiply compositing +mode + + + + + + + + + +<guilabel>Burn</guilabel>, <guilabel>Dodge</guilabel>, +<guilabel>Divide</guilabel> and <guilabel>Screen</guilabel> + + +The Burn, Dodge, +Divide and Screen modes all add an +extra burning effect by following contours instead of using +straight lines. In addition, Burn and +Divide use the inverted colors instead of the actual +colors of the composited layer. + + + + +The gradient applied with the Burn compositing +mode + + + + + +The gradient applied with the Burn compositing +mode + + + + + + + + +The gradient applied with the Dodge compositing +mode + + + + + +The gradient applied with the Dodge compositing +mode + + + + + + + + +The gradient applied with the Divide compositing +mode + + + + + +The gradient applied with the Divide compositing +mode + + + + + + + + +The gradient applied with the Screen compositing +mode + + + + + +The gradient applied with the Screen compositing +mode + + + + + + + + + +<guilabel>Overlay</guilabel> + + +Like Multiply, the Overlay mode +colorizes the underlying layer. The resulting image is about as light as +the original layer. + + + + +The gradient applied with the Overlay compositing +mode + + + + + +The gradient applied with the Overlay compositing +mode + + + + + + + + + +<guilabel>Darken</guilabel> + + +The Darken mode darkens the underlying layer while +colorizing it to match the colors in the composited layer. + + + + +The gradient applied with the Darken compositing +mode + + + + + +The gradient applied with the Darken compositing +mode + + + + + + + + + +<guilabel>Lighten</guilabel> + + +The Lighten mode lightens the underlying layer while +colorizing it to match the colors in the composited layer. + + + + +The gradient applied with the Lighten compositing +mode + + + + + +The gradient applied with the Lighten compositing +mode + + + + + + + + + +<guilabel>Hue</guilabel>, <guilabel>Saturation</guilabel> and +<guilabel>Value</guilabel> + + +The Hue, Saturation and +Value modes respectively apply the hue, saturation and +value components of the composited layer to the underlying layer. + + + + +The gradient applied with the Hue compositing +mode + + + + + +The gradient applied with the Hue compositing +mode + + + + + + + + +The gradient applied with the Saturation compositing +mode + + + + + +The gradient applied with the Saturation compositing +mode + + + + + + + + +The gradient applied with the Value compositing +mode + + + + + +The gradient applied with the Value compositing +mode + + + + + + + + + +<guilabel>Color</guilabel> + + +The Color mode colorizes the underlying layer, yielding +very strong colors. + + + + +The gradient applied with the Color compositing +mode + + + + + +The gradient applied with the Color compositing +mode + + + + + + + + + + + +Layer Masks + + +Basically, a layer mask is a mask that you place on your paint layer. This +will literally mask areas of the layer, so that the content underneath shows +through. You can paint on it with greyscale colors: the more black the color, +the less the layer under it will shine through, the more white, the less the +layer under it will be shown. So complete white will let nothing through, +complete black will let everything through. Basically, it is a bit like +selecting a piece of your image, and then cutting it, so that the selected +bits go away. So what is the use for a mask here? The big advantage is that it +is non-destructive: if you decide that you masked out the wrong part of your +layer, you can easily remove the mask and start anew, something a lot harder +(not to say near impossible, especially in between sessions) with regular +selection-cutting. + +So, how to create a mask? There are 2 ways: + + + + +Start from scratch. +LayerMaskCreate +Mask. The mask starts with everything being +retained, that is, a complete white mask. Basically you will not see any +changes as long as you do not paint on it. + + +Start from the current selection. +LayerMaskMask +From Selection. The selectedness will be converted +to whiteness. This means that fully selected area will be visible, fully +unselected areas will be invisible, and the rest will be partially visible, +depending on how much the area was selected. + + + + +Editing the mask + + +First, make sure you are editing the mask, not the layer, by making sure +LayerMaskEdit +Mask is checked. (This is checked by default.) Then +you can paint on the layer just like before, only now you are +painting on the mask, instead of on the layer itself. To stop painting on the +mask, you can uncheck the Edit Mask checkbox. There's +also the option to show the mask, through checking +LayerMaskShow +Mask. (This is not checked by +default). This option will render the entire layer as a visual representation +of the mask in greyscale, instead of the actual layer. This can be handy to +see where your mask is, but it might be not as handy when you want to edit it, +since you cannot look at the actual layer. + +Other actions: you can also remove the mask if you are not satisfied with it, +and want to start over again, or just want to remove it, with +LayerMaskRemove +Mask. You can also apply the mask, +meaning that the mask will be made permanently. This means that the mask is +removed, but that its effect of transparency will be committed to the layer. + + + + + + diff --git a/doc/krita/using-selections-1.png b/doc/krita/using-selections-1.png new file mode 100644 index 000000000..b3ff682a7 Binary files /dev/null and b/doc/krita/using-selections-1.png differ diff --git a/doc/krita/using-selections-2.png b/doc/krita/using-selections-2.png new file mode 100644 index 000000000..4b23bb5fd Binary files /dev/null and b/doc/krita/using-selections-2.png differ diff --git a/doc/krita/using-selections-3.png b/doc/krita/using-selections-3.png new file mode 100644 index 000000000..cca123636 Binary files /dev/null and b/doc/krita/using-selections-3.png differ diff --git a/doc/krita/using-selections-4.png b/doc/krita/using-selections-4.png new file mode 100644 index 000000000..5d82cafba Binary files /dev/null and b/doc/krita/using-selections-4.png differ diff --git a/doc/krita/using-selections-5.png b/doc/krita/using-selections-5.png new file mode 100644 index 000000000..5c524be80 Binary files /dev/null and b/doc/krita/using-selections-5.png differ diff --git a/doc/krita/using-selections-6.png b/doc/krita/using-selections-6.png new file mode 100644 index 000000000..16d76bc34 Binary files /dev/null and b/doc/krita/using-selections-6.png differ diff --git a/doc/krita/using-selections.docbook b/doc/krita/using-selections.docbook new file mode 100644 index 000000000..5465b8a6d --- /dev/null +++ b/doc/krita/using-selections.docbook @@ -0,0 +1,200 @@ + +Selections + + +This chapter gives a short introduction on selections. + +You can select a part of an image masking off the rest. This is handy when +you want to cut, copy or just modify a part of the image without affecting +the rest. For processing selected objects &krita; applies a mask. Each pixel of +the selection is processed based on a value of its mask, or the level +of the selection, that can range from 0 (unselected) to 255 +(selected). Yes, that is right, you can have fractionally selected pixels. +And by working on individual pixels you can paint your selection. + +The selection mask is visualized with unselected pixels having a blueish +tint, and selected pixels looking like normal. Fractionally selected pixels +are shown as something in between. Additionally a red border is drawn around +the selected areas. Fractionally selected pixels are inside the border, so +even inside the red border you can possibly see the blueish tint on some pixels. + + + +Making a selection + +A whole range of tools exist to make selections. From rectangles, ellipses +and freehand to the more exotic like color range select. When you make +several selections they add up. So a rectangle select followed by an +ellipse select select both areas. Later on, you can subtract areas from +the selection by using, for example, the Erase Selection tool. + +To get back to normal (no active selection), choose +SelectDeselect +. To select all pixels, choose +SelectSelect All +. + +You may think that those two actions give the same result, but it +is much more efficient to have no active selection than to have selected +everything. + +After having deselected you can bring your selection back by choosing +SelectReselect +. + + + + +Painting your selection + +As said above you can essentially paint your selection, and just like +when you paint normally you can choose to paint your selection freehand or +guided with rectangles, ellipses, &etc;. You also have the choice of different +paint tools like pen, brush, airbrush, &etc;. Choose the guide tool, and the +paint tool in the toolbox, and go ahead and paint your +selection. + +The guide tools work just like you may be used to from other applications. So +holding down shift while drawing a rectangle or an ellipse still forces them to +be a square or a circle respectively. + + + +Painting a selection + + + + + +Painting a selection + + + + + +Painting a selection + + + + + +Painting a selection + + + + + + + + +Unselecting + +All the selection paint tools have an option to add or subtract from the +selection. This means that you can use all your familiar tools to both select +and unselect. There is also a true selection eraser among the selection paint +tools. + + + +Unselecting + + + + + +Unselecting + + + + + + + +Making a new selection + +When you want to make a new selection, replacing the currently active one, you +first need to deselect the active selection. Choose +SelectDeselect +. + + + + +Selecting a contiguous area (magic wand) + +To follow the analogy of painting your selection &krita; also provides an +equivalent to filling a contiguous area. Some paint applications call this +selection tool the magic wand tool. What it does is select the nearby +pixels as long as they have nearly the same color as the pixel you click +on. The selection floods out from the point you click on. In the fuzziness +option you can set how different the colors are allowed to be before the +flooding stops. + + + +Before the magic wand + + + + + +Before the magic wand + + + + + + +A magic wand selection + + + + + +A magic wand selection + + + + + + + + +Selecting similar colors + +The Select Similar tool lets you pick a pixel and then select all pixels that +have a similar color. Picking a color in one corner of the image may select a +pixel in another corner if they have similar color. +With the Fuzziness option you can set how similar the colors must be to become +selected. + + + +Selecting similar colors + + + + + +Selecting similar colors + + + + + + + +Inverting the selection + +In some cases it is easier to specify your selection the other way around. That +is, first you select the parts that ultimately should not be selected and then +then you choose +SelectInvert +. +What invert does, is that for every pixel it flips the selection level so to +speak, by setting it to 256 minus the current selection level. Thus what was +selected becomes unselected and vice versa. + + + + diff --git a/doc/krita/using-views.docbook b/doc/krita/using-views.docbook new file mode 100644 index 000000000..6760209ef --- /dev/null +++ b/doc/krita/using-views.docbook @@ -0,0 +1,167 @@ + +Views + + +One of the most important things you need to know when working with a painting +or image editing application, is how to adapt the view of your image to your +(changing) needs. This chapter describes the various possibilities &krita; +offers. + + + +Zooming + + +By zooming, you can view your images at various levels of detail. Zooming out +will show a larger part of the image, but with less detail. &krita; offers a +couple of options that affect which part of the image is shown: + + + + +Zooming in +Zooming in allows you to see more details, but you will only +see a smaller part of the image. You can zoom in by choosing the +ViewZoom +in menu item, by clicking the + + Zoom in button on the +toolbar, or by pressing the &Ctrl;+ keys. +You can zoom in up to 1600% (a 16:1 ratio) via a number of fixed zoom levels. + + + +Zooming out +Zooming out allows you to see a larger part of the image while +losing some detail. Zooming out can be done by choosing the +ViewZoom +out menu item, by clicking the + + Zoom out button on the +toolbar, or by pressing the &Ctrl;- keys. +You can zoom out up to 0.2% (a 1:500 ratio) via a number of fixed zoom levels. + + + +Going back to 100% +As viewing your image at its real size is quite handy at +times, you can do so via the +ViewActual +pixels menu item or by pressing &Ctrl;0. + + + +Zooming in and out from the Overview +tab +The Overview tab of the control box +(usually found at the right hand side of the &krita; window) also allows you +to change the zoom level by using the slider or the spinbox. Slightly +different zoom levels are available here, so if zooming in or out as described +above does not produce a view you want, you can try using this option. The +1:1 button offers another way of getting back to a 100% +zoom. + + +Special zooms +There are two more special ways of zooming. The +ViewFit to +Page menu item zooms your image such that it is +as large as possible while remaining entirely visible. The +ViewFull Screen +Mode menu item (pressing &Ctrl;&Shift;F will also activate +this mode) enlarges the &krita; window to fill your entire screen, removing +the title bar as well. Although this is not a real way of +zooming, it can help you by showing just that little bit more of your +image. + + + + + + + +Working with views + + +Apart from changing the zoom level of your view, you can also open different +views for the same image. This way, you can for example look at two different +parts of your image that would not fit on your screen together otherwise. + + + + +New view windows +You can open a new &krita; window for your image by choosing +ViewNew +View Both windows are independent from each other +(so you can select different tools, view different parts of your image, +&etc;), but changes you make to the image in one window are immediately +visible in the other. To close a window, use the normal window closing button. +There is also an option ViewClose +All Views, which closes all newly created views and +leaves only the original window open. + + +Splitting views +You can also split a window into two views. Like a new window, +one view of a split window has its own settings for brushes, zoom levels and +the like, but both views are shown in the same window. To split your window, +choose ViewSplit +View. The viewing area of the &krita; window will +then be divided into two halves. You can switch between horizontal and +vertical division with the +ViewSplitter +Orientation menu, and get back to one view by +choosing ViewRemove +View. + + + + + + + +Miscellaneous view options + + +&krita; also offers two options that can help you with knowing where you are. + + + + +Rulers +You can have &krita; show rulers along the sides of your +image, indicating x and y coordinates. To do so, choose +ViewShow +Rulers or press &Ctrl;R. The rulers will +automatically adapt to your zoom level to show a proper amount of +subdivisions. To remove the rulers, choose the same menu option (now called +Hide Rulers) or press &Ctrl;R again. + + +Grid +In order to see grid lines, choose +ViewShow +Grid. You can set the distance between grid lines +with ViewGrid +Spacing and you can choose different colours for the +lines in the SettingsConfigure +&krita;... dialog (see the Grid section of the Settings +chapter). + + + + + + + + diff --git a/doc/kspread/Makefile.am b/doc/kspread/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kspread/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kspread/a11y.docbook b/doc/kspread/a11y.docbook new file mode 100644 index 000000000..c7ceaee57 --- /dev/null +++ b/doc/kspread/a11y.docbook @@ -0,0 +1,320 @@ + + + + +Gary +Cramblitt + + + + + +For Users with Disabilities +This section of the documentation discusses accessibility features in &kspread; +for users with disabilities. Some of these features apply to &kde; as a whole and are controlled from +&kcontrolcenter;. Some apply to all &koffice; applications, +and some are specific to &kspread;. + + +Installing the <command>kdeaccessibility</command> Module +kdeaccessibility + +Most of the features described in this chapter are enabled by installing the +kdeaccessibility module. +The kdeaccessibility module is part of the &kde; project +http://www.kde.org. The kdeaccessibility +package can be obtained from &kde-ftp;, the +main ftp site of the &kde; project. + + +Many distributions offer precompiled binaries on their ftp sites. Please check your distribution's web sites for more information. + +More information about &kde; accessibility can be obtained by +visiting http://accessibility.kde.org/. + + + + +Visual Impairments +Visual Impairments + +&kspread; is not usable by totally blind users. It is hoped that +a general screen reader for the blind will be available in future versions of &kde;. + + + +Theming +Theming +For low-sighted or light allergic users, several features are available in the &kcontrolcenter; +Appearance & ThemesTheme Manager, +like high contrast color themes. If you are light allergic, the +HighContrastDark or HighContrastLight themes +may be helpful. If you have difficulty reading small fonts or seeing small icons, the +HighContrastDark-big or HighContrastLight-big +themes will increase the size of text, buttons, and icons. You may also customize +background, colors, fonts, and icons from the same dialog. A set of monochrome icons +is available. + + +If you choose one of the Big themes, you may discover that +some windows are too large to fit your monitor. Purchasing a larger monitor will be helpful. +You can drag the portions of the window not visible into the visible area by +holding down the &Alt; key and dragging with the &LMB; anywhere +within the screen. If you have trouble operating a mouse, you can also move screens by pressing +&Alt;F3. In +the dropdown Windows Operations Menu, choose +Move. +Move the screen with the arrow keys and press &Esc; to finish the move. + + + + + +&kmagnifier; +magnifier +The kdeaccessibility module includes a screen magnifier +application called &kmagnifier;. +If it is installed, you can run it from +K-ButtonUtilities +KMag (Screen Magnifier). + + + + +Text-to-Speech +Text-to-Speech +TTS +The kdeaccessibility module includes a Text-to-Speech +component called KTTS. If KTTS is installed, you can configure &kspread; to +speak the text that is under the mouse pointer or speak the text of each +screen widget as it receives focus. Before using this feature, first configure +KTTS. See The KTTS Handbook for details. +To turn on the TTS feature in &kspread;, +select SettingsConfigure +&kspread;... from the menubar. +This will display a dialog box. +Clicking on TTS will allow you to change +the following. + + + + + + + + + +Speak widget under mouse pointer +When checked, &kspread; will speak the text of each widget +as the mouse pointer moves over the widget. + + + +Speak widget with focus +When checked, &kspread; will speak the text of each widget +as it receives focus. + + + +Speak tool tips +When checked, &kspread; will speak the popup tool tip +for each widget in addition to the text of the widget. + + + +Speak Whats This +When checked, &kspread; will speak the Whats This help +for each widget in addition to the text of the widget. + + + +Say whether disabled +When checked, &kspread; will speak the word "disabled" +if the widget is currently disabled (grayed). + + + +Speak accelerators +When checked, &kspread; will speak the accelerator +of the widget in addition to the text of the widget. +Accelerators are the underlined letters you see in the text of the +widget. For example, in the main menu, the +Quit menu item +has the "Q" underlined. You can choose it by pressing Q. +To speak the accelerator, check this option and enter the +word you want to speak before the accelerator in the +Prefaced by the word box. In this +example shown above, &kspread; will speak "Accelerator Q". + + + +Polling interval +This option determines how often &kspread; will +check for a change in the widget under the mouse pointer or +a new focused widget. You should leave this option on the +default setting. + + + + + +If the TTS option does not appear +on this screen, you do not have the KTTS component installed +in your system. + + +Not all widgets are spoken. For example, +the items on the main menubar are not spoken. + + + + + + + +Motor Impairments and Mouseless Operation +Motor Impairments +Mouseless Operation + + +KMouseTool +If you can operate a mouse, but have trouble clicking, the +KMouseTool application may help. Run it from +K-ButtonUtilities +KMouseTool (Automatik Mouse Click). + + + + +XAccess Features +XAccess +Sticky Keys +Slow Keys +Bounce Keys + +The &kcontrolcenter; offers several keyboard features collectively called XAccess. +They include: + + +Sticky Keys +This feature permits operation of meta keys, such as +&Alt;, &Ctrl;, and &Shift; without having to hold the keys down. It is useful +when you can only use one finger or one hand to operate the keyboard. +With Sticky Keys on, press and release a &Alt;, &Ctrl;, or &Shift; key, then +press another key. The result is as if you pressed both keys at once. +Press the &Alt;, &Ctrl;, or &Shift; key again to turn off the sticky key. +Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Modifier Keys. + + + +Slow Keys +This feature is useful if you have hand tremors or difficulty +accurately pressing keys. It prevents +inadvertent key presses by requiring that a key be held down for a minimum +time before it is accepted. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Keyboard Filters. + + + +Bounce Keys +This feature is also useful if you have hand tremors. It prevents +inadvertent repeated key presses by preventing another keystroke for +a certain amount of time. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Keyboard Filters. + + + + + + + +Mouse Emulation +Mouse Emulation +Mouse Emulation permits you to move and click the mouse using the keyboard. +Press &Alt;F12 to activate it. Use the arrow keys +to move the mouse pointer to the desired location, and press spacebar +to "click" the mouse. Unfortunately, you cannot use Mouse Emulation to perform +&RMB; clicks or dragging. + + + + +Mouse Navigation +Mouse Navigation +This feature permits you to emulate the mouse using the numeric keypad +of your keyboard. To activate it, go to +K-Button&kcontrolcenter; +PeripheralsMouse +Mouse Navigation. +Check the Move pointer with keyboard (using the num pad) box. When you do this, the other settings will become enabled, and you can customize the keyboard pointer behavior further, if required. + The various keys on the number pad move in the direction you would expect. Note that you can move diagonally as well as up, down, left and right. The 5 key emulates a click to a pointer button, typically &LMB;. You change which button is emulated by using the / key (which makes it &LMB;), +* key (which makes it middle mouse button) and - (which makes it &RMB;). + Using the + emulates a doubleclick to the selected pointer button. You can use the +0 key to emulate holding down the selected pointer button (for easy dragging), +and then use the . to emulate releasing the selected pointer button. + + + + + + + + + + + +Keyboard shortcuts + +Use the Menu key to pop up the context +menu. On most keyboards, the Menu key is on the righthand +side of the keyboard between the &Windows; and &Ctrl; +keys. It has a menu icon on it. + + + + + +Resizing panels + +If you have activated two or more views of a spreadsheet, +you can move the sizing bar between the views by pressing F8. A sizing icon appears +overtop the sizing bar. Use the arrow keys to move the bar up or down, or left or right. +Press F8 again or &Esc; when finished sizing. + + + + + +Setting focus to widgets + +Normally, one can use the and &Shift; +to move focus from one widget to the next in any application. However, in &kspread;, +pressing does not move the focus; instead it moves the cell selection forwards. +You can set focus to any widget that can receive focus by +pressing &Alt;F8. A small lettered box appears +overtop each widget on the screen that can receive focus. + + + + + + + + +Press the letter to move focus to the corresponding widget. Press +&Alt;F8 again or &Esc; +to abandon moving the focus. + + + + + + + diff --git a/doc/kspread/advanced.docbook b/doc/kspread/advanced.docbook new file mode 100644 index 000000000..f6aadfab6 --- /dev/null +++ b/doc/kspread/advanced.docbook @@ -0,0 +1,815 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +
    +
    +Advanced &kspread; + +Series +When constructing a spreadsheet you often need to include a series of +values, such as 10, 11, 12..., in a row or column. There are several ways you +can do this in &kspread;. +For a simple short series such as 5, 6, 7, 8... the Drag and Copy + method is the simplest. Enter the starting value into the starting +cell and the next value of the series into an adjacent cell. +Then select both cells and move the mouse pointer so that it is over the small +square at the bottom right corner; the cursor will change to a +diagonal double headed arrow. Then hold the left +mouse button down while you drag the cells down or across as needed. +The step size is calculated as the difference between the two starting +values that you have entered. +For example if you enter 4 into cell A1 and +3.5 into A2 then select both cells and Drag and Copy +them down, the step size will be the value in A2 minus the value +in A1, -0.5 in this case so you will get the series 4, 3.5, 3, 2.5, 2... + +The Drag and Copy method will even cope with series where +the step value is not a constant value but is itself a series. So that if you +start with 1, 3, 4, 6 Drag and Copy will extend it to 1, 3, 4, 6, 7, 9, 10, +12..., the step value in this example being the series 2, 1, 2, 1... + +&kspread; also recognizes some special series such as +the days of the week. Try entering Friday into a cell +(note the capitalization) then Drag and Copy it down. To see what special series +are available, and perhaps create your own, select Tools +Custom Lists... . + +If you select a cell and choose Series... +from the Insert menu you will see the Series + dialog box. This is useful for creating series that are too long +to be conveniently constructed using the Drag and Copy method, or for +creating geometric series such as 1, 1.5, 2.25, 3.375... where the step value, +1.5 in this case, is used as a multiplier. +If the type of series that you want is too complicated for any of the +previous methods, consider using a formula and Drag and Copying that. For +example to create a series with the values 2, 4, 16, 256... enter +2 into A1, =A1*A1 into A2, and +Drag and Copy cell A2 down. + + + +Formulae + +Built in Functions +&kspread; has a huge range of built in mathematical and other functions +that can be used in a formula cell. They can be seen and accessed by selecting +a cell then choosing Function... from the +Insert menu. This brings up the Function + dialog box. +Select the function you want to use from the listbox at the left of the +dialog box. The Help tab page will then display a description, +the return type, Syntax, Parameters, and Examples for this function. +In addition this page provides often links to Related Functions. +Then press the button with the down arrow key symbol on it to paste +it into the text edit box at the bottom of the dialog. +The Parameters tab page will then be displayed +to let you enter the parameter(s) for the function you have just +chosen. If you want to enter an actual value for a parameter, just type it +into the appropriate text box in the Parameters page. To +enter a cell reference rather than a value, left +click on the appropriate text box in the Parameters page; +then left click on the target cell in +the spreadsheet. +Instead of using the Parameters page, cell +references such as B6 can be entered by typing them +directly into the edit box at the bottom of the Function +dialog. If a function has more than one parameter separate them with a +semi-colon (;). +Pressing the OK button will insert the +function into the current cell and close the Function +dialog. +You can of course do without the Function +dialog and simply type the complete expression into the Formula toolbar's +main edit box. Function names are not case sensitive. Do not forget that all +expressions must start with an = symbol. + + + +Logical Comparisons +Logical functions such as IF(), AND(), OR() take parameters which have the +logical (boolean) values True or False. This type of value can be produced by +other logical functions such as ISEVEN() or by the comparison of values in +spreadsheet cells using the comparison expressions given in the following +table. + + +
    + + Expression + Description + Example + + + +== +Is equal to +A2==B3 is True if the value in A2 is equal to +the value in B3 + + +!= +Is not equal to +A2!=B3 is True if the value in A2 is not equal +to the value in B3 + + +<> +Is not equal to +Same as A2!=B3 + + +< +Is less than +A2<B3 is True if the value in A2 is less than +the value in B3 + + +<= +Is less than or equal to +A2<=B3 is True if the value in A2 is less than +or equal to the value in B3 + + +> +Is greater than +A2>B3 is True if the value in A2 is greater +than the value in B3 + + +>= +Is greater than or equal to +A2>=B3 is True if the value A2 is greater than +or equal to the value in B3 + + + + +Thus if you enter =IF(B3>B1;"BIGGER";"") into +a cell it will display BIGGER if the value in B3 is greater than that in B1, +otherwise the cell will show nothing. + + + +Absolute Cell References +If a formula contains a cell reference that reference will normally be +changed when the cell is copied to another part of the worksheet. To prevent +this behavior put a $ symbol before the column letter, row +number or both. + + + +If A1 contains the formula =D5 then on copying the +cell to B2 it will become =E6 (the normal behavior). + + +If A1 contains the formula =$D5 then on copying the +cell to B2 it will become =D6 (column letter not +changed). + + +If A1 contains the formula =D$5 then on copying the +cell to B2 it will become =E5 (row number not +changed). + + +If A1 contains the formula =$D$5 then on copying the +cell to B2 it will remain as =D5 (neither the column +letter nor the row number are changed). + + + +When you are entering or editing a cell reference in a formula the +shortcut key F4 can be used to step through these four +possibilities. +Named cells can be used in a similar +way to include a unchanging cell reference in a formula. + + + + + +Arithmetic using Special Paste +Sometimes you may want to add a single value to a number of +cells, or subtract a value from them, or multiply or divide them all by a +single value. The Special Paste... option lets you +do this quickly and easily. +First, enter the modifier value into any spare cell on your spreadsheet +and Copy it. Then select the area of cells you want +to change, choose Special Paste... from the +Edit or right mouse button menu +and select Addition, Subtraction, +Multiplication or Division from the +Operation section of the dialog box. +You can also apply different modifier values to different rows or +columns of the target area by copying an area containing the wanted modifiers +before selecting the target area and doing Special Paste... + . For example, if you enter 5 into cell +A1, 10 into B1, select both cells and do a +Copy then Special Paste... +Addition into cells A10 to D15, 5 will be added to A10:A15 and +C10:C15, and 10 to B10:B15 and D10:D15. +Note that a modifier value can be a formula as well as a simple numeric +value. If it is a formula then &kspread; will adjust the cell references as +for a normal Paste operation. + + + +Goal Seeking +&kspread; can be used to solve algebraic expressions such as +x + x^2 = 4 or For what value of x does x + x squared +equal 4 ? +For this example you could enter =A2+A2*A2 +into A1 then either try different values in A2 until the result in A1 is as +close as you wish to 4 or, preferably, use &kspread;'s +Goal Seek feature which automatically adjusts the +value in one cell to try to make the value in another cell as close as +possible to a target value. +It is invoked by selecting Goal Seek from +the Data menu. This brings up a dialog box in which you +should enter the reference of the target value cell (A1 +in this case) into the Set cell: box, the target value +itself (4) into the To value: box +and the reference of the cell that is to be changed +(A2) into the By changing cell: +box. Note that you need to have entered some initial value into the cell that +is to be changed before starting Goal Seek. +Pressing the Start button will start the +calculation. When it finishes and if it has found a solution press the +OK button to accept the result or +Cancel to keep the original value. + + + + +Using more than one Worksheet +When you start a new, empty, document with &kspread; it will create a +number of blank worksheets. The number of sheets it creates is determined +by the Number of sheets open at the beginning: setting in +the Interface page of &kspread;'s +configuration dialog box. +InsertSheet + will add another sheet to the document. +If the Show tabs box in the Interface + page of &kspread;'s configuration dialog box is checked a small +tab will be shown near the bottom left of &kspread;'s window for each sheet. +Left click on one of these tabs to see that sheet. + +You can also switch between worksheets by using the +&Ctrl;PageDown +to move to the next sheet, +&Ctrl;PageUp to move to +the previous one. +Worksheets are given the default names of Sheet1, +Sheet2... You can give a sheet a different name by +right clicking on the tab and selecting +Rename Sheet.... +To remove a sheet from the document use the Remove Sheet + option in the Format +Sheet submenu or in the little +menu that pops up when you right click on the tab +for the sheet you want to remove. +Other entries in the Format +Sheet submenu allow you to show or hide a sheet in +much the same way as rows and columns can be hidden. +If you want a formula in one sheet to refer to a cell in another sheet, +the cell reference must start with the sheet name followed by an exclamation +mark (!). For example if you enter =Sheet2!A2 + into a cell in Sheet 1, that cell will take the value from A2 of +Sheet2. Note that sheet names are case sensitive. + + + +Consolidating Data +You may have constructed a document containing several worksheets +containing similar data but for, say, different months of the year, and wish +to have summary sheet containing the consolidated (⪚, sum or average) values +of the corresponding data items in the other sheets. +This task can be made slightly easier by using the +Consolidate... item from the Data menu. +Selecting this option brings up the Consolidate +dialog box. +For each of the source sheets, enter a reference to the desired data area +in the Reference: box. Press Add to +transfer it to the Entered references: box. The reference +should include the name of the sheet containing the source data, such as +January!A1:A10, and can be entered automatically by +selecting the area in the appropriate sheet. +After entering the references for all of the source data sheets +select the cell in the target sheet where you want the top left corner of the +consolidated results to appear. Then choose the appropriate function from +the Function: combo box and press the +OK button. +If you check the Copy data box in the +Consolidate dialog the values resulting from the consolidation will +be placed into the target cells rather than the formulae to calculate them. + + + + + +Inserting a Chart +You can insert a chart into a sheet to give a graphical view of your +data. +First select the area of cells containing the data and choose +InsertChart +. The cursor will change to a small cross shape which you +should drag across the sheet while holding the left + mouse button down to define the area where you want the +chart to appear, there is no need to be too accurate at this stage as the +chart size can easily be changed at any time. When you release the mouse +button a chart wizard dialog box will appear. +The wizard allows you to define the type of chart, labels and legend +that you need. You may wish to refer to the &kchart; Handbook at this stage, +but again if you make a wrong choice you can correct it later. +When you press the Finish button the wizard will +vanish and you will see the chart embedded into the worksheet. + + + + + + +Screenshot of embedded chart + + + +To move, resize or even delete the embedded chart click anywhere +within the chart area. It should now appear with a diagonal hatch border +and with a small black square at each corner and in the middle of each edge. + +If you move the cursor over any of the black squares it should change +to a double headed arrow. You can resize the chart by dragging one of these +squares with the left mouse button pressed. To +delete the chart right click on one of the +squares and select Delete Embedded Document. +To move the chart move the cursor so that it is over one of the +hatched borders. The cursor should then change to a hand, press the +left mouse button and you will be able to drag the +chart to where you want it to be. +To restore the chart to its normal appearance simply click anywhere +outside of the chart area. +To change the format of the chart itself left +click twice within the chart area. It should then appear with a diagonal +hatch border without any small black squares and &kchart;'s +Chart Toolbar should appear in &kspread;'s window. You can then +use these &kchart; tools or a selection from the menu that pops up when you +right click in the chart area to change the chart. + + + +Inserting External Data +You can insert data from a text file or from the clipboard into a +worksheet by first selecting the cell where you want the top left item of the +inserted data to appear, then choosing From Text File... + or From Clipboard... from the +InsertExternal Data + sub menu. +In both cases &kspread; will assume that the data is in +CSV form and will open a +dialog box allowing you to control how the data is extracted from the file or +clipboard and placed into the worksheet cells. +If support for it has been included in your system, &kspread; can also +insert data from a SQL database into a worksheet. This is +done by using the Insert +External DataFrom Database... + option. + + + +Link Cells +A spreadsheet cell can be linked to an action so that +left clicking on the cell will, for example, open your +browser. To make a cell act in this way select it and choose +InsertLink... +. This will bring up the Insert Link +dialog box, which lets you choose between four types of link: + + +An Internet link cell will try to +open your default browser at the &URL; entered in the +Internet address: text box of the Insert +Link dialog when it is clicked. This could be, for example, +http://www.koffice.org. + + +Clicking on a cell containing a Mail +link will open your email composer using the address entered in the +Email: text box as the To: address. For example +anon@example.com. + + +A File link cell holds the path to +a file or folder, as entered into the File location: +text box, and will try to open that file or folder with a suitable +application when clicked on. + + +The Cell type of link cell holds a +&kspread; cell reference, entered in the Cell: text box. +Left clicking on this type of link cell causes +&kspread;'s focus to move to the target cell. + + + +All four types of link cell need some suitable text to be entered into +the Comment: field of the Insert Link +dialog. This is the text that appears in the cell, you can set +its style to Bold or Italic if you +wish. + + + +Validity Checking +&kspread; can automatically check the validity of entered data against +a number of criteria, and pop up a message box if the data is invalid. +To enable this feature, select the cell(s) to be monitored and choose +EditValidity... +. This will bring up &kspread;'s Validity +dialog box which has two tabbed pages. +In the Values page select what type of data is to +be considered valid from the Allow: combo box list then +define the valid range of values by choosing one of the options in the +Data: combo box and entering suitable value(s) into +one or both of the edit box(es). +When you have done this change to the Error Alert +tab page. Here you can choose the type of message box +(Stop, Warning +or Information) that will appear when an invalid +value is entered, and define the message box title and message text. +Note that this feature only checks data that you enter into the cell, +for a way of checking the results from formulae cells see the Conditional Cell Attributes section of this +Handbook. + + + +Protection + + +Document Protection +Protecting the document means that without the password a user cannot add +or delete sheets. Document protection does not protect cells. +Select ToolsProtect +Document.... +A dialog appears asking you for a password. The Password: strength meter +indicates if your password is secure enough. The longer the indicator is, the +more secure your password. + + + + + + +The Protect Document dialog + + + +That password will then be required to unprotect the document. + + + + + + +The Unprotect Document dialog + + + +When a document is protected, you may not: + + +Rename a sheet + + +Insert a sheet + + +Remove a sheet + + +Hide a sheet + + +Show a sheet + + +See the sheet properties + + +Merge or dissociate cells + + + + + +Sheet protection +Protecting a sheet means protecting the contents of all protected cells +and objects on a sheet. Individual cells or a selection of cells can be +unprotected within a protected sheet, see next section. +To protect a sheet, select +ToolsProtect Sheet.... +A dialog appears asking you for a password. The Password strength meter +indicates if your password is secure enough. The longer the indicator is, the +more secure will be your password. +That password will then be required to unprotect the sheet. +When a sheet is protected, you may not: + + +Insert any object or chart + + +Format any cell + + +Insert a row or a column + + +Edit and change cell content + + +Change any content in the sheet + + + +Protecting a sheet is especially useful for preventing accidental +erasure of formulae. + + + +Cell or selected cells protection +Cell protection is active for all cells by default and is +effective when you enable sheet protection. So if you keep the default and if +you protect the sheet, all cells will be protected. +If you want only certain cells to be protected, this default protection +must be turned off for all other cells. For example you might want most cells +to accept user input so you will uncheck Protected for +those and choose to keep protected cells that should stay unchanged (such as +titles). So you need 3 steps in order to protect only some cells: unprotect all +the cells, select the cells to protect and protect them and then protect the +whole sheet. +To unprotect all the cells: + + +Select the entire spreadsheet with the mouse. + + +In the menubar, select FormatCell +Format.... + + +In the dialog that appears, go to the Cell Protection tab. + + +Check Hide all and uncheck Protected +to remove the protection on all cells. The cells are now all unprotected. + + +To protect a range of selected cells or a selection of non-contiguous +cells: + + +Highlight the range of cells that are to be protected or use the &Ctrl; key to select non-contiguous cells. + + +When all of the desired cells are selected, go to +the FormatCell +Format... menu. + + +In the dialog that appears, go to the Cell Protection tab. + + +Click on the box next to Protected then click +on OK. + + +Once the cells are marked for protection, the protection option must be +enabled at the sheet level, that means you must protect the entire sheet for the +cell to be effectively protected: + + +Select +ToolsProtect Sheet.... + + +In the dialog that appears, provide a safe password, then confirm it by typing +it again. Click on OK. + + +Protected cells in a protected sheet cannot be edited without unprotecting the +whole sheet, and any sheet changes are disabled. For example, no one can +insert rows or columns, change column width, or create embedded charts. + + + + + +Hide cell formula +You might want to hide your formulae so other people cannot see +them. By default, every cell is protected and not hidden. But it is important to +remember that these attributes have no effect unless the sheet itself is +protected. + + + + + + +A default cell with a formula + + + +To hide cell formulae, select the appropriate cell or range of cells or +non-contiguous cells with &Ctrl; and +then choose the FormatCell +Format... menu. In the Cell format +dialog, click the Cell Protection tab and select Hide formula. +After you protect the sheet, the results of the formulae will be visible, but +the formulae will not. +You have now to protect the sheet: choose +ToolsProtect Sheet... +to display the Protect Sheet dialog box. Enter a safe password twice to prevent +others from unprotecting the sheet. +When Hide formula is enabled and +Protected is disabled, the formula is hidden after +protecting the sheet but the cell content can be changed. + + + + + + +Hide formula is enabled but the cell is not protected and the +sheet is protected + + + +When Hide formula and Protected +are enabled, the formula is hidden after protecting the sheet and the cell +content cannot be changed. + + + + + + +Hide formula and Protected are enabled in Cell Protection and the +sheet is protected + + + +Keep in mind that it is very easy to break the password for a +protected sheet so if you are looking for real security, this is not the +best solution. + + + +Hide all in the cell +You can hide both the formula and the content of the cell by +choosing Hide all in the Cell Protection tab in the +FormatCell +Format... menu. In the screenshot below, the +cell itself is not protected (Protected is unchecked) thus +the cell content can be changed. + + + + + + +Hide all only is enabled (no cell protection) and +the sheet is protected + + + +Here the cell itself is protected so it cannot be overwritten. + + + + + + +Hide all and Protected are +enabled in Cell Protection and the sheet is protected + + + + + + + + +Other Features + + +Splitting the View +If your spreadsheet is so large that you cannot see all of it at once, +splitting &kspread;'s window into two or more views can help you work on it. +This is done by selecting View +Split View which will split the current view into +two parts. ViewSplitter Orientation + lets you choose between +Horizontal and Vertical +splitting. +This technique is particularly useful when you want to select an area +of the spreadsheet that is larger than can be shown in one view, perhaps to +paste a copied cell into it. +Use the scrollbars to position the two views to show the top left and +bottom right cells of the wanted area, select the top left cell in one +view then hold the &Shift; key pressed while you select the +bottom right cell with the left mouse button. +If there is more than one sheet in your document, you can show a +different sheet in each of the split views. +The relative sizes of the views can be changed by dragging the thick bar +separating the views. +To remove a view select View +Remove View + + + + +Named Cells and Areas +You can give a name such as foo to a cell or to +any area of a sheet by selecting the cell or area then selecting +Area Name... from the right mouse +button menu. This will bring up the Area Name dialog box +where you can enter any name you wish. +You can also name a cell or area by selecting it then typing the name +into the small text box at the left end of the Formula toolbar, overwriting the +cell reference that normally appears here. +If you enter a name that has already been used into this text box +&kspread;'s selection will change to show the named cell(s). +The DataShow Area... + option will give you a list of existing names +and let you change &kspread;'s focus to any of them or let you remove a name. + +Named cells are particularly useful in formulae as an alternative to + absolute cell references as the names can +be used in place of normal cell references and do not change when the +cell containing the formula is copied. When a name is used in this way it +should be enclosed in single quotation marks. +For example, if cell A1 has been given the name fred + then you can enter a formula such as ='fred' + 2 + into another cell which would always give the result of adding +2 to the value in A1 no matter where the formula cell was copied to. +Note that cell and area names are treated as being in lowercase. + + + +Cell Comments +A cell can contain a text comment that can be viewed when working on +the spreadsheet but which is not printed and not normally seen. +To add a comment select the cell and choose Add/Modify +Comment... from the right mouse +button menu or from the Insert +Cell Comment menu and type your comment into the +resulting Cell Comment dialog box. +To see the comment hover the mouse pointer over the top right corner of +the cell. The comment will appear as if it were a Tooltip. + +If you check the Show comment indicator box of the +Sheet Properties dialog, those +cells containing comments will be highlighted by a small red triangle in the +top right corner. +To open this dialog, click with the right mouse +button onto the sheet tab at the bottom of the main window and select +Sheet Properties from the popup menu. Or select it from the +FormatSheet menu. + +To remove a comment from a cell, select Remove Comment + from the right mouse button menu or +choose EditClear +Comment. + + + + + + + diff --git a/doc/kspread/basics.docbook b/doc/kspread/basics.docbook new file mode 100644 index 000000000..2a06be215 --- /dev/null +++ b/doc/kspread/basics.docbook @@ -0,0 +1,637 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +&kspread; Basics + +Like the rest of &kde;, &kspread; is highly configurable, which can +cause problems for readers trying to compare the text in a document such as +this with what they see on the version of &kspread; running on their desktop. +To cut down on some of the possibilities for confusion, it it suggested that +when you first start to use &kspread; you set the default options in all pages +of the &kspread; configuration dialog (obtained by selecting +SettingsConfigure +&kspread;...) except for Completion mode: + in the Misc page, which should be set to +None. + +You may also find it helpful to globally Enable tooltips +in &kcontrolcenter; in Appearance & +ThemesStyle +on the Style page. + + +Spreadsheets for Beginners + +This section attempts to explain by example what a spreadsheet program +such as &kspread; actually does, and why it is such a useful tool in any +situation where you have to deal with numbers. If you have already used a +spreadsheet program you may wish to skip to the next section. + +The first thing to do is to start up &kspread;. You can do this by +left clicking on a &kspread; icon if there is one +on your desktop or panel, or you can select +Office&kspread; + +from the K menu. + + + + + + + +&kspread; at first run + + +When it has started you will be given the choice of opening a recent +document, creating a new document from a template (with templates categories) or +opening an existing document . Select the General category +on the left and choose the Blank Worksheet template. Then +click the Use This Template button. + +Looking at &kspread; once it has started up, you will see a sheet of +empty rectangular cells arranged in numbered rows and lettered columns. This +is where you enter data or formula, text or charts. + + + + + +Screenshot starting1 + + + +Now, enter the text and values shown in the first 5 rows of the above +screenshot into the same cells of your spreadsheet. Ignore what is in row 7 +for the moment. To enter anything into a cell first select the cell by +left clicking inside it, then type whatever you +want, then press Enter or use the arrow keys to move the +selection point to another cell. + +What we have entered so far could be a simple budget for the next two +months, listing how much we think we will be spending for Food, Shelter, +Clothing and any Other expenditure. Now select cell B7 (column B, row 7), +type in =B2+B3+B4+B5 and press Enter. +Because it begins with a = symbol &kspread; sees this as a +formula, something it has to calculate, in this case by adding together the +values in the 4 cells B2 to B5, and what is shown in the cell B7 is the result +of that calculation. +You could enter a similar formula into cell C7, except that in this case +it would have to be =C2+C3+C4+C5, but there is an +easier way which is to Copy cell B7 and Paste it into C7. &kspread; will +automatically adjust the cell references from B.. to C.. when the Paste is +done. +At this point you may think that &kspread; is doing no more than you +could manage with pencil, paper and a calculator, and you could be right, but +remember that this is a very small example of a spreadsheet, doing simple +calculations on only a few numbers. For any reasonably amount of values or data +using a spreadsheet to do the calculations is much quicker and more accurate +than doing them manually. +Also, a spreadsheet lets you play the What if? game. +Because each formula is automatically recalculated whenever any of the values +it refers to are changed, you can quickly see what happens if you alter any of +them. Using our example you can see the effect of reducing the amount spent on +food in December by just entering a new value into cell C2. If you had a +spreadsheet that modelled the greenhouse effect accurately you could perhaps +see the effect of a 50 percent reduction in the amount of methane released +into the atmosphere. + + + +Selecting Cells +You can select a single cell or a rectangular area of cells in the +spreadsheet. The selected cell(s) are displayed with a thick black border. + + +You can select a single cell in one of the following ways +left click on it +enter the cell reference (for example B5) +into the cell reference box at the left end of the Formula toolbar and press +Enter +use the ViewGoto +Cell... menu option + + +You can also steer your way around with the arrow keys. +Pressing the Enter key will move the current selection one +position up, down, left or right depending on the setting in the Misc + page of &kspread;'s configuration dialog +box. If you hold the &Shift; key down while using the +arrow keys the selection will move to the start or end of the +block of occupied cells. +To select an area of contiguous cells drag the mouse cursor across the +desired area with the left button held down, or enter +the references of the top left and bottom right cells separated by a colon into +the Formula toolbar cell reference box (for example B7:C14 +) and press Enter, or enter these cell references +in a similar format into the dialog box brought up by +ViewGoto Cell.... +You can also select an area of cells by selecting the cell in one corner +of the wanted area then holding the &Shift; key down while using the +left mouse button to select the cell in the opposite +corner. + +To select a complete row or column of cells left + click on the row number at the left of the worksheet or on the +column letters at the top. To select adjacent rows or columns drag the mouse +pointer over the appropriate row numbers or column letters with the +left button held down. + +To select non-contiguous cells, click on the first cell you want to select +then hold the &Ctrl; key and select the other +cells. + + + + +Entering Data +Entering data into a cell can be as simple as selecting the cell, typing +your data, then pressing Enter or moving the selection to +another cell with one of the arrow keys. Depending on how you +enter the data, &kspread; will interpret it as a number, date, time or text: + + +Numbers are entered in the obvious way; 123, +-123, 456.7 or in scientific notation +-1.2E-5. + + +Dates should be entered in your System format, as defined in +the &kcontrolcenter; in +Regional & Accessibility +Country/Region & LanguageTime & Dates + dialog box. If, for example, you are using the DD/MM/YYYY form +you should enter 30/03/2002 for 30th March 2002. +Leading zeroes can be omitted from the day and month fields and only the last +one or two digits of the year need to be entered if the date is in the current +century, for example 9/1/2 for 9th January 2002. + + +Times should also be entered using the System format. For +example if you are using a 12 hour clock then enter times in HH:MIN am|pm or +HH:MIN:SS am|pm format such as 9:42 am or +10:30:52 pm. + + +&kspread; defines any input data as text if it cannot +recognize the data as being a number, date or time. + + +By default, &kspread; right justifies numbers, dates and times +within a cell and left justifies anything else. This can be a useful guide +to whether you have entered a date or time in the correct format. But +remember that how items are displayed can be changed by altering +the cell format. + +The main text entry box in the Formula toolbar provides an easy way of +editing the contents of a selected cell. Press Enter or +left click on the green tick mark when you are +happy with what you have entered, or click on the red cross to cancel your +edits. + + +Generic Cell Format + +&kspread; uses the Generic cell format as default. As long +as this format is used, &kspread; autodetects the actual data type depending +on the current cell data. For example if you enter some text into a cell and +later enter a number into the same cell, &kspread; automatically interprets +the new data as a number. If you want to define the type of data yourself, you +can explicitly set it in the cell format. +You can change the format back to Generic at any time. + + + + + + +Copy, Cut and Paste + +At first glance, &kspread;'s Cut, +Copy and Paste appear +to be similar to these functions in other &kde; applications. Having selected +a cell or cells, you can choose Copy or +Cut from the Edit menu or from +the drop down menu you get by holding the right +mouse button down on a selected cell. You can also use the shortcuts +&Ctrl;C + or &Ctrl;X +, then move the selection to the target cell and choose +Paste or press +&Ctrl;V. However there are some +subtleties associated with these functions in &kspread; and these are discussed +below. + +If a cell contains a formula then the formula itself is copied rather +than the displayed result, and if the formula contains a reference to another +cell, then that reference is changed by the Cut +or Copy and Paste +operation to point to the cell that is in the same relative position as in +the original cell. For example if cell A2 contains the formula +=B3 and is copied to C4, cell C4 will contain =D5 +. +This may seem to be a rather strange way of doing a copy, but +99 percent of the time it is exactly what is wanted (if it is not then see the +section about absolute cell references). +For example in the simple shopping list shown below, cell D2 should contain +=B2 * C2, D3 should be =B3 * C3, +D4 should be =B4 * C4 and so on. Instead of having to +enter a different formula in each cell, you can just enter the first formula +into D2 and then copy it into the cells below, letting &kspread; adjust the +cell references to suit. + + + + + +Screenshot copy1 + + + + +Copying and Pasting Cell Areas +In the above example D2 can be copied into all three cells D3 to D5 at +once by just copying D2 then selecting the complete cell area D3:D5 before +doing the paste. +A rectangular area of cells can be cut or copied in one operation by +selecting the area before doing the cut or copy. Then select the top left +corner cell of the area you want to paste into before doing the paste. +If you cut or copy a rectangular area of cells, say B2:C3, and paste it +into a larger area such as A10:D13 the original pattern of cells will be +repeated to fill the target area. +&kspread; also provides a Drag and Copy method for +copying cells down into other cells immediately below or to the +right of the original cell(s). To use this method select the cell(s) to be +copied then position the mouse pointer over the small black square at the +bottom right corner of the selected cell(s) so the cursor changes to a double +headed arrow. Then hold the left mouse button down +while you drag the selected cell(s) as far as you wish. Note that cell +references in formulae are incremented according to the +relative position change. Absolute references are not changed. + + + +Other Paste Modes +A cell may contain text, a value, or a formula, and may also contain +special font, border or background formatting +information. &kspread; has special versions of Paste that let +you handle these items in different ways. + +EditSpecial +Paste...brings up the Special +Paste dialog box. By selecting the appropriate item from +the top part of this dialog you can choose to paste just +Text , the cell Format, any +Comment in the cell(s) or Everything +without border. The items in the bottom part of this dialog +box allow you to do simple arithmetic +on an area of cells. + + +Paste with Insertion... inserts the copied +cell(s) into the sheet by moving the cells that would otherwise be overwritten +a suitable number of rows of columns down or to the right. It can also be used +to insert complete copied row(s) or column(s) into the worksheet. + + + + + +Insert and Delete +Use the Delete key or Edit +ClearText + to remove the text, value or formula from selected cell(s), +row(s) or column(s) without affecting anything else. + +To delete everything in the selected cell(s), row(s) or column(s), +including comments and special formatting, use +&Shift;Delete or choose the Delete + option from the Edit menu or from the pop +up menu you get when you right click on a selection. + +To remove selected row(s) or column(s) completely, use the +Delete Rows or Delete +Columns options from the right mouse +button pop up menu. +If you select a cell or cells and choose Remove Cells... + from the right mouse button pop up +menu, you can then choose whether other cells in the worksheet will be moved +up or to the left to fill in the space left by the cell(s) you have chosen to +remove. +If you want to insert new, blank, row(s) or column(s) into the +sheet, select row(s) or column(s) where you wish the new row(s) or +column(s) to be placed and choose the Insert Rows, +Insert Columns option from the +right mouse button pop up menu. +You can insert new cells into the worksheet by selecting the +area where you want them to appear then choosing the +Insert Cells... option from the right +mouse button pop up menu. You will then be asked whether the existing cell(s) +in the selected area should be moved down or to the right to make room for the +new ones. + + + + +Simple Sums +If the first character in a cell is an equals sign (=) +&kspread; will take the cell contents to be a formula which is to be +calculated. The result of the calculation will be displayed in the cell rather +than the formula itself. For example, enter =2+3 +into a cell and it should display 5. +More usefully, a formula can contain references to other cells, so +that =B4+A3 will calculate the sum of the values in +cells B4 and A3, and this calculation will be updated whenever cells B4 or A3 +are changed. +As well as addition, a formula can make use of the - +symbol for subtraction, * for multiplication, and +/ to perform division. The round bracket symbols ( +and ) can also be used as in normal algebra, so you could +enter more complex formulae such as =((B10 + C3) *5 - F11) / 2 +. + +Cells containing a formula will be marked with a small blue triangle +at the bottom left corner if the Show formula indicator +check box in the Format +SheetSheet Properties + dialog is checked. +&kspread; also includes a large number of built-in functions for +applications such as statistical, trigonometrical and financial calculations. +Their use will be examined in more depth in a +later section of this manual, but if you are interested at this stage +choose Function... from the Insert + menu and take a look through the Function + dialog box that will be displayed.. +For the time being, however, the SUM function may +be of interest as it calculates the sum of all values in a specified area of +cells. For example =SUM(B4:C10) calculates the sum of +all values in the cell area B4 to C10. +If &kspread; displays a row of # symbols when you have +entered your formula this usually means that it cannot understand what +you have entered, but if the row of # symbols ends with a +small red arrow this just means that the cell is not wide enough to display +the complete result, in which case you should either make the cell(s) wider +or change their format so that the result +does fit properly. + + +Recalculation +If the Automatic recalculation box in the +Format +SheetSheet Properties + dialog box is +checked, &kspread; will recalculate the values of cells whenever anything that +affects them is changed in the sheet. +When Automatic recalculation is not checked for the current sheet, you can instruct &kspread; to perform a recalculation at any time by +using the Recalculate Sheet or +Recalculate Document option in the Tools +menu or their shortcuts &Shift;F9 + or F9. + + + + +Sorting Data +In the simple example shown below, the data consist of the names and +countries of a number of mountains together with their height above sea level. +&kspread; can sort data such as this in different ways. + + + + + + +Screenshot of sorted data + + + +We may want the data sorted so that the names are in +alphabetical order. To do this select the area containing the data (A2:C7 +in this case) and choose Sort... from the Data +menu. This opens the Sorting dialog box. +Sorting is done alphanumerically, and the default is case sensitive, numbers coming +before uppercase letters which come before lowercase letters, so that cells +containing the entries Cat, bar, +77 and Bat would be sorted into +the following order: 77 Bat Cat bar. + +Using the Sort Criteria page of this dialog box +lets you Sort Rows or Sort Columns. +If you check the First row contains headers box data in the +first row will not be included in the sort operation. +You can choose which column or which row of the data is to be used as a primary sort key and, +if you wish, other columns or rows to be used as secondary and tertiary keys. Using +the example in the above screenshot, choosing column B as the first key and +column C as the second would sort the data by country and, for each country, +by height. + +The Options page of the dialog allows you to sort using the +order of items in a custom list such as January, February... instead +of alphanumerically. +The cell format is moved with the cell content, if you select +Copy cell Formatting (Borders, Colors, Text Style) +Uncheck the option Case sensitive sort to get a sort +not depending on capitalization. + + + + + +The Status bar Summary Calculator +The left hand end of the Status bar shows a summary of the values in +the selected cell(s). According to the setting of the Method of +calc: combo box in the Misc page of +&kspread;'s configuration dialog the summary can be: + + + +Sum +The value displayed is the sum of the values in the selected +cells. + + + + +Min +The value displayed is the minimum of the values in the selected +cells. + + + + +Max +The value displayed is the maximum of the values in the selected +cells. + + + + +Average +The value displayed is the average of the values in the selected +cells. + + + + +Count +The value displayed is the number of cells containing numeric +values. + + + + +None +No summary calculation is performed. + + + +The method of calculation can also be changed by right + clicking on the summary calculation result area of the +Status bar and choosing an item from the pop up menu. + + + + +Saving your Work +&kspread; saves the complete document, which may include more than one +worksheet, as a single document file. +If you have created a new document, or want to save an existing one +under a different name, use File +Save As.... This will bring up &kde;'s common +Save Document As dialog box. +Choose the folder where you want to save the document and enter a +suitable file name into the Location: text box. &kspread; +documents are normally automatically saved with a .ods +extension, you do not need to add this to the filename but do make sure that +the Filter: selection is set to +OASIS OpenDocument SpreadSheet. +To save your document without changing its name, just use +FileSave. + +You can also save a &kspread; document in a foreign format: see + the Import/Export section for more information +about doing this. +When you save a modified version of an existing document +&kspread; will keep the previous version as a backup file, adding a +~ to the end of the filename. +&kspread; can provide some protection against losing your work because +of a computer crash or because you have closed &kspread; without saving the +current document. It does this by automatically saving the latest version of +the document you are working on every few minutes using a modified file name. +The autosaved version is normally removed when you next save your document, +so that it will only exist if it is more up to date than the version that was +saved manually. +When you open a document &kspread; checks to see if an autosaved +version exists, and if it finds one it will offer to open that instead. +Autosaved documents are saved with a file name of the form +.yourfilename.autosave (note the leading period), +so that spread1.ods would be autosaved as +.spread1.ods.autosave. The autosave feature is +user configurable in the settings dialog. + + +Templates +If you are going to be creating a lot of similar documents you can +save yourself time and trouble by first creating a template and then +using that as the basis for the individual documents. +To do this first create a document containing the common elements, +then save it as a template by choosing File +Create Template From Document.... +Doing this opens the Create Template dialog box. +Enter a name for your new template into the Name: text +box and press OK. The next time you start a new +document by choosing FileNew + or when you next start &kspread; the +startup dialog window will give you the option of creating the +new document from your template. +The Create Template dialog box also lets you +choose a different picture to be displayed above the template name in the +startup dialog window, and lets you save your templates +under different group names, which will appear as different pages in +the dialog. + + + + + +Printing a Spreadsheet +Printing a spreadsheet is basically done by selecting +FilePrint... which +brings up &kde;'s common Print dialog box where you can +choose, among other options, the printer to be used, the number of copies and +whether all or only selected pages are to be printed. +By default &kspread; will print all items in the current worksheet, but +you can restrict this by first selecting the area that you want to be +printed then choosing Define Print Range from the +FormatPrint Range + sub menu. +&kspread; will print as many pages as are necessary to include all +items in the current worksheet. You can quickly see how a worksheet will be +spilt into separate pages for printing by checking the +View +Show Page Borders box. The boundaries +of each printed page will then be marked by colored lines in the +worksheet. + +For a more detailed view of what is to be sent to the printer, including +anything you have asked to be included in the page headers and footers (see +below), choose FilePrint +Preview.... + +To improve the appearance of the printed output , you can change the +fonts, colors, borders and sizes of the cells in the worksheet, see the +Spreadsheet Formatting section for more +details about how to do this. + +You can also use the Page Layout dialog box, +invoked by selecting FormatPage +Layout..., to change the orientation of the printed +pages, the paper size (this should be suitable for your printer) and the size +of the page borders. +The Header & Footer page of the +Page Layout dialog box also lets you add text, including items such +as the filename, date and page number to the header and footer, of each +printed page. +The Ranges section of the Options + page of the Page Layout dialog box provides +an alternative way of restricting the printed output to just one part of the +worksheet and allows you to repeat selected column(s) or row(s) on each printed +page. This page also lets you select whether or not to print the grid, +comment indicators and formula indicators, objects and charts. +In the section Scale Printout you can set a scalefactor +or limit the number of pages for the print. + + + +
    + + diff --git a/doc/kspread/cellformat0.png b/doc/kspread/cellformat0.png new file mode 100644 index 000000000..fe692bf8f Binary files /dev/null and b/doc/kspread/cellformat0.png differ diff --git a/doc/kspread/cellformat1.png b/doc/kspread/cellformat1.png new file mode 100644 index 000000000..cf3a23331 Binary files /dev/null and b/doc/kspread/cellformat1.png differ diff --git a/doc/kspread/cellformat2.png b/doc/kspread/cellformat2.png new file mode 100644 index 000000000..a7752f036 Binary files /dev/null and b/doc/kspread/cellformat2.png differ diff --git a/doc/kspread/cellformat3.png b/doc/kspread/cellformat3.png new file mode 100644 index 000000000..eb36f521b Binary files /dev/null and b/doc/kspread/cellformat3.png differ diff --git a/doc/kspread/cellformat4.png b/doc/kspread/cellformat4.png new file mode 100644 index 000000000..2bb297061 Binary files /dev/null and b/doc/kspread/cellformat4.png differ diff --git a/doc/kspread/cellformat5.png b/doc/kspread/cellformat5.png new file mode 100644 index 000000000..5c4b7b150 Binary files /dev/null and b/doc/kspread/cellformat5.png differ diff --git a/doc/kspread/cellformat6.png b/doc/kspread/cellformat6.png new file mode 100644 index 000000000..358ede349 Binary files /dev/null and b/doc/kspread/cellformat6.png differ diff --git a/doc/kspread/cellformat7.png b/doc/kspread/cellformat7.png new file mode 100644 index 000000000..2760c71df Binary files /dev/null and b/doc/kspread/cellformat7.png differ diff --git a/doc/kspread/cellprotection1.png b/doc/kspread/cellprotection1.png new file mode 100644 index 000000000..6f95cb941 Binary files /dev/null and b/doc/kspread/cellprotection1.png differ diff --git a/doc/kspread/cellprotection2.png b/doc/kspread/cellprotection2.png new file mode 100644 index 000000000..eda1e10cf Binary files /dev/null and b/doc/kspread/cellprotection2.png differ diff --git a/doc/kspread/chart1.png b/doc/kspread/chart1.png new file mode 100644 index 000000000..3cdf6055c Binary files /dev/null and b/doc/kspread/chart1.png differ diff --git a/doc/kspread/commands.docbook b/doc/kspread/commands.docbook new file mode 100644 index 000000000..1c2ae0445 --- /dev/null +++ b/doc/kspread/commands.docbook @@ -0,0 +1,1540 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +Command Reference + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N + +File +New + +Create a new document. + + + + + +&Ctrl;O + +File +Open... + +Open an existing document. + + + + +File +Open Recent + +Open an existing document by selecting it +from a combo box of recently used files. + + + + + +&Ctrl;S + +File +Save + +Save the document. + + + + +File +Save As... + +Save the document with a new name or format. + + + + + +File +Reload + +Reloads the document. + + + + + +File +Import... + +Import other documents. + + + + + +File +Export... + +Save a document to any supported format. +The document does not become the exported file. + + + + + +File +Mail... + +Send the file as an email attachment. + + + + + +File +Create Template From Document... + +Create a &kspread; template +based on this document. + + + + + + +&Ctrl;P + +File +Print... + +Print the document. + + + + +File +Print Preview... + +View the document as it will be printed. + + + + + +File +Document Information + +View or enter information about the document and +author. + + + + + + +&Ctrl;W + +File +Close + +Close the current document but leave &kspread; running. + + + + + + +&Ctrl;Q + +File +Quit + +Quit &kspread;. + + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + + + +&Ctrl;Z + +Edit +Undo + +Undo the last action. + + + + + +&Ctrl;&Shift;Z + +Edit +Redo + +Redo the last undone action. + + + + + + +&Ctrl;X + +Edit +Cut + +Put selected item(s) into the clipboard and remove +them from the original location. If you then +do a Paste the item(s) will be be inserted at +the new location. + + + + + + +&Ctrl;C + +Edit +Copy + +Copy selected item(s) to the clipboard. + + + + + + +&Ctrl;V + +Edit +Paste + +Paste item(s) from the clipboard to the selected +cell(s). + + + + + +Edit +Special Paste... + +Special forms of Paste. + See the sections Other Paste +Modes and Arithmetic using Special +Paste for more details. + + + + + +Edit +Paste with Insertion + +Move content of the paste area either to the right +or down and paste item(s) from the clipboard to the selected cell(s). + + + + + +Edit +Fill + +Fills up the selected area with the values from the +first item-set. All four directions are supported. Note that the +term "item-set" describes the first set of values seen in the fill direction. +If the fill direction is Left then the first item-set is the last column of the +selection. + + + + + + +&Ctrl;F + +Edit +Find... + +Find cell containing given text. + + + + + + +F3 + +Edit +Find Next + +Find the next cell containing given text. + + + + + + +&Shift;F3 + +Edit +Find Previous + +Find the previous cell containing given text. + + + + + + +&Ctrl;R + +Edit +Replace... + +Find and replace given text in cell(s). + + + + + +Edit +Clear + +Clear Text, +Comment, Validity or +Conditional Cell +Attributes from selected cell(s). + + + + + +Edit +Delete + +Delete everything from selected cell(s). + + + + + +Edit +Remove Link + +Remove the link while leave the displayed text. + + + + + +Edit +Conditional Cell Attributes... + +Add or modify conditional cell attributes. + + + + + +Edit +Validity... + +Set or modify the error checking criteria and error +alert message for selected cell(s). See +Validity Checking for more details. + + + + + + +&Ctrl;M + +Edit +Modify Cell + +To modify selected cell in-situ. + + + + + + + + +The <guimenu>View</guimenu> Menu + + + + + +View +New View + +Open a new instance of &kspread; +with the same document. + + + + + + +&Ctrl;&Shift;W + +View +Close All Views + +Close all open instances of &kspread; + + + + + +View +Split View + +Split current view into two parts. + + + + + +View +Remove View + +Remove current view. (Where the window +contains two or more views) + + + + + +View +Splitter Orientation + +Change view split to Horizontal or Vertical. + + + + + +View +Goto Cell... + +Change &kspread;'s focus to show defined cell. + + + + + +View +Show/Hide Page Borders + +Toggle marking of printed page borders in the sheet +with red lines. + + + + + + +View +Zoom + +Increase or decrease the magnification used to display +the spreadsheet. Range from 33% to 500%. + + + + + + + + + + +The <guimenu>Insert</guimenu> Menu + + + + + + + +Insert +Cell Comment + +Add/Modify Comment... or +Remove Comment. + + + + + +Insert +Function... + +Insert a mathematical function. See the +section Formulae for more details. + + + + + +Insert +Series... + +Insert a series. See the section +Series for more details. + + + + + +Insert +Link... + +Insert a link into the selected cell. +See the section +Link Cells for more details. + + + + + +Insert +Special Character... + +Insert a special character into the selected cell. + + + + + +Insert +Object + +Embed another &koffice; document into the sheet. + + + + + +Insert +Chart + +Insert a chart. See the section +Inserting a Chart for more details. + + + + + +Insert +Picture + +Opens the standard &kde; file dialog +to insert a picture. + + + + + +Insert +External Data + +Insert data From Database..., +From Text File... or From +Clipboard.... See the section Inserting +External Data for more details. + + + + + + + + +The <guimenu>Format</guimenu> Menu + + + + + +&Alt;&Ctrl;F + +Format +Cell Format... + +Format selected cell(s). See the +Spreadsheet Formatting section for more +details. + + + + + +Format +Properties + +Opens a dialog to change the properties of +an inserted object or picture. + + + + + +Format +Change Angle... + +Change angle of displayed text in selected cell(s). + + + + + + +Format +Decrease Indent + +Move text in selected cell(s) to the left. + + + + + +Format +Increase Indent + +Move text in selected cell(s) to the right. + + + + + +Format +Increase Precision + +Increase displayed precision of numbers in selected +cell(s). + + + + + +Format +Decrease Precision + +Decrease displayed precision of numbers in selected +cell(s). + + + + + +Format +Adjust Row & Column + +Set row and column sizes to show selected cell(s) +properly. + + + + + +Format +Row + +Resize, equalize, hide or show row(s). + + + + + +Format +Column + +Resize, equalize, hide or show column(s). + + + + + +Format +Sheet + +Remove, hide, show worksheet or configure +advanced sheet properties. + + + + + +Format +AutoFormat... + +Autoformat the selected cells: a dialog let you choose betwen two proposed formats. + + + + + +Format +Style Manager + +Create, Modify or delete cell format styles. + + + + + +Format +Style + +Apply a style to selected cell(s). +To manage styles use +FormatStyle Manager... + + + + + + +Format +Create Style From Cell... + +Create a new style from the format of the +selected cell. +To manage styles use +FormatStyle Manager... + + + + + + +Format +Page Layout... + +Format printed page layout. + + + + + +Format +Print Range + +Define or reset the print range. + + + + + + + +The <guimenu>Data</guimenu> Menu + + + + +Data +Sort... + +Sort data in selected cells. See the section +Sorting Data for more details. + + + + + +Data +Text to Columns... + +This option attempts to interpret text in the selected cell(s) +as CSV data, placing each +item into a different cell in the row. + + + + + +Data +Insert Columns + +Insert new column(s) at left of selected column(s). + + + + + + +Data +Insert Rows + +Insert new row(s) above selected row(s). + + + + + + +Data +Delete Columns + +Delete selected column(s). + + + + + +Data +Delete Rows + +Delete selected row(s). + + + + + +Data +Insert Cells... + +Insert new cell(s). + + + + + +Data +Remove Cells... + +Remove selected cell(s). + + + + + +Data +Merge Cells + +Merge selected cells. + + + + + +Data +Dissociate Cells + +Dissociate (split apart) previously merged cells. + + + + + + +Data +Show Area... + +Change &kspread;'s focus to show a previously +named area. See the section Named Cells +and Areas for further details. + + + + + +Data +Subtotals... + +Create different kinds of subtotals to a +database. + + + + + +Data +Goal Seek... + +Open the Goal Seek dialog box. See +Goal Seeking for details. + + + + + +Data +Consolidate... + +Consolidate data. See the section +Consolidating Data for more details. + + + + + + + +The <guimenu>Tools</guimenu> Menu + + + + +Tools +Spelling... + +Check spelling of words in the worksheet. + + + + + +Tools +Custom Lists... + +View or amend the special series of words recognized +by &kspread;. + + + + + +Tools +Protect Sheet... + + +Protect the sheet with a password. A dialog pops up prompting you for a password. Unchecking this option will prompt you for the password in order to unprotect the sheet. Protecting a sheet means protecting all cells in the sheet. In a protected sheet, the cells cannot be reformatted or overwritten. + + + + + +Tools +Protect Document... + + +Protect the whole document with a password. A dialog pops up prompting +you for a password. Unchecking this option will prompt you for the password in +order to unprotect the document. In a protected document you cannot rename or +remove a sheet. Document protection does not mean that each individual sheet +is protected. + + + + + + +&Shift;F9 + +Tools +Recalculate Sheet + +Recalculate formulae in the current sheet. + + + + + + +F9 + +Tools +Recalculate Document + +Recalculate all sheets. + + + + + +Tools +Insert Calendar... + +Insert a calendar in your sheet. A dialog asks you for the start and end dates. The corresponding calendar is then inserted from the current cell. + + + + + + +Tools +Script Manager... + +Opens the Scripts Manager dialog to execute, load, unload, install, uninstall and get more scripts. + + + + + +Tools +Scripts + +Here you can execute the script Export to HTML File or start the Script Editor. + + + + + + + +The <guimenu>Settings</guimenu> Menu + + + + +Settings +Show/Hide Status Bar + +Show or hide the Status Bar. +The Status Bar shows additional information for selected items and +instant calculations of the selected cells. + + + + + +Settings +Show/Hide Tab Bar + +Show or hide the Tab Bar. +All Sheets of the current Document can be accessed through the Tab Bar. + + + + + +Settings +Show/Hide Formula Bar + +Show or hide the Formula Bar. +The Formula Bar can be used to edit the content of the selected cell. + + + + + +Settings +Toolbars + +Show or hide the toolbars: File, +Edit, Navigation, +Format and Color/Border. + + + + + +Settings +Configure Shortcuts... + +Configure the keyboard shortcuts used by &kspread;. + See the section on configuring shortcuts + for more details. + + + + + + +Settings +Configure Toolbars... + +Configure the toolbars. The section on +configuring toolbars has more +information. + + + + + +Settings +Configure &kspread;... + +General &kspread; configuration. See the +section on &kspread; configuration for +more details. + + + + + + + + +The <guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + + + +The Right Mouse Button Menu +This section describes the items in the pop up menu obtained by +right clicking on a selected cell or cells, +row(s) or column(s). + + + + + + +&Alt;&Ctrl;F + +Cell Format... + +Format selected cell(s). See the +Spreadsheet Formatting section for more +details. + + + + + + +&Ctrl;X + +Cut + +Put selected item(s) into the clipboard. If +you then do a Paste the item(s) will be moved from the +original location to the new one. + + + + + + +&Ctrl;C + +Copy + +Copy selected item(s) into the clipboard. + + + + + + +&Ctrl;V + +Paste + +Paste item(s) from the clipboard to the selected cells. + + + + + + +Special Paste... + +Special forms of Paste. + See the sections Other Paste +Modes and Arithmetic using Special +Paste for more details. + + + + + +Paste with Insertion + +Paste from the clipboard to the selected cell(s), moving the +previous cell(s) to make room. + + + + + +Delete + +Delete contents of selected cell(s). + + + + + +Adjust Row & Column + +Change size of row and column to display selected +cell(s) completely. + + + + + +Default + +Set default formats for selected cell(s). + + + + + +Area Name... + +Name selected area. See the section +Named Areas for more details. + + + + + +Resize Row... + +Change height of selected row. + + + + + +Adjust Row + +Change height of selected row to display cell(s) +completely. + + + + + +Resize Column... + +Change width of selected column. + + + + + +Adjust Column + +Change width of selected column to display cell(s) +completely. + + + + + +Insert Cells... + +Insert new cell(s) at selected location, moving +existing cell(s) to make room. + + + + + +Remove Cells... + +Remove selected cell(s), moving other cell(s) to +occupy the space left by the removed cell(s). + + + + + +Insert Rows + +Insert new row(s) above selected row(s). + + + + + + +Delete Rows + +Delete selected row(s). + + + + + +Hide Rows + +Hides selected row(s). + + + + + +Show Rows + +Shows selected row(s). +In order to show hidden rows you need to select a range of rows that +includes the hidden rows. + + + + + +Insert Columns + +Insert new column(s) at left of selected column(s). + + + + + + +Delete Columns + +Delete selected column(s). + + + + + +Hide Columns + +Hides selected column(s). + + + + + +Show Columns + +Shows selected column(s). +In order to show hidden columns you need to select a range of columns that +includes the hidden columns. + + + + + +Add/Modify Comment... + +Add or modify a comment to the selected cell. + + + + + +Selection List... + +Lets you select and paste text from any +cell of the current selection of cells into the selected cell. + + + + + +Show Related Words + +Opens the Related Words dialog box. + + + + + + + +Other Shortcuts +This section describes those &kspread; shortcut keys used for operations +that do not appear in any of the menus. + + + + + +&Ctrl;Arrow keys + +If the selected cell is occupied then move the +cell cursor to the start or end of the occupied block in the current row or +column. If the selected cell is not occupied then move the cell cursor to +the start or end of the block of unoccupied cells in the current row or column. + + + + + + +&Ctrl;&Shift;Arrow keys + +If the selected cell is occupied then select all +occupied cells to the start or end of that block of occupied cells in the +current row or column. +If the selected cell is not occupied then select all unoccupied cells to the +start or end of that block of unoccupied cells in the current row or column. + + + + + + +Page Down + +Move the cell cursor 10 cells down. + + + + + +Page Up + +Move the cell cursor 10 cells up. + + + + + +&Ctrl;Page Down + +Move to the next sheet. + + + + + +&Ctrl;Page Up + +Move to the previous sheet. + + + + + +F4 + +Change cell reference between normal and +absolute reference types. + + + + + +&Ctrl;& + +Add a border to the selected cell(s). + + + + + +&Ctrl;$ + +Display the value of the selected cell(s) in Money +format. + + + + + +&Ctrl;% + +Display the value of the selected cell(s) in +Percentage format. + + + + + +&Ctrl;^ + +Display the value of the selected cell(s) in +Scientific format. + + + + + +&Ctrl;# + +Display the value of the selected cell(s) in +Date format. The value is taken as the number of days since +1 January 1900. + + + + + +&Ctrl;@ + +Display the value of the selected cell(s) in +Time format. The value is taken as the number of seconds since +midnight. + + + + + +&Ctrl;! + +Display the value of the selected cell(s) in +normal Number format. + + + + + + + +
    + + diff --git a/doc/kspread/config.docbook b/doc/kspread/config.docbook new file mode 100644 index 000000000..23f1a29fe --- /dev/null +++ b/doc/kspread/config.docbook @@ -0,0 +1,145 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +Configuring &kspread; Shortcuts and Toolbars + + +Shortcuts +To change the shortcut key arrangements used by &kspread; select +SettingsConfigure Shortcuts... +. This will launch a dialog box as shown below. + + + + + + +Shortcut config screenshot 1 + + +Search through the list box to find the action you want to add or +change the shortcut keys for and select it by left +clicking on the name. By entering the name of the action in the search bar at the +top you can quickly find the desired action. You will then be able to change the shortcut +by selecting the None, Default or +Custom radio button or by clicking on the large button in +the Shortcut for Selected Action area. +The Configure Shortcut dialog box will then open. + + + + + + +Simple shortcut configuration + + +You can now simply press the key combination you want to act as the +shortcut, for example +&Ctrl;&Shift;S. The Configure +Shortcut dialog box will then close by itself as soon as the shortcut +is configured. + + + + + + +Advanced shortcut configuration + + + +You can also click on the Advanced >> button in the +Configure Shortcut dialog to get more options. +There you can configure a Primary shortcut: and a secondary +Alternate shortcut:. +You can even choose Multi-key mode, which lets you add additional +keys to the shortcut. + + +Configuring the shortcut with the simple dialog sets the primary +shortcut. + + + +User Defined Menus +You can add your own pop up menu to &kspread; so that pressing one key +combination will make the menu appear then pressing a second key, or using the +Up arrow and Down arrow keys and pressing +Enter, will select an item from it. +To do this add a Custom shortcut for each of the +actions you want to appear in the menu and in the Configure Shortcut + dialog check the Multi-key mode box, press the +key combination that you want to bring up your new menu then, separately, +press the key that will choose that item from the menu. + + + + +Toolbars +&kspread; has five toolbars: File, +Edit, Navigation, +Format and Color/Border. +each of which may or may not be shown depending on the choices made in the +Settings menu. +You can choose whether a toolbar appears at the Top, +Left, Right or +Bottom of &kspread;'s window by right clicking on +the toolbar, which brings up the Toolbar Menu, and making +a selection from the Orientation sub menu. This +Toolbar Menu also has sub menus for choosing whether the +toolbar displays icons, text or both, and the size of the icons. + +Another way of moving a toolbar is by positioning the mouse pointer over +the two vertical bars at the left end of each toolbar and holding the +left mouse button down while you drag the toolbar +to the wanted position. When you drag the toolbar in this way you can release +the mouse button when it is some distance from any of &kspread;'s window +sides, and then you will get a floating toolbar, which is not locked to any +particular part of &kspread;'s window and can in fact be moved outside of +the window. To put a floating toolbar back into one of the traditional +positions right click on its titlebar to bring +up the Toolbar Menu then choose one of the options in +the Orientation sub menu. +You can also flatten a toolbar by left + clicking on the two vertical bars at the left end of the +toolbar or by selecting Orientation +Flat from the Toolbar +Menu. A flattened toolbar appears as a small +rectangle containing two horizontal bars just under &kspread;'s Menubar. It +can be restored to normal by left clicking on it. + +Selecting Configure Toolbars... from the +Settings menu will bring up a dialog box which lets you add +buttons to or remove them from &kspread;'s toolbars. +To use this Configure Toolbars dialog box first +select a toolbar from the Toolbar: combo box. The +right hand Current actions: window will then show the +buttons currently present on the toolbar. You can remove a button by selecting +it in this window then pressing the left arrow button, or move it around by +pressing the up and down arrow buttons. To add a new button to the toolbar +select it in the Available actions: list then press the +right arrow button. + +
    + + diff --git a/doc/kspread/configdialog.docbook b/doc/kspread/configdialog.docbook new file mode 100644 index 000000000..8936eef58 --- /dev/null +++ b/doc/kspread/configdialog.docbook @@ -0,0 +1,377 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +The &kspread; Configuration Dialog Box + +Selecting Settings +Configure &kspread;... opens a dialog box +with several pages, selected with the icons at the left of the dialog box, +which allow you to change many aspects of &kspread;'s operation. + + +<guilabel>Locale Settings</guilabel> + + + + + + + Locale Settings Configuration. + + + +This page of &kspread;'s configuration dialog box shows how items +such as numbers, date, time and money are displayed. +If you have loaded a spreadsheet that was generated using a different +locale, then pressing the Update Locale Settings +button on this page will update it to conform to your locale settings as they are fixed in &kcontrolcenter;. + + + +<guilabel>Interface</guilabel> + + + + + + + Interface Configuration. + + + +This page of &kspread;'s configuration dialog box (obtained by selecting +Configure &kspread;... from the Settings + menu) controls some more &kspread; features: + + + +Number of sheets open at the beginning: +Controls how many worksheets will be created if the +option Blank Worksheet is chosen when +&kspread; is started. + + + + +Number of files to show in Recent Files list: +Controls the maximum number of filenames that are shown +when you select File +Open Recent. + + + + +Autosave Delay (minutes): +Here you can select the time between autosaves, or disable +this feature altogether by choosing Do not save automatically +(drag the slider to the far left). + + + + +Create backup files +Check this box if you want some backup files created. This is checked per default. + + + + +Show vertical scrollbar +Check or uncheck this box to show or hide the vertical +scrollbar in all sheets. + + + + +Show horizontal scrollbar +Check or uncheck this box to show or hide the horizontal +scrollbar in all sheets. + + + + +Show column header +Check this box to show the column letters across the top of each +worksheet. + + + + +Show row header +Check this box to show the row numbers down the left side. + + + + +Show tabs +This check box controls whether the sheet tabs are shown +at the bottom of the worksheet. + + + + +Show formula toolbar +Here is where you can choose to show or hide the Formula bar. + + + + +Show status bar +Uncheck this box if you want to hide the status bar. + + + + + + + + +<guilabel>Misc</guilabel> + + + + + + + Miscellaneous Configuration. + + + +The Misc page of &kspread;'s configuration +dialog box contains the following items; + + + +Completion mode: +Lets you choose the (auto) text completion mode from a +range of options in the drop down selection box. + + + + +Pressing enter moves cell cursor: +Select whether pressing the Enter +key will move the cursor Down, Up, +Right, Left or Down, +First Column as determined by the setting in this drop down selection box. + + + + +Method of calc: +This drop down selection box can be used to choose the +calculation performed by the Statusbar Summary + function. + + + + +Indentation step (cm): +Lets you define the amount of indenting used by the +Increase Indent option in the Format + menu. + +The unit taken here is the one you fixe in the Configure +&kspread; dialog, in the Page Layout tab in the Default page +unit: setting. + + + +Show error message for invalid formulae +If this box is checked a message box will pop up when what +you have entered into a cell cannot be understood by &kspread;. + + + + + + + + + + +<guilabel>Color</guilabel> + + + + + + + Color Configuration. + + + +This page of &kspread;'s configuration dialog box lets you choose the +color of the sheet grid. If you do not want the grid to appear at all, uncheck the Show grid box in +the FormatSheetSheet Properties dialog. + +This page also lets you select the color of the lines used to indicate +the printed page borders when the Show Page Borders +box in the View menu is checked. +Click on the current color to display the standard KDE Select Color dialog. + + + + +Grid color: +Click here to change the grid color &ie; the color of the borders of each cell. + + + + +Page borders: +When the ViewShow Page Borders menu item is checked, the page borders are displayed. Click here to choose another color for the borders than the default red. + + + + + + + + +<guilabel>Page Layout</guilabel> + + + + + + + Page Layout Configuration. + + + +This page of &kspread;'s configuration dialog box lets you set up the +default page size, orientation and units used by the printer and by the +Page Layout dialog box (obtained by selecting +Page Layout... from the Format + menu. + + + + +Default page size: +Choose the default page size for your worksheet among all the most common page sizes. Note that you can overwrite the page size for the current sheet using the FormatPage Layout... dialog. + + + + +Default page orientation: +Choose the default sheet orientation: portrait or landscape. +Note that you can overwrite the orientation for the current sheet using the +FormatPage +Layout... dialog. + + + + +Default page unit: +Choose the default unit that will be used in your all your sheets. Note that you can overwrite the unit for the current sheet using the FormatPage Layout... dialog. + + + + + + + + +<guilabel>Spelling</guilabel> + + + + + + + Spelling Configuration. + + + +This page lets you configure the behavior of &kspread;'s spell +checker. + + + +Create root/affix combinations not in dictionary + +If this box is checked then when &kspread; finds a word in +the document which it does not recognize but which consists of a recognized +root word plus a recognized prefix or suffix it will accept it, whereas if +the box is not checked the spell checker will reject it. + + + + +Consider run-together words as spelling errors + +If this box is checked then common words which are run +together will be considered to be spelling errors, for example +cannot. + + + + +Dictionary: +This drop down selection box can be used to select +alternative dictionaries. + + + + +Encoding: +To select the character encoding that should be used. + + + + +Client: +This combo box lets you select between different spell +checking programs that may be present on your computer. + + + + +Skip all uppercase words +Check this box if you want the spellchecker to ignore +uppercase words, which are usually acronyms such as &kde;. + + + + +Do not check title case +Check this box if you want the spellchecker to ignore +the title case, for example My Own Spreadsheet or My own spreadsheet. If this is unchecked, the spell checker will ask for a uppercase letter in the title nouns. + + + + + + +Configure Text-To-Speech options +See the Text-to-Speech section +in the accessibility chapter for further details. + +
    + + diff --git a/doc/kspread/configure1.png b/doc/kspread/configure1.png new file mode 100644 index 000000000..7d2271307 Binary files /dev/null and b/doc/kspread/configure1.png differ diff --git a/doc/kspread/configure2.png b/doc/kspread/configure2.png new file mode 100644 index 000000000..af956024d Binary files /dev/null and b/doc/kspread/configure2.png differ diff --git a/doc/kspread/configure3.png b/doc/kspread/configure3.png new file mode 100644 index 000000000..d12ca56a6 Binary files /dev/null and b/doc/kspread/configure3.png differ diff --git a/doc/kspread/configure4.png b/doc/kspread/configure4.png new file mode 100644 index 000000000..549b8f1b8 Binary files /dev/null and b/doc/kspread/configure4.png differ diff --git a/doc/kspread/configure5.png b/doc/kspread/configure5.png new file mode 100644 index 000000000..3d1794210 Binary files /dev/null and b/doc/kspread/configure5.png differ diff --git a/doc/kspread/configure6.png b/doc/kspread/configure6.png new file mode 100644 index 000000000..92910c625 Binary files /dev/null and b/doc/kspread/configure6.png differ diff --git a/doc/kspread/copy1.png b/doc/kspread/copy1.png new file mode 100644 index 000000000..4833e0d5a Binary files /dev/null and b/doc/kspread/copy1.png differ diff --git a/doc/kspread/currency.png b/doc/kspread/currency.png new file mode 100644 index 000000000..5143aeb19 Binary files /dev/null and b/doc/kspread/currency.png differ diff --git a/doc/kspread/decreasedecimal.png b/doc/kspread/decreasedecimal.png new file mode 100644 index 000000000..6167f5dda Binary files /dev/null and b/doc/kspread/decreasedecimal.png differ diff --git a/doc/kspread/faq.docbook b/doc/kspread/faq.docbook new file mode 100644 index 000000000..c8687449a --- /dev/null +++ b/doc/kspread/faq.docbook @@ -0,0 +1,45 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +Questions and Answers + + + + +How many rows and columns can I have in a sheet? + +Theoretically up to 32767 rows and 32767 columns. + + + +Where are the templates stored? + +As .kst files under +~/.kde/share/apps/kspread/templates/. + + + + +
    + + + diff --git a/doc/kspread/format.docbook b/doc/kspread/format.docbook new file mode 100644 index 000000000..afe5787cc --- /dev/null +++ b/doc/kspread/format.docbook @@ -0,0 +1,693 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +Raphael +Langerhorst + +
    raphael.langerhorst@kdemail.net
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +
    +
    +Spreadsheet Formatting + + + +Cell Format +To change the format and appearance of selected cell(s), row(s) or column(s) use +the Cell Format... option from the Format + menu or from the right mouse button popup +menu. + + + + + + +Right mouse button context menu. + + + +This will bring up the Cell Format dialog box +which has several tabbed pages: + + +Data Formats and Representation + + + + + + +Data Format page. + + + +The Data Format page of the Cell Format dialog box +lets you control how the values of cells are displayed. +The top part of this page lets you select the format to be used when +displaying numeric values, dates or times. A Preview pane +allows you to see the effect of the new format. + +You can set the same data format for a row or a column by selecting the +row or column and calling the Cell Format dialog with the &RMB;. +You can increase the precision decimal for any number in Generic, +Number, Percent, Money or +Scientific formats using the Increase decimal +precision icon in the Format toolbar: + + +You can decrease the precision decimal for any number in Generic, +Number, Percent, Money or +Scientific formats using the Decrease decimal precision icon +in the Format toolbar: + + + + + +Generic +This is the default format and &kspread; autodetects the +actual +data type depending on the current cell data. By default, &kspread; right +justifies numbers, dates and times within a cell and left justifies anything +else. +If the Generic format does not suit you, you can change to a specific +format among the choices below. + + + +Number +The number notation uses the notation you globally choose in +&kcontrolcenter; in Regional & +AccessibilityCountry/Region & LanguageNumbers. +Numbers are right justified by default. + + + +Percent +When you have a number in the current cell and you switch the +cell format from Generic to Percent, the current cell number will be multiplied +by 100%. +For example if you enter 2 and set the cell format to Percent, the number +will then be 200 %. Switching back to Generic cell format will bring it back to +2. +You can also use the Percent icon in the Format +Toolbar: + + + + + +Money +The Money format converts your number into money notation using +the settings globally fixed in &kcontrolcenter; in Regional +& AccessibilityCountry/Region & LanguageMoney. The +currency symbol will be displayed and the precision will be the one set in +&kcontrolcenter;. +You can also use the Currency icon in the Format toolbar to set the +cell formatting to look like your current currency: + + + + + + +Scientific +The Scientific format changes your number using the scientific +notation. For example, 0.0012 will be changed to 1.2E-03. Going back using +Generic cell format will display 0.0012 again. The Generic cell data format does +not keep scientific notation so if you want this notation, you have to specify +it using this menu item. + + + +Fraction +The Fraction format changes your number into a fraction. For +example, 0.1 can be changed to 1/8, 2/16, 1/10, &etc;. You define the type of +fraction by choosing it in the field on the right. If the exact fraction is not +possible in the fraction mode you choose, the nearest closest match is chosen. +For example: when we have 1.5 as number, we choose Fraction +and Sixteenths 1/16 the text displayed into cell is "1 +8/16" which is an exact fraction. If you have 1.4 as number in your cell and you +choose Fraction and Sixteenths 1/16 +then the cell will display "1 6/16" which is the nearest closest Sixteenth +fraction. + + + +Date format +To enter a date, you should enter it in one of the formats set +in &kcontrolcenter; in Regional & +AccessibilityCountry/Region & LanguageTime & +Dates. There are two formats set here: the date format +and the short date format. +A random natural number NN will be transformed in the date from 30st +December 1899 (which is 0) with the number of days NN added. For example if you +have a cell with 100 and you choose Date format, "1900-04-09" will be +displayed in the cell which is 100 days after 30st December 1899. This starting +date is two days early as it was a bug in Lotus 123 and then it stayed that way +in Excel in order to keep compatibility. Few people will need to calculate from +1st January 1900 anyway and adding 9 days to 1st November 2000 for example will +give you 10th November 2000 so all normal calculations on dates are +correct. +When a cell is in the Date format, you can drag this cell down as +you do with numbers and the next cells will also get +dates, each date being increased by one day. + + + +Time format +This formats your cell content as a time. To enter a time, you +should enter it in the Time format set in &kcontrolcenter; +in Regional & AccessibilityCountry/Region & +LanguageTime +& Dates. In the Cell Format +dialog box you can set how the time should be displayed by choosing one of the +available time format options. The default format is the system format set in +&kcontrolcenter;. When the number in the cell does not make sense as a time, +&kspread; will display 00:00 in the global format you have in +&kcontrolcenter;. + + + +Text +This formats your cell content as text. This can be useful if +you want a number treated as text instead as a number, for example for a ZIP +code. Setting a number as text format will left justify it. When numbers are +formatted as text, they cannot be used in calculations or formulas. It also +change the way the cell is justified. + + + +Custom +Does not work yet. To be enabled in the next release. + + + + +The lower part of the Data Format page lets you add +a Prefix: such as a $ symbol at the start of each item or +a Postfix: such as $HK to the end. You can also control +how many digits are displayed after the decimal point for numeric values, +whether positive values are displayed with a leading + sign and whether +negative values are shown in red. + + + + +Fonts and Text Settings + + + + + + +Font page. + + + +The Font page lets you select the font family, Style:, +Size:, Weight: +and Color: for the current cell, including some additional options like +underlined or striked out text. +The lower part of the page gives a Preview of the selected text format. +The default font is set for all cells in the +FormatStyle +Manager menu with the currently used style. + + + + +Style: +Choose the style for your font for the currently selected cells. +When you select several cells with different styles, the displayed style is set +to Varying (No Change) and leaving it that way will keep +all your current style settings for each cell. Changing to +Roman for example will change all the selected cells style +text to Roman. + + + +Size: +Choose the size for your font for the currently selected cells. +When you select several cells with different sizes, the displayed size is set to + (no number written) and leaving it that way will keep all +your current size settings for each cell. Changing to 14 +for example will change all the selected cells font size to +14. + + + +Weight: +Choose the weight for your font for the currently selected +cells. When you select several cells with different font weight, the displayed +weight is set to Varying (No Change) and leaving it that +way will keep all your current weight settings for each cell. Changing to +Bold for example will change all the selected cells font +weight to Bold. + + + +Color: +Choose the color for the currently selected cells' text. +Clicking on the color bar will bring you the standard KDE Select Color dialog +where you will be able to choose the new color. + + + +Underline +Underlines the currently selected cells' text if checked. This +is +not checked per default. + + + +Strike out +This will strike out the currently selected cells' text if this +is checked. This is not checked per default. + + + + + + + +Text Position and Rotation + + + + + + +Position page. + + + +From the Position page you can control the position +of text within a cell by making suitable selections in the Horizontal + and Vertical areas or by setting the +Indent value. You can also choose to have the text +appear vertically rather than horizontally, or even at an angle. + + + +Horizontal +Set the content position horizontally in the cell. +Standard is default and is set from the data format you choose. +Left means the content will be displayed on the left of the cell. +Center means the content will be in the center horizontally in the cell. +Right means the content of the cell will be displayed on the right of the +cell. + + + +Vertical +Set the content position vertically in the cell. +Top means the content will be displayed on top of the cell. +Middle means the content will be in the middle vertically in the cell. +Bottom means the content of the cell will be displayed at the bottom of the +cell. + + + +Text Option +This is only available when the rotation is 0°. +Wrap text wraps the text so it fits in the previous cell size. If this is not +checked, the text will stay on one line. +Vertical text puts your text vertically. + + + +Rotation +Your text will appear oriented in the angle you set here. +Positive values will move it counter-clockwise and negative values will move it +clockwise. + + + +Merge Cells +When checked, this has the same effect +as DataMerge +Cells. You need to have at least two +consecutive cells selected. Those consecutive cells are then merged into a +bigger one. +When a merged cell is selected and when you uncheck this, then all cells +come back to their original size as before the merging. It has the same effect +as DataDissociate +Cells. + + + +Indent +Set the amount of indent that will be used in the cell when you +choose the FormatIncrease +Indent or +FormatDecrease +Indent menus. + + + +Size of Cell +You set here the size of the cell, either a custom width and +height or choose the default width and height. + + + + + + +Cell Border + + + + + + +Border page. + + + +The Border page lets you set the appearance of the +cell borders. If you have selected more than one cell you can apply different +styles to the borders between the cells and that surrounding the selected area. + +First select the pattern and color from the Pattern +section of the Border page then apply that to +different parts of the border by clicking on the appropriate button in the +Border section, or on one of the Preselect + buttons. The left hand button in the Preselect + section will clear any previously applied border(s). Note that you +can also add a diagonal strike-through line to the cell(s). + + +Cell Background + + + + + + +Background page. + + + +The cell background pattern and color can be selected from the +Background page. +Simply choose a desired Pattern, then select the pattern +Color and the Background color. +At the bottom of this page you can see a Preview of the configured +cell background. + + +Cell Protection + + + + + + +Cell protection page. + + + +You can change the way the content of a cell is protected in the +Cell Protection page. +All cells are protected by default (that means cell content cannot be +changed) and for the cell protection to be active you also need to protect the +sheet using the ToolsProtect Sheet... +menu and to provide a password. +You can also hide the cell formula in order to protect the way you calculate the +formula. This also needs to enable sheet protection to work. +You can hide the cell content with Hide all and again this needs sheet +protection. +You can learn more about all these settings in the Advanced &kspread; chapter, Protection +section. + + +Hide all +This hides the cell content and works only when the sheet is +protected which means that changing the Hide all +attribute of a cell has no effect unless the sheet is protected. Whether the +cell itself is protected or not does not matter. + + + + + + +Hide all. + + + +When Hide all is selected, Protected +and Hide formula are disabled as when the +sheet is protected Hide all hides the cell content and the +formula and thus masks and protects the cell content. + + + +Protected +If checked, the cell content will be protected. This is +the default behaviour. You need to protect the whole sheet using the +ToolsProtect Sheet... +menu for this individual cell protection to work. When a cell is protected, its +content cannot be changed. + + + +Hide formula +When this is checked, the cell is still visible. However, +its contents do not appear in the Formula bar. Hiding formula is only working +for cells that contain formulae so the user cannot view the formula. And the +sheet must be protected for this to work. + + + + +Do not print text +If you check Do not print text then the +text in the cell will not be printed. This is unchecked per default which means +that the cell text will always be printed by default. + + + + + + + +Conditional Cell Attributes +You can make the appearance of a cell change according to the value it +contains, useful perhaps if you are using &kspread; to keep track of your +household expenses and want to highlight any item greater than, say, one +thousand dollars. +To do this select the cell(s) then choose Conditional Cell +Attributes... from the Edit menu. This will +bring up the Conditional Cell Attributes dialog box where +you can make the font type and color of a cell change when the value meets +one or more conditions. Note that the second and third conditions only apply +if the previous condition(s) are not met. +Use ClearConditional +Cell Attributes from the Edit +menu to clear any conditional attributes from selected cells. + + + +Changing Cell Sizes +The Position page in the Cell Format + dialog lets you alter the size of the selected cell(s). Note that +changing the height of a single cell will change the height for all cells in +that row, similarly changing the width will affect the entire column. +You can also select the row(s) or column(s) to be changed then select +Resize Row... or Resize Column... + from the right mouse button pop up +menu or from the FormatRow + or Format +Column menu. +If you move the mouse cursor so that its tip is over the line between +two of the row numbers at the left of &kspread;'s window the cursor will +change to show two parallel lines each with a short arrow headed line coming +from it. When the cursor is in this state you can hold the left + mouse button down and drag the border between the two rows, +changing the height of the upper row. A similar technique can be used to +change the width of a column. + +To set the row height or column width to the minimum needed to +display the contents, select the whole row or column, and click with the &RMB; +on the row or column label. In the menu which appears, select +Adjust Row or Adjust +Column. The row or column will resize to the minimum +necessary. You can also select a single cell or range of cells, and +click Adjust Row & Column from either +the &RMB; popup menu or the Format menu. + +You can make a number of adjacent rows or columns the same size by +selecting them then choosing Format +RowEqualize Row or +FormatColumn +Equalize Column. + + + + +Merging Cells +It is often convenient to have one cell that spreads across two or more +columns or down more than one row. This can be done by merging two or more +cells into one. Select the cells to be merged than choose +DataMerge Cells. +To reverse this process, select the merged cell then choose +Dissociate Cells from the Data menu. + + + +Hiding Rows and Columns +A finished spreadsheet can often be made to look more attractive by +hiding the cells containing intermediate calculations so that only the +important data input and result areas are shown. +In &kspread; you can hide selected rows or columns by +using the Hide Rows and Hide +Columns options from the Format +Row, Format +Column or +right mouse button menus. Hidden rows and columns +are not displayed on the screen or included in a print out. +Hiding cells in this way also makes them slightly less prone to +accidental change. +To un-hide a row or column select Row +Show Rows... or +ColumnShow Columns... + from the Format +menu. In the dialog box which appears, you can select any number of +rows to show (use &Ctrl; + click to select +multiple rows or columns). + + + +Sheet properties +You can access the current sheet properties either by right clicking +on the sheet tab and choosing Sheet Properties or by +using the Format +SheetSheet +Properties menu. Please note that you can only +access the Sheet Properties when the document or the sheet is not +protected. +You can set different properties that will be valid in the current +sheet. Clicking on OK will validate your changes +and Defaults will bring back the default settings. + + + + + + +Sheet Properties dialog. + + + + + +Layout direction: +Let you choose the sheet orientation. Default is that the first +column of the sheet is on the left. If you choose Right to Left, then the first +column will be on the right and the others added from right to left. + + + +Hide zero +If this box is checked any cell containing the value zero will +appear blank. + + + +Automatic recalculation + This setting controls whether formulae are recalculated +automatically when the value of any cell they refer to changes. + + + +Show column as numbers +If this box is checked the column headings will show as numbers +rather than as letters. Letters are default. + + + +Use LC mode +If this box is checked the cell reference shown at the left end +of the Formula Bar will be displayed in LC mode (i.e. L2C3) rather than in its +normal form B3. This does not seem to be of much use at the moment. + + + +Convert first letter to uppercase +Check this box and the first letter of any text you type in will +automatically be converted to uppercase. + + + +Show grid +If checked the grid (the cell limits) will be shown. This is +default. If you uncheck it, the grid will be hidden. + + + +Show page borders +If you check this option, the page borders will be drawn on your +current sheet. Per default the page borders are not displayed. It is useful to +see the page borders if you want to print your sheet. + + + +Show formula +If this box is checked &kspread; will display the actual +formulae in cells rather than the results. + + + +Show formula indicator +If this box is checked &kspread; will display a small blue +triangle at the bottom left corner of cells containing formulae. This is useful +if you want to protect cells with formulae. + + + +Show comment indicator +If this box is checked cells containing comments will be marked +by a small red triangle at the top right corner. + + + + +
    + + diff --git a/doc/kspread/hideformula1.png b/doc/kspread/hideformula1.png new file mode 100644 index 000000000..5a9b589a2 Binary files /dev/null and b/doc/kspread/hideformula1.png differ diff --git a/doc/kspread/hideformula2.png b/doc/kspread/hideformula2.png new file mode 100644 index 000000000..f4f1fe26c Binary files /dev/null and b/doc/kspread/hideformula2.png differ diff --git a/doc/kspread/hideformula3.png b/doc/kspread/hideformula3.png new file mode 100644 index 000000000..9b2c58ca1 Binary files /dev/null and b/doc/kspread/hideformula3.png differ diff --git a/doc/kspread/hideformula4.png b/doc/kspread/hideformula4.png new file mode 100644 index 000000000..cb5b5a7f5 Binary files /dev/null and b/doc/kspread/hideformula4.png differ diff --git a/doc/kspread/hideformula5.png b/doc/kspread/hideformula5.png new file mode 100644 index 000000000..a0ebc9e55 Binary files /dev/null and b/doc/kspread/hideformula5.png differ diff --git a/doc/kspread/importexport.docbook b/doc/kspread/importexport.docbook new file mode 100644 index 000000000..e5c36f3a9 --- /dev/null +++ b/doc/kspread/importexport.docbook @@ -0,0 +1,105 @@ + + + + +Pamela +Robert + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +
    +
    +Importing and Exporting Foreign Formats +&kspread; has a limited ability to import (read) and export (write) +spreadsheet files with foreign formats. &kspread;'s capabilities at the time +of writing are summarized in the table below, for more up to date +information visit +http://www.koffice.org/filters/status.phtml. + + +
    + + Format + Import + Export + + + +Applix Spreadsheet +Beta +None + + +Comma Separated Values (CSV +) +Good +Good + + +dBase +Beta +None + + +Excel 97/2000 +Good +None + + +Gnumeric +Beta +Beta + + +HTML +None +Beta + + +Quattro Pro +Beta +None + + + + +To import a foreign file just load it as though it were a &kspread; +native file with File +Open.... +To export a &kspread; file in a different format select +FileSave As... +and select the format from the Filter: combo box. +Although &kspread; automatically adds a +.ksp extension to the names of files saved in its native format, +you should add the correct extension for foreign formats. + + +<acronym>CSV</acronym> Data +Tables of data are often held in text files with the values in a +line being separated by a comma, space, tab or other character, +for example 123, 456, 789, abcd, efgh. Such files +are commonly called CSV (Comma Separated +Values) files, even though the separating character may not be a comma. +If you ask &kspread; to open a text file it assumes that the file is +in CSV format and launches a dialog box that allows you to +specify the delimiter (separating character) used by the file, and shows how +the data items will be placed into different spreadsheet cells. +Other options in this dialog box let you define the Format + of the spreadsheet cells, whether text quote characters should be +removed, and whether the first line(s) of the file should be ignored. + + + + + diff --git a/doc/kspread/increasedecimal.png b/doc/kspread/increasedecimal.png new file mode 100644 index 000000000..bb56dd929 Binary files /dev/null and b/doc/kspread/increasedecimal.png differ diff --git a/doc/kspread/index.docbook b/doc/kspread/index.docbook new file mode 100644 index 000000000..171b78a6e --- /dev/null +++ b/doc/kspread/index.docbook @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + +]> + + + + +The &kspread; Handbook + + + + + +Pamela +Roberts + +
    pamroberts@blueyonder.co.uk
    +
    +
    + +Anne-Marie +Mahfouf + +
    annemarie.mahfouf@free.fr
    +
    +
    + +Gary +Cramblitt + +
    garycramblitt@comcast.net
    +
    +
    + +
    + + +2002 +Pamela Roberts + + + +2005 +Anne-Marie Mahfouf + + + +2006 +Gary Cramblitt + + + + +&FDLNotice; + +2006-06-12 +1.5.2 + + + + +&kspread; is a full featured spreadsheet program. + + + + +KDE +Koffice +KSpread +Spreadsheet + + +
    + + +Introduction + +This handbook is dedicated to the memory of Visicalc. + +&kspread; is a full featured spreadsheet program. It is part of the &koffice; +productivity suite for the K Desktop Environment (&kde;). +Other &koffice; applications include &kword;, (word processing), +&kpresenter; (slide presentation creator) and &kchart; (for producing charts +and graphs) among others. + +You might care to visit +http://www.kde.org for more information about &kde; in general, or the +&koffice; web site at +http://www.koffice.org + + + +&basics; + +&format; + +&advanced; + +&config; + +&configdialog; + +&a11y; + +&commands; + +&faq; + + + +Credits and License + + +&kspread; + + +Program copyright 1998-2002 The KSpread Team: + + + +Torben Weis weis@kde.org + +Laurent Montel lmontel@mandrakesoft.com + +David Faure faure@kde.org + +John Dailey dailey@vt.edu + +Philipp Müller philipp.mueller@gmx.de + +Ariya Hidayat ariya@kde.org + +Norbert Andres nandres@web.de + +Shaheed Haque srhaque@iee.org + +Werner Trobin trobin@kde.org + +Nikolas Zimmerman wildfox@kde.org + +Helge Deller deller@gmx.de + +Percy Leonhart percy@eris23.org + +Eva Brucherseifer eva@kde.org + +Phillip Ezolt phillipezolt@hotmail.com + +Enno Bartels ebartels@nwn.de + +Graham Short grahshrt@netscape.net + + + + + +Documentation copyright 2002 Pamela Roberts +pamroberts@blueyonder.co.uk + + +Minor updates to documentation for &koffice; 1.3 by +&Philip.Rodrigues; &Philip.Rodrigues.mail;. + +&underFDL; +&underGPL; + + + +Installation + +&kspread; is part of &kde;'s &koffice; package and uses various +&koffice; libraries. &koffice; itself is part of &kde; and depends on the +general &kde; libraries. +For instructions on acquiring and installing &kde;, &koffice; and +&kspread; please visit +http://www.kde.org and +http://www.koffice.org. + + + +&documentation.index; +
    + + + diff --git a/doc/kspread/kbd-focus-ext.png b/doc/kspread/kbd-focus-ext.png new file mode 100644 index 000000000..f7aa6f585 Binary files /dev/null and b/doc/kspread/kbd-focus-ext.png differ diff --git a/doc/kspread/mousenav.png b/doc/kspread/mousenav.png new file mode 100644 index 000000000..462c6051f Binary files /dev/null and b/doc/kspread/mousenav.png differ diff --git a/doc/kspread/newdocument.png b/doc/kspread/newdocument.png new file mode 100644 index 000000000..923a61b6a Binary files /dev/null and b/doc/kspread/newdocument.png differ diff --git a/doc/kspread/percent.png b/doc/kspread/percent.png new file mode 100644 index 000000000..75649e5b9 Binary files /dev/null and b/doc/kspread/percent.png differ diff --git a/doc/kspread/sheetproperties.png b/doc/kspread/sheetproperties.png new file mode 100644 index 000000000..ee325f869 Binary files /dev/null and b/doc/kspread/sheetproperties.png differ diff --git a/doc/kspread/shortcut1.png b/doc/kspread/shortcut1.png new file mode 100644 index 000000000..df152f854 Binary files /dev/null and b/doc/kspread/shortcut1.png differ diff --git a/doc/kspread/shortcut2.png b/doc/kspread/shortcut2.png new file mode 100644 index 000000000..d47fab20d Binary files /dev/null and b/doc/kspread/shortcut2.png differ diff --git a/doc/kspread/shortcut3.png b/doc/kspread/shortcut3.png new file mode 100644 index 000000000..34a25dea4 Binary files /dev/null and b/doc/kspread/shortcut3.png differ diff --git a/doc/kspread/sort1.png b/doc/kspread/sort1.png new file mode 100644 index 000000000..cc1436b43 Binary files /dev/null and b/doc/kspread/sort1.png differ diff --git a/doc/kspread/starting1.png b/doc/kspread/starting1.png new file mode 100644 index 000000000..0bcc216e3 Binary files /dev/null and b/doc/kspread/starting1.png differ diff --git a/doc/kspread/tts.png b/doc/kspread/tts.png new file mode 100644 index 000000000..332d77bf8 Binary files /dev/null and b/doc/kspread/tts.png differ diff --git a/doc/kugar/Makefile.am b/doc/kugar/Makefile.am new file mode 100644 index 000000000..e786da562 --- /dev/null +++ b/doc/kugar/Makefile.am @@ -0,0 +1,3 @@ + +KDE_LANG = en +KDE_DOCS = AUTO diff --git a/doc/kugar/add_detail.png b/doc/kugar/add_detail.png new file mode 100644 index 000000000..852d7361a Binary files /dev/null and b/doc/kugar/add_detail.png differ diff --git a/doc/kugar/add_detail_footer.png b/doc/kugar/add_detail_footer.png new file mode 100644 index 000000000..2db8829c4 Binary files /dev/null and b/doc/kugar/add_detail_footer.png differ diff --git a/doc/kugar/add_detail_header.png b/doc/kugar/add_detail_header.png new file mode 100644 index 000000000..44cbc5704 Binary files /dev/null and b/doc/kugar/add_detail_header.png differ diff --git a/doc/kugar/datadtd.docbook b/doc/kugar/datadtd.docbook new file mode 100644 index 000000000..d393e1b84 --- /dev/null +++ b/doc/kugar/datadtd.docbook @@ -0,0 +1,46 @@ + + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +<sgmltag class="element">KugarData</sgmltag> Document Type +Definition + + +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE KugarData [ + <!ELEMENT KugarData (Row*)> + <!ATTLIST KugarData + Template CDATA #REQUIRED> + + <!ELEMENT Row EMPTY> + <!ATTLIST Row + level CDATA #REQUIRED + col1 CDATA #IMPLIED + col2 CDATA #IMPLIED + ... CDATA #IMPLIED + coln CDATA #IMPLIED> + ]> + +
    diff --git a/doc/kugar/dataref.docbook b/doc/kugar/dataref.docbook new file mode 100644 index 000000000..30f56ec35 --- /dev/null +++ b/doc/kugar/dataref.docbook @@ -0,0 +1,130 @@ + + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +<sgmltag class="element">KugarData element</sgmltag> + + +The KugarData element defines a +report's data source. The basic structure is a collection of rows and +columns. This document does not define data types and their attributes. +The report template defines column data type information. + + + +The document creator can apply an &XSL; style sheet to an existing +document to convert it to this format. If &XSL; is used, the creator +can apply custom macros using &XSL; for column calculations, sorting, +&etc;. + + + +<!ELEMENT KugarData (Row*)> +<!ATTLIST KugarData + Template CDATA #REQUIRED> + +<!ELEMENT Row EMPTY> +<!ATTLIST Row + level CDATA #REQUIRED + col1 CDATA #IMPLIED + col2 CDATA #IMPLIED + ... CDATA #IMPLIED + coln CDATA #IMPLIED> + + + + +Kugar data element + +The KugarData element contains zero +or more Row elements. A Row must contain one level +attribute with a value corresponding to detail level in the template. Other attributes +represent data columns. + + +The value of the Template +attribute is the &URL; of the report template +used to format the data. + + + + + +Row element + + + + +Attributes + + + + + +level + + +The attribute value indicates which detail in the report template +is used to display data. Rows can contain various column sets for various levels, +so any attribute except level should +be stated as #IMPLIED. + + + + + +column + + +The name of the attribute is the column name, and uses the format as given +in the KugarData definition. +The attribute name is used in the report template to bind the data to the +report fields. + + + + + + + + + + +
    + diff --git a/doc/kugar/designer.docbook b/doc/kugar/designer.docbook new file mode 100644 index 000000000..34195ca36 --- /dev/null +++ b/doc/kugar/designer.docbook @@ -0,0 +1,364 @@ + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +Report Template Designer Manual + +&kudesigner; allows interactive creation and modification of +report templates, and placement of report sections and section items onto a +report. + + &kudesigner; is a WYSIWYG +application. Report page size defines the report +dimensions on the screen. At the present moment, the scale is set +to 100% automatically and cannot be changed. + + +Every report template may contain the following report sections: +Report Header +Page Header +Detail Header +Detail +Detail Footer +Page Footer +Report Footer + + + +Report sections may contain the following report items: +Label +Field +Calculated Field +Special Field +Line + + +Report sections and items can be placed onto the report template by +using menus or toolbars. + +Every element, such as a report template, a report section or an +item has its own properties. These properties define geometrical, +textual and any other parameters. Every time an element is placed, a set +of default properties is applied. For example, when +Label is placed, its Text property value is +set to Text. + +To change properties, use the Report Item +Options dialog. This dialog can be called by &RMB; clicking +on an item or with an Edit Properties button in the +Edit Toolbar. + See screenshot below (properties for a Field item): + + + +To delete an item, &MMB; click on it or use the Delete button in the +Edit Toolbar. + + + + + + + + +New Report dialog + + + + + +The &kudesigner; menu reference + + + +&Ctrl; +N + +File +New + + +Bring up the New Report dialog +to create a new report template. + +As seen on the screenshot, the report page size, orientation and margins +must be set before the report can be created. + + + + + + + +New Report dialog + + + + + + + + +&Ctrl; +O + +File +Open... + +Open the previously saved report template. + + + + +File +Open Recent + +Display a list of recently opened templates. +Select a file to open it. + + + + +&Ctrl; +S + +File +Save + +Save the current report template into a text file in &XML; format. + + + + +File +Save As... + +Save the current report template into a file and give it another name. + + + + +&Ctrl; +W + +File +Close + +Close the current report template. + + + + +&Ctrl; +P + +File +Print + +Print... the current report template as text in &XML; format. + + + + +&Ctrl; +Q + +File +Quit + +Quit the program. + + + + +Edit +Clear Selection + +Cancel any edit action, so no properties +will be edited or items deleted. + + + + +Edit +Edit Properties + +Edit properties of the selected item. + + + + +Edit +Delete + +Delete the selected item. + + + + +Sections +Report Header + +Place the Report Header section onto the report template. + + + + +Sections +Page Header + +Place the Page Header section onto the report template. + + + + +Sections +Detail Header + +Place the Detail Header section onto the report template. +Before placing the section, the Add Detail Header dialog will be shown to +specify the detail level. The Detail header will be added to the detail section of the given level. + + + + + + +Add Detail Header dialog + + + + + + + + +Sections +Detail + +Place the Detail section onto the report template. +Before placing the section, the Add Detail dialog will be shown to +specify the detail level. + + + + + + +Add Detail dialog + + + + + + + + +Sections +Detail Footer + +Place the Detail Footer section onto the report template. +Before placing the section, the Add Detail Footer dialog will be shown to +specify the detail level. The Detail footer will be added to the detail section of the given level. + + + + + + +Add Detail Footer dialog + + + + + + + + +Sections +Page Footer + +Place the Page Footer section onto the report template. + + + + +Sections +Report Footer + +Place the Report Footer section onto the report template. + + + + +Items +Clear Selection + +Clear item selection, so no report item will be added to the section. + + + + +Items +Label + +Place the Label element onto the section. + + + + +Items +Field + +Place the Field element onto the section. + + + + +Items +Calculated Field + +Place the Calculated Field element onto the section. + + + + +Items +Special Field + +Place the Special Field element onto the section. + + + + +Items +Line + +Place the Line element onto the section. + + + +
    diff --git a/doc/kugar/file_new.png b/doc/kugar/file_new.png new file mode 100644 index 000000000..310c0e46c Binary files /dev/null and b/doc/kugar/file_new.png differ diff --git a/doc/kugar/index.docbook b/doc/kugar/index.docbook new file mode 100644 index 000000000..cbe87b760 --- /dev/null +++ b/doc/kugar/index.docbook @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + +]> + + + + +The &kugar; Handbook + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    + +2000 +2001 +Phil Thompson + + +2002 +Alexander Dymo + + +&FDLNotice; + +2002-06-11 +1.02.00 + + + + + +&kugar; is a template based &XML; report engine. +&kudesigner; is a flexible &GUI; report template designer for &kugar; report engine. + + + + +KDE +kdeutils +kugar +kudesigner +report +generator +engine +designer + + +
    + + +Introduction + + &kugar; is a report creation tool for &Qt; and &kde;. It includes +a &GUI; report template designer, a report engine, a &konqueror; part +for easy report preview and a set of examples. + + The &kudesigner; is a report template creation tool +for the &kugar; report engine. The &kugar; report engine uses an &XML; +based report template file (which can be created by hand or with +&kudesigner;) and a data file (also in &XML; format) to create +reports. To get more information on &kudesigner; refer to the Report Template Designer Manual. + + + See The KugarTemplate Document +Type Definition for an overview of the template's +DTD (file format), KugarData Document Type Definition and +Tutorial for a step-by-step explanation +on how reports can be created. + + Programmers should also refer to the Programmer's guide to find information +about using &kugar; in their own applications. + + +&tutorial; + +&starting; + +&designermanual; + +&progguide; + + +Credits and License + + +&kugar; + + + +Copyright 2000 Mutiny Bay Software + + +Copyright 2000, 2001, Phil Thompson + + +Copyright 2002 Alexander Dymo + + +Portions of the documentation Copyright 2000, 2001 Phil Thompson +and Copyright 2002 Alexander Dymo + + +&underFDL; +&underGPL; + + + + +Document Structure +&templatedtd; +&template; +&templateelements; +&datadtd; +&dataelements; + + + +Installation + +&install.intro.documentation; +&install.compile.documentation; + + +
    diff --git a/doc/kugar/kugar.png b/doc/kugar/kugar.png new file mode 100644 index 000000000..7232fa5cf Binary files /dev/null and b/doc/kugar/kugar.png differ diff --git a/doc/kugar/progguide.docbook b/doc/kugar/progguide.docbook new file mode 100644 index 000000000..5b60db0d2 --- /dev/null +++ b/doc/kugar/progguide.docbook @@ -0,0 +1,544 @@ + + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +Programmer's Guide + + +How to use &kugar; for reporting in your own programs + + +There are several ways to use &kugar; + + +Create a temporary file and fill it with data, organized according to the +KugarData Document Type Definition. Then +call the kugar shell command ( + +kugar + + + + + + + +) to preview and print the report. +See Using &kugar; shell for previewing reports +for a detailed description. + + + + +Use &kugar; directly in the application's code. +See Using &kugar; classes for reporting +for a detailed description. + + + + +Create a &Qt; designer plugin, use it to build the application &GUI; in the designer and +link it to the program dynamically. +See Creating a &Qt; designer plugin +for a detailed description. + + + + + The last two ways are acceptable for &Qt; and &kde; developers; +but &kugar; is designed to be a report generator, independent from a +programming language and/or IDE. It uses &XML; +format for describing report templates and data files. So any program +can produce output in &kugar; data file format as described in KugarData DTD or +even a report template file format (see KugarTemplate DTD). +&kugar; shell (report viewer) can be used to preview and print the +generated report. + + + + +Using &kugar; shell for previewing reports + + +The way to create and preview (print) a report is: + + +Create a report template file with &kudesigner; + + + + +Create a data file with column values for detail bands of the report. +Use KugarData DTD to produce correct data files. + + + + +Run &kugar; shell to preview and print a report. For example, to do this, in C or C++ +languages call: + + +system(). + + + +Don't forget to include stdlib.h. + + + + + + +Using &kugar; classes for reporting + +The &kugar; library includes two widgets for use. + + +The KReportViewer class is designed for &kde; +developers. It supports a &kde; printing system and &UNIX; localization +via i18n() calls. + + +The MReportViewer class is designed for &Qt; +developers and provides real crossplatforming. It can be used not +only on &UNIX; platforms, but also on &Windows; and &MacOS;. + + +In order to build a program that uses the &kugar; library, it should be linked +with libkugar.so shared library, which is provided with the &kugar; distribution on all +&UNIX; platforms. + + +Include files are kugarqt.h and kugar.h +for &Qt; and &kde; programs respectively. + +For a detailed example of how &kugar; classes can be used, look in the /shell +folder in the &kugar; sources. + + +MReportViewer (and KReportViewer too) +contains several public methods that can be used. + + + +void renderReport + + +Renders the report onto a screen. + + + + +void printReport + + +Calls the print dialog to print the report. + + + + +void clearReport + + +Clears the report on a screen and frees report data. +Call this before opening the new report. + + + + +bool setReportData +const QString &data_file_name + +Sets report data from data_file_name file. + + + + +bool setReportData +const QIODevice &data_io_device + +Sets report data from data_io_device file. +IO device can be any successor of the QIODevice class. +For example, to fetch records directly from the database, +create a QIODevice successor and redefine all necessary +functionality. + + + + + +bool setReportTemplate +const QString &template_file_name + +Sets report template from template_file_name file. + + + + +bool setReportTemplate +const QIODevice &template_io_device + +Sets report template from template_io_device file. +IO device can be any successor of the QIODevice class. +For example, to obtain a report template from network storage or database, +create a QIODevice successor and redefine all necessary functionality. + + + + + + +Creating &Qt; designer plugin + + +This is the example code of how a designer plugin is created. The code below creates a plugin for +a &kde; KReportViewer widget. + + + +If a &Qt; +widget is desired, replace KReportViewer with +MReportViewer and kugar.h with +kugarqt.h in the plugin code. + + + +Plugin usage + +The designer plugin will allow the usage of &Qt; Designer to place a KReportViewer +widget onto a window and preview it correctly. + + + +Programs that make use of this plugin must be linked dynamically with it. +The corresponding library is called libkugar_plugin.so. +Widgets or dialogs that include KReportViewer +widget must include <kugar.h> in implementation and have a forward declaration +of class KReportViewer. Includes can be done with &Qt; +Designer's Object Explorer (Source tab). + + + +To build the plugin run: + +qmake +kugar_plugin.pro + + +make + + + + + + +Plugin code + + +The plugin code consists of three files: +kugar_plugin.h +kugar_plugin.cpp +kugar_plugin.pro + +A header file for the KugarWidgetPlugin, QWidgetPlugin successor; +A source file for the KugarWidgetPlugin, QWidgetPlugin successor; +A project file for the QMake utility. + + + + +kugar_plugin.h + + +#include <qwidgetplugin.h> + +class KugarWidgetPlugin:public QWidgetPlugin +{ +public: + KugarWidgetPlugin (); + + QStringList keys () const; + QWidget *create (const QString & classname, QWidget * parent = + 0, const char *name = 0); + QString group (const QString &) const; + QIconSet iconSet (const QString &) const; + QString includeFile (const QString &) const; + QString toolTip (const QString &) const; + QString whatsThis (const QString &) const; + bool isContainer (const QString &) const; +}; + + + + + +kugar_plugin.cpp + + +#include "kugar_plugin.h" +#include <kugar.h> + +static const char *kugar_pixmap[] = { + "22 22 127 2", + ".d c #000000", + ".c c #131313", + ".b c #282828", + ".a c #434241", + ".e c #4e463a", + ".# c #595551", + ".G c #66553b", + "#F c #68635f", + "#R c #6b4f23", + "#q c #6e6862", + "#M c #6f5229", + ".n c #6f6146", + ".w c #735310", + ".V c #755c2a", + ".I c #775f34", + ".0 c #77694a", + "#n c #7e6434", + ".o c #806f50", + "#C c #835d2d", + ".P c #837c75", + "#B c #85653a", + "#k c #85827e", + ".x c #866d46", + ".U c #877967", + ".X c #888888", + ".F c #89724d", + "#x c #8b6d2a", + ".S c #8d7759", + ".z c #8e733b", + "#L c #906e49", + "#Q c #947b56", + ".r c #948058", + ".J c #957844", + ".4 c #987736", + ".q c #998969", + ".k c #999897", + ".R c #9a8a75", + "#i c #9f8348", + "#I c #a37c4b", + ".u c #a38d66", + ".E c #a58558", + "#A c #a8834b", + ".s c #a9967a", + ".t c #aa9467", + ".C c #ae9f8d", + "#6 c #afa49d", + "#5 c #afa9a4", + "#W c #b18e4d", + ".K c #b1935a", + ".B c #b39660", + "#V c #b49866", + "#a c #b49d6c", + "## c #b49d72", + ".j c #b5b4b4", + "#0 c #b7a597", + ".O c #b9b1a9", + ".L c #bb9c61", + ".M c #bb9e6b", + ".A c #bca778", + "#j c #bea46b", + ".T c #bfb37d", + ".v c #c0b391", + ".W c #c3a262", + ".i c #c4c4c4", + "#m c #c5b7aa", + "#8 c #c69f80", + ".D c #c6b79b", + "#3 c #c7a589", + ".7 c #c7a76c", + "#u c #c7bbaf", + ".6 c #c8ad74", + "#7 c #c8b7a9", + "#r c #c8beb5", + ".m c #c8c8c8", + "#U c #cbad96", + "#f c #ccb681", + "#h c #cdac6c", + "#P c #cdb49f", + "#X c #cdb8a6", + "#H c #ceb7a4", + ".y c #ceb892", + ".N c #cecac3", + "#Z c #cfb16f", + "#O c #cfbdad", + ".Z c #cfc7c0", + "#w c #d0bcab", + ".5 c #d1ad6b", + "#s c #d1bfb1", + ".h c #d5d5d5", + "#l c #d6cdc6", + "#D c #d8b36e", + ".H c #dac592", + "#t c #dbb977", + ".g c #dcdcdc", + ".1 c #e0dcc1", + ".f c #e0e0df", + "#1 c #e3c8b1", + "#S c #e4cdb9", + ".3 c #e4d9a3", + "#4 c #e6c1a1", + "#2 c #e7c4a5", + "#K c #e9c179", + "#g c #e9c47e", + "#Y c #e9c8ac", + ".2 c #eae6c0", + "#T c #ebcdb3", + ".Q c #ebd4b9", + "#E c #ecca87", + "#z c #ecd799", + ".l c #ececeb", + "#G c #efd7c2", + "#e c #efe3ab", + ".8 c #efe8e3", + "#v c #f1dcca", + "#. c #f2e2d4", + ".p c #f4f4f4", + "#y c #f5daa0", + "#J c #f6cf7f", + ".9 c #f7ede4", + "#p c #f9d995", + ".Y c #fcf9f6", + "#d c #fefcc5", + "#c c #fefdda", + "#b c #fefee1", + "#N c #ffd685", + "#o c #fff0a9", + "Qt c #ffffff", + "QtQtQtQtQtQt.#.a.a.a.b.b.b.c.c.d.d.dQtQtQtQt", + "QtQtQtQtQtQt.e.f.g.g.f.g.g.h.i.j.d.k.dQtQtQt", + "QtQtQtQtQtQt.a.gQtQtQtQtQtQt.l.f.c.m.k.dQtQt", + "QtQtQtQtQt.n.n.n.n.n.o.g.pQtQt.l.bQt.m.k.dQt", + "QtQtQt.q.q.r.q.s.t.r.q.u.u.g.pQt.a.fQt.m.k.d", + "QtQt.s.s.v.w.x.y.y.t.z.A.t.B.i.p.#.a.b.c.d.d", + "Qt.C.C.D.E.F.G.A.H.F.I.J.K.L.M.i.p.l.N.O.P.d", + "Qt.s.v.Q.q.R.S.T.A.R.U.V.L.W.W.X.g.Y.f.Z.k.d", + ".0.s.t.Q.1.U.R.2.3.S.U.4.5.6.6.7.j.8.9#..O.d", + ".G##.V#a#b.1#c#c#d#e#f#g#h#i#j.W#k#l.9#.#m.d", + ".G.4.F#n#c#c#c#d#d#o#p#g.x.w#i.L#q#r#.#.#s.d", + ".e.J.J.I.3#d.H#j.6#f#p#t#n.w.E.L#q#u#.#v#w.d", + ".G.A#x.z#y#z#A#B#B#C#D#E.4.4.6#h#F#m#v#G#H.d", + ".o.s.A#j#E#t#I#I#I#C#A#J#p#p#K#t#F#m#v#G#H.d", + "Qt##.A.6.7#I#I#A.E#L#M.W#N#J#K.a.U#O#G.Q#P.d", + "Qt#a.M.L.J#A#I.4.E#Q.x#R#D#J#g.#.C#S.Q#T#U.d", + "QtQt#V.K.z#Q.s.S.x.S#B#M#W#E.a.U#X.Q#T#Y#U.d", + "QtQtQt.M#i#B.r#Q#Q.r#Q.z#Z.a#q#0#1#T#Y#2#3.d", + "QtQtQtQtQt#j.L.L.W.5#t.a.#.U#0#1#T#Y#2#4#3.d", + "QtQtQtQtQtQt.d#F#q#q#q.P.C#O#S.Q#T#Y#2#4#3.d", + "QtQtQtQtQtQt.d#5#5#6#6#0#7#w#H#P#U#U#3#3#8.d", + "QtQtQtQtQtQt.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d.d" +}; + +KugarWidgetPlugin::KugarWidgetPlugin () +{ +} + +QStringList KugarWidgetPlugin::keys () const +{ + QStringList list; + list << "KReportViewer"; + return list; +} + +QWidget* KugarWidgetPlugin::create (const QString & key, QWidget * parent, + const char *name) +{ + if (key == "KReportViewer") + return new KReportViewer (parent, name); + return 0; +} + +QString KugarWidgetPlugin::group (const QString & feature) const +{ + if (feature == "KReportViewer") + return "Display"; + return QString::null; +} + +QIconSet KugarWidgetPlugin::iconSet (const QString &) const +{ + return QIconSet (QPixmap (kugar_pixmap)); +} + +QString KugarWidgetPlugin::includeFile (const QString & feature) const +{ + if (feature == "KReportViewer") + return "kugar.h"; + return QString::null; +} + +QString KugarWidgetPlugin::toolTip (const QString & feature) const +{ + if (feature == "KReportViewer") + return "Kugar report viewer widget"; + return QString::null; +} + +QString KugarWidgetPlugin::whatsThis (const QString & feature) const +{ + if (feature == "KReportViewer") + return "A widget to view xml reports"; + return QString::null; +} + +bool KugarWidgetPlugin::isContainer (const QString &) const +{ + return FALSE; +} + +Q_EXPORT_PLUGIN( KugarWidgetPlugin ) + + + + +kugar_plugin.pro + + +SOURCES += kugar_plugin.cpp +HEADERS += kugar_plugin.h + +DESTDIR = $(QTDIR)/plugins/designer +TARGET = kugar_plugin + +target.path=$$plugins.path +isEmpty(target.path):target.path=$$QT_PREFIX/plugins +PROJECTNAME = KugarPlugin +TEMPLATE = lib +CONFIG += qt warn_on release plugin +unix:LIBS += -lkugar +LANGUAGE = C++ + + + + + + +
    diff --git a/doc/kugar/props.png b/doc/kugar/props.png new file mode 100644 index 000000000..7a110f891 Binary files /dev/null and b/doc/kugar/props.png differ diff --git a/doc/kugar/starting.docbook b/doc/kugar/starting.docbook new file mode 100644 index 000000000..555df6a9f --- /dev/null +++ b/doc/kugar/starting.docbook @@ -0,0 +1,60 @@ + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +Starting &kugar; and &kudesigner; + +The &kugar; program takes two commandline arguments: + + + +kugar + + + + + + + + + +For example, kugar +sample1.kdf +sample1.ktf + + + +The &kudesigner; program can be started with no arguments +or with a report template file name as an argument: + + +kudesigner + +template.ktf + + + +
    diff --git a/doc/kugar/template-elements.docbook b/doc/kugar/template-elements.docbook new file mode 100644 index 000000000..d48bb2a72 --- /dev/null +++ b/doc/kugar/template-elements.docbook @@ -0,0 +1,2493 @@ + + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +<sgmltag class="element">KugarTemplate</sgmltag> template +elements + + + +
    + +Section bands +Section elements + + + + +ReportHeader +Line + + +PageHeader +Label + + +DetailHeader +Field + + +Detail +CalculatedField + + +DetailFooter +Special + + +PageFooter +Page Footer + + +ReportFooter +Report Footer + + + + + + + +<sgmltag class="element">ReportHeader</sgmltag> and <sgmltag +class="element">ReportFooter</sgmltag> sections + + +The ReportHeader and ReportFooter elements define report sections +that are usually printed at the beginning and end of the report. + + + +<!ELEMENT ReportHeader (Line*, Label*, Special*)> +<!ATTLIST ReportHeader + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + + +<!ELEMENT ReportFooter (Line*, Label*, Special*, CalculatedField*)> +<!ATTLIST ReportFooter + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + + + + +Attributes + + + + +Height + +Sets the height of the report section. If you don't want +this section, set this value to 0. + + + + + +PrintFrequency + + +Set the print frequency of the section. + + + + + + +Value +Print Frequency + + + + +0 +First Page + + +1 +Every Page + + +2 +Last Page + + + + + + + + + + + + + +<sgmltag class="element">PageHeader</sgmltag> and <sgmltag +class="element">PageFooter</sgmltag> sections + + +The PageHeader and PageFooter elements define report sections +that are usually printed on every page of the report. + + + +<!ELEMENT PageHeader (Line*, Label*, Special*)> +<!ATTLIST PageHeader + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + + +<!ELEMENT PageFooter (Line*, Label*, Special*)> +<!ATTLIST PageFooter + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + + + + +Attributes + + + + +Height + +Sets the height of the report section. If you don't want +this section, set this value to 0. + + + + + +PrintFrequency + + +Set the print frequency of the section. + + + + + + +Value +Print Frequency + + + + +0 +First Page + + +1 +Every Page + + +2 +Last Page + + + + + + + + + + + + + + +<sgmltag class="element">DetailHeader</sgmltag> and <sgmltag +class="element">DetailFooter</sgmltag> sections + + +The DetailHeader and DetailFooter elements define report sections +that are printed before and after details of a given level and below on the report. + + + +<!ELEMENT DetailHeader (Line*, Label*, Special*)> +<!ATTLIST DetailHeader + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + + +<!ELEMENT DetailFooter (Line*, Label*, Special*)> +<!ATTLIST DetailFooter + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + + + + +Attributes + + + + +Height + +Sets the height of the report section. If you don't want +this section, set this value to 0. + + + + + +Level + + +Set the hierarchy level of the section. Sections with higher levels will be printed +before sections with lower ones. Level can be any number beginning from 0. + + + + + + + + + + + + +<sgmltag class="element">Detail</sgmltag> section + + +The Detail element defines the report +section that contains the report data. The report can have multiple details, +which are accessed by the detail's Level attribute. + + + +<!ELEMENT Detail (Line*, Label*, Special*, Field*)> +<!ATTLIST Detail + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + + + +Attributes + + + + +Height + +Sets the height of the report section. If you don't want +this section, set this value to 0. + + + + +Level + + +Set the hierarchy level of the section. Sections with higher levels will be printed +before sections with lower ones. Level can be any number beginning from 0. This is an attribute +of a row element in a data file. + + + + + + + + + + + + +<sgmltag class="element">Line</sgmltag> + + +The Line element defines a report +object used to draw lines on a report. + + + +<!ELEMENT Line EMPTY> +<!ATTLIST Line + X1 CDATA #REQUIRED + Y1 CDATA #REQUIRED + X2 CDATA #REQUIRED + Y2 CDATA #REQUIRED + Width CDATA #REQUIRED + Color CDATA #REQUIRED + Style CDATA #REQUIRED> + + + + +Attributes + + + + +X1 + + +Sets the starting x coordinate (relative to the section's upper left corner) for the line. + + + + + +Y1 + + +Sets the starting y coordinate (relative to the section's upper left corner) for the line. + + + + + +X2 + + +Sets the ending x coordinate (relative to the section's upper left corner) for the line. + + + + + +Y2 + + +Sets the ending y coordinate (relative to the section's upper left corner) for the line. + + + + + +Width + + +Sets the width of the line. + + + + + +Color + + +Sets the color of the line. The color is defined as an RGB (Red Green Blue) value +(r,g,b). r, g and b must be in the range 0..255. + + + + + +Style + + +Sets the drawing style for the line. + + + + + + +Value +Line Style + + + + + +0 +No Pen + + +1 +Solid + + +2 +Dash + + +3 +Dot + + +4 +Dash Dot + + +5 +Dash Dot Dot + + + + + + + + + + + + + +<sgmltag class="element">Label</sgmltag> + + +The Label element defines a report +object used to draw fixed text on a report. + + + + <!ELEMENT Label EMPTY> + <!ATTLIST Label + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED> + + + + +Attributes + + + + +Text + + +Sets the label's text. + + + + + +X + + +Sets the x coordinate (relative to the section's upper left corner) for positioning the label. + + + + + +Y + + +Sets the y coordinate (relative to the section's upper left corner) for positioning the label. + + + + + +Width + + +Sets the width of the label. + + + + + +Height + + +Sets the height of the label. + + + + + +BackgroundColor + + +Sets the background color of the label. The color is defined as an +RGB (Red Green Blue) value (r,g,b). r, g and b must be in the range 0..255. + + + + + +ForegroundColor + + +Sets the foreground color of the label. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderColor + + +Sets the border color of the label. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderWidth + + +Sets the border width for the label. + + + + + +BorderStyle + + +Sets the border style for the label. + + + + + + +Value +Border Style + + + + +0 +None + + +1 +Solid + + +2 +Dash + + +3 +Dot + + +4 +Dash Dot + + +5 +Dash Dot Dot + + + + + + + + +FontFamily + + +Sets the font family for the label's text. + + + + + + +FontSize + + +Sets the font size for the label's text. + + + + + +FontWeight + + +Sets the font weight for the label's text. + + + + + + +Value +Font Weight + + + + +25 +Light + + +50 +Normal + + +63 +Demi Bold + + +75 +Bold + + +87 +Black + + + + + + + + + +FontItalic + + +Sets the font italic flag for the label's text. + + + + + + +Value +Italic + + + + +0 +False + + +1 +True + + + + + + + + + +HAlignment + + +Sets the label's horizontal text alignment. + + + + + + +Value +Horizontal Alignment + + + + +0 +Left + + +1 +Center + + +2 +Right + + + + + + + + +VAlignment + + +Sets the label's vertical text alignment. + + + + + + +Value +Vertical Alignment + + + + +0 +Top + + +1 +Middle + + +2 +Bottom + + + + + + + + +WordWrap + + +Sets the word wrap flag for the label's text. + + + + + + +Value +Word Wrap + + + + +0 +False + + +1 +True + + + + + + + + + + + + + + +<sgmltag class="element">Field</sgmltag> + + +The Field element defines a report +object used to draw data on a report. + + + +<!ELEMENT Field EMPTY> +<!ATTLIST Field + Field CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DataType CDATA #REQUIRED + DateFormat CDATA #REQUIRED + Precision CDATA #REQUIRED + Currency CDATA #REQUIRED + NegValueColor CDATA #REQUIRED + CommaSeparator CDATA #REQUIRED> + + + + +Attributes + + + + +Field + + +Sets the data field for the object. This is an attribute of a row element in a data file. + + + + + +Text + + +Not used. + + + + + +X + + +Sets the x coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Y + + +Sets the y coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Width + + +Sets the width of the field. + + + + + +Height + + +Sets the height of the field. + + + + + +BackgroundColor + + +Sets the background color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +ForegroundColor + + +Sets the foreground color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderColor + + +Sets the border color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderWidth + + +Sets the border width for the field. + + + + + +BorderStyle + + +Sets the border style for the field. + + + + + + +Value +Border Style + + + + +0 +None + + +1 +Solid + + +2 +Dash + + +3 +Dot + + +4 +Dash Dot + + +5 +Dash Dot Dot + + + + + + + + +FontFamily + + +Sets the font family for the field's text. + + + + + + +FontSize + + +Sets the font size for the field's text. + + + + + +FontWeight + + +Sets the font weight for the field's text. + + + + + + +Value +Font Weight + + + + +25 +Light + + +50 +Normal + + +63 +Demi Bold + + +75 +Bold + + +87 +Black + + + + + + + + + +FontItalic + + +Sets the font italic flag for the field's text. + + + + + + +Value +Italic + + + + +0 +False + + +1 +True + + + + + + + + + +HAlignment + + +Sets the field's horizontal text alignment. + + + + + + +Value +Horizontal Alignment + + + + +0 +Left + + +1 +Center + + +2 +Right + + + + + + + + +VAlignment + + +Sets the field's vertical text alignment + + + + + + +Value +Vertical Alignment + + + + +0 +Top + + +1 +Middle + + +2 +Bottom + + + + + + + + +WordWrap + + +Sets the word wrap flag for the field's text. + + + + + + +Value +Word Wrap + + + + +0 +False + + +1 +True + + + + + + + + + +DataType + + +Sets the field's data type. + + + + + + +Value +Data Type + + + + +0 +String + + +1 +Integer + + +2 +Float + + +3 +Date + + +4 +Currency + + + + + + + + +DateFormat + + +Sets the field's date format. For this to work, the format of the date +from the data document must be in the format mm/dd/yyyy or mm-dd-yyyy, +otherwise the original date format is used. If the data type is other than +date, set this to 0. + + + + + + +Value +Date Format + + + + +0 +m/d/yy + + +1 +m-d-yy + + +2 +mm/dd/yy + + +3 +mm-dd-yy + + +4 +m/d/yyyy + + +5 +m-d-yyyy + + +6 +mm/dd/yyyy + + +7 +mm-dd-yyyy + + +8 +yyyy/m/d + + +9 +yyyy-m-d + + +10 +dd.mm.yy + + +11 +dd.mm.yyyy + + + + + + + + +Precision + + +Sets the field's numeric precision. If the data type is other than a numeric +type, set this to 0. + + + + + +Currency + + +Sets the field's currency symbol If the data type is other than currency, set +this to 36 ($). The value is a number +representing a Unicode character. + + + + + +NegValueColor + + +Sets the color for negative numeric values. The color is defined as an +RGB (Red Green Blue) value (r,g,b). r, g and b must be in the range 0..255. If data is +other than a numeric type, set to 255,0,0. + + + + + +CommaSeparator + + +Sets whether commas are used in numeric fields. If the data type is other than +a numeric type, set this to 0. + + + + + + +Value +Comma Separator + + + + +0 +False + + +1 +True + + + + + + + + + + + + + + +<sgmltag class="element">CalculatedField</sgmltag> + + +The CalculatedField element defines a report +object used to draw calculated values on a report. + + + +<!ELEMENT CalculatedField EMPTY> +<!ATTLIST CalculatedField + CalculationType CDATA #REQUIRED + Field CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DataType CDATA #REQUIRED + DateFormat CDATA #REQUIRED + Precision CDATA #REQUIRED + Currency CDATA #REQUIRED + NegValueColor CDATA #REQUIRED + CommaSeparator CDATA #REQUIRED> + + + + +Attributes + + + + +CalculationType + + +Sets the calculation type for the field. + + + + + + +Value +Calculation + + + + +0 +Count + + +1 +Sum + + +2 +Average + + +3 +Variance + + +4 +Std Deviation + + + + + + + + + +Field + + +Sets the data field for the object. This is an attribute of a row element in a data file. + + + + + +Text + + +Not used. + + + + + +X + + +Sets the x coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Y + + +Sets the y coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Width + + +Sets the width of the field. + + + + + +Height + + +Sets the height of the field. + + + + + +BackgroundColor + + +Sets the background color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +ForegroundColor + + +Sets the foreground color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderColor + + +Sets the border color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderWidth + + +Sets the border width for the field. + + + + + +BorderStyle + + +Sets the border style for the field. + + + + + + +Value +Border Style + + + + +0 +None + + +1 +Solid + + +2 +Dash + + +3 +Dot + + +4 +Dash Dot + + +5 +Dash Dot Dot + + + + + + + + +FontFamily + + +Sets the font family for the field's text. + + + + + + +FontSize + + +Sets the font size for the field's text. + + + + + +FontWeight + + +Sets the font weight for the field's text. + + + + + + +Value +Font Weight + + + + +25 +Light + + +50 +Normal + + +63 +Demi Bold + + +75 +Bold + + +87 +Black + + + + + + + + + +FontItalic + + +Sets the font italic flag for the field's text. + + + + + + +Value +Italic + + + + +0 +False + + +1 +True + + + + + + + + + +HAlignment + + +Sets the field's horizontal text alignment. + + + + + + +Value +Horizontal Alignment + + + + +0 +Left + + +1 +Center + + +2 +Right + + + + + + + + +VAlignment + + +Sets the field's vertical text alignment. + + + + + + +Value +Vertical Alignment + + + + +0 +Top + + +1 +Middle + + +2 +Bottom + + + + + + + + +WordWrap + + +Sets the word wrap flag for the field's text. + + + + + + +Value +Word Wrap + + + + +0 +False + + +1 +True + + + + + + + + +DataType + + +Sets the field's data type. + + + + + + +Value +Data Type + + + + +0 +String + + +1 +Integer + + +2 +Float + + +3 +Date + + +4 +Currency + + + + + + + + +DateFormat + + +Sets the field's date format. For this to work, the format of the date +from the data document must be in the format mm/dd/yyyy or mm-dd-yyyy, +otherwise the original date format is used. If the data type is other than +date, set this to 0. + + + + + + +Value +Date Format + + + + +0 +m/d/yy + + +1 +m-d-yy + + +2 +mm/dd/yy + + +3 +mm-dd-yy + + +4 +m/d/yyyy + + +5 +m-d-yyyy + + +6 +mm/dd/yyyy + + +7 +mm-dd-yyyy + + +8 +yyyy/m/d + + +9 +yyyy-m-d + + +10 +dd.mm.yy + + +11 +dd.mm.yyyy + + + + + + + + +Precision + + +Sets the field's numeric precision. If the data type is other than a numeric +type, set this to 0. + + + + + +Currency + + +Sets the field's currency symbol. If the data type is other than currency, set +this to 36 ($). The value is a number +representing an unicode character. + + + + + +NegValueColor + + +Sets the color for negative numeric values. The color is defined as an +RGB (Red Green Blue) value (r,g,b). r, g and b must be in the range 0..255. If data is +other than a numeric type, set to 255,0,0. + + + + + +CommaSeparator + + +Sets whether commas are used in numeric fields. If the data type is other than +a numeric type, set this to 0. + + + + + + +Value +Comma Separator + + + + +0 +False + + +1 +True + + + + + + + + + + + + + + + +<sgmltag class="element">Special</sgmltag> + + +The Special element defines a report +object used to draw page numbers and the current date on a report. + + + +<!ELEMENT Special EMPTY> +<!ATTLIST Special + Type CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DateFormat CDATA #REQUIRED> + + + + +Attributes + + + + +Type + + +Sets the type of special object. + + + + + + +Value +Type + + + + +0 +Current Date + + +1 +Page Number + + + + + + + + +Text + + +Not used. + + + + + +X + + +Sets the x coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Y + + +Sets the y coordinate (relative to the section's upper left corner) for positioning the field. + + + + + +Width + + +Sets the width of the field. + + + + + +Height + + +Sets the height of the field. + + + + + +BackgroundColor + + +Sets the background color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +ForegroundColor + + +Sets the foreground color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + + +BorderColor + + +Sets the border color of the field. The color is defined as an RGB (Red Green Blue) +value (r,g,b). r, g and b must be in the range 0..255. + + + + + +BorderWidth + + +Sets the border width for the field. + + + + + +BorderStyle + + +Sets the border style for the field. + + + + + + +Value +Border Style + + + + +0 +None + + +1 +Solid + + +2 +Dash + + +3 +Dot + + +4 +Dash Dot + + +5 +Dash Dot Dot + + + + + + + + +FontFamily + + +Sets the font family for the field's text. + + + + + + +FontSize + + +Sets the font size for the field's text. + + + + + +FontWeight + + +Sets the font weight for the field's text. + + + + + + +Value +Font Weight + + + + +25 +Light + + +50 +Normal + + +63 +Demi Bold + + +75 +Bold + + +87 +Black + + + + + + + + + +FontItalic + + +Sets the font italic flag for the field's text. + + + + + + +Value +Italic + + + + +0 +False + + +1 +True + + + + + + + + + +HAlignment + + +Sets the field's horizontal text alignment. + + + + + + +Value +Horizontal Alignment + + + + +0 +Left + + +1 +Center + + +2 +Right + + + + + + + + +VAlignment + + +Sets the field's vertical text alignment. + + + + + + +Value +Vertical Alignment + + + + +0 +Top + + +1 +Middle + + +2 +Bottom + + + + + + + + +WordWrap + + +Sets the word wrap flag for the field's text. + + + + + + +Value +Word Wrap + + + + +0 +False + + +1 +True + + + + + + + + +DateFormat + + +Sets the field's date format. For this to work, the format of the date +from the data document must be in the format mm/dd/yyyy or mm-dd-yyyy, +otherwise the original date format is used. If the data type is other than +date, set this to 0. + + + + + + +Value +Date Format + + + + +0 +m/d/yy + + +1 +m-d-yy + + +2 +mm/dd/yy + + +3 +mm-dd-yy + + +4 +m/d/yyyy + + +5 +m-d-yyyy + + +6 +mm/dd/yyyy + + +7 +mm-dd-yyyy + + +8 +yyyy/m/d + + +9 +yyyy-m-d + + +10 +dd.mm.yy + + +11 +dd.mm.yyyy + + + + + + + + +Precision + + +Sets the field's numeric precision. If the data type is other than a numeric +type, set this to 0. + + + + + + + + + + + + + + diff --git a/doc/kugar/template.docbook b/doc/kugar/template.docbook new file mode 100644 index 000000000..f5299fcea --- /dev/null +++ b/doc/kugar/template.docbook @@ -0,0 +1,357 @@ + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +<sgmltag class="element">KugarTemplate</sgmltag> element + + +The KugarTemplate element defines +report attributes relating to page size, orientation, and margins. + + + +<!ELEMENT KugarTemplate (ReportHeader, PageHeader, DetailHeader*, Detail*, DetailFooter*, PageFooter, ReportFooter)> +<!ATTLIST KugarTemplate +PageSize CDATA #REQUIRED +PageOrientation CDATA #REQUIRED +TopMargin CDATA #REQUIRED +BottomMargin CDATA #REQUIRED +LeftMargin CDATA #REQUIRED +RightMargin CDATA #REQUIRED> + + + + + +Elements + + + + +The KugarTemplate element contains +the following elements: + + + + +ReportHeader + + +The ReportHeader element defines +report sections that are usually printed at the beginning of the report. + + + + + +PageHeader + + +The PageHeader element defines report +sections that are usually printed at the top of every page of the +report. + + + + + +DetailHeader + + +The DetailHeader element defines report +sections that are printed before details of a given level on the report. + + + + + +Detail + + +The Detail element defines the report +section that contains the report data. The report can have an unlimited number +of details. + + + + + +DetailFooter + + +The DetailFooter element defines report +sections that are printed after details of a given level and below on the report. + + + + + +PageFooter + + +The PageFooter element defines report +sections that are usually printed at the end of every page in the +report. + + + + + +ReportFooter + + +The ReportFooter element defines report +sections that are usually printed at the end of the report. + + + + + + + + + + + +Attributes + + + + +PageSize + + +Sets the size of the report page. The following values are available: + + + + +
    + +Value +Page Size + + + + + +0 +A4 + + +1 +B5 + + +2 +Letter + + +3 +Legal + + +4 +Executive + + +5 +A0 + + +6 +A1 + + +7 +A2 + + +8 +A3 + + +9 +A5 + + +10 +A6 + + +11 +A7 + + +12 +A8 + + +13 +A9 + + +14 +B0 + + +15 +B1 + + +16 +B10 + + +17 +B2 + + +18 +B3 + + +19 +B4 + + +20 +B6 + + +21 +B7 + + +22 +B8 + + +23 +B9 + + +24 +C5E + + +25 +Comm10E + + +26 +DLE + + +27 +Folio + + +28 +Ledger + + +29 +Tabloid + + +30 +NPageSize + + + + + + + + + + +PageOrientation + + +Sets the report page orientation. + + + + + + +Value +Orientation + + + + +0 +Portrait + + +1 +Landscape + + + + + + + + +TopMargin + + +Sets the top margin of the report page. + + + + + +BottomMargin + + +Sets the bottom margin of the report page. + + + + + +LeftMargin + + +Sets the left margin of the report page. + + + +RightMargin + + +Sets the right margin of the report page. + + + + + + + + diff --git a/doc/kugar/templatedtd.docbook b/doc/kugar/templatedtd.docbook new file mode 100644 index 000000000..70d75015b --- /dev/null +++ b/doc/kugar/templatedtd.docbook @@ -0,0 +1,188 @@ + + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +The KugarTemplate Document Type Definition + + + +<?xml version="1.0" encoding="UTF-8"?> + +<!DOCTYPE KugarTemplate [ + <!ELEMENT KugarTemplate (ReportHeader, PageHeader, DetailHeader*, Detail*, DetailFooter*, PageFooter, ReportFooter)> + <!ATTLIST KugarTemplate + PageSize CDATA #REQUIRED + PageOrientation CDATA #REQUIRED + TopMargin CDATA #REQUIRED + BottomMargin CDATA #REQUIRED + LeftMargin CDATA #REQUIRED + RightMargin CDATA #REQUIRED> + + <!ELEMENT ReportHeader (Line*, Label*, Special*)> + <!ATTLIST ReportHeader + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + <!ELEMENT PageHeader (Line*, Label*, Special*)> + <!ATTLIST PageHeader + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + <!ELEMENT DetailHeader (Line*, Label*, Special*)> + <!ATTLIST DetailHeader + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + <!ELEMENT Detail (Line*, Label*, Special*, Field*)> + <!ATTLIST Detail + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + <!ELEMENT DetailFooter (Line*, Label*, Special*)> + <!ATTLIST DetailFooter + Height CDATA #REQUIRED + Level CDATA #REQUIRED> + + <!ELEMENT PageFooter (Line*, Label*, Special*)> + <!ATTLIST PageFooter + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + <!ELEMENT ReportFooter (Line*, Label*, Special*, CalculatedField*)> + <!ATTLIST ReportFooter + Height CDATA #REQUIRED + PrintFrequency CDATA #REQUIRED> + + <!ELEMENT Line EMPTY> + <!ATTLIST Line + X1 CDATA #REQUIRED + Y1 CDATA #REQUIRED + X2 CDATA #REQUIRED + Y2 CDATA #REQUIRED + Width CDATA #REQUIRED + Color CDATA #REQUIRED + Style CDATA #REQUIRED> + + <!ELEMENT Label EMPTY> + <!ATTLIST Label + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED> + + <!ELEMENT Field EMPTY> + <!ATTLIST Field + Field CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DataType CDATA #REQUIRED + DateFormat CDATA #REQUIRED + Precision CDATA #REQUIRED + Currency CDATA #REQUIRED + NegValueColor CDATA #REQUIRED + CommaSeparator CDATA #REQUIRED> + + <!ELEMENT CalculatedField EMPTY> + <!ATTLIST CalculatedField + CalculationType CDATA #REQUIRED + Field CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DataType CDATA #REQUIRED + DateFormat CDATA #REQUIRED + Precision CDATA #REQUIRED + Currency CDATA #REQUIRED + NegValueColor CDATA #REQUIRED + CommaSeparator CDATA #REQUIRED> + + <!ELEMENT Special EMPTY> + <!ATTLIST Special + Type CDATA #REQUIRED + Text CDATA #REQUIRED + X CDATA #REQUIRED + Y CDATA #REQUIRED + Width CDATA #REQUIRED + Height CDATA #REQUIRED + BackgroundColor CDATA #REQUIRED + ForegroundColor CDATA #REQUIRED + BorderColor CDATA #REQUIRED + BorderWidth CDATA #REQUIRED + BorderStyle CDATA #REQUIRED + FontFamily CDATA #REQUIRED + FontSize CDATA #REQUIRED + FontWeight CDATA #REQUIRED + FontItalic CDATA #REQUIRED + HAlignment CDATA #REQUIRED + VAlignment CDATA #REQUIRED + WordWrap CDATA #REQUIRED + DateFormat CDATA #REQUIRED> + ]> + +
    diff --git a/doc/kugar/tut_edit_height.png b/doc/kugar/tut_edit_height.png new file mode 100644 index 000000000..da4618f77 Binary files /dev/null and b/doc/kugar/tut_edit_height.png differ diff --git a/doc/kugar/tut_empty_report.png b/doc/kugar/tut_empty_report.png new file mode 100644 index 000000000..7effe6dd4 Binary files /dev/null and b/doc/kugar/tut_empty_report.png differ diff --git a/doc/kugar/tut_file_new.png b/doc/kugar/tut_file_new.png new file mode 100644 index 000000000..a06492e3e Binary files /dev/null and b/doc/kugar/tut_file_new.png differ diff --git a/doc/kugar/tut_rep_complete.png b/doc/kugar/tut_rep_complete.png new file mode 100644 index 000000000..1ac79a225 Binary files /dev/null and b/doc/kugar/tut_rep_complete.png differ diff --git a/doc/kugar/tut_rep_generated.png b/doc/kugar/tut_rep_generated.png new file mode 100644 index 000000000..7b8be5490 Binary files /dev/null and b/doc/kugar/tut_rep_generated.png differ diff --git a/doc/kugar/tut_rep_look1.png b/doc/kugar/tut_rep_look1.png new file mode 100644 index 000000000..1fad4189d Binary files /dev/null and b/doc/kugar/tut_rep_look1.png differ diff --git a/doc/kugar/tut_rep_look2.png b/doc/kugar/tut_rep_look2.png new file mode 100644 index 000000000..e01a61fb5 Binary files /dev/null and b/doc/kugar/tut_rep_look2.png differ diff --git a/doc/kugar/tut_set_level.png b/doc/kugar/tut_set_level.png new file mode 100644 index 000000000..9a364a24e Binary files /dev/null and b/doc/kugar/tut_set_level.png differ diff --git a/doc/kugar/tutorial.docbook b/doc/kugar/tutorial.docbook new file mode 100644 index 000000000..67cd0f42c --- /dev/null +++ b/doc/kugar/tutorial.docbook @@ -0,0 +1,313 @@ + + + + + +Alexander +Dymo + +
    cloudtemple@mksat.net
    +
    +
    + +Phil +Thompson + +
    phil@river-bank.demon.co.uk
    +
    +
    + +
    +
    +Tutorial + +This tutorial attempts to be a brief introduction to Kugar. + +You will create a sample report template with &kudesigner;, +a sample data file and finally generate a complete report. + +The source code for sample templates and data files can be found +in sample1.ktf and sample1.kdf +that are distributed with &kugar;. + + + +Creating the report template with &kudesigner; + + +Run Kugar Designer by typing kudesigner in the shell. + + + +After you start the designer, choose File|New +and set the page size to Letter and paper orientation to +Landscape. Set the left and right margins to 48, top +and bottom margins to 40. All dimensions in &kudesigner; (page +margins, sizes, positions, &etc;) are measured in millimeters. + + + + + + +New Report dialog + + + + + + +A new report is now created and all buttons on the Items Toolbar +and Sections Toolbar are now enabled (the corresponding +menu items from Items and Sections are also enabled). + + + + + + +Empty Report window + + + + + +Now it is the time to add some sections to the report and determine +their sizes. We will add report header and footer, +page header and footer and a single +detail section. Report headers and footers are printed on the +first page and on the last page of the report before and after any other report data accordingly. +Report footers are good places for calculated fields. +Page headers and footers are printed at the top and bottom of each page. +Our report will have one detail section with level 0. This means that all our data rows +have identical structure (&ie; fields). If the data structure is more complex or it is +organized according to a master-detail relationship, more detail levels should be created. +See sample3.ktf and sample3.kdf for an example +of how that can be done. +Refer to the template elements descriptions +for additional information. + + +Sections are added by using Sections menu +or a Sections Toolbar. Now add a report header and footer, +a page header and footer and then a detail section. +When adding a detail section, set +its level to 0 as shown on the screenshot below. + + + + + + +Setting the detail level + + + + + + +Our report should now look like this one in the screenshot. + + + + + + +Report with sections + + + + + + +All our sections have a predefined height - 50mm. Let's change it. +To do this &RMB; click on the Report Header section or click the Edit Properties +button on the Edit Toolbar and then choose a section. +The Properties window should be shown. + + + + + + +Height of the section editing + + + + + + +Now set the Report Header's height to 70. Let's perform that procedure +for all other sections. Set the Page Header's height to 45 and the Detail's to 30. +The Page and Report Footers should be 32 mm in height. + + + +A report template with properly sized sections is ready to be filled with +report items. + + + + + + +Report with sized sections + + + + + + +You can now add items to the sections on the report. Five different types of +items can be added to the report. Label +is a rectangular area that can have borders and can be filled by +any kind of textual data. The Label's foreground and background colors, +as well as fonts, can be changed. Border line types and line colors are also +customizable. Fields can be placed +on to a detail section. Fields represent data fields; their values +will be collected from a data file while generating a report. +Counts, sums, averages, &etc; for field values can be printed on the report +by means of Calculated Fields. +Specials are labels with predefined text, +such as current date or page number. The general report appearance can be refined +with Lines. + + + +To add a report item click the corresponding item button on the Items Toolbar +and place (click) it on the section. The chosen item will be placed on the selected section +with the upper left corner at the given coordinates. Other properties are set to default +values and can be changed with the Report Item Options dialog (the same way +we used to change the section's height). + + + +So, let's add labels to the report header and page header as shown on the screenshot below. +Note that the Mutiny Bay Software label has its BorderStyle +and BorderWidth set to 0 and Software Inventory Report - 1mm. +Any colors are set as a combination of three values (RGB - red,green,blue) separated by commas. + + + +We will also add field elements to the detail section. Just assume we have four fields +- title, version, platform and copies. So, four Field elements should be placed and +their Field properties set. Note that Text +property is automatically set to [field_name]. + + + +Our page footer is a good place to show the current date and page number, so add two +special fields and set their Type properties to 0 and 1. +A special with Type=0 will represent date and one with Type=1 - page number. Note that +special's Text property is changed automatically. + + + +The last element to be placed is a Calculated Field for the copies +field. To acquire a sum (copies) set the calculated field's Field property +to copies and CalculationType to 1 (sum function). + + + +Finally, our report template should look like this: + + + + + + +Complete report + + + + + + + + + + +Creating the report data file + + +Generally speaking, data files may be created in several ways. Some will use xsl transformation tables +to generate proper &XML; from another &XML; document (like a &kspread; spreadsheet); others will use +their own program to fetch data from a database and fill the data file. In this tutorial we will +simply create it by hand. The source code for the example can be found in file sample1.kdf +or copied from the example below. + + + +<?xml version=1.0 encoding=UTF-8?> + +<!DOCTYPE KugarData [ + <!ELEMENT KugarData (Row* )> + <!ATTLIST KugarData + Template CDATA #REQUIRED> + + <!ELEMENT Row EMPTY> + <!ATTLIST Row + level CDATA #REQUIRED + title CDATA #REQUIRED + version CDATA #REQUIRED + platform CDATA #REQUIRED + copies CDATA #REQUIRED> +]> + +<KugarData Template="sample1.ktf"> + <Row level="0" title=" BRU" version="15.0" platform="x86" copies="1"/> + <Row level="0" title=" Caldera Open Linux" version="2.2" platform="x86" copies="3"/> + <Row level="0" title=" K Desktop" version="1.1.1" platform="x86" copies="1"/> + <Row level="0" title=" Netscape Communicator" version="4.6" platform="x86" copies="10"/> + <Row level="0" title=" Redhat Linux" version="5.0" platform="x86" copies="11"/> + <Row level="0" title=" Redhat Linux" version="5.1" platform="x86" copies="12"/> + <Row level="0" title=" Redhat Linux" version="5.2" platform="x86" copies="14"/> + <Row level="0" title=" Redhat Linux" version="6.0" platform="x86" copies="15"/> + <Row level="0" title=" Star Office" version="5.0" platform="x86" copies="1"/> + <Row level="0" title=" Star Office" version="5.1" platform="x86" copies="3"/> + <Row level="0" title=" Microsoft Windows NT" version="3.1" platform="x86" copies="1"/> + <Row level="0" title=" Microsoft Windows NT" version="3.51" platform="x86" copies="1"/> + <Row level="0" title=" Microsoft Windows NT" version="4.0" platform="x86" copies="1"/> + <Row level="0" title=" Microsoft Windows NT" version="5.0" platform="x86" copies="1"/> + <Row level="0" title=" Sun Solaris" version="2.5" platform="Sparc" copies="1"/> +</KugarData> + + + + + +Generating the report + + +At this moment we have a report template (sample1.ktf) and +a report data file (sample1.kdf). + + +To generate a report, type the following command in the shell: +kugar + + + + +This will bring up a &kugar; shell window with the report generated. + + + + + + +Generated report + + + + + + + +
    diff --git a/doc/kword/ChooseTempDia.png b/doc/kword/ChooseTempDia.png new file mode 100644 index 000000000..10852c0e2 Binary files /dev/null and b/doc/kword/ChooseTempDia.png differ diff --git a/doc/kword/Makefile.am b/doc/kword/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kword/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kword/Tut1.png b/doc/kword/Tut1.png new file mode 100644 index 000000000..f2203f595 Binary files /dev/null and b/doc/kword/Tut1.png differ diff --git a/doc/kword/Tut11a.png b/doc/kword/Tut11a.png new file mode 100644 index 000000000..349690bb1 Binary files /dev/null and b/doc/kword/Tut11a.png differ diff --git a/doc/kword/Tut11b.png b/doc/kword/Tut11b.png new file mode 100644 index 000000000..7d8ae6d0d Binary files /dev/null and b/doc/kword/Tut11b.png differ diff --git a/doc/kword/Tut13.png b/doc/kword/Tut13.png new file mode 100644 index 000000000..0af51f9c9 Binary files /dev/null and b/doc/kword/Tut13.png differ diff --git a/doc/kword/Tut13a.png b/doc/kword/Tut13a.png new file mode 100644 index 000000000..82a8cf935 Binary files /dev/null and b/doc/kword/Tut13a.png differ diff --git a/doc/kword/Tut14.png b/doc/kword/Tut14.png new file mode 100644 index 000000000..44101725f Binary files /dev/null and b/doc/kword/Tut14.png differ diff --git a/doc/kword/Tut14a.png b/doc/kword/Tut14a.png new file mode 100644 index 000000000..8754ea732 Binary files /dev/null and b/doc/kword/Tut14a.png differ diff --git a/doc/kword/Tut14b.png b/doc/kword/Tut14b.png new file mode 100644 index 000000000..01863a1fb Binary files /dev/null and b/doc/kword/Tut14b.png differ diff --git a/doc/kword/Tut15.png b/doc/kword/Tut15.png new file mode 100644 index 000000000..4c685c187 Binary files /dev/null and b/doc/kword/Tut15.png differ diff --git a/doc/kword/Tut15b.png b/doc/kword/Tut15b.png new file mode 100644 index 000000000..77ec43309 Binary files /dev/null and b/doc/kword/Tut15b.png differ diff --git a/doc/kword/Tut16.png b/doc/kword/Tut16.png new file mode 100644 index 000000000..d753485ab Binary files /dev/null and b/doc/kword/Tut16.png differ diff --git a/doc/kword/Tut18.png b/doc/kword/Tut18.png new file mode 100644 index 000000000..01863a1fb Binary files /dev/null and b/doc/kword/Tut18.png differ diff --git a/doc/kword/Tut19.png b/doc/kword/Tut19.png new file mode 100644 index 000000000..c997e2731 Binary files /dev/null and b/doc/kword/Tut19.png differ diff --git a/doc/kword/Tut2.png b/doc/kword/Tut2.png new file mode 100644 index 000000000..06844d062 Binary files /dev/null and b/doc/kword/Tut2.png differ diff --git a/doc/kword/Tut21.png b/doc/kword/Tut21.png new file mode 100644 index 000000000..48948a3ea Binary files /dev/null and b/doc/kword/Tut21.png differ diff --git a/doc/kword/Tut22.png b/doc/kword/Tut22.png new file mode 100644 index 000000000..191b2cb15 Binary files /dev/null and b/doc/kword/Tut22.png differ diff --git a/doc/kword/Tut3.png b/doc/kword/Tut3.png new file mode 100644 index 000000000..64ed92984 Binary files /dev/null and b/doc/kword/Tut3.png differ diff --git a/doc/kword/Tut4.png b/doc/kword/Tut4.png new file mode 100644 index 000000000..a75b86435 Binary files /dev/null and b/doc/kword/Tut4.png differ diff --git a/doc/kword/Tut7.png b/doc/kword/Tut7.png new file mode 100644 index 000000000..8c12d42ee Binary files /dev/null and b/doc/kword/Tut7.png differ diff --git a/doc/kword/Tut8.png b/doc/kword/Tut8.png new file mode 100644 index 000000000..fc9d6d1e3 Binary files /dev/null and b/doc/kword/Tut8.png differ diff --git a/doc/kword/a11y.docbook b/doc/kword/a11y.docbook new file mode 100644 index 000000000..bcf95101a --- /dev/null +++ b/doc/kword/a11y.docbook @@ -0,0 +1,365 @@ + + + + +Gary +Cramblitt + + + + + +For Users with Disabilities +This section of the documentation discusses accessibility features in &kword; +for users with disabilities. Some of these features apply to &kde; as a whole and are controlled from +&kcontrolcenter;. Some apply to all &koffice; applications, +and some are specific to &kword;. + + +Installing the <command>kdeaccessibility</command> Module +kdeaccessibility + +Most of the features described in this chapter are enabled by installing the +kdeaccessibility module. +The kdeaccessibility module is part of the &kde; project +http://www.kde.org. The kdeaccessibility +package can be obtained from &kde-ftp;, the +main ftp site of the &kde; project. + + +Many distributions offer precompiled binaries on their ftp sites. Please check your distribution's web sites for more information. + +More information about &kde; accessibility can be obtained by +visiting http://accessibility.kde.org/. + + + + +Visual Impairments +Visual Impairments + +&kword; is not usable by totally blind users. It is hoped that +a general screen reader for the blind will be available in future versions of &kde;. + + + +Theming +Theming +For low-sighted or light allergic users, several features are available in the &kcontrolcenter; +Appearance & ThemesTheme Manager, +like high contrast color themes. If you are light allergic, the +HighContrastDark or HighContrastLight themes +may be helpful. If you have difficulty reading small fonts or seeing small icons, the +HighContrastDark-big or HighContrastLight-big +themes will increase the size of text, buttons, and icons. You may also customize +background, colors, fonts, and icons from the same dialog. A set of monochrome icons +is available. + + +If you choose one of the Big themes, you may discover that +some windows are too large to fit your monitor. Purchasing a larger monitor will be helpful. +You can drag the portions of the window not visible into the visible area by +holding down the &Alt; key and dragging with the &LMB; anywhere +within the screen. If you have trouble operating a mouse, you can also move screens by pressing +&Alt;F3. In +the dropdown Windows Operations Menu, choose +Move. +Move the screen with the arrow keys and press &Esc; to finish the move. + + + + + +&kmagnifier; +magnifier +The kdeaccessibility module includes a screen magnifier +application called &kmagnifier;. +If it is installed, you can run it from +K-ButtonUtilities +KMag (Screen Magnifier). + + + + +Text-to-Speech +Text-to-Speech +TTS +The kdeaccessibility module includes a Text-to-Speech +component called KTTS. If KTTS is installed, you can configure &kword; to +speak the text that is under the mouse pointer or speak the text of each +screen widget as it receives focus. Before using this feature, first configure +KTTS. See The KTTS Handbook for details. +To turn on the TTS feature in &kword;, +select SettingsConfigure +&kword;... from the menubar. +This will display a dialog box. +Clicking on TTS will allow you to change +the following: + + + + + + + + + +Speak widget under mouse pointer +When checked, &kword; will speak the text of each widget +as the mouse pointer moves over the widget. + + + +Speak widget with focus +When checked, &kword; will speak the text of each widget +as it receives focus. + + + +Speak tool tips +When checked, &kword; will speak the popup tool tip +for each widget in addition to the text of the widget. + + + +Speak What's This +When checked, &kword; will speak the What's This help +for each widget in addition to the text of the widget. + + + +Say whether disabled +When checked, &kword; will speak the word "disabled" +if the widget is currently disabled (grayed). + + + +Speak accelerators +When checked, &kword; will speak the accelerator +of the widget in addition to the text of the widget. +Accelerators are the underlined letters you see in the text of the +widget. For example, in the main menu, the +Quit menu item +has the "Q" underlined. You can choose it by pressing Q. +To speak the accelerator, check this option and enter the +word you want to speak before the accelerator in the +Prefaced by the word box. In this +example shown above, &kword; will speak "Accelerator Q". + + + +Polling interval +This option determines how often &kword; will +check for a change in the widget under the mouse pointer or +a new focused widget. You should leave this option on the +default setting. + + + + + +If the TTS option does not appear +on this screen, you do not have the KTTS component installed +in your system. + + +Not all widgets are spoken. For example, +the items on the main menubar are not spoken. The text of the +&kword; document window is also not spoken, but see + for another way to speak the document. + + + + + + + +Motor Impairments and Mouseless Operation +Motor Impairments +Mouseless Operation + + +KMouseTool +If you can operate a mouse, but have trouble clicking, the +KMouseTool application may help. Run it from +K-ButtonUtilities +KMouseTool (Automatik Mouse Click). + + + + +XAccess Features +XAccess +Sticky Keys +Slow Keys +Bounce Keys + +The &kcontrolcenter; offers several keyboard features collectively called XAccess. +They include: + + +Sticky Keys +This feature permits operation of meta keys, such as +&Alt;, &Ctrl;, and &Shift; without having to hold the keys down. It is useful +when you can only use one finger or one hand to operate the keyboard. +With Sticky Keys on, press and release a &Alt;, &Ctrl;, or &Shift; key, then +press another key. The result is as if you pressed both keys at once. +Press the &Alt;, &Ctrl;, or &Shift; key again to turn off the sticky key. +Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Modifier Keys. + + + +Slow Keys +This feature is useful if you have hand tremors or difficulty +accurately pressing keys. It prevents +inadvertent key presses by requiring that a key be held down for a minimum +time before it is accepted. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Keyboard Filters. + + + +Bounce Keys +This feature is also useful if you have hand tremors. It prevents +inadvertent repeated key presses by preventing another keystroke for +a certain amount of time. Activate this feature in +K-Button&kcontrolcenter; +Regional & AccessibilityAccessibility +Keyboard Filters. + + + + + + + +Mouse Emulation +Mouse Emulation +Mouse Emulation permits you to move and click the mouse using the keyboard. +Press &Alt;F12 to activate it. Use the arrow keys +to move the mouse pointer to the desired location, and press spacebar +to "click" the mouse. Unfortunately, you cannot use Mouse Emulation to perform +&RMB; clicks or dragging. + + + + +Mouse Navigation +Mouse Navigation +This feature permits you to emulate the mouse using the numeric keypad +of your keyboard. To activate it, go to +K-Button&kcontrolcenter; +PeripheralsMouse +Mouse Navigation. +Check the Move pointer with keyboard (using the num pad) box. When you do this, the other settings will become enabled, and you can customize the keyboard pointer behavior further, if required. + The various keys on the number pad move in the direction you would expect. Note that you can move diagonally as well as up, down, left and right. The 5 key emulates a click to a pointer button, typically &LMB;. You change which button is emulated by using the / key (which makes it &LMB;), +* key (which makes it middle mouse button) and - (which makes it &RMB;). + Using the + emulates a doubleclick to the selected pointer button. You can use the +0 key to emulate holding down the selected pointer button (for easy dragging), +and then use the . to emulate releasing the selected pointer button. + + + + + + + + + + + +Keyboard shortcuts + +&kword; has a number of keyboard shortcuts that will be useful +to users who cannot operate a mouse. See for +details. In addition, the following tips will be useful: + + + + +Several of the functions that can only be performed with the mouse in the +main document panel can be performed with the keyboard in the +Document Structure area. See . +You can switch from the document panel +to the Document Structure area by pressing +&Alt;1. Switch to the +document panel by pressing +&Alt;2. + +Use the Menu key to pop up the context +menu. On most keyboards, the Menu key is on the righthand +side of the keyboard between the &Windows; and &Ctrl; +keys. It has a menu icon on it. + + +When inserting a new frame into the document, you can insert the frame +at the current position of the text caret, instead of positioning it with +the mouse. Just press &Enter; when the crosshairs appear. You can resize +the new frame or change its position by changing the numbers in the +Connect Frame dialog. See + for details. + + +In order to change the properties of a frame or delete a frame, you must first select it. +To do so without using the mouse, position the text caret anywhere inside the frame and +choose EditSelect Frame +from the main menubar. Alternatively, press &Alt;1 to +go to the Document Structure area, +scroll to the desired frame, press the Menu key to pop up the context +menu and choose +Properties +or Delete Frame. + +You cannot use the arrow keys to move the text caret into some +frames within the document panel. To move the caret inside the frame, +press &Alt;1 to +go to the Document Structure area, +scroll to the desired frame, press the Menu key to pop up the context +menu and choose Edit Text. + + + + + + +Resizing panels + +You can move the sizing bar between the Document Structure area +and the main document panel by pressing F8. A sizing icon appears +overtop the sizing bar. Use the arrow keys to move the bar left or right. +Press F8 again or &Esc; when finished sizing. + + + + + +Setting focus to widgets + +Normally, one can use the and &Shift; +to move focus from one widget to the next in any application. However, when focus is on +the main document in &kword;, pressing does not move the focus; instead it inserts +a tabulator into the document. You can set focus to any widget that can receive focus by +pressing &Alt;F8. A small lettered box appears +overtop each widget on the screen that can receive focus. + + + + + + + + +Press the letter to move focus to the corresponding widget. Press +&Alt;F8 again or &Esc; +to abandon moving the focus. + + + + + + + diff --git a/doc/kword/addentry.png b/doc/kword/addentry.png new file mode 100644 index 000000000..0ecdeea3c Binary files /dev/null and b/doc/kword/addentry.png differ diff --git a/doc/kword/addrecord.png b/doc/kword/addrecord.png new file mode 100644 index 000000000..bb9796d00 Binary files /dev/null and b/doc/kword/addrecord.png differ diff --git a/doc/kword/alignBlock.png b/doc/kword/alignBlock.png new file mode 100644 index 000000000..5a2e0b898 Binary files /dev/null and b/doc/kword/alignBlock.png differ diff --git a/doc/kword/alignCenter.png b/doc/kword/alignCenter.png new file mode 100644 index 000000000..07f0e5c9b Binary files /dev/null and b/doc/kword/alignCenter.png differ diff --git a/doc/kword/alignLeft.png b/doc/kword/alignLeft.png new file mode 100644 index 000000000..6aa981854 Binary files /dev/null and b/doc/kword/alignLeft.png differ diff --git a/doc/kword/alignRight.png b/doc/kword/alignRight.png new file mode 100644 index 000000000..c725fc197 Binary files /dev/null and b/doc/kword/alignRight.png differ diff --git a/doc/kword/auto1.png b/doc/kword/auto1.png new file mode 100644 index 000000000..0935d7538 Binary files /dev/null and b/doc/kword/auto1.png differ diff --git a/doc/kword/auto2.png b/doc/kword/auto2.png new file mode 100644 index 000000000..e3c0f22c6 Binary files /dev/null and b/doc/kword/auto2.png differ diff --git a/doc/kword/auto3.png b/doc/kword/auto3.png new file mode 100644 index 000000000..d41beaaa0 Binary files /dev/null and b/doc/kword/auto3.png differ diff --git a/doc/kword/auto4.png b/doc/kword/auto4.png new file mode 100644 index 000000000..c631d5e1b Binary files /dev/null and b/doc/kword/auto4.png differ diff --git a/doc/kword/autocompdlg.png b/doc/kword/autocompdlg.png new file mode 100644 index 000000000..56d168ccc Binary files /dev/null and b/doc/kword/autocompdlg.png differ diff --git a/doc/kword/back.png b/doc/kword/back.png new file mode 100644 index 000000000..4b7765e42 Binary files /dev/null and b/doc/kword/back.png differ diff --git a/doc/kword/basic.png b/doc/kword/basic.png new file mode 100644 index 000000000..fa46a6758 Binary files /dev/null and b/doc/kword/basic.png differ diff --git a/doc/kword/basics.docbook b/doc/kword/basics.docbook new file mode 100644 index 000000000..cf1ef6133 --- /dev/null +++ b/doc/kword/basics.docbook @@ -0,0 +1,194 @@ + + + + +Mike +McBride + + + + +The &kword; Window + + +Overview +screen + +&kword;, like most &GUI; based programs, divides +the window up into several areas. Each area of the window is used to +perform a group of similar features. When you examine the &kword; +window, it is divided into 5 major areas: + + +The &kde; Titlebar +(which remains at the top of all programs run under +&kde;). + +The Menubar. + +An assortment of +Toolbars. + +The Document Structure Area. + +The Document +Area, including the rulers and scrollbars. + +The Status bar. + + + + + + + + + + +The &kde; Titlebar +The &kde; titlebar sits on top of all applications run under &kde;. +For more information on the titlebar, please see the &kde; User Guide. + + + +The Menubar + +The menubar provides access to all of &kword;'s functions and +options. Each part of the &kword; menubar is detailed in the section +entitled: The Menubar. + + + +The Toolbars + +The toolbars provide shortcuts to commonly used functions. +&kword; uses 8 toolbars, with similar functions grouped together. + + + + +Document Structure Area +The Document Structure area places individual types of data into useful groups +(pictures, tables, text, etc) to help you find the correct data in a complicated document. For +more information, see the section on Document Structure. + + + + +The Statusbar +The status bar provides important information during the editing of your document. +In the lower left corner, &kword; gives you the current page number and the total number of pages. There will be helpful text shown in +the status bar whenever you hold the mouse over a menu item. +The status bar can be toggled on and off. +See the section on Configure &kword; User Interface. + + + +The Document Area + +The document area consists of: + + +Horizontal and Vertical Rulers - +The rulers can be used to help you layout your document. For more +information on rulers, see Using +Rulers. + + + +Scrollbars - The scrollbars are used to move through a &kword; document +quickly. The &kword; scrollbars functions similar to all scrollbars in +&kde; or &Windows;. +The scrollbars can be toggled on and off. +See the section on Configure &kword; User Interface. + + +Tab Selector - This is used to select and place tab stops in your document for +easy formatting. For more information on tab stops, see the section +entitled Using Tab Stops. + + + +Document View - This is the area of the screen which is used to enter text. It +shows you the current status of your document, and allows you to adjust +frames, select text, and cut and paste text. + + + + + + + + + + +Using Rulers +rulers +Along the top and left edges of the document area, are a +horizontal and a vertical ruler. + +These rulers measure from the top left corner of the page. + +Each ruler has a bright area surrounded by a dark area. The +bright area shows the size and location of the currently edited frame +on that page. As you change frames, the bright area changes to reflect +the new frame's settings. + + + + + + + + +The ruler can measure the page in many common units of measure including: + + +Millimeters (mm) +Points (pt) +Inches (in) +Centimeters (cm) +Decimeters (dm) +Pica (pi) +Didot (dd) +Cicero (cc) + + +To change the units of the ruler, place the mouse cursor over one +of the rulers (either one), and click with the +&RMB;. + +Select the units you want to use from the popup menu. You will notice both rulers +change to the new unit of measure. + +You may also notice two vertical arrows (one pointed up, the other +pointed down), on the left side of the bright area of the horizontal +ruler. These are used to adjust the margin of a paragraph. For more +information, see the section entitled Formatting Paragraphs. + +Finally, you may see some black marks, which are not part of the +ruler. They may appear as L shaped, a Reverse-L, an Upside-down T, or +an Upside-down T with a dot in it. These are locations of tab stops. +For more information see the section entitled Using Tab Stops. + + +To quickly format the page layout, you can right mouse click on +either ruler. A small sub menu will appear. Simply select Page Layout..., +and the Page Layout Dialog box +will appear. + + + +If you don't want the rulers in your document area, they +can be switched off. Simply select +ViewHide Rulers from the menubar. +This will remove the rulers from the document area. Simply select +ViewShow Rulers to display the rulers again. + + + + + + diff --git a/doc/kword/bbord.png b/doc/kword/bbord.png new file mode 100644 index 000000000..218a0ea72 Binary files /dev/null and b/doc/kword/bbord.png differ diff --git a/doc/kword/bdcolorbut.png b/doc/kword/bdcolorbut.png new file mode 100644 index 000000000..9c372cd81 Binary files /dev/null and b/doc/kword/bdcolorbut.png differ diff --git a/doc/kword/bdselbut.png b/doc/kword/bdselbut.png new file mode 100644 index 000000000..b93a6ae33 Binary files /dev/null and b/doc/kword/bdselbut.png differ diff --git a/doc/kword/bdsizebut.png b/doc/kword/bdsizebut.png new file mode 100644 index 000000000..31bc4d6c4 Binary files /dev/null and b/doc/kword/bdsizebut.png differ diff --git a/doc/kword/beginning.png b/doc/kword/beginning.png new file mode 100644 index 000000000..0e2d3df25 Binary files /dev/null and b/doc/kword/beginning.png differ diff --git a/doc/kword/bkgdcolorbut.png b/doc/kword/bkgdcolorbut.png new file mode 100644 index 000000000..43ac05c6b Binary files /dev/null and b/doc/kword/bkgdcolorbut.png differ diff --git a/doc/kword/bold.png b/doc/kword/bold.png new file mode 100644 index 000000000..6e353e3b0 Binary files /dev/null and b/doc/kword/bold.png differ diff --git a/doc/kword/bookmarks.docbook b/doc/kword/bookmarks.docbook new file mode 100644 index 000000000..2015a5366 --- /dev/null +++ b/doc/kword/bookmarks.docbook @@ -0,0 +1,69 @@ + + + + +Mike +McBride + + + + +Document bookmarks +bookmarks + +Bookmarks are invisible placeholders that allow you to move easily to specified points in a large document. +Some other wordprocessors have bookmarks as part of their interface. If you are familiar with their use, you will +find that &kword; functions in a similar manner. +It should be noted that bookmarks are attached to the text near the cursor, not the page location. If +the text moves forward or backward in the document (as text is inserted or deleted respectively), the bookmark moves with the text. + +Creating a new bookmark +Creating a bookark is simple. +Place the cursor where you want the bookmark to be inserted. Select +InsertBookmark... from +the menubar. +A small dialog box will appear. +Type a short description of the bookmark location (i.e. Chapter 1, Appendix, Abstract, etc). This description will identify the +bookmark for you. +Click OK to create the bookmark. +Click Cancel to return to your document without creating a bookmark. + + + +Jump to a previously created bookmark +To jump to a previously created bookmark, select +ToolsSelect Bookmark... from +the menubar. +A small dialog will appear. Double click on the desired bookmark with the &LMB;. You will immediately be taken to +the location in the document that is attached to that bookmark. +Alternatively, you can click once on the desired bookmark with the &LMB;, and then click on +OK. This will function the same as double clicking on the bookmark. + + + + +Rename a bookmark +To rename a bookmark, select +ToolsSelect Bookmark... from +the menubar. +A small dialog will appear. Click on the desired bookmark with the &LMB;. Now click Rename Bookmark. +A small dialog will appear. Enter the new name for your bookmark. Click OK. The +bookmark is renamed immediately. + + + +Delete a bookmark +To delete a bookmark, select +ToolsSelect Bookmark... from +the menubar. +A small dialog will appear. Click on the desired bookmark with the &LMB;. +Be sure you have selected the correct bookmark from the list before proceeding. &kword; does not ask for +confirmation before deleting the selected bookmark. +Now click Delete Bookmark. +The bookmark is deleted immediately. + + + + + + diff --git a/doc/kword/borbutB.png b/doc/kword/borbutB.png new file mode 100644 index 000000000..66624ae71 Binary files /dev/null and b/doc/kword/borbutB.png differ diff --git a/doc/kword/borbutL.png b/doc/kword/borbutL.png new file mode 100644 index 000000000..889074a95 Binary files /dev/null and b/doc/kword/borbutL.png differ diff --git a/doc/kword/borbutR.png b/doc/kword/borbutR.png new file mode 100644 index 000000000..fbcc60442 Binary files /dev/null and b/doc/kword/borbutR.png differ diff --git a/doc/kword/borbutT.png b/doc/kword/borbutT.png new file mode 100644 index 000000000..bd8555aff Binary files /dev/null and b/doc/kword/borbutT.png differ diff --git a/doc/kword/bord.png b/doc/kword/bord.png new file mode 100644 index 000000000..e414b5a6e Binary files /dev/null and b/doc/kword/bord.png differ diff --git a/doc/kword/bordtb.png b/doc/kword/bordtb.png new file mode 100644 index 000000000..1f3711c1b Binary files /dev/null and b/doc/kword/bordtb.png differ diff --git a/doc/kword/bullist.png b/doc/kword/bullist.png new file mode 100644 index 000000000..d0eda054b Binary files /dev/null and b/doc/kword/bullist.png differ diff --git a/doc/kword/cftb.png b/doc/kword/cftb.png new file mode 100644 index 000000000..5f4036758 Binary files /dev/null and b/doc/kword/cftb.png differ diff --git a/doc/kword/chapnumb.docbook b/doc/kword/chapnumb.docbook new file mode 100644 index 000000000..bbeb8a062 --- /dev/null +++ b/doc/kword/chapnumb.docbook @@ -0,0 +1,15 @@ + + + + +- +- + + + + + Chapter numbering + chapter numbering + + Not written yet + diff --git a/doc/kword/chcase.png b/doc/kword/chcase.png new file mode 100644 index 000000000..051e822a1 Binary files /dev/null and b/doc/kword/chcase.png differ diff --git a/doc/kword/chcolorbut.png b/doc/kword/chcolorbut.png new file mode 100644 index 000000000..51579475a Binary files /dev/null and b/doc/kword/chcolorbut.png differ diff --git a/doc/kword/chfontbut.png b/doc/kword/chfontbut.png new file mode 100644 index 000000000..b748cda50 Binary files /dev/null and b/doc/kword/chfontbut.png differ diff --git a/doc/kword/chsizebut.png b/doc/kword/chsizebut.png new file mode 100644 index 000000000..ab8b81214 Binary files /dev/null and b/doc/kword/chsizebut.png differ diff --git a/doc/kword/chstylebut.png b/doc/kword/chstylebut.png new file mode 100644 index 000000000..5ee496499 Binary files /dev/null and b/doc/kword/chstylebut.png differ diff --git a/doc/kword/clearright.png b/doc/kword/clearright.png new file mode 100644 index 000000000..d88f16257 Binary files /dev/null and b/doc/kword/clearright.png differ diff --git a/doc/kword/colin.png b/doc/kword/colin.png new file mode 100644 index 000000000..cea3c68d7 Binary files /dev/null and b/doc/kword/colin.png differ diff --git a/doc/kword/colorseldlg.png b/doc/kword/colorseldlg.png new file mode 100644 index 000000000..11539ae9b Binary files /dev/null and b/doc/kword/colorseldlg.png differ diff --git a/doc/kword/colout.png b/doc/kword/colout.png new file mode 100644 index 000000000..1aa020376 Binary files /dev/null and b/doc/kword/colout.png differ diff --git a/doc/kword/columns.docbook b/doc/kword/columns.docbook new file mode 100644 index 000000000..a48135e8d --- /dev/null +++ b/doc/kword/columns.docbook @@ -0,0 +1,56 @@ + + + + +Mike +McBride + + + + + +Columns +columns + +You can divide the page into several columns, of equal width, with +a user controlled space in between each column. + + +This feature is only available in Text Oriented documents. + +If you are working in a Page Layout document, you can +build up several columns using a different frame for each column. + + +To change the number and width of columns select +FormatPage Layout... +from the menubar. + +This will bring up a dialog box. + + + + + + + +Click on the tab labeled Columns. + +This will change the dialog box. + + + + + + + +You can now select the number of columns in the spin box labeled Columns:, and the spacing +between columns in the text box labeled Column spacing:. + +The preview box shows you what your page will look like. + +Click OK when you are done. + +Click Cancel to abort changes. + + diff --git a/doc/kword/ctab.png b/doc/kword/ctab.png new file mode 100644 index 000000000..2255874de Binary files /dev/null and b/doc/kword/ctab.png differ diff --git a/doc/kword/ctab2.png b/doc/kword/ctab2.png new file mode 100644 index 000000000..777871060 Binary files /dev/null and b/doc/kword/ctab2.png differ diff --git a/doc/kword/decindbut.png b/doc/kword/decindbut.png new file mode 100644 index 000000000..8b8a99717 Binary files /dev/null and b/doc/kword/decindbut.png differ diff --git a/doc/kword/delentry.png b/doc/kword/delentry.png new file mode 100644 index 000000000..5453f9f57 Binary files /dev/null and b/doc/kword/delentry.png differ diff --git a/doc/kword/delrecord.png b/doc/kword/delrecord.png new file mode 100644 index 000000000..a8feb98e6 Binary files /dev/null and b/doc/kword/delrecord.png differ diff --git a/doc/kword/doccomments.docbook b/doc/kword/doccomments.docbook new file mode 100644 index 000000000..0f409ccd9 --- /dev/null +++ b/doc/kword/doccomments.docbook @@ -0,0 +1,69 @@ + + + + +Mike +McBride + + + + +Document Comments +comments + +Document comments are included in &kword; to allow you to have your documents read by another +person. That person can make comments about the text and the comment will appear right next to the text. + +Adding a comment to a document +To add a comment to a document, select the text you want the comment to apply to. +Select +Insert +Comment... + from the menubar. This will bring up a small dialog box. +Type the text of your comment in the dialog box provided. If you click on the +Add Author Name, the text will be signed, dated and the current time will be added. +The authors name must be entered in the Document Information +dialog or the name will not be included. +When you have entered all of your text, click OK to add your comment. +The comment will appear as a small yellow box at the cursor location. + + +Adding to or changing the comment in a document +To add more comments or change previous comments place the mouse pointer over the comment you +want to edit. Click once with the &RMB;. A popup menu will appear. Select Edit Comment.... +You can now make your changes to the comment. + + +Deleting a comment from a document +To delete a comment, place the mouse pointer over the comment you +want to edit. Click once with the &RMB;. A popup menu will appear. Select Remove Comment. +The comment is immediately deleted. + + +Hiding all comments in a document +To hide all comments, select +Settings +Configure &kword;... + from the menubar. +This will bring up a dialog box. + + + + + + + + +Click on Misc. + + + + + + + + +The check box labeled Display comments is used to toggle the comments on and off. + + + diff --git a/doc/kword/doclinks.docbook b/doc/kword/doclinks.docbook new file mode 100644 index 000000000..8f2c4cb25 --- /dev/null +++ b/doc/kword/doclinks.docbook @@ -0,0 +1,81 @@ + + + + +Mike +McBride + + + + +Document Links +document links + +&kword; has the ability to insert Internet addresses, email addresses, locations within the current document (bookmarks) and external file locations with a descriptor. This is most often used to +create web pages in &kword;. + +Once inserted into the document, the descriptor will be visible in &kword;, but when saved as a web document, the descriptor will become + the hyperlink for the location specified with the address. + +Insert a new document link +To insert a document link select +Insert +Link... + from the menubar. This will bring up a small dialog box. + + + + + + + + +Using the icon bar on the left, choose which link type you want to insert. +In the comment field, type the text you want to appear in your web document (for example: The KOffice Web Site). +In the address field, type the Internet address, email address or +file location you want the comment to be linked with (for example: http://www.koffice.org) +Click OK. +By default, &kword; displays links underlined (as in most browsers). You can turn this behavior on and off by +selecting SettingsConfigure +&kword;... from the menubar and selecting the Misc page. More information can be found +here. + +Opening a document link +You an use a document link from within &kword;. +Simply click once on the document link with the &RMB;. A popup menu will appear. Select Open Link. +A document link to a web site will open a new browser window and take you directly to that web site. A document link to an +email address, will open a new message in your email program. A document link to a file will open the appropriate viewer or editor for +that file type. + + +Copy a document link +You an use a document link in another application, by copying it from a &kword; document. +Simply click once on the document link with the &RMB;. A popup menu will appear. Select Copy Link. +The link address has now been inserted into the clipboard. You can paste your clipboard entry into any other application. + +Changing a document link +To change the details of a document link Simply click +once on the document link with the &RMB;. A popup menu will appear. Select Change Link.... +The Insert Link dialog box will appear, with the current settings of the link displayed. + + + + + + + +Make any appropriate changes and click OK to make your changes. + +Deleting a document link +You can delete a document link like any other text in your document. +Simply place the cursor at the end of the document link, and press &Backspace;. Alternatively, place +the cursor at the beginning of the document link and press Delete on the keyboard. The document link is deleted in its entirety. + +Converting a document link to text +If a document link is no longer needed as a link, but you want to preserve the text that is the link, click once on the document link with the &RMB;. A popup menu will appear. Select Remove Link.... The linked text will now become plain text, and the link will be deleted. + + + + + + diff --git a/doc/kword/docstruct.docbook b/doc/kword/docstruct.docbook new file mode 100644 index 000000000..cef30613d --- /dev/null +++ b/doc/kword/docstruct.docbook @@ -0,0 +1,148 @@ + + + + +Mike +McBride + + + + +<guilabel>Document Structure</guilabel> +document structure + +Sometimes, when editing a complicated document, it can be helpful to look at an organized view of your document. +You can use this organized view to jump immediately to certain text +frames, select picture frames, change frame properties, delete frames, + or simply review your document. + + +Show and hide <guilabel>Document Structure</guilabel> area +Because simple documents do not need the information provided in the Document Structure area, &kword; +has the ability to toggle the Document Structure area on and off. +To toggle the Document Structure area on and off, select +ViewShow Doc Structure + from the menubar to make the Document Structure area visible. Select +ViewHide Doc Structure + from the menubar to make the Document Structure area disappear. + +You can move focus to the document structure area by pressing +&Alt;1. You can move focus to the main document panel by pressing +&Alt;2. + + + + +Navigating the document structure area +Lets examine a sample Document Structure area. + + + + + + +As you can see, there are five groups of frames categorized (Text +Frames/Frame Sets +Pictures, Tables, Formula +Frames, +Embedded Objects). + + + +Text Frames/Frame Sets +Within this category, is a list of all text framesets. Below +each frameset, each frame is listed. Below each frame, each paragraph is +listed. + + + +Pictures +Within this category is a list of all frames that contain +pictures, and the folder the pictures were loaded from. + + + +Tables +Within this category is a list of all frames that contain +tables. Note that a table behaves very much like a frameset. +Each cell of the table is a frame, and each frame may contain +multiple paragraphs. + + + +Formula Frames +Within this category is a list of all frames that contain +formulas. + + + +Embedded Objects +Within this category, is an alphabetical list of all frames +that contain data from other &koffice; applications. + + +You can use your mouse to select the category you want, or first +put focus in the document structure area (press &Alt;1) +then use the up and down arrow keys to scroll through the list. +Double click on a category to expand or collapse the category, +or press the right or left arrow keys. + +Depending on your document, you may not have all categories in your +Document Structure area. The category only +appears when there is at least one frame in the +category. + + + + + +Edit a text frame, frameset, or paragraph using the document structure area +To edit a text frame, frameset, or paragraph, click on the +item with the &RMB; or scroll to the item and press the +Menu key. A popup menu will appear. Select Edit +Text from the menu. + + + +Speak the text of a text frame, frameset, or paragraph using the document structure area +If you have the KTTS component installed in your system, you can have the computer +speak the text of the document. To speak the text of a frame, frameset, or paragraph, click on the +item with the &RMB; or scroll to the item and press the +Menu key. A popup menu will appear. Select Speak +Text from the menu. + + +The Speak Text menu item will be disabled if KTTS +is not installed in your system. + +If KTTS fails to speak the text, or speaks the text in the wrong +language, make sure you have a Talker in +KTTS configured with the correct language. See The KTTS Handbook +for details. Also, make sure the Global Language is properly +set in the &kword; settings. + + + + +Jump to a frame, frameset, or paragraph using the document structure area +To display a frame, frameset, or paragraph in the main document panel, click on the +item with the &RMB; or scroll to the item and press the +Menu key. A popup menu will appear. Select Show + from the menu. + + +Delete frame or frameset using the document structure area +To delete a frame or frameset, click on the +frame title with the &RMB; or scroll to the frame title and press the +Menu key. A popup menu will appear. Select Delete +Frame from the menu. + + +Edit a frame or paragraph properties using the document structure area +To change the properties of a frame or paragraph, click on the +item with the &RMB; or scroll to the item and press the +Menu key. A popup menu will appear. Select +Properties from the menu. + + + diff --git a/doc/kword/docstruct.png b/doc/kword/docstruct.png new file mode 100644 index 000000000..10a52edfd Binary files /dev/null and b/doc/kword/docstruct.png differ diff --git a/doc/kword/docvariables.docbook b/doc/kword/docvariables.docbook new file mode 100644 index 000000000..d8e8cc971 --- /dev/null +++ b/doc/kword/docvariables.docbook @@ -0,0 +1,486 @@ + + + + +Mike +McBride + + + + +Document Variables +variablesintroduction + +A variable is a simple way of allowing &kword; to modify the document in very +specific ways to reflect the changing nature of the document or report. +A variable can be a number (such as a page number, the total number of pages in a document, etc), +a selection of words (clients name, product name, the documents filename, etc), +a date, a time, or nearly anything you desire. +Once the variable is defined, a placeholder is inserted in the document. +&kword; will replace this placeholder with the value of that variable each time the placeholder is used. +Variables can either be fixed (which means that once inserted, their value does not +change), or variable (where the placeholder is +updated by &kword; to reflect +the current value of the variable). +This chapter will begin with a few examples of commonly used variables +(date, +time, and +page numbers), +then detail the +remaining variables + available to you. Finally, it will detail how to +create +custom variables for documents. + +Date and Time +Many letters, reports and documents contain +information about the dates or times they correspond to. The date and time +information may establish the creation of a document (which will remain +fixed as long as the document is around), or the date and time may serve as +a notice of the last date of modification (which would change with each passing day). +&kword; allows for both fixed and variable date and time variables in the document. +Insert Date +variablesinsert date +insert date + +To insert the date in the document, simply place the cursor in the text box where the date +should be inserted and select + +InsertVariableDate + from the menubar. This will bring up several selections. To insert the current date, select one of two +options: +Current date (fixed) and Current date (variable). + + + +Current date (fixed) +Selecting this option will insert the current date into the current cursor position. +This date is determined by checking with the computers system clock. Once entered, this value +will not change, even when &kword; is asked to update the document +variables. +This item is ideal for dates of document creation, or when including data in a report from todays work. +Compare this choice to Current date (variable). + + + +Current date (variable) +Selecting this option will insert the current date into the current cursor position. +This date is determined by checking with the computers system clock. This value will +change when &kword; is asked to update the document +variables. +This option is good for any point in the document where the current date is always wanted. +Compare this choice to Current date (fixed) + + + +Once the date has been selected, a dialog box will appear. + + + + + + +The top combo box determines the layout of the variable. Your choices are: + + + +Locale date format +This inserts the date in the format specified in the +&kde; Control Center. +To select this option, simply make sure the upper combo box says +Locale date format. A preview of the date format will appear above the +OK button. If satisfied click OK. + + + + +Preformatted date strings +&kword; comes with 19 predefined date strings. These predefined strings will +be all that are needed in most circumstances. Simply select the predefined string in the upper +combo box. A preview of the date format will appear above the +OK button. If satisfied click OK. + + + + +Custom String +If the appropriate format for the date cannot be found, it is possible to create custom +date format strings. +A date format string consists of a list of letters and numbers which follow +specific rules (which are outlined below) to create the completed date. +The date format string consists of placeholders and +separators. The placeholders are defined in the following three tables. +Days + + + +Day placeholdersdddddddddd +Example606ThuThursday + +Months + + + +Month placeholdersMMMMMMMMMM +Example303MarMarch + +Year + + + +Year placeholdersyyyyyy +Example022002 + +Simply combine placeholders with normal text (separators) to create completed date strings. + +For example: +MM/dd/yyyy is translated to 01/06/2004 +and +MMMM d, yyyy becomes January 6, 2004 +Notice that only the placeholders change. Spaces, commas, slashes and other text remains unchanged. +It is important to remember that placeholders are case sensitive. +DD is not a placeholder, + only dd. +To create a custom date string, place a mark in the Custom check box. +Now type placeholders and separators text into the upper combo box. Alternatively +select the format from the Insert: +combo box, and the +placeholder will be inserted into the date format string at the cursor location. + + + + + +There is a spinbox labeled Correct in Days. You can use this spin box to adjust the date up or +down one or more days from the current date. + +A preview of the current date +string is visible above the +OK button. Click OK when +the date format string is correct to insert the variable into the document. + +Once the date has been inserted into the document, it can be reformatted to a different layout +and toggled between fixed and variable dates. Simply click once with the &RMB; on the date. +A small menu will appear. Select Change Variable To and a submenu will appear. Select your new +variable or new layout from the menu and the variable is immediately updated. + + + There are three additional dates you can insert into your document: + + +Date of Last Printing +Selecting this option will insert the date this document was last printed into the current cursor position. + + + + +Date of File Creation +Selecting this option will insert the date this document created into the current cursor position. + + + + +Date of File Modification +Selecting this option will insert the date this document was last edited into the current cursor position. + + + + + + + + +Insert Time +variablesinsert time +insert time + +To insert the time in the document, simply place the cursor in the text box where the time should +be inserted and select + +InsertVariableTime + from the menubar. This will bring up two selections: +Current time (fixed) and Current time (variable). + + + +Current time (fixed) +Selecting this option will insert the current time into the current cursor position. +This time is determined by checking with the computers system clock. Once entered, this value +will not change, even when &kword; is asked to update the document +variables. +This item is ideal for timestamps. +Compare this choice to Current time (variable). + + + +Current time (variable) +Selecting this option will insert the current time into the current cursor position. +This time is determined by checking with the computers system clock. This value will +change when &kword; is asked to update the document +variables. +This option is good for any point in your document where the current time is always wanted. +Compare this choice to Current time (fixed) + + + +This brings up a dialog box. + + + + + + +The top combo box determines the layout of the variable. The choices are: + + + +Locale format +This inserts the time in the format specified in the +&kde; Control Center. +To select this option, simply make sure the upper combo box says +Locale format. A preview of the current time +string is visible above the OK button. If satisfied click OK. + + + + +Preformatted time strings +&kword; comes with 6 predefined time strings. These predefined strings will +be all that are needed in most circumstances. Simply select the predefined string in the upper +combo box. A preview of the current time +string is visible above the OK button. If satisfied click OK. + + + +Custom String +If the appropriate format cannot be found, a custom +time format string can be created. +A time format string consists of a list of letters and numbers which follow +specific rules (which are outlined below) to create the completed time. +The time format string consists of placeholders and +separators. The placeholders are defined in the following five tables. +Hours + + + +Hour placeholdershhh +Example606 + +Minutes + + + +Minutes placeholdersmmm +Example303 + +Seconds + + + +Seconds placeholderssss +Example202 + +Milliseconds + + + +Milliseconds placeholderszzz +Example022 + +Seconds + + + +AM/PM placeholdersapAP +ExampleamAM + + +Simply combine placeholders with normal text (separators) to create completed time strings. + +For example: +hh:mm:ss becomes 06:23:13 +and +h:mm ap becomes 6:23 am +Notice that only the placeholders change. Spaces, colons and other text remains unchanged. +It is important to remember that placeholders are case sensitive. +HH is not a placeholder, + only hh +To create a custom time string, place a mark in the Custom check box. +Type the placeholders and separator text into the upper combo box. Alternatively, +you can select the format from the Insert: +combo box, and the +placeholder will be inserted into the time format string at the cursor location. +A preview of the current time +string is visible below the Custom check box. Click OK when +the time format string is correct to insert the variable into your document. + + + + +A preview of the current time +string is visible below the Custom check box. Click OK when +the time format string is correct to insert the variable into your document. + +Once the time has been inserted into the document, it can be reformatted to a different layout +and toggled between fixed and variable times. Simply click once with the &RMB; on the time in the document. +A small menu will appear. Select Change Variable To and a submenu will appear. Select your new +variable or new layout from the menu and the variable is immediately updated. + + + + + +Page Numbering +variablesinsert page numbers +insert page numbers + +Inserting page numbers is easy in &kword;. +There are five variables that relate to page numbers: Page Number, +Number of Pages,Section TitleNext Page, +and Previous Page. +To insert the current page number, place the cursor where you want the page number and select + +InsertVariablePage +Page Number + from the menubar. The page number will be inserted at the current cursor location. +To insert the total number of pages, place the cursor where you want the variable and select + +InsertVariablePage +Number of Pages + from the menubar. The total number of pages will be inserted. +To insert the title of the section, place the cursor where you want the variable and select + +InsertVariablePage +Section Title + from the menubar. The section title will be inserted. +By selecting +InsertVariablePage +Next Page + from the menubar, a reference to the page number after the current page will be inserted at the current cursor location. +Likewise, by selecting +InsertVariablePage +Previous Page + from the menubar, a reference to the page number before the current page will be inserted at the current cursor location. + +Page numbers are updated dynamically as the document +is edited. +Page numbers are usually best located within +headers and footers. This ensures that +every page will have a page number at the appropriate place. + +Section Title +You can insert the section title anywhere in your document by selecting + +InsertVariablePage +Section Title + from the menubar. +&kword; determines the Section title by beginning a search from the top of the current page. The first paragraph with a style of +Head 1 is the section title. If there are no paragraphs on the current page, &kword; does the same search along +on previous pages until it finds a section title. + + +Other Variables +variablesmiscellaneous variables + +&kword; provides other commonly used variables that you might find useful. This set of variables +are specific to the document. You can insert these variables by selecting + +InsertVariableDocument Information + from the menubar. This will bring up a list of variables. The variables are detailed below. + + + +VariableExampleDetails + + +Author NameJoseph UserThe name of the author as specified in the Document information box. +CityPhiladelphiaThe city specified in the Document information box. +Company&kde;The company name specified in the Document information box. +CountryUnited StatesThe country name specified in the Document information box. +Directory Name/home/juser/kwordThis is the folder name for the document. The filename is not included in the folder name variable. +Directory & Filename/home/juser/kword/Resume.kwdThe folder and filename of the current file. +Document AbstractThis is a current resume. The document abstract specified in the Document information box. +Document KeywordsResume, job, application The document keywords specified in the Document information box. +Document SubjectMy resume. The document subject line specified in the Document information box. +Document TitleMy ResumeThe document title specified in the Document information box. +Emailjoeuser@kde.orgThe email address of the author as specified in the Document information box. +FaxAny valid telephone numberThe fax machine number specified in the Document information box. +File NameResume.kwdThe complete name of the file. +File Name without extensionResumeThe filename without the suffix (usually .kwd). +InitialsJCUThe initials specified in the authors section of the Document information box. +Postal codeAny valid postal codeThe postal code specified in the Document information box. +Street123 Main St.The street address specified in the Document information box. +Telephone (work)Any valid telephone numberThe telephone number specified in the Document information box. +Telephone (private)Any valid telephone numberThe telephone number specified in the Document information box. +TitleDirector of Information SystemsThe title specified in the authors section of the Document information box. + +Additionially, there are numerous variables under the Statistics submenu for inserting the number of words, lines, frames, etc. These variables should be self explanitory. +Uninitialized variables will appear as <none>, until you define their +value in the +Document information box. + +Custom Variables +variablescustom + +&kword; has many predefined variables. You may encounter documents where it would be nice +to define your own variables for a document. +Using Custom Variables, you can create an unlimited number of variables for each document. +Create a new custom variable +variablescreate custom variable + +To create a new custom variable, place the cursor at the location in the document to insert the new variable. +Select +InsertVariableCustom +New from the menubar. This will bring up a dialog box. +Enter the variable name and its current value in the text boxes provided. +Click OK to create the new variable name and insert it at the current +cursor location. Click Cancel to cancel the creation of the new variable. + +It is now possible to insert this new variable at any +place in your document. + +Edit a custom variables value +variablesedit custom variables + +In order for variables to be useful, you need to be able to give them a value, and be able to +change that value easily. To change the value of a variable: +Select +Tools +Custom Variables... from the menubar. +This will bring up a dialog box. +Each custom variable has a line in this table. The first column is the name of the variable, and +the second column is the value. +To change the value of a variables, simply click within the text box to the right of +the variable name. Enter the desired value. +When all the changes have been complete, simply click OK and all the +variables will be updated. + +Insert a custom variable +variablesinsert custom variable + +To insert a new custom variable select +InsertVariableCustom + from the menubar. The custom variable is listed in the submenu. Click on the name of +the variable and &kword; will insert the variable, with its current value, at the cursor location. + + +Updating All Variable Values +variablesupdating + +You can tell &kword; to update all variable values (to make sure all variables are set to their +current values). This is especially important with dates and times. +Simply select +InsertVariableRefresh All Variables + from the menubar. + +Updating One Date or Time Variable Value +You can tell &kword; to update a single date or time variable value, and leave the others unchanged. +Simply place the mouse pointer over the variable you want to update and click with the &RMB;. +Select Change Variable To. A small menu will appear which will show +several new date or time formatting options and the option to change either dates or times to fixed or variable time formats. Simply select +the new option and this variable will be updated. + + diff --git a/doc/kword/dtab.png b/doc/kword/dtab.png new file mode 100644 index 000000000..c8513bd29 Binary files /dev/null and b/doc/kword/dtab.png differ diff --git a/doc/kword/dtab2.png b/doc/kword/dtab2.png new file mode 100644 index 000000000..0c5d00d13 Binary files /dev/null and b/doc/kword/dtab2.png differ diff --git a/doc/kword/dtpfmtpg1.png b/doc/kword/dtpfmtpg1.png new file mode 100644 index 000000000..63518acd7 Binary files /dev/null and b/doc/kword/dtpfmtpg1.png differ diff --git a/doc/kword/editcopy.png b/doc/kword/editcopy.png new file mode 100644 index 000000000..1e6c38ad2 Binary files /dev/null and b/doc/kword/editcopy.png differ diff --git a/doc/kword/editcut.png b/doc/kword/editcut.png new file mode 100644 index 000000000..84ba0e15d Binary files /dev/null and b/doc/kword/editcut.png differ diff --git a/doc/kword/editing.docbook b/doc/kword/editing.docbook new file mode 100644 index 000000000..733da6677 --- /dev/null +++ b/doc/kword/editing.docbook @@ -0,0 +1,1903 @@ + + + + +Mike +McBride + + + + +Detailed Guides: Editing your Document + +This section of the guide will cover more advanced features of +data editing. This section focuses entirely on text data. For working +with other types of data, please see the section entitled More than just text. + + +Selecting Text +selecting text +For many editing and formatting functions in &kword;, certain actions (bold face, underline,&etc;) should be +applied to a +certain section of text, not the document as a whole. You specify which +text should be altered by selecting (or highlighting) the text you want changed. + +Selected text has a colored background to separate it from +unselected text. + + + + + + + + +Select text by designating a start and an end +point. All the text in between the start and end point is selected +text. + +Text can be selected with either the mouse or the keyboard. + + +Using The Mouse + +To select text with the mouse, place the mouse pointer at the start point. Click and hold down the +&LMB; and drag the mouse pointer. This +selects all text between the initial click of &LMB; and the +current position of the mouse cursor. When the mouse pointer is at the desired end point, release the button. +The start and endpoints will become fixed. + + + + +Using The Keyboard +To use the keyboard, &kword; takes the initial position of the text cursor as the start point. +Use the following key combinations to move the endpoint to the desired location. + + +Key CombinationFunction + +&Shift;Left ArrowMoves the endpoint one character to the left. +&Ctrl;&Shift;Left ArrowMoves the endpoint one word to the left. +&Shift;Right ArrowMoves the endpoint one character to the Right. +&Ctrl;&Shift;Right ArrowMoves the endpoint one word to the Right. + +&Shift;Up ArrowSelects all characters from the start of the selection, to the character directly up one line. +&Ctrl;&Shift;Up ArrowSelects all characters from the start of the selection, to the first character of the line directly above. + +&Shift;Down ArrowSelects all characters from the start of the selection, to the character directly down one line. +&Ctrl;&Shift;Down ArrowSelects all characters from the start of the selection, to the last character of the line directly below. + +&Shift;HomeSelects all characters from the start of the selection, to the beginning of the line. +&Ctrl;&Shift;HomeSelects all characters from the start of the selection, to the beginning of the document. + +&Shift;EndSelects all characters from the start of the selection, to the end of the line. +&Ctrl;&Shift;EndSelects all characters from the start of the selection, to the end of the document. + +&Shift;Page-UpMoves the current endpoint one screen up. +&Ctrl;&Shift;Page-UpMoves the current endpoint one page up. The endpoint is located at the first character of this page. + + +&Shift;Page-DownMoves the current endpoint down one screen. + +&Ctrl;&Shift;Page-DownMoves the current endpoint down one page. The endpoint is locate at the first character of this page. +&Ctrl;ASelect all text in the current frameset. + + +Once the start and endpoints have been defined, all text between the startpoint and endpoint is selected. + + + + + + +Using Multiple Views +viewsusing multiple + +Introduction +When editing very large documents, there will be times when it is helpful to +edit two parts of the document. In a situation such as this, +&kword; can open additional windows to edit the same document. +These new windows are called Views, since they provide +a different viewpoint of the the same document. +Views are very important tools when working with large documents. +Set one view to edit one part of the document, and using the other view, freely +move through the document making updates and changes. These changes are automatically revealed in all views. + + + + +Creating a new view +viewscreate new view +Creating a new view creates an entirely new window, with toolbars, menubars etc. +Compare this with the Split View command. + +To create a new view select ViewNew View + from the menubar. + +A new window will be created. Alterations to your document can be made in either view. +Updates in one window will be immediately visible in the other. + + + + +Splitting the current view into two separate views. +viewssplit current view +It is also possible to split one view into two views. Both views are contained within one window, and +use the same toolbars, menubars, etc. Contrast this to the effect of the New View command. + +To split the current view, select +ViewSplit View from the menubar. + +The current document area will be split into two views. Alterations to your document can be made in either view. +Updates in one view will be immediately visible in the other. + +The views can either be split horizontally or vertically. See the next section for instructions. + + + + +Changing the split view orientation +viewschange split view orientation +To change the direction that the views are split, simply select +ViewSplitter Orientation from the menubar. +This will show a submenu. Select either Horizontal or Vertical. + +All views in the current window will immediately change to the new orientation. + + + + +Changing the size of views +viewsresizing +The relative sizes of each view can be adjusted with your mouse. +To adjust the view size, look at the border between the scrollbar of one view +(the upper or right view) and the ruler of the other view (the lower or left view). There is a +solid border which appears raised between the scrollbar and the ruler. As the mouse pointer passes +over this bar, it changes from an arrow to double lines with double arrows. + + +Screen shot + +When the mouse pointer changes, click once with the &LMB; and hold the button +down. Drag that border to the new location. When the mouse button is released, the +views will change to the new proportions. + + + + + +Remove View +viewsremoving +To remove a view, simply place the mouse pointer in the view to be deleted and click with the &LMB;. +Then select ViewRemove View +from the menubar. + + + + +Close all views To close all views, select +viewsclosing all views +ViewClose All Views +from the menubar. + + + + +Undo/Redo +undoing last edit +redoing previously undone edit +It happens all the time. While working on a document, a change is made. +The change was wrong, now you want to back out of your changes. + +Fortunately, &kword; has a solution. + +Each time a change is made to a document, &kword; remembers what +the change was. &kword; can +Undo each change once a time. + +As an example, you are writing a business letter and type in the following sentence: + +It is a pleasure for me to give you this letter of introduction to your newest employee. + +But that doesn't seem right, so you change it: + +It is a joy for me to give you this letter of introduction to your newest employee. + +You decide it was better the first time and you want to change it back. + +Simply select +EditUndo from +the menubar. + +The text now reads pleasure again. + +It is a pleasure for me to give you this letter of introduction to your newest employee. + +If, after you Undo a change, and then want to reverse that decision, +select +EditRedo and +the Undo is reversed. + + +Sometimes it is not possible for &kword; to undo an edit. In these instances, &kword; +will display the Undo function gray and the function is not +accessible. + +Othertimes, &kword; will only perform a partial undo of the previous task. +This is because &kword; processes changes to documents differently then might +initially be expected. Simply select +EditUndo +again, and more of the edits will be undone. + +By default, &kword; keeps track of the last 30 edits to the document. +This number can be adjusted up or down. For details, see Configuring &kword;. +The Undo and Redo commands can +be accessed from the menubar (as in the examples above), by using keyboard shortcuts or from the toolbar. + + + +CommandToolbar ButtonKeyboard Shortcut + +Undo +&Ctrl;Z +Redo +&Ctrl;&Shift;Z + + + + + + + +Cut/Copy/Paste and the Clipboard +clipboardusing + +The clipboard is a concept familiar to most people +who have used modern word processors. It is a piece of your computers +memory which is set aside as a temporary storage space. Text can be +Cut or Copied from your document into +the clipboard. You can move to another part of the document or to +another application entirely, and Paste this text at the new +location. + +The most common use for the clipboard is to move or copy text +which has already entered into one part of the document to another +part of the same document or to another document entirely. + +This concept is probably best described with an example. + +To do this, we begin with a test sentence + +The big, red fox jumped over the lazy dog. + +Using the mouse or keyboard, select the phrase + big, red (notice the space before big is selected). + +Now select +EditCopy from +the menubar. + +This has moved a copy of the selected text to the +clipboard. + +Now place the mouse cursor directly behind the word +lazy and click once. + +Now select +EditPaste +from the menubar. + +The resulting sentence is: + +The big, red fox jumped over the lazy big, red dog + +The clipboard is not limited to text. +The clipboard can contain tables, pictures, spreadsheets or any other type of information. + + +The <guimenuitem>Copy</guimenuitem> Command +clipboardcopying text to +The Copy command can be invoked 4 ways: + + + +By selecting +EditCopy from +the menubar + + + +By clicking +on the toolbar. + + + +Using the keyboard shortcut: &Ctrl;C or the alternate keyboard shortcut: +&Ctrl;Insert + + + +After the text is selected, click once with the &RMB; and hold the button down. +A small popup menu will appear. Simply select Copy + + + + +The Copy command moves a copy of the selected data +to the clipboard. The original data is +unaffected. + + + + +The <guimenuitem>Cut</guimenuitem> Command +clipboardmoving text to +The Cut command can be invoked 4 ways: + + + +By selecting +EditCut from +the menubar + + + +By clicking +on the toolbar. + + + +Using the keyboard shortcut: &Ctrl;X or the alternate keyboard shortcut: +&Shift;Delete + + +After the text is selected, click once with the &RMB; and hold the button down. +A small popup menu will appear. Simply select Cut + + +The Cut command moves a copy of the selected data +to the clipboard. The selected data is then deleted from the +document. + + + + +The <guimenuitem>Paste</guimenuitem> Command +clipboardmoving text from +The Paste command can be invoked 4 ways: + + + +By selecting +EditPaste +from the menubar + + + +By clicking +on the toolbar. + + + +Using the keyboard shortcut: &Ctrl;V or the alternate keyboard shortcut: +&Shift;Insert + + + +Place the cursor where the contents of the clipboard +should be inserted. Click once with the &RMB; and hold the button down. A small +popup menu will appear. Simply select Paste + + + + +The Paste command inserts a copy of all the data in +the clipboard at the current position of the cursor. The clipboard is +unaffected. (So another paste command will produce yet another copy of +the data in the document.) + + +If no text in the document is currently highlighted, the +Paste command inserts +the data at the current position of the cursor. + +If there is selected text when the +Paste command is executed, the selected text +is replaced with the contents of the +clipboard. + + +The clipboard is not limited to the bounds of the current document. If +text is copied (or cut) from a document, this text can be pasted +into another open document, or another application entirely. + + + + + +Finding and Replacing Text + + +The <guimenuitem>Find</guimenuitem> Command +searching for text +finding text in a document + +The Find command can be invoked 3 ways: + + + +By selecting +EditFind... +from the menubar + + + +You can use the keyboard shortcut:&Ctrl;F + + + +By clicking on +the toolbar. + + + +When the Find Command is invoked, a dialog appears. + + + + + + + + +Basic Text Search +The combo box labelled Text to find, +provides a place for you to enter the text of your search command. (In +the screenshot, that box is currently filled with +KDE). + +If you click on +Find, then &kword; will search the document until it +finds a match to your text. If &kword; cannot find a match, a dialog +box will appear that says No matches found for "Text to find". +If you want to repeat a recent search, simply select the arrow in the drop-down +box and a list of your most recent searches will appear. Simply select your search +from the list and click Find. + + + +Refining Your Search + +&kword;'s find feature is much more sophisticated than we +discussed above. Using the options in the dialog box, you can narrow +down your search to find exactly what you +want. + + +Regular Expressions in &kword; + +The default action for &kword; is to search for an exact match of +the text. &kword; has the ability to match text +that follows a pattern or a set of rules. + +To enable patterns, place a mark in the box labeled Regular expression. + +This will enable the Edit button. +This button can be a quick way to create regular expressions for people unfamiliar +with &UNIX; regular expressions. + +A more thourough discussion of regular expressions in KDE can be found in the help manual for &kregexpeditor;, which can be found in the &khelpcenter;. + + + +Formatting options +&kword; also has the ability to search your document for text that matches +certain formatting options as well as the text itself. + +To include formatting options in your search, click the button labeled +Show Formatting Options. + +Once Show Formatting Options has been clicked, a new dialog will appear. + + + + + + + + +You can use this dialog to select the options you want to include in your search. +The left column consists of 13 check boxes. If there is a mark in the check box, then &kword; will evaluate +any searchable text for that property. If no mark is in the check box, &kword; does not consider that property when performing a search. + + + + +Family: + +Use this combo box to select the font family you want to include in your search text. + + + + +Size: + +Use this spin box to set the font size you want &kword; to search for. + + + + +Color: and Background color: + +Clicking on either of these two buttons allows you to select the font color and/or background color respectively, +you want &kword; to search +for. For more information on selecting a color, see the +section on Selecting Colors from the Color Dialog. + + + + +Bold: and Italic: + +Use these Yes/No radio boxes to determine whether you want &kword; +to include boldface or italicized fonts in the search text. + + + + +Strikeout: + +You can select None, Single, Double +or Simple Bold to modify your search. + + + + +Underline: + +You can select None, Single, Double, Simple Bold +or Wave to modify your search. + + + + +Vertical alignment: + +You can select Normal, Subscript or +Superscript to determine what font alignment you want &kword; to search for. + + + + +Shadow: and Word by word: + +Use these Yes/No radio boxes to determine whether you want &kword; +to include shadow text in the search text and whether to search for word by word underlining and strikethrough text. + + + + +Capitalization: + +You can select Normal, Uppercase, Lowercase, or +Small Caps to determine what capitalization you want &kword; to search for. + + + + +Language: + +You can select the language of the text you want &kword; to search for using this dropdown box. + + + +Once you have selected your options, click OK to accept your search options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the default values. +Click Clear to remove all marks from the checked options. + + + + +Other Search options + +In addition to pattern matching, you can limit the search results +with a few useful options. + + + +Case sensitive + +When this option is selected, &kword; will not only search for the +string of letters, but will verify that the case of the letters is the +same. For example. Searching for: +KDEwill match: +KDE and +hiddenKDEinwords but not: Kde, +kde or hiddenkdeinwords. + + + + +Find backwards + +This option changes the direction of the search. This can be +useful when you only want to search for a string of text before the +current cursor position, not after. This option is usually used in +conjunction with From cursor, but if that option is +not specified, &kword; will start searching from the end of the document +backwards. + + + + +Whole words only + +When this option is selected, &kword; will only return search +items that are surrounded by spaces, paragraph marks or punctuation. For +example. Searching for: KDEwill +match: KDE but not: +hiddenKDEinwords or KDElike. + + + + +Selected Text +If you want to limit your search to a specific part of +the document (a few paragraphs, for example), you can select the part of +the document you want to search prior to selecting +the Find command. When text is selected, &kword; +will default to only searching the selected text. You can use this +option to enable or disable this restriction. + +This option will not be available if you have not selected text +prior to selecting the Find command. + + + + + +From cursor + +By default, &kword; begins searching at the beginning of the +document. If this option is selected, &kword; begins its search from +the current position of the cursor. The direction that &kword; searches +is, by default forward in the document, but can be changed with the +Find backwards option. + + + + + + + + +The <guimenuitem>Replace</guimenuitem> Command + +The Replace command is an extension of the Find command. If you +are familiar with the Find command, you will see many +similarities. + +The Replace command can be invoked 2 +ways: + + + +By selecting +EditReplace... +from the menubar + + + +You can use the keyboard shortcut: &Ctrl;R + + + +When the Replace command is invoked, a dialog +appears. + + + + + + + +Basic Search and Replace +replacing text + +The combo box labeled Text to find:, +provides a place for you to enter the text of your search command. (In +the screenshot, that box is currently filled with +KDE) + +You can enter your replacement text in the text box labeled +Replacement text:. You can now click +OK to replace all occurrences in the document, or +you can further refine your search. + + + + +Refining Your Search + +&kword;'s find feature is much more sophisticated than we +discussed above. Using the options in the dialog box, you can narrow +down your search to find exactly what you +want. + + +Regular Expressions in &kword; + +The default action for &kword; is to search for an exact match of +the text. &kword; has the ability to match text +that follows a pattern or a set of rules. + +To enable patterns, place a mark in the box labeled Regular expression. + +This will enable the Edit button. +This button can be a quick way to create regular expressions for people unfamiliar +with &UNIX; regular expressions. + +A more thourough discussion of regular expressions in KDE can be found in the help manual for &kregexpeditor;, which can be found in the &khelpcenter;. + + + +Formatting options +&kword; also has the ability to search your document for text that matches +certain formatting options as well as the text itself. + +To include formatting options in your search, click the button labeled +Show Formatting Options. + +Once Show Formatting Options has been clicked, a new dialog will appear. + + + + + + + + +You can use this dialog to select the options you want to include in your search. +The left column consists of 13 check boxes. If there is a mark in the check box, then &kword; will evaluate +any searchable text for that property. If no mark is in the check box, &kword; does not consider that property when performing a search. + + + + +Family: + +Use this combo box to select the font family you want to include in your search text. + + + + +Size: + +Use this spin box to set the font size you want &kword; to search for. + + + + +Color: and Background color: + +Clicking on either of these two buttons allows you to select the font color and/or background color respectively, +you want &kword; to search +for. For more information on selecting a color, see the +section on Selecting Colors from the Color Dialog. + + + + +Bold: and Italic: + +Use these Yes/No radio boxes to determine whether you want &kword; +to include boldface or italicized fonts in the search text. + + + + +Strikeout: + +You can select None, Single, Double +or Simple Bold to modify your search. + + + + +Underline: + +You can select None, Single, Double, +Simple Bold or Wave to modify your search. + + + + +Vertical alignment: + +You can select Normal, Subscript or +Superscript to determine what font alignment you want &kword; to search for. + + + + +Shadow: and Word by word: + +Use these Yes/No radio boxes to determine whether you want &kword; +to include shadow text in the search text and whether to search for word by word underlining and strikethrough text. + + + + +Capitalization: + +You can select Normal, Uppercase, Lowercase, or +Small Caps to determine what capitalization you want &kword; to search for. + + + + +Language: + +You can select the language of the text you want &kword; to search for using this dropdown box. + + + +Once you have selected your options, click OK to accept your search options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the default values. +Click Clear to remove all marks from the checked options. + + + + +Other Search options + +In addition to pattern matching, you can limit the search results +with a few useful options. + + + +Case sensitive + +When this option is selected, &kword; will not only search for the +string of letters, but will verify that the case of the letters is the +same. For example. Searching for: +KDEwill match: +KDE and +hiddenKDEinwords but not: Kde, +kde or hiddenkdeinwords. + + + + +Find backwards + +This option changes the direction of the search. This can be +useful when you only want to search for a string of text before the +current cursor position, not after. This option is usually used in +conjunction with From cursor, but if that option is +not specified, &kword; will start searching from the end of the document +backwards. + + + + +Whole words only + +When this option is selected, &kword; will only return search +items that are surrounded by spaces, paragraph marks or punctuation. For +example. Searching for: KDEwill +match: KDE but not: +hiddenKDEinwords or KDElike. + + + + +Selected Text +If you want to limit your search to a specific part of +the document (a few paragraphs, for example), you can select the part of +the document you want to search prior to selecting +the Find command. When text is selected, &kword; +will default to only searching the selected text. You can use this +option to enable or disable this restriction. + +This option will not be available if you have not selected text +prior to selecting the Find command. + + + + + +From cursor + +By default, &kword; begins searching at the beginning of the +document. If this option is selected, &kword; begins its search from +the current position of the cursor. The direction that &kword; searches +is, by default forward in the document, but can be changed with the +Find backwards option. + + + + +Once you have selected your options, click OK to accept your search options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the default values. +Click Clear to remove all marks from the checked options. + + + +Replace with formatted text +&kword; also has the ability to replace the found text with formatted text. + +To include formatting options in your search, click the button labeled +Show Formatting Options in the Replace With section. + +Once Show Formatting Options has been clicked, a new dialog will appear. + + + + + + + + +You can use this dialog to select the format of the replaced text. +The left column consists of 13 check boxes. If there is a mark in the check box, then &kword; will change +any replaced text to match the property selected. +If no mark is in the check box, &kword; does not consider that property when replacing text. + + + + +Family: + +Use this combo box to select the font family you want your replacement text to use. + + + + +Size: + +Use this spin box to set the font size you want &kword; to use for your replaced text. + + + + +Color: and Background color: + +Clicking on either of these two buttons allows you to select the font color and/or background color respectively, +you want &kword; to use. For more information on selecting a color, see the +section on Selecting Colors from the Color Dialog. + + + + +Bold: and Italic: + +Use these Yes/No radio boxes to determine whether you want &kword; +to change the fonts to boldface or italicized fonts. + + + + +Strikeout: + +You can select None, Single, Double +or Simple Bold to use for the replacement text. + + + + +Underline: + +You can select None, Single, Double, +Simple Bold or Wave to use for the replacement text. + + + + +Vertical alignment: + +You can select Normal, Subscript or +Superscript to determine what font alignment you want &kword; to use. + + + +Shadow: and Word by word: + +Use these Yes/No radio boxes to determine whether you want &kword; +to use shadow text and/or word by word underlining and strikethrough in the replacement text. + + + + +Capitalization: + +You can select Normal, Uppercase, Lowercase, or +Small Caps to determine what capitalization to use for the replacement text. + + + + +Language: + +You can select the language of the text you will use to replace the found text. + + + + +Once you have selected your options, click OK to accept your text options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the initial values prior to making any changes. +Click Clear to remove all marks from the checked options. + + + +Using placeholders +Placeholders are useful when you want to add text to complex search strings. Currently &kword; has only one placeholder: +Complete text string. +This placeholder will contain the entire text string matched by the Find command. +For example: +You create a search string, using regular expressions: Reference \d +In order for this string example to work, a mark must be placed in the check box labeled +Regular expression +Regular expressions are available by placing a mark in this checkbox. The use of regular expressions is beyond the +scope of this manual. For more information see the KDE Regular Expression Manual (Available in the &kde; help center). +Now in the Replace With section of the replace dialog, you place a mark in the check box labeled +Use placeholders. Click the Insert Placeholder button and select +Complete Match. &kword; will insert a \0 in the +Replacement text: text box. +Now surround the placeholder with parentheses, so your text string is: (\0) +When this is executed, whenever &kword; encounters the find text (ie. Reference 0, Reference 1, +Reference 2, etc) it will surround the text in parenthesis ((Reference 0), (Reference 1), +(Reference 2), respectively). +As you can see, the placeholder will maintain a copy of the search text. You can use this placeholder to add text to the ends of any +search string you can imagine. + + + +Other Replace Options + +Additional options in the dialog are: + + +Case sensitive + +When this option is selected, &kword; will not only +search for the string of letters, but will verify that the case of the +letters is the same. For example. Searching for: +KDEwill match: +KDE and hiddenKDEinwords but +not: Kde, kde or +hiddenkdeinwords. + + + + +Find backwards + +This option changes the direction of the search. This can be +useful when you only want to search for a string of text before the +current cursor position, not after. This option is usually used in +conjunction with From cursor, but if that option is +not specified, &kword; will start searching from the end of the document +backwards. + + + + +Whole words only + +When this option is selected, &kword; will only return search +items that are surrounded by spaces, paragraph marks or punctuation. For +example. Searching for: KDEwill +match: KDE but not: +hiddenKDEinwords or KDElike. + + + + +Selected Text +If you want to limit your search to a specific part of +the document (a few paragraphs, for example), you can select the part of +the document you want to search prior to selecting +the Find command. When text is selected, &kword; +will default to only searching the selected text. You can use this +option to enable or disable this restriction. + + +This option will not be available if you have not selected text +prior to selecting the Find command. + + + + + +From cursor + +By default, &kword; begins searching at the beginning of the +document. If this option is selected, &kword; begins its search from +the current position of the cursor. The direction that &kword; searches +is, by default forward in the document, but can be changed with the +Find backwards option. + + + + +Prompt on replace + +If this option is selected, &kword; will prompt the user +before each replacement. This allows you to +approve or disapprove each replacement. + + + + + + + + + + + + + +Spellchecking +spellingcheck spelling of document +&kword; can compare each word in your document to several commonly available dictionaries. It will offer you +the opportunity to change any words it believes are misspelled. +By default, if any text in the document is selected, +&kword; only checks the spelling of currently selected text. +If you want to check the spelling of a +specific part of your document, simply select the text you want to check the +spelling of. +To check the entire document, leave all text in the document unsellected, and &kword; will check +the entire document. +You can check the spelling of text 2 ways: + + + +By selecting +ToolsSpellcheckSpelling... +from the menubar + + + +By clicking on +the toolbar. + + + +Spellchecking your document is controlled through a dialog +box. + + + + + + + + +In this example, the misspelled word &kword; found, was +youve. The currently suggested replacement word is listed in the text box labeled +Replace with:. In the list box labeled Suggested Words is a list of words +the spelling program has determined as possible correct spellings. + +From here you have eight options: + + + +Replace + +Replaces the current word with the suggested word. Only replaces this +occurrence. + + + + +Replace All + +Replaces all occurrences of the current word with the +suggested word through the entire document. + + + + +Ignore + +Do not make any changes to this occurrence. Ask again if this +word appears further down in the document. + + + + +Ignore All + +Do not make any changes to this or any other occurrence of this word. Do not +ask about this word again. + + + + +Add + +Add the current word to the dictionary. + + + + +Stop + +Keep the current changes, but stop any further checking. + + + + +Cancel + +Stop spellchecking. + + + + +Help + +Loads a help file for the spellchecker. + + + + +When the entire document has been checked, &kword; will return the cursor to the same spot +in the document that the spellchecking was begun. + + +If the document does not have any spelling errors, &kword; does +not show a dialog box informing you there were no spelling errors. + +When spellchecking is started, it +will proceed to check all of the document against the dictionary, and +if there are no spelling errors it will close the spellcheck dialog box. With short documents, +this may happen quickly. &kword; has spellchecked the document! + + +There are several options for configuring the spelling application used. +For more details, please see the section entitled +Configure Spelling. + + +Automatically mark misspelled words +spellingautomatically mark misspelled words + +&kword; can check the spelling of your document as you edit it. It will underline in red any word which +it cannot find in the dictionary. This behavior can be turned on and off by the user. By selecting +ToolsSpellcheckAutospellcheck +from the menubar you can toggle autospellchecking on and off. + + + + + +Finding related word (Thesaurus) +thesaurus, using +Wordnet +related words + +&kword; comes with a small thesaurus based on the Wordnet project. For more information on Wordnet, visit the +Wordnet homepage. +You can invoke the thesaurus two ways: + + +Simply click on the desired word with the &RMB;. A popup menu will appear. Select +Show Related Words from the menu and a dialog will appear. +By selecting +ToolsShow Related Words +from the menubar + + +Which ever method you choose, &kword; opens the &kthesaurus; dialog box. + + + + + +The word you selected from your document appears in the combo box labeled Search for:. +There are three columns of alternate words: Synonyms, More General words (hypernyms), More Specific Words (hyponyms). +If you find an appropriate alternate word, simply click on the word in the list, and this word will now be listed in the text box labeled +Replace With:. +To finalize the replacement click Replace. +To keep your original word, click Cancel. +To obtain more specific help, or for help on using the full version of Wordnet, click the Help button for help with +&kthesaurus; (including additional thesauri for non-english languages). + + + + +Autocorrection +autocorrectionusing + +Auto correction is a system for correcting common typing errors, +converting abbreviations to their full spelling and adjusting +capitalization. As you could guess from its name, this all occurs +automatically, while you are editing your document. + + +Enabling/Disabling Autocorrection + +To toggle autocorrection on, select +ToolsAutocorrection +Enable Autocorrection +from the menubar. When enabled, autocorrection makes changes to your document as you type. You can +determine which changes to make by configuring autocorrection. + +To toggle autocorrection off, select +ToolsAutocorrection +Disable Autocorrection +from the menubar. When disabled, autocorrection changes are not made. You can, however, +apply autocorrection manually. + + + +Configuring Autocorrection Options +autocorrectionconfiguring + +To adjust the options for autocorrection, select +SettingsConfigure Autocorrection... +from the menubar. + +A dialog window appears to help you set your options. + + +Simple Autocorrection + + + + + + + + + + + +Convert first letter of a +sentence automatically to uppercase + +When selected, &kword; will automatically capitalize the first +letter after a period. You can tell &kword; when not to alter capitalization +in certain instances (ie Sr. or Jr.. For more details, see the section entitled +Autocorrection Exceptions. + + + + +Convert two uppercase letters to one uppercase and one +lowercase letter + +When selected, &kword; will automatically convert a double capital +letter (a common typographical error), into a single capital +letter. You can tell &kword; when not to alter capitalization +in certain instances. For more details, see the section entitled +Autocorrection Exceptions. + + + + +Autoformat URLs + +When selected, &kword; will scan text for patterns which suggest a certain section +of text is a URL and automatically creates a link. +For more details on links, see the section entitled +Document Links. + + + + +Suppress double spaces + +When checked, &kword; will ignore the second space typed. +This prevents users from adding double spaces between words or sentences + + + + +Remove spaces at the beginning and end of paragraphs + +When selected, &kword; will automatically remove spaces at the beginning and/or the end of a line of text. + + + + +Automatically do bold and underline formatting + +When selected, &kword; will look for words surrounded by asterisks ( * ). It will remove the asterisks and change the font of all +words in between the two asterisks to bold face. +&kword; will also look for words surrounded by underscores ( _ ). It will remove the underscores and underline all +words in between the two underscores. + + + + +Replace 1/2... with ½... + +When selected, &kword; will automatically change 1/2, 1/3 and 3/4 to their single character equivalents. + + + + +Use autonumbering for numbered paragraphs + +If you start a paragraph with a number and a symbol ( 1) for example). &kword; will automatically +convert that paragraph to a numbered paragraph. All future paragraphs will be consecutively numbered. + + + + +Replace 1st with 1^st + +When selected, &kword; will automatically change 1st to 1st. + + + + +Capitalize name of days + +Automatically capitalize the days of the week (Sunday, Monday, Tuesday, etc...). + + + + +Use list-formatting for bulleted paragraphs + +When selected, &kword; will look for lines that begin with - , and automatically convert the paragraph style +to a bulleted list. The bullet is selected with the left button below this option. + + + + + + + +Custom Quotes +Select the tab labeled Custom Quotes + + + + + + + + + +Replace double quotes with typographical quotes + +When selected, this option will replace the standard keyboard double +quotes, with typographical quotation marks. If you want to change the +quotation character, click on one of the buttons. Clicking on +Default, restores the default paragraph marks. + + + + +Replace single quotes with typographical quotes + +When selected, this option will replace the standard keyboard single +quotes, with typographical quotation marks. If you want to change the +quotation character, click on one of the buttons. Clicking on +Default, restores the default paragraph marks. + + + + + +Advanced Autocorrection + +To switch to the Advanced Autocorrection, click on the tab labeled +Advanced Autocorrection. + + + + + +This allows you to automatically have &kword; replace one string +of text with another. This can be useful for special symbols, commonly +used abbreviations that you want spelled out, or abbreviations. + +&kword; uses different autocorrection strings depending on the language. +Set the correct language using the combo box labeled +Replacements and exceptions for language:. + +The check box labeled Enable word replacement is used to +toggle on and off the autoreplacement features of &kword;. If there is no mark in the check box, +then &kword; will not perform any autoreplacements from the list in this dialog. + +If there is a mark in the check box labeled Replace text with format +&kword; will not only change the text when it finds a match, but it will change the formatting of the new text. +If there is no mark in this check box, then +&kword; uses the same formatting options for the replaced text as it found in the search text. For more information +on setting the format options for replacement text, see the section on +Changing the format of the autocorrection string. + + +Adding an autocorrection string + +To add an autocorrection string, simply type the text you want &kword; to +check for in the text box labeled +Find, then enter the text you want &kword; +to substitute in the text box labeled Replace. + + +If you want to insert symbols or special characters not available on your +keyboard, you can click the +buttons with three periods on them and select a special character from the table provided. + +When these are entered, click Add. Your text +strings are now added to the table. + + + +Editing an autocorrection string +Changing the text you want to find. +&kword; does not allow you to change the text to search for. +This is to prevent disastrous mistakes. +Instead, you must delete the current autocorrection rule and +add a new text string with the corrected text to find. + +Changing the text you want to replace. +Begin by clicking once on the string you want to edit. It will be +highlighted and the find and replace text will be listed in the text boxes +above. You can alter the replacement text. When you +are done, simply select Modify. + + + + +Deleting an autocorrection string. + +Simply click on the string you want to delete. Now click the +Remove button. The string is removed. + + +Be aware that &kword; does not give you a chance to back out once +you have deleted a string. Be sure you have selected the correct string +before you click the Remove +button. + + + + +Changing the format of the autocorrection string. +Currently, you must create the autocorrection string before you can format it. +Once the autocorrection string has been created, simply click on it once with the &LMB;. +Now click on the Change Format... button. A small dialog will appear: + + + + + + + +You can use this dialog to select the format of the replaced text. +The left column consists of 13 check boxes. If there is a mark in the check box, then &kword; will change +any replaced text to match the property selected. +If no mark is in the check box, &kword; does not consider that property when replacing text. + + + + +Family: + +Use this combo box to select the font family you want your replacement text to use. + + + + +Size: + +Use this spin box to set the font size you want &kword; to use for your replaced text. + + + + +Color: and Background Color: + +Clicking on either of these two buttons allows you to select the font color and/or background color respectively, +you want &kword; to use. For more information on selecting a color, see the +section on Selecting Colors from the Color Dialog. + + + + +Bold: and Italic: + +Use these Yes/No radio boxes to determine whether you want &kword; +to change the fonts to boldface or italicized fonts. + + + + +Strikeout: + +You can select None, Single, Double +or Simple Bold to use for the replacement text. + + + + +Underline + +You can select None, Single, Double, +Simple Bold or Wave to use for the replacement text. + + + + +Vertical alignment: + +You can select Normal, Subscript or +Superscript to determine what font alignment you want &kword; to use. + + + +Shadow: and Word by word: + +Use these Yes/No radio boxes to determine whether you want &kword; +to use shadow text and/or word by word underlining and strikethrough in the replacement text. + + + + +Capitalization: + +You can select Normal, Uppercase, Lowercase, or +Small Caps to determine what capitalization to use for the replacement text. + + + + +Language: + +You can select the language of the text you will use to replace the found text. + + + + +Once you have selected your options, click OK to accept your text options. +Click Cancel to ignore all changes. +Click Reset to restore the options dialog box to the initial values prior to making any changes. +Click Clear to remove all marks from the checked options. + + + + +Autocorrection Exceptions +autocorrection +exceptions + +There are instances where &kword; will make autocorrection changes +that are inappropriate. You can use the fourth tab of this dialog to define +exceptions to the rules previously discussed. +The dialog for exceptions is shown below: + + + + + +To prevent &kword; from deciding an abbreviation or other text is +the end of a sentence, simply enter the text fragment in the text box below +Do not treat as the end of a sentence:. Then click +Add. +As an example: Adding Jr. to this dialog prevents +Robert Jones Jr. is a friend of the family. +from being changed to: +Robert Jones Jr. Is a friend of the family. +To remove an erroneous entry, simply click once on the wrong entry with the &LMB; +and click on the Remove button. +The second set of boxes performs a similar function to the first except +text entered in these boxes will allow two capital letters in a word if it +is entered in this text box. +Simply enter the word in the text box below +Accept two uppercase letters in:. Then click +Add. +As an example: Adding CD to this dialog prevents +CD +from being changed to: +Cd +To remove an erroneous entry, simply click once on the wrong entry with +the &LMB; and click on the Remove button. + + + + +Manually applying autocorrection +autocorrectionmanually +applying + +If autocorrection is turned off in your document, you can manually enable autocorrection. +To manually apply autocorrection, first configure your options by using the +autocorrection dialogs. +Then select +ToolsAutocorrection +Apply Autocorrection +from the menubar. +&kword; will start at the beginning of the document and apply all selected +autocorrection options to the entire document. +When &kword; is finished, it will return you to your document for further editing. +For more information on enabling and disabling autocorrection, +see Enabling/Disabling Autocorrection. + + + + + +Autocompletion +autocompletion + +Autocompletion allows you to type the first few letters of a commonly +used word (often technical or job specific), and tell &kword; to +finish typing the word for you. This is often very useful when you have lengthy +technical words. + +Using autocompletion +Using autocompletion could not be easier. Simply type the first few +letters of the word you want &kword; to finish, and press +&Ctrl;E. &kword; will look +through the list of autocompletion words and if it finds a word which begins +with those letters, it will finish entering the remainder of the word. + +Adding words to autocompletion +&kword; maintains a list of words for each user that will be used for +autocompletion. +You can add words to this list one of two ways: + +&kword; can automatically add new words to the completion list +for later approval. +This is selected using the dialog. +Individual words can be added to the list by using +the dialog. + + + + +Configuring autocomplete +To configure autocompletion, select +SettingsConfigure +Completion... +from the menubar. This will bring up a dialog. + + + + + + + + + + +Enable word completion +It is used to toggle autocompletion on and off. + + + +Add + +By clicking this button you can manually add +an individual word to the completion list. + + + + +Remove + +To remove words from the completion list, select the word with the &LMB; +from the list, then click this button. + + + + +Automatically add new words to suggestion list + +This option will add any word equal to or longer than +the Characters needed: to the list of proposed +autocompletion words. +The large listbox in the center of the dialog contains the current +proposed list of autocompletion words. +Not all words listed in the list box will be immediatly affected by +autocompletion when entered into this dialog. + + + + +Show words in tooltip + +If this option is enabled, a tool tip box will appear when you type the +beginning of a word that exists in the completion list. To complete the word, +press the key you set to accept suggestions in the Key to accept +suggestion: drop-down list. + + + + + +Characters needed: + +Use this spinbox/slider combination to prevent &kword; +from automatically adding short words to the completion list. You can select +any value from 5-100 and the words will need to be at least the number of +characters set here to be added in the list. + + + + +Suggest words: + +This spinbox/slider combination can be adjusted to allow more or less +words into the autocompletion list. This option is most important when +Automatically add new words to suggestion list is enabled. +This option keeps the list from becoming too cumbersome. You can select any +value from 1 to 500. + + + + +Append space + +If checked, it adds a single space to the end of a word after +autocompletion, this means it is not necessary to add the space manually for the +next word. + + + + +Key to accept suggestion: + +Set the key you want to use when an autocompleted word is suggested to you +and you want to accept it. You can choose +Enter, Tab, Space, +End or Right. + + + + +Make Default + +A word is not part of autocompletion until the list is +saved to disk. At that moment, &kword; +will use that saved list for all autocompletion, until the list is replaced with +another saved list. +Some of the words in the autocompletion list may not have been saved +yet.To save the current list to disk and have &kword; begin using +this new list for autocompletion, +click this button. + + + + +Click OK to save your options. Click +Cancel to abort all changes. Click +Reset to reset to the state after you clicked on the +Make Default button. + + + + + + diff --git a/doc/kword/editpaste.png b/doc/kword/editpaste.png new file mode 100644 index 000000000..121448cf4 Binary files /dev/null and b/doc/kword/editpaste.png differ diff --git a/doc/kword/edittb.png b/doc/kword/edittb.png new file mode 100644 index 000000000..8235f46d1 Binary files /dev/null and b/doc/kword/edittb.png differ diff --git a/doc/kword/end.png b/doc/kword/end.png new file mode 100644 index 000000000..13797589c Binary files /dev/null and b/doc/kword/end.png differ diff --git a/doc/kword/enumlist.png b/doc/kword/enumlist.png new file mode 100644 index 000000000..bc5559686 Binary files /dev/null and b/doc/kword/enumlist.png differ diff --git a/doc/kword/exoffset.png b/doc/kword/exoffset.png new file mode 100644 index 000000000..9c9998d4e Binary files /dev/null and b/doc/kword/exoffset.png differ diff --git a/doc/kword/expression.png b/doc/kword/expression.png new file mode 100644 index 000000000..a9c69da4d Binary files /dev/null and b/doc/kword/expression.png differ diff --git a/doc/kword/expressions.docbook b/doc/kword/expressions.docbook new file mode 100644 index 000000000..0d0a3f334 --- /dev/null +++ b/doc/kword/expressions.docbook @@ -0,0 +1,93 @@ + + + + +Mike +McBride + + + + +Expressions +expressions + +Expressions are a way to quickly insert common phrases into a document. Once an expression has been selected, the +text is inserted into &kword;. + Expressions are different from variables. Expressions are inserted as regular text, can only be +changed later by manually editing the text. Variables, insert a placeholder in the document which can be automatically updated at +a later date. +Using expressions +To use an expression could not be easier. +Simply place the cursor at the location you want the expression inserted and select + +InsertExpression + from the menubar. This will give you a submenu with groups of expressions. Select the group that is appropriate +for your expression. This will bring up a list of expressions available to you. Select the appropriate expression. +Once selected, that expression will be inserted at the cursor position. + +Add, change and delete expression groups and expressions +Adding an expression is accomplished by selecting +ToolsEdit Personal Expressions... + from the menubar. This will bring up a dialog box. + + + + + + +The list at the left shows you all available groups (Employees and Notices +in the example above). +Notices is the currently selected group. +Add a new group +You will need to create a new group the first time you want to add a new expression. &kword; + will not allow the user to edit or remove any predefined expressions. You create a new group by clicking on the + New located below the group list. A new group will be created + with the name new group. You can change the name of the new group by clicking on the + newly created group in the group list on the left, then editing the text box on the right labeled Group name:. + +Change the name of a group +To change the name of a group, simply click on the group in the list on the left side of the dialog. Type the new name in the text +box labeled Group name:. + +Delete a group +To delete a group, click on the group in the list on the left side of the dialog. +Be sure you have selected the correct group prior to clicking on the Delete +button. &kword; will not give you the opportunity to restore the group if it is accidentally deleted. + Click on the +Delete button below the group list. The group and all of the expressions it +contained are immediately deleted. +Deleting an expression with this dialog does not delete the expression from any document. It only removes the +expression from the menus. + +Add a new expression to a group +The left side of the dialog box lists all the available groups. Select the group you want to add your expression to by +clicking with the &LMB; on the name of the group. The list on the right of the dialog labeled +Expressions lists all the current expressions in the current group. +To add an expression, click on the New located below the expression list. +A new expression is created called empty. Type your new expression in the textbox below the list of expressions. + +Edit an expression in a group +The left side of the dialog box lists all the available groups. Select the group that contains your expression to by +clicking with the &LMB; on the name of the group. The list on the right of the dialog labeled +Expressions lists all the current expressions in the current group. +Click on the expression you want to edit in the expression list on the right. +Click in the text box below the expression list. You can now edit your expression in the textbox below the list of expressions. +When you are finished adding new expressions, simply click OK. + +Delete an expression +To delete an expression, click on the group in the list on the left side of the dialog. This will show a list of the expressions +belonging to that group in the listbox on the right labeled Expressions. +Select the expression you want to delete by clicking once with the &LMB;. +Be sure you have selected the correct expression prior to clicking on the Delete +button. &kword; will not give you the opportunity to restore the expression if it is accidentally deleted. + Click on the +Delete button below the expression list. The +expression is immediately deleted. +Deleting an expression with this dialog does not delete the expression from any document. It only removes the +expression from the menus. +When you are finished making changes, simply click OK. + + + + + diff --git a/doc/kword/exst.png b/doc/kword/exst.png new file mode 100644 index 000000000..87297239f Binary files /dev/null and b/doc/kword/exst.png differ diff --git a/doc/kword/exul.png b/doc/kword/exul.png new file mode 100644 index 000000000..32a366199 Binary files /dev/null and b/doc/kword/exul.png differ diff --git a/doc/kword/fchardlg.png b/doc/kword/fchardlg.png new file mode 100644 index 000000000..444f0601f Binary files /dev/null and b/doc/kword/fchardlg.png differ diff --git a/doc/kword/fchardlg2.png b/doc/kword/fchardlg2.png new file mode 100644 index 000000000..d491493f9 Binary files /dev/null and b/doc/kword/fchardlg2.png differ diff --git a/doc/kword/fchardlg3.png b/doc/kword/fchardlg3.png new file mode 100644 index 000000000..592a342bf Binary files /dev/null and b/doc/kword/fchardlg3.png differ diff --git a/doc/kword/fchardlg4.png b/doc/kword/fchardlg4.png new file mode 100644 index 000000000..ceadfb81e Binary files /dev/null and b/doc/kword/fchardlg4.png differ diff --git a/doc/kword/fchardlg5.png b/doc/kword/fchardlg5.png new file mode 100644 index 000000000..942c0e1e2 Binary files /dev/null and b/doc/kword/fchardlg5.png differ diff --git a/doc/kword/filefloppy.png b/doc/kword/filefloppy.png new file mode 100644 index 000000000..57d25a644 Binary files /dev/null and b/doc/kword/filefloppy.png differ diff --git a/doc/kword/filenew2.png b/doc/kword/filenew2.png new file mode 100644 index 000000000..d6ffc9647 Binary files /dev/null and b/doc/kword/filenew2.png differ diff --git a/doc/kword/fileopen.png b/doc/kword/fileopen.png new file mode 100644 index 000000000..5ba1875b7 Binary files /dev/null and b/doc/kword/fileopen.png differ diff --git a/doc/kword/fileprint.png b/doc/kword/fileprint.png new file mode 100644 index 000000000..b4c9d55da Binary files /dev/null and b/doc/kword/fileprint.png differ diff --git a/doc/kword/fileprint2.png b/doc/kword/fileprint2.png new file mode 100644 index 000000000..51eee9ddf Binary files /dev/null and b/doc/kword/fileprint2.png differ diff --git a/doc/kword/filetb.png b/doc/kword/filetb.png new file mode 100644 index 000000000..d0b1b5b5f Binary files /dev/null and b/doc/kword/filetb.png differ diff --git a/doc/kword/find.png b/doc/kword/find.png new file mode 100644 index 000000000..515a840f5 Binary files /dev/null and b/doc/kword/find.png differ diff --git a/doc/kword/finddlg.png b/doc/kword/finddlg.png new file mode 100644 index 000000000..d8cf12c6b Binary files /dev/null and b/doc/kword/finddlg.png differ diff --git a/doc/kword/finddlg2.png b/doc/kword/finddlg2.png new file mode 100644 index 000000000..98fefdf8a Binary files /dev/null and b/doc/kword/finddlg2.png differ diff --git a/doc/kword/footcfg1.png b/doc/kword/footcfg1.png new file mode 100644 index 000000000..713263e45 Binary files /dev/null and b/doc/kword/footcfg1.png differ diff --git a/doc/kword/footcfg2.png b/doc/kword/footcfg2.png new file mode 100644 index 000000000..830094ede Binary files /dev/null and b/doc/kword/footcfg2.png differ diff --git a/doc/kword/footcfg3.png b/doc/kword/footcfg3.png new file mode 100644 index 000000000..d50fbcf9d Binary files /dev/null and b/doc/kword/footcfg3.png differ diff --git a/doc/kword/footend.png b/doc/kword/footend.png new file mode 100644 index 000000000..6dffe55bf Binary files /dev/null and b/doc/kword/footend.png differ diff --git a/doc/kword/footendnotes.docbook b/doc/kword/footendnotes.docbook new file mode 100644 index 000000000..5ec62451f --- /dev/null +++ b/doc/kword/footendnotes.docbook @@ -0,0 +1,200 @@ + + + + +Mike +McBride + + + + +Footnotes and Endnotes +footnotesintroduction +endnotesintroduction + +&kword; has a complete set of tools to create and manage footnotes and endnotes. When you assign a footnote, &kword; automatically +places the footnote at the bottom of the correct page. When you assign an endnote, the notation is located in a numbered list at the end of your text. + If the footnote or endnote reference point is moved to a new page, the footnote automatically +follows and is renumbered as needed (if the user desires). +&kword; also has the ability to separately manage endnotes and footnotes in the same document. +You have the option of having &kword; control the numbering of your footnotes. Alternatively, you can manually specify each footnote. +There are multiple automatic numbering schemes and your footnotes can be separated from the text with a dividing line. + + +Add a new footnote or endnote +footnotescreating +endnotescreating + +To add a new footnote or endnote, place your cursor at the end of the text you want to reference. Then select +InsertFootnote/Endnote... +from the menubar. This will bring up a dialog box. + + + + + + + + + +If you want &kword; to automatically number your footnotes or endnotes for you, make sure that Automatic is selected. +If you want to manually enter all footnotes in, then select Manual and enter the footnote or endnote entry in +the text box to the right. +If at all possible, try to allow &kword; to automatically number the footnotes and endnotes for you. If &kword; controls the numbering, and you +insert, delete or move footnotes, &kword; will automatically renumber or reorder the footnotes for you. + +Then select either Footnote or Endnote. Footnotes will appear at the bottom of the +page where the notation occurs. Endnotes will appear as an ordered list at the end of your document. + +Click Configure to change the look of your footnotes or endnotes. +Click Cancel to return to your document without inserting a footnote or endnote. + +Click OK to insert the footnote or endnote. &kword; will create the footnote or endnote +entry, and place the cursor at the beginning of the entry for you to enter the desired reference information. +Type your reference information in the space provided. + +When you have finished entering your footnote or endnote reference information, simply move your cursor over the footnote or endnote +number. Click with the &RMB;. A popup menu will appear. Select Go to Footnote and &kword; will move the cursor back to the text +where the reference was made. + + + +Change reference of footnote +footnotesediting +endnotesediting + +There are two ways to change reference information for a footnote: + +Place the mouse pointer over the footnote you want to change, and click once with the &RMB;. +A popup menu will appear. Select Edit Footnote. &kword; will immediately move your +cursor to the appropriate footnote reference. +Simply move to the bottom of the page (if it is a footnote) or the end of the document +(if it is an endnote). Locate the footnote or endnote reference, and click once with the &LMB;. +You can jump to the end of the document by typing &Ctrl;End. + + + + +Delete a footnote or endnote +footnotesdeleting +endnotesdeleting + +To delete a footnote, simply delete the footnote or endnote number. &kword; will remove the reference information and resize the footnote frame. + + + +Change the look of footnotes +footnoteschange appearance + +To configure the appearance of footnotes, select Format +Footnote... from the menubar. A dialog will appear. + + + + + + + + +There are 5 predefined numbering methods for footnotes. Those methods are listed in the left +side of the dialog box. Begin by selecting the numbering method you want by clicking once with the &LMB;. +In the text box labeled Prefix text:, you can enter any characters you want to +appear before the footnote number. +In the text box labeled Suffix text:, you can enter any characters you want to +appear after the footnote number. +You can adjust the starting position of the footnote counter using the spinbox labeled Start at:. + + + +Change the appearance of separator line +To change the appearance of the separator line, click on the tab labeled Separator Line. + + + + + + + +You can determine the alignment of the separator line by selecting Left, +Centered or Right +Determine the length of the line using the spin box labeled Size on page:. +The spinbox labeled Width: is used to determine the thickness of the seperator line. +Do not confuse this option with the Size on page: option. The Width: is used to set the thickness of the line, not its distance across the page. +Use the combo box labeled Style to determine what kind of line is drawn. +Click OK to change the look of all footnotes or click Cancel to keep +the previous options. + + + +Change the placement of the footnotes +You can determine how much space separates the main text frame and the footnotes. Select + +FormatPage Layout... +from the menubar. This will bring up a dialog: + + + + + + + + +Click on the tab labeled Header & Footer. + + + + + + + + +At the bottom of the dialog is a text box is labeled +Spacing between footnote and body. As the label +suggests, you can use this text box to specify the distance between +the bottom edge of the main frame, and the top edge of the footnotes. +When you have entered the desired spacing, click +OK, and the footnotes will change position on +the page. + +If both footnotes and endnotes are on the current page, the +setting will apply to the space between the body and the +footnotes. + + + +Change the look of endnote entries +endnoteschange appearance + +To configure the appearance of endnotes, select Format +Footnote... from the menubar. A dialog will appear. + + + + + + + +Click on the tab labeled Endnotes. + + + + + + + + +There are 5 predefined numbering methods for footnotes. Those methods are listed in the left +side of the dialog box. Begin by selecting the numbering method you want by clicking once with the &LMB;. +In the text box labeled Prefix text:, you can enter any characters you want to +appear before the endnote number. +In the text box labeled Suffix text:, you can enter any characters you want to +appear before the endnote number. +You can adjust the starting position of the endnote counter using the spinbox labeled Start at:. + +If you want a line seperating the text of the document from your endnotes, instructions +for this can be found in the section entitled Change the appearance of separator line. + + + + + diff --git a/doc/kword/formabs.png b/doc/kword/formabs.png new file mode 100644 index 000000000..df2e5d7ec Binary files /dev/null and b/doc/kword/formabs.png differ diff --git a/doc/kword/formatchar.docbook b/doc/kword/formatchar.docbook new file mode 100644 index 000000000..724a726cd --- /dev/null +++ b/doc/kword/formatchar.docbook @@ -0,0 +1,319 @@ + + + + +Mike +McBride + + + + +Formatting Characters +textformatting +fontformatting +formatting text + +This section will cover the changes that can be made to individual characters or +blocks of characters including: + + +Character size +Font +Font style (italic, bold, etc). +Underlines, superscript, subscript, strikeout, etc. +Character color and background color. +Character case. + + + + +Changing Size, Font, Font Style, Text color and Background Color +textchange size +change text size +textchange font +change text font +textchange color +change text color +textchange background color +change text background color +textbold +bold text +textitalicized +italicized text +textunderlined +underlined text +textstrikethrough +strikethrough text +textsuperscript +superscript text +textsubscript +subscript text + + + +Using the Keyboard or toolbars + +There are several keyboard shortcuts which you can use to make +common changes to character formatting. After selecting the text, you +can use these key combinations to toggle each attribute. + +The Format toolbar also has buttons which you can use to +toggle these same attributes. + +The following table details each attribute, the toolbar buttons +and the keyboard shortcuts. + + + +AttributeToolbar +ButtonKey Combo + +Font Size +Decrease font size: Ctrl< Increase font size: Ctrl> +Font- +Bold Face&Ctrl;B +ItalicsCtrlI +UnderlineCtrlU +Strikethrough- +Superscript- +Subscript- +Font Color- + + + + +You cannot change the all text attributes using the keyboard or a button on a +toolbar. For these attributes, you must use the dialog +box. + + + + + +Using the Dialog Box + +If you have many changes to make, you can also use a dialog box to +set these same attributes. + +You can open the Select Font dialog box in one of three +ways: + + + +Select +FormatFont... +from the menubar. + + + +Click on the selected text with the &RMB;. A small menu will appear. Select Font... from the +menu. + + + + +You can use the keyboard shortcut: +&Alt;&Ctrl;F + + + +Either method will open a dialog box + + + + + + + + +Using this dialog box, you can select the font, size, +italics and boldface options from the top three list boxes. + +The preview box along the middle of the dialog, will show you how your current +settings will appear. + +If the default preview string is not appropriate, you can change it by clicking once +inside the preview box with the &LMB;. A text cursor will appear. You can edit the text to suit your needs. +The sample sentence will revert to the default the next time you +open this dialog. + + +If you click the tab labeled Highlighting, the dialog changes to: + + + + + + + + +The subsection labeled Underlining: has two combo boxes and a color selector box. +In the left most combo box select between +no underline (None), Single, Simple Bold, +Double or Wave underlining. + + + + + + + + + +Use the center combo box to select the style of underlining (Solid line, dashed line, etc.). +Use the right color selector box to select a color for the underline using the +color selection dialog box. + +The subsection labeled Strikethrough: has two combo boxes. +Use the left combo box to select between +no strikethrough (None), Single, Double or +Simple Bold strikethrough. Use the right combo box to select the line style. + + + + + + + + +The checkbox labeled Word by word determines how underlining and strikethrough are drawn. + + + + + + + + +The section labeled Capitalization lets you select one of four special capitalization options. +This will change the capitalization of the selected text. Examples of each scheme are shown below. + + + + + + + + +The changes to capilalization will only affect the selected text at the current moment. This formatting is not enforced after closing the dialog box. + +The third tab labeled Decoration allows you to change the color of the font, change the background color and create artificial shadows for your characters. Click on the tab: + + + + + + + + +Using the buttons labeled Text color: and Background color: you can change the color of the text or the background behind the text. + +To create the illusion of a shadow behind your text, select the color you want your shadow by clicking the button labeled Shadow color:. Then select the distance between the shadow and +the text using the spin box labeld Shadow & distance:. Finally, select the direction of your shadow by +selecting one of the eight red squares. A preview of your shadow appears at the bottom of the dialog box. + +The fourth tab labeled Layout allows you to create superscripts and subscripts. It also lets you select automatic hyphenation on a character by character basis. + + + + + + + + +The section labeled Position has four radio buttons and two spin boxes. Selecting Normal, produces text of normal height and at the normal vertical position. Selecting Superscript or Subscript will convert the currently selected text. If you select Custom, you can use the spin box labeled Offset: to move the selected text up or down relative to normal text alignment. Look at the example below: + + + + + + + + +Notice how a positive offset raises the text, and a negative offset lowers the text. + +You can also use the spinbox labeled Relative size: to make the selected font larger or smaller. + +The checkbox labeld Auto hyphenation is used to toggle automatic hyphenation on or off for the selected text. + +The fifth tab labeled Language allows you to change the language. Click on the tab: + + + + + + + + +You can select the language to use on the selected text with the drop down box. If the selected text allows for automatic hyphenation, +&kword; will use general rules of spelling for the selected language to automatically hyphenate the selected text. + +Clicking OK will commit your changes to the +document and close the dialog box. + +Clicking Apply will commit your changes to the +document but keep the dialog box open. + +Clicking Reset will restore the default settings to the selected text. + +Clicking Cancel will abort all changes +made. + + + + + +Changing Font Case +textchanging case +change case of text + +&kword; can change the case (uppercase or lowercase) of large blocks of text to one of five pre-defined styles. +Begin by selecting the block of text you want changed. Select +ToolsChange Case... +from the menubar. +A small dialog box will appear with five options: + + +Uppercase +Will convert all characters to uppercase. +Example: KWORD WILL AUTOMATICALLY CHANGE CASES. + + + + +Lowercase +Will convert all characters to lowercase. +Example: kword will automatically change cases. + + + + +Title case +Will capitalize every word. +Example: Kword Will Automatically Change Cases. + + + + +Toggle case +Converts all lowercase letters to uppercase and +converts all uppercase letters to lowercase. + + + + +Sentence case +Capitalizes the first character after a period. + + + + + +When you have selected the desired options click OK and &kword; will make the changes. + + + + + + + diff --git a/doc/kword/formatframes.docbook b/doc/kword/formatframes.docbook new file mode 100644 index 000000000..ab081ddde --- /dev/null +++ b/doc/kword/formatframes.docbook @@ -0,0 +1,503 @@ + + + + +Mike +McBride + + + + +Setting the Properties for a Frame +framesconfigure + +For each frame in your document, you can determine: + + + +how &kword; handles full text frames + + + +how text wraps around or through overlapping +frames + + + +the exact size of the frame + + + +establish margins within a frame. + + + +set a background color and pattern for the frame. + + + +All of these options can be altered using a set of dialog boxes, +or by using a previously defined framestyle. +A framestyle is a predefined set of frameset formatting options which is given a name. Once a frameset +has been assigned a framestyle, any changes made to the framestyle will be reflected in all framesets which are +assigned that framestyle. +You may be noticing that framestyles function in a way similar to text styles. The main difference, is +framestyles control the look of the frame, and textstyles control the look of paragraphs within the frame. + + +Using the frame settings dialogs + +All of these settings can be determined in the Frame +Properties dialog box. + +In order to adjust the properties of any frame, you must first +select the frame you want to change. + +Simply click once on the frame border of the frame you want to +edit. (Or by holding down the &Ctrl; key and clicking inside the frame with the +&LMB;.) + +You edit the properties of a frameset using a set of dialogs which you can +open one of two ways: + + + +Select +FramesFrame/Frameset Properties +from the menubar. + + + +Place the mouse pointer on the border of the frame, and click once +with the &RMB;. A small menu +will appear. Select Frame/Frameset Properties.... + + + + +The Properties dialog consists of one dialog box, with six index +tabs labeled Options, +Text Run Around, +Connect Text Frames, +Geometry, +Background and +Borders. + +General Options +framesconfigure automatic creation +framesprotect contents of + + + + + + + + +The tab labeled Options is used to determine how +&kword; behaves when there is too much text +to fit within the current bounds of the +frame. + +&kword; has three solutions to this situation: + + + +Create a new +page +When a frame becomes full, &kword; automatically +creates a new page. On this new page, it may create a new frame, of the +same size and position, if you choose. + + + +Resize last +frame +When a frame becomes full, &kword; +automatically extends the bottom border of the text frame to accommodate +the new text. It will continue to expand as new text is added. Conversely, it will shrink again if text is removed from the frame. + + + +Don't show the extra text +&kword; does not +create a new frame or change the current frame in any way. You will +need to manually resize the current frame, or add a new frame to the +frame set. + + + +Simply make your selection in the section labeled If Text is Too Long for Frame. + +In the section entitled On New Page Creation, you have three options available. You must select one. + + + +Reconnect frame to current flow +Create a new frame, the same size and shape on a new page, and make it the last frame in the frameset. + + + +Do not create a followup frame +Creates a new page, but not a new frame. + + + +Place a copy of this frame +Creates a new page, with a new frame the same size, shape and position on the page. Additionally, &kword; +copies the contents of the frame from the previous page. +This is useful for title frames, headers and footer frames. Each page will have an automatic copy of this information +on any new pages. + + + + + +If you place a mark in the check box labled Changes will be applied to all +frames in frameset, then any changes made in the frame properties dialog box +will automatically be applied to all frames within the frameset. + +If you place a mark in the check box labeled Protect content, &kword; +will not allow any changes to the text within the frame, or the formatting of the text within the frameset. + +You can still reshape or even delete the frame, but the content within the frame is locked. To lock the location +and size of the frame, see the Geometry tab. + +To make changes to the text, you need to remove the mark from Protect content. + + +Text Flow around frames +framesforce text around + +To adjust how text flows around overlapping frames, click the tab +labeled Text Run Around. + + + + + + + + +When you overlay two text frames, and text from both frames is +competing for the same space on the page, &kword; can (at your option), +make sure that text from two frames does not overlap. + + + + + + + + + + + +As you can see from the options in the dialog box, there are three +possible choices. + + + +Text will run through this frame + +By selecting this option, &kword; will ignore this frame +when it displays the text in overlapping frames. + + + + +Text will run around the frame + +By selecting this option, &kword; will wrap the text +of overlapping frames around this frame. +If this option is selected, you can determine which side the text runs around in the section labeled +Run Around Side. Simply choose Left, Right, +or Longest side. + + + + +Text will not run around this frame + +By selecting this option, &kword; will not wrap any +text around the edges of this frame, but instead, will skip down below +this frame before continuing to display text in overlapping frames. + + + + +You can also determine how close your frames appear by setting the +Distance Between Frame & Text in the spin boxes provided. If you place a mark in the +checkbox labeled Synchronize changes +&kword; will make all distances equal. + + +Move a frame to a new frameset +framesedit framesets +framesetsedit + +You can change which frameset the current frame belongs to by selecting +the Connect Text Frames tab. + + + + + + + + +This dialog gives you the option to create a new frameset for the current frame or move the selected frame to a current frameset. +Select Select existing frameset to connect frame to:, to add the current frame to a previously created +frameset. Choose one of the +framesets listed in the table below to specify which frameset. +To create a new frameset, select Create a new frameset: and type the name of the new frameset in the +text box labeled Name of frameset. &kword; will create a new frameset with the current frame +as the only frame in the frameset (for now). +It is helpful to name your framesets with descriptive names. Name the frameset with a description of the contents +so that you can quickly refer to it again later. + + +Frame size and position +framesgeometry +framesdetermine size (dialog box) +framesdetermine position (dialog box) + +You can adjust the size and position of your frame by +clicking on the tab labeled Geometry. + + + + + + + + +This dialog box allows you to specify exactly +where the frame goes and how large it is. + +If you put a mark in the check box labeled Protect size and position, the frame size and position will +be fixed at their current location. You will not be able to move the frame on the page until this box is unchecked. + +Determine Size and Position +You can locate your frame on the page by first entering the Left: +and Top: measurements. This determines where the top left corner of the +frame will be. All measurements are from the top left corner of the +page. + +You can also determine the exact size of the frame by entering its +Height: and Width: in the text boxes provided. These two measurements are +relative to the top left corner of the frame you specified above. not to the size of the page. + +Determine Margins in the Frame + +Using the boxes labeled +Left:, Right:, Top: and Bottom:, you can establish +margins within the frame. This should not be confused with margins for the page, which are defined in the +page properties dialog box. + +If the Synchronize changes check box has a mark in it, &kword; will take any changes you +make to one margin, and automatically apply them to the other 3 margins. + +In other words, if this check box is selected, and you enter a margin of 1 cm in any of the 4 margin boxes, all 4 frame margins will now +become 1 cm in size. + +If this option is off, each text box can be given a different value. + + + + +Frame Background +framesbackground colors and patterns + +You can adjust the background color of the text frame by selecting the Background tab. + + + + + + + + +Select the color of the background by clicking on the button labeled +Background color:. The color is selected using the +Color selection dialog. + + +Frame Borders +framesborders + +You can change the borders of the text frame by selecting the Borders tab. + + + + + + + + +Select the Style: and Width: of the borders +with the two drop down boxes on the left side of the dialog. +Select the color of the borders by clicking on the button labeled +Color:. The color is selected using the +Color selection dialog. +Use the four icons (Border Left, Border Right, Border Top +and Border Bottom) below the Color button +to determine on which side of the frame you want to have a border. +A Preview of the selected settings is shown on the right side of the dialog. + + +Click OK to accept all of your changes and to close the dialog box. +Click Apply to accept all of your changes without closing the dialog box. +Click Cancel to forget all of your changes. + + + + +Using frame styles +framesframe styles +frame styleusing + + +Formatting a frame with a framestyle +frame styleapply frame style to a frame + +To format a frame using a predefined framestyle simply: +Select the frame(s) by holding down &Ctrl; and clicking within the frame with the &LMB;. +Select +FramesFramestyle +from the menubar. A submenu will appear, listing all the currently defined framestyles. Select the name of the framestyle +you want and all selected frames will automatically be formatting using the options of that framestyle. + + + +Editing a framestyle +frame styleediting + +To change the options of a framestyle, you will need to use the framestyle manager. +Select +FramesFrame Style Manager... +from the menubar. A dialog box will appear. + + + + + + + + +All of the currently defined framestyles are listed in the listbox on the left. The currently selected framestyle is highlighted, and +the name of the currently selected framestyle is listed in the text box labeled Name. (In this example, +the currently selected framestyle is Light Gray.) +Select the framestyle you want to change by clicking on the name of the framestyle in the listbox on the left. +There are three tabs in on the right side of the dialog box: General, Borders +and Background +In the General tab, you can change the name of the liststyle by typing the new name in the text box +labeled Name. You can also see a preview of what your frame will look like in the preview box. +The Borders tab works the same as the tab of the same name when formatting a paragraph. For more specific +information click here. +The Background tab operates identically to the same tab when formatting a frame. Click +here for more specific instructions. +Once all changes have been made, click OK to save your changes. All of the affected framesets will +be changed to reflect the new options. + + + +Creating a new framestyle +frame stylecreate new + +To create a new framestyle, select +FramesFrame Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Select a framestyle from the list at the left which most closely matches your new desired framestyle by clicking on the name with the &LMB;. +The selected framestyle will be used as a template for the new framestyle. +Click on the New button. &kword; will generate a new framestyle, which is a copy +of the previously selected framestyle. +Choose a name for your new framestyle, and type it in the text box labeled Name. +You can now change your frame border and background options. For details, see +Editing a framestyle. +When you are finished creating your framestyle, click OK, and your framestyle is saved. +Framestyles are specific for each document. A framestyle created in one document can not be used in another document unless you +import the framestyle from that document. + + + +Deleting a framestyle +frame styledeleting + +To delete framestyle, select +FramesFrame Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Select the framestyle you want to delete by clicking once with the &LMB; in the list on the left. +Click on the Delete button. +&kword; will not allow you to delete the Plain framestyle. + + + +Changing the order of the framestyles in the list +To change the order that the framestyles are listed, select +FramesFrame Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +The order the framestyles are listed in the menu is determined by the order of the framestyles in the list on the left. +Select the framestyle you want to move from the list at the left by clicking once with the &LMB;. +Now click on the up and down arrows located at the bottom of the list of framestyles. This will move the +selected framestyle up or down in the list of framestyles. +When you are satisfied with the order of the list, select OK. + + + +Importing a framestyle from another &kword; file +frame styleimporting from another file + +To import a framestyle from another &kword; file, select +FramesFrame Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Click the button labeled Import From File... to open the +file selection dialog. +  Choose your file, and click OK. +A new dialog box will appear listing all available framestyles for importing. + + + + + + + +If &kword; encounters a duplicate framestyle name in the selected file, it will append a number to the end of the +framestyle name to identify the imported style. +As an example, if you import the Plain framestyle from another &kword; file, &kword; will change +the name to Plain-1. +Select all the framestyles you want to import. Then click +OK. +The framestyles will now appear at the bottom of your list of framestyles. Click OK +to save the framestyles to the new document. + + + diff --git a/doc/kword/formatpara.docbook b/doc/kword/formatpara.docbook new file mode 100644 index 000000000..88d78aa5b --- /dev/null +++ b/doc/kword/formatpara.docbook @@ -0,0 +1,388 @@ + + + + +Mike +McBride + + + + +Formatting Paragraphs +paragraphformatting +This section will detail all the options available to format paragraphs. + +To format a paragraph, place the cursor in the paragraph. To format more than +one paragraph at a time, simply select the paragraphs with the mouse or keyboard. + +You can format one or more paragraphs one of three ways: + + + +Select +FormatParagraph... +from the menubar + + +Type &Alt;&Ctrl;P + + +Place the mouse pointer in the paragraph and click once +with the &RMB;. A small menu +will appear. Select Paragraph.... + + + +A dialog will appear. + +The Paragraph Settings dialog consists of five tabbed sections +labeled Indent and Spacing, General Layout, Borders, +Bullets/Numbering, and +Tabulators. + + +Indents and Spaces +paragraphindent lines +paragraphchange line spacing +paragraphkeep lines and paragraphs together + +With this dialog box the +spacing between lines, and the spacing between paragraphs can be specified. + + + + + + + + +The first section of this dialog box is labeled +Indent, and consists of three spin boxes: + + + +Left + +Enter a value in this box to indent the lines of the selected paragraphs away from the left margin. +The first line is unaffected by this spin box. To +alter the first line, specify that value in the spin box labeled First Line. + + + + +Right + +Enter a value in this spin box to indent all lines of the selected paragraph +(including the first line) away from the right +margin. + + + + +First Line +Enter a number in this spin box to indent the first line of a paragraph away from the left +margin. +Entering a negative value in this spin box will create a hanging indention. + + + + +The next section is labeled Line Spacing. It +consists of a combo box and a spin box. + +The combo box determines the method of calculating the spacing between lines. It has several choices: + + + +Single, 1.5 Lines and Double + +If any of these options are selected, the paragraph will have single, 1 and 1/2 or double spacing respectively. + + + + +Proportional + +If this option is selected, the spin box is enabled. When you enter a number in the spin box, &kword; uses that number as a multiplier for line spacing. To look at it another way, if you enter 1.00 in this box, &kword; will use single spacing. If you enter 2.00 in this box, &kword; will use double spacing. If you enter 3.00 in this box, &kword; will use triple spacing, etc. You are not limited to whole numbers. You could enter 1.87 in this box and &kword; would use 1.87 line spacing. + + + + +Line Distance + +If this option is selected, the spin box is enabled. When you enter a number in the spin box, &kword; places a measured amount of space between each line. As an example, if you enter 0.75 and the units used by &kword; are inches, then &kword; will place 0.75 inches between each line. + + + + +At least + +This sets the minimum line spacing value. This can be useful if you have paragraphs with widely differing font sizes. Typically, &kword; calculates the distance between lines by looking at the tallest character in the line. You can use this feature to overide close linespacing in small font paragraphs to make them even with large font paragraphs. &kword; will not cause any fonts to overlap using this spacing technique. + + + + +Fixed + +This sets the distance between the tops of each line to a specific unit of measure. If this option is set too small, &kword; will overlap characters, which will obscure the bottom parts of the characters. +This should not be confused with Line Distance which inserts a specific unit of space between lines. Fixed specifies the distance between the top of one line and the top of the next line. + + + + + + +The last section is labeled Paragraph Space. +It consists of two entries: + + + +Before + +By entering a value here, additional spacing is added before each paragraph. + + + + +After + +By entering a value here, additional spacing is added after each paragraph. + + + + +On the right of the dialog box, is a preview box, which will +approximate the final layout of your +document. + + + + +General Layout +paragraphjustification +paragraphcenter paragraph +paragraphleft/right aligns +paragraphhorizontally align paragraphs + +This section determines how the text is placed within +the line. With other applications, you may have referred to +this simply as alignment, or +justification. + + + + + + + + +Once again, a preview pane is shown on the right side of the dialog box. + +In the upper left corner of the dialog box is a section labeled Alignment. + +If Left, +Right or Center are selected, the text will +be moved on the line so that it aligns with the left margin, aligns with +the right margin, or is centered between the margins +respectively. + +If Justify is selected, &kword; will increase +the space between words, so that each line (with +the exception of the last line in a paragraph), reaches both the left +and right margins. + +You can use toolbar buttons to quickly change the justification of one or more paragraphs + + + +ButtonCommand + + +Left Align +Center Align +Right Align +Justify Text + + + + + +The lower section controls how &kword; divides paragraphs when a +paragraph will not fit entirely within the current frame or page. + +The first option is labeled Keep lines +together. If this option is selected, then all of the lines +of the paragraph will remain on the same page. If this is not selected, +&kword; may choose to move part of a paragraph to a new page or frame. +For most work, this option is usually left +unchecked. + +The next two options are labeled Insert Break Before Paragraph + and Insert Break After Paragraph. +When one of these options is checked, and the paragraph moves to the +next frame in the frame set, a hard frame break will be inserted in front +of the current paragraph or after the previous paragraph (depending on the option selected). +This will serve to keep the paragraph in the +next frame, even if text prior to that frame is deleted. This option is +often used in conjunction with Keep lines together, +to ensure that the paragraph does not creep back onto the page during +editing. + + + + +Decorations +paragraphborders + +The next section is used to define the background color of the current paragraphs and configure graphical borders +around your paragraphs. + + + + + + + + +Clicking the color button to the right of Background color:, will let you select a color to serve as the background +of your paragraph. +&kword; can surround (on some or all sides) a +paragraph with a border. This border can be solid or not, of any color +and of many sizes. This dialog panel is used to adjust the +borders. + + + +Style + +Use this combo box to select the overall type +of the new border. +The choices are previewed in each selection. + + + + +Width + +This will determine how wide the resulting border will be. It is +measured in points. + + + + +Color + +Clicking on the color bar will allow you to select a color using the color selection dialog +box. + + + +Now that it is determined how the borders should look, specify which edges of the paragraphs need borders. + + + + + + +Select/Unselect Left Border. Clicking this +button will apply the current options to the left paragraph border. +Clicking a second time will remove the left paragraph border. + + + + +Select/Unselect Right Border. Clicking this +button will apply the current options to the right paragraph border. +Clicking a second time will remove the right paragraph border. + + + + +Select/Unselect Top Border. Clicking this button +will apply the current options to the top paragraph border. Clicking a +second time will remove the top paragraph border. + + + + +Select/Unselect Bottom Border. Clicking this +button will apply the current options to the bottom paragraph border. +Clicking a second time will remove the bottom paragraph border. + + + + + +It is possible to mix and match border styles, widths and colors in one paragraph. +Simply determine the border style, width and color for one border edge, and select the border +using the border buttons. Now alter the style width or color to create a new border look and click the new border button. + + + +The Preview window will show you how your +paragraph borders will look. + + + + +Bullets and Numbering +paragraphbulleted +paragraphnumbered +lists + +A very common element of a document, is a list of items. The list +contains several elements which may be numbered, for easy +reference. Alternatively, the list elements may be simply set off from +the rest of the text with a special character preceding each element. These special characters +are called bullets. + +This dialog box is used to define your bullets or the +numbering method of lists in the document. This dialog box can also be used to number chapters and sections. + + + + + + + + +The top section of the dialog box has three options: None, List +and Chapter. + +If None is selected, the text is not marked as +either a list or a chapter. No other features of this dialog +box will alter the text when this option is chosen. + +List is used to create +lists in the document. These lists are +automatically numbered and formatted to appear similar. +For more information on lists, see the section entitled Lists. + +Chapter is used to +number chapters and sections of a document. + + + + +Tabulators + + + + + + + + + +This dialog is used to adjust the tab stops. For more details, +see Using Tab Stops. + + + + diff --git a/doc/kword/formbrac.png b/doc/kword/formbrac.png new file mode 100644 index 000000000..c9f471d43 Binary files /dev/null and b/doc/kword/formbrac.png differ diff --git a/doc/kword/formcbrac.png b/doc/kword/formcbrac.png new file mode 100644 index 000000000..d15b971c4 Binary files /dev/null and b/doc/kword/formcbrac.png differ diff --git a/doc/kword/formfrac.png b/doc/kword/formfrac.png new file mode 100644 index 000000000..5cf409d6f Binary files /dev/null and b/doc/kword/formfrac.png differ diff --git a/doc/kword/formframe1.png b/doc/kword/formframe1.png new file mode 100644 index 000000000..c922d70b2 Binary files /dev/null and b/doc/kword/formframe1.png differ diff --git a/doc/kword/formframe2.png b/doc/kword/formframe2.png new file mode 100644 index 000000000..dff85d2d2 Binary files /dev/null and b/doc/kword/formframe2.png differ diff --git a/doc/kword/formframe3.png b/doc/kword/formframe3.png new file mode 100644 index 000000000..12dba009f Binary files /dev/null and b/doc/kword/formframe3.png differ diff --git a/doc/kword/formframe4.png b/doc/kword/formframe4.png new file mode 100644 index 000000000..8d7a18d1b Binary files /dev/null and b/doc/kword/formframe4.png differ diff --git a/doc/kword/formframe5.png b/doc/kword/formframe5.png new file mode 100644 index 000000000..c9cfb0a73 Binary files /dev/null and b/doc/kword/formframe5.png differ diff --git a/doc/kword/formframe6.png b/doc/kword/formframe6.png new file mode 100644 index 000000000..713a2b6a3 Binary files /dev/null and b/doc/kword/formframe6.png differ diff --git a/doc/kword/forminteg.png b/doc/kword/forminteg.png new file mode 100644 index 000000000..12a1aad44 Binary files /dev/null and b/doc/kword/forminteg.png differ diff --git a/doc/kword/formllind.png b/doc/kword/formllind.png new file mode 100644 index 000000000..72ea58a0c Binary files /dev/null and b/doc/kword/formllind.png differ diff --git a/doc/kword/formlrind.png b/doc/kword/formlrind.png new file mode 100644 index 000000000..6c7ba3244 Binary files /dev/null and b/doc/kword/formlrind.png differ diff --git a/doc/kword/formmat.png b/doc/kword/formmat.png new file mode 100644 index 000000000..9a49be623 Binary files /dev/null and b/doc/kword/formmat.png differ diff --git a/doc/kword/formover.png b/doc/kword/formover.png new file mode 100644 index 000000000..da6b9c1f0 Binary files /dev/null and b/doc/kword/formover.png differ diff --git a/doc/kword/formprod.png b/doc/kword/formprod.png new file mode 100644 index 000000000..f8ea9d64b Binary files /dev/null and b/doc/kword/formprod.png differ diff --git a/doc/kword/formsbrac.png b/doc/kword/formsbrac.png new file mode 100644 index 000000000..b14e5db89 Binary files /dev/null and b/doc/kword/formsbrac.png differ diff --git a/doc/kword/formspecchar.png b/doc/kword/formspecchar.png new file mode 100644 index 000000000..e00f843a7 Binary files /dev/null and b/doc/kword/formspecchar.png differ diff --git a/doc/kword/formsqrt.png b/doc/kword/formsqrt.png new file mode 100644 index 000000000..fbeca9f9b Binary files /dev/null and b/doc/kword/formsqrt.png differ diff --git a/doc/kword/formsum.png b/doc/kword/formsum.png new file mode 100644 index 000000000..580dd2a2b Binary files /dev/null and b/doc/kword/formsum.png differ diff --git a/doc/kword/formtb.png b/doc/kword/formtb.png new file mode 100644 index 000000000..b6ba11e1a Binary files /dev/null and b/doc/kword/formtb.png differ diff --git a/doc/kword/formulas.docbook b/doc/kword/formulas.docbook new file mode 100644 index 000000000..fa8d9344f --- /dev/null +++ b/doc/kword/formulas.docbook @@ -0,0 +1,69 @@ + + + + +Mike +McBride + + + + +Formulas +formulas + +&kword; has the ability to directly create formulas using the formula editor common to all &koffice; applications. +This is a formula editor for creating graphical versions of formulas. &kword; does not currently have the ability +to solve mathematical equations. + +Add a formula +There are three ways to insert a formula into a document: + + +By selecting +InsertFormula from +the menubar + + + +Using the keyboard shortcut: F4 + + + +or by clicking on the toolbar. + + +&kword; creates a formula frame at the current cursor location. +Formula frames behave differently than most other frames in &kword;: + +All formula frames are inserted inline by default. +This frame can later be +converted to a non-inline frame later. +Formula frames expand and contract depending on the resulting size of the formula. +Formula frames automatically determine where in the line they are lined up. + + + + + +Moving a formula +By default, formula frames are created as inline frames by default. The formula frame +will move with the text as any other inline frame would. +If you want to have more control over where the formula is placed, you can convert it to a framed formula by clicking on the +frame surrounding the formula with the &RMB;. A popup menu will appear. Simply select Inline Frame and the formula will +now be a freely movable frame. +Once converted to a freely movable frame, you can move the frame +just like any other frame in &kword;. + + +Removing a formula +To delete a formula in &kword;, simply delete the frame around it. + + +Editing a formula +Editing a formula is beyond the scope of this documentation. +Please see the &kformula; handbook for help with the editing of the formula. + + + diff --git a/doc/kword/formulind.png b/doc/kword/formulind.png new file mode 100644 index 000000000..35128d7d7 Binary files /dev/null and b/doc/kword/formulind.png differ diff --git a/doc/kword/formunder.png b/doc/kword/formunder.png new file mode 100644 index 000000000..2ae09dfc3 Binary files /dev/null and b/doc/kword/formunder.png differ diff --git a/doc/kword/formurind.png b/doc/kword/formurind.png new file mode 100644 index 000000000..f8fe2afc2 Binary files /dev/null and b/doc/kword/formurind.png differ diff --git a/doc/kword/forward.png b/doc/kword/forward.png new file mode 100644 index 000000000..03f5200fd Binary files /dev/null and b/doc/kword/forward.png differ diff --git a/doc/kword/fpara1.png b/doc/kword/fpara1.png new file mode 100644 index 000000000..452c02d9d Binary files /dev/null and b/doc/kword/fpara1.png differ diff --git a/doc/kword/fpara2.png b/doc/kword/fpara2.png new file mode 100644 index 000000000..978eb0d44 Binary files /dev/null and b/doc/kword/fpara2.png differ diff --git a/doc/kword/fpara3.png b/doc/kword/fpara3.png new file mode 100644 index 000000000..f88d63caf Binary files /dev/null and b/doc/kword/fpara3.png differ diff --git a/doc/kword/fpara4.png b/doc/kword/fpara4.png new file mode 100644 index 000000000..c797b8ec0 Binary files /dev/null and b/doc/kword/fpara4.png differ diff --git a/doc/kword/fpara5.png b/doc/kword/fpara5.png new file mode 100644 index 000000000..d3165325d Binary files /dev/null and b/doc/kword/fpara5.png differ diff --git a/doc/kword/fpicture.png b/doc/kword/fpicture.png new file mode 100644 index 000000000..d73158ee1 Binary files /dev/null and b/doc/kword/fpicture.png differ diff --git a/doc/kword/framers.png b/doc/kword/framers.png new file mode 100644 index 000000000..0460c83e8 Binary files /dev/null and b/doc/kword/framers.png differ diff --git a/doc/kword/frames.docbook b/doc/kword/frames.docbook new file mode 100644 index 000000000..639538ee8 --- /dev/null +++ b/doc/kword/frames.docbook @@ -0,0 +1,435 @@ + + + + +Mike +McBride + + + + +Working with Frames +framesintroduction +Since &kword; is a frames based word processor, an understanding of +frames and framesets is necessary for all but the most simple of documents. + +This section is designed to give you a firm understanding of how +to create, destroy and manipulate frames so &kword; can provide you with +the exact document you want. + + +Framesets +framesetsintroduction + +Before we continue our discussion of Frames, its important that we +define a couple terms now: + + + +Frame + +A frame is a rectangular space on the page. This space defines an +area where text (or other data), can be placed. + + + + +Frameset + +A frameset is a group of frames. Each frame in the frameset has a +position within the frameset + +The position is determined by their placement on the page. If frames extend across the entire width of the page, the frame which begins closest +to the top of the page is Frame #1. The next frame that is closest to the top of the page is Frame #2, etc. +If the frames do not extend across the width of the page, the frame whose +left edge is closest to the left margin will be frame #1. In this case, +the vertical position of the frame is ignored. + +All text flows from one frame to another within a +frameset, and only within a frameset. Text flows from frame +to frame within the frameset according to the position of each +frame on the page (and therefore the order of the frames within the frameset). + +As an example: If we have a frameset that consists of three +frames (#1, #2, and #3). + +As we type text into Frame #1, the text is shaped to the outline +of Frame #1. + +When the text will no longer fit within Frame #1, it is +automatically continued into Frame #2. + + + + +Text moves freely between frames +within a frameset. If you insert text in the middle of a frame, all text after the inserted text is +rearranged as you type. + + + + +Selecting a frame +framesselecting + +You can select a frame within a frameset two ways: + +By clicking on the text frame border of the frame you want +to select. +By holding down the &Ctrl; key and clicking anywhere within the frame. + +There should now be 8 squares around the edges of the frame. + + + +Adding a Text Frame to a Document +framesadding a text frame + +Adding a text frame can be done one of three ways: + + + +By selecting +InsertText +Frame from the menubar + + + +You can use the keyboard shortcut: +F10 + + + +or by clicking on the toolbar. + + + +Whatever method you choose, &kword; responds by changing the cursor +to a set of cross hairs. + +Using the mouse, place the crosshairs at the desired position of the upper left corner of the +new text frame. + +Click once with the &LMB;. + +Alternative, first position the text caret at the place where you want to insert +the frame. When the mouse cursor changes to crosshairs, press &Enter;. + + +A dialog box appears. + + + + + + + +This dialog box is used to determine which frameset this new frame will belong to. + +Using the screenshot as an example, a new text frame has been created in a +document which currently has two framesets (called Text Frameset +1, and Text Frameset 2). + +You now have the option of either: + + + +Add the new frame to one of the previously created +framesets. + +To do this, simply select the frameset you want the new frame to belong to. + (Either Text Frameset 1, or +Text Frameset 2 in the example.) + +When this text frame is created, the new text frame will become +a member of the selected frameset. + + + +Create a new frameset. + +If you want this to be a new frameset, you should enter a descriptive +name for your new frameset. (A name which will tell you what you might +find in that frameset). This name should be entered in the text box +labeled Name of frameset:. +This newly added frame will be the +only frame in the frameset. + + + +The other tabs in this dialog box, can be used to set some options +for this frame. For more information on these options, see the section +entitled Setting the properties for a frame. + +If you click OK, the new frame will be +created. + +If you click Cancel, the new frame will not +be created, and you will be returned to editing your document. + + +By default, &kword; creates a small frame with the upper left corner of the +frame located on the page where you clicked with the mouse cursor. After the frame is +created, you are expected to reshape the frame to fit your needs. + +If you would prefer to establish the shape of your frame while you are +creating the frame, simply click the &LMB; where you want the upper left corner to +be placed and hold the button down. Drag the mouse towards the opposite corner of the frame to establish the +boundaries of the new frame. As +you drag the mouse, you will see a box drawn. This box represents the +boundaries of your new text frame. When you are satisfied with the size and shape of the new text +frame, release the mouse button. + + + + +Deleting a Frame From a Document +framesdeleting + +You may decide you no longer need a frame in your document. You +could leave it blank (so it would not be visible in the final output), +but you should delete it to keep your document as simple as +possible. + +Begin by clicking on the text frame border of the frame you want +to delete. (Or holding down the &Ctrl; key and clicking inside the frame with the +&LMB;.) + +There are now 8 squares on the edges of the frame. + +If this is the frame you want to delete, you can do so by: + + + +Press the Delete key. + + + +Selecting +FramesDelete +Frame from the menubar + + + +While the cursor is on the border of the frame you want to delete, +click once with the &RMB;. A small menu will appear. Select Delete +Frame. + + + + + + + +Moving a Frame +framesmoving + +Moving a frame around on the page is easy. + +Begin by clicking on the text frame border of the frame you want +to move. (Or holding down the &Ctrl; key and clicking inside the frame with the +&LMB;.) + +There are now 8 squares on the edges of the frame. + +Click and hold the &LMB; on the border again and drag the cursor in the direction you want to move the +frame. + +You will see an outline of the frame as you move it. When the +outline is where you want it, release the mouse button. + +A faster way to move the frame, can be done by holding down the +&Ctrl; and &Shift; keys on the keyboard and click and hold with the &LMB;. Drag +the mouse cursor on the page and when the frame is in the correct location, release +the &LMB;. + + + + + +Resizing a Frame +framesresizing + +It is also easy to change the size or shape of a frame. + +Begin by clicking on the text frame border of the frame you want +to change. (Or holding down the &Ctrl; key and clicking inside the frame with the +&LMB;.) This selects +this frame as the current frame. + +There are now 8 squares on the edges of the frame. By moving +these squares, you will be able to drag the frame border(s) to a new +location. + +Each square will move a different combination of borders. + + + + + + + + +As an example: To move the bottom border of a frame, place the +mouse over the box at the six o'clock position in the frame. When the +mouse is over the box, it will change to a double headed arrow. + +Now click with the &LMB; +and hold the button down. As you move the mouse up and down on the +page, you will see that the frame changes shape to match the movements of +the mouse. When the bottom edge of the frame is at the new location, +simply release the mouse button, and the changes will become +permanent. + + +If you are using a Text Oriented Template, you cannot change +the size of the primary frame by dragging the edges of the frame. If you +want to resize this frame, you must do so by Changing the margins + + + + + +Reconnecting Frames in a Frameset/Changing text flow. +framescreate/edit framesets + +Normally, each new text frame is created with a specific +purpose. Sometimes, however, as the document is changed, changes to the text flow +will need to be made. To accomplish this, you will need +to know how to move a frame from one frameset to another. + +First click on the frame border of the frame you want to +move to another frameset. + +You can change the frameset of the currently selected frame by +selecting +FramesFrame/Frameset Properties +from the menubar + +You can also accomplish this by clicking on the frame border once with the &RMB;, and selecting +Frame/Frameset Properties... from the popup menu. + +This will bring up a dialog box with five tabs. Select the tab +labeled Connect Text Frames. + +You will be presented with a list of framesets. Simply select the new +frameset. + +When you click OK, the currently selected frame will be added +to that frameset. + + + +Raise and Lower Frames +framesraise +frameslower + +When two frames occupy the same place on a page, they must overlap. +When they overlap, one frame sits above the other frame. +You can raise and lower the frames to change which frame sits above the other frames by using four commands. + + + +Bring to Front +To raise a frame, select the frame by clicking once on the frame border with the &LMB;. +Select +FramesBring to Front + from the menubar. +This will place the frame on top of all other frames that it overlaps. + + + + +Raise Frame +To raise a frame, select the frame by clicking once on the frame border with the &LMB;. +Select +FramesRaise Frame + from the menubar. +This will move the frame up one level of any frame that it overlaps. +Pressing &Ctrl;&Shift;R is the +same as selecting Raise Frame from the menubar. + + + + +Send to Back +To lower a frame, select the frame by clicking once on the frame border with the &LMB;. +Select +FramesSend to Back + from the menubar. +This will place the frame below all other frames that it overlaps. + + + +Lower Frame +To lower a frame, select the frame by clicking once on the frame border with the &LMB;. +Select +FramesLower Frame + from the menubar. +This will move the frame down one level of any frame that it overlaps. +Pressing &Ctrl;&Shift;L is the +same as selecting Lower Frame from the menubar. + + + + + + +Hard Frame Breaks +framesframe breaks +page breaks + +A hard frame break is a special formatting character. It is +invisible on the final printed output. + +The purpose of a hard frame break, is to force all the +text that follows it into the next frame in the frameset. + +If we have the following sentence: We have nothing to +fear but fear itself + +and we insert a Hard Frame Break, just before the word +but, we will end up with one frame containing We have nothing +to fear, and the next frame in the frameset beginning with +but fear itself. + +To add a Hard Frame Break, you should first place the keyboard +cursor where you want the break to be located in the document. + +A Hard Frame Break can be inserted one of two ways: + + + +Select InsertPage Break from the menubar + + + +You can use the keyboard shortcut: +CtrlReturn + + + +If you want to remove a Hard Frame Break, you simply delete it +like you would any other character. +Since this is not a character that +you can normally see in &kword;, it will be easier to delete a Hard Frame Break with the following procedure. + + + +Select +ViewFormatting +Characters from the menubar. This will make the breaks visible. + +Find the newly revealed Page Break, labeled --- Frame Break ---. + Place the mouse pointer in +front of this and click once with the &LMB;. This will place the cursor directly in front of the page break. + +Now press the Delete key. + + + + + diff --git a/doc/kword/framestylist.png b/doc/kword/framestylist.png new file mode 100644 index 000000000..9f6b059e6 Binary files /dev/null and b/doc/kword/framestylist.png differ diff --git a/doc/kword/fundimentals.docbook b/doc/kword/fundimentals.docbook new file mode 100644 index 000000000..2556809d9 --- /dev/null +++ b/doc/kword/fundimentals.docbook @@ -0,0 +1,178 @@ + + + + +Mike +McBride + + + + + +Fundamentals +This section of the documentation discusses starting &kword;, introduces the user to templates and +discusses an important difference between two major types of templates. + + + +Starting &kword; +starting &kword; + +&kword; can be started one of four ways: + + + +You can select &kword; through the system menus, under: +K-ButtonOffice +KWord. + + + +If you are in a terminal program (&konsole;, Xterm, &etc;), you can type: +$ kword & + +Or + +$ kword filename & + + + +Using &konqueror;, you can click on your data file (&kword; +documents end in .kwd). This will +automatically start &kword; and begin editing the file. + + + +Using the &koffice; Workspace. + + + + + + + +An Introduction to Templates +templatesintroduction + +OK, so the first question a new user may have is: + +Why do I need to use a frames based word processor, when +I am perfectly happy writing my letters on my current (page layout) word +processor? + +Well the good news is, adjusting to a frames based word processor +is easy and once a template is selected, &kword; can act just like a +page layout word processor. There are templates +available for simple correspondence and day to day use. + +When a more complex document (newsletters, +posters, &etc;) needs to be created, you will not need to switch to a different +application to generate these special documents. There are templates in +&kword; which will help generate newsletters or other more +complicated documents. + +What are templates and what can they do for +the user? + +A template can be thought of as an initial mold for a document. + +When a user sits down to write a document, they already have an idea of +what the final product will look like. If they are writing a letter to a +business, a document with only one column, which goes all the +way across the page, and from top to bottom of the page is appropriate. When a user sits +down to author a newsletter for a local organization, however, they may +want a large title across the top, and several columns for quick news +articles. + +With &kword;, this predetermined notion of how the +document should look is used to select a template. By using a template, +a set of frames is created to approximate this final layout. For +a business letter, a document with one large frame that covers the +page from top to bottom and side to side would be selected. +For a newsletter, however, a two or +three column document is more appropriate. Once this +template is selected, &kword; will create the frames automatically. + +What if the user decides to change the +layout after a template is selected? + +This is not a problem. If a document begins as a single +column document and it is decided later that two columns is better, another column can be added. +The purpose of templates is not to +limit the ability to change the layout of a document, but rather to take some of the +work load off the user whenever possible. Choosing the correct template when +beginning a document will simplify the formatting (as opposed to +always selecting the default template and making changes later). +Choosing the wrong template +will not limit the flexibility of the document later on. + +The next section, consists of one more important topic which +you should understand before we begin using &kword;. + + + + + +The difference between Text Oriented and Page Layout +templates +templatesText oriented/Page Layout + +It is vital that the +difference between Text Oriented and Page Layout templates is clear in +your mind. + + + +Text Oriented + +The Text Oriented templates are designed to act like page-oriented +word processors. When you select a Text Oriented template, you will +create a template with one or more frames. The first frame is distinctly +tied to the paper size of your document. When you increase or decrease +the paper size or change the margins, the frame size is automatically +adjusted. You are not able to move this frame +around on the page and you cannot delete this frame. If you need to +adjust the size or position of this frame, you must adjust the margins. On top of the first +frame, you can, of course, add additional frames. These frames can +contain pictures, text or whatever you want. These new frames can be +moved, re-sized and deleted to suit your needs. If you want it, &kword; +will even wrap the text from the first frame around any information in +any subsequent frames. + + + + +Page Layout + +These templates are designed for desktop publishing. When you +select a template from this class, all of the frames are created +equal. This is where the difference between Page Layout and Text +Oriented template lies. None of the frames in a Page Layout template are +tied to the page as tightly as the main frame in a Text Oriented +template is. Each of the frames is independent of the page size, and can +be moved or re-sized without changing margins, &etc; Of course this also +means that altering the margins or paper size of your document requires +that you individually move/resize each frame. + +In addition to not having a main text frame, Page Layout +documents cannot use the automatic headers or footers (though these can be +added in as frames). Additionally, footnotes must be managed by hand while +in Page Layout Mode. + + + + + +As you can see, the choice between Page Layout and Text Oriented +templates is a choice between flexibility (Page Layout) and convenience +(Text Oriented). You can create any document you like with either type +of template. + +If the concept of templates is still unclear, please follow along +with the following tutorial. The first document you create will use a +Page Layout template. This should help clarify exactly how templates +function. + + + diff --git a/doc/kword/graphics.docbook b/doc/kword/graphics.docbook new file mode 100644 index 000000000..6e46b5ecb --- /dev/null +++ b/doc/kword/graphics.docbook @@ -0,0 +1,238 @@ + + + + +Mike +McBride + + + + +Graphics +graphicsintroduction + +&kword; is very good at handling textual information. &kword; can also be used to incorporate +graphical images with text. +A source of great clipart that is free to use is the Open Clip Art Library. This project has a large collection of vector graphics indexed and sorted by category, all released into the public domain. +Pictures can be inserted into a document as either framed or inline images. +Framed images are pictures that have a frame around them. The frame around a picture functions +exactly the same as a frame around text. It contains the picture and determines the size and shape of the picture. +An inline image has a frame around it, but this frame is inserted within the current text +frame. If text is inserted in front of the picture, the picture travels down the frame just like any text would. This means the picture will +stay in the same area of the page as the text that surrounds it. +Framed pictures, on the other hand, need to be moved by hand on the page. + +&kword; can use pictures already stored in a file or acquire an image from a scanner. +Insert Graphics from a file +graphicsinserting + +There are three ways to insert a picture into a document: + + +By selecting +InsertPicture... from +the menubar + + + +Using the keyboard shortcut: &Shift;F5 + + + +or by clicking on the toolbar. + + + +All three methods open a file selection dialog. + + + + + + + +Use this dialog to select the picture. + +Pressing Esc at this point will cancel the insertion of a picture into your document. + +Once the appropriate picture file is located, click on the filename once with the &LMB;. Click +OK to continue. +A new dialog box appears. + + + + + + +The right half of this dialog box contains a preview window. The picture should be visible in this window. +The left part of this box contains one button and two check boxes. + + +Choose Picture... +Click this button and &kword; will open a +new file dialog to choose a different picture. + + +Insert Picture Inline +If there is a mark in this check box, the picture will be an inline picture. If there is no mark, a new frame will be +created. For details on the differences, see the introduction. + + +Retain original aspect ratio +Aspect ratio is defined in the &kword; glossary. +If a there is a mark in this check box, &kword; will not allow any change the aspect ratio of the picture. This prevents +inappropriate stretching and compressing of the image. It will still be possible to change the overall size of the image, but it +will not be possible to change the horizontal measurement without also changing the vertical measurement. +If there is no mark in this check box, the horizontal and vertical sizes of the picture can be changed independently. + + + +To insert the picture, click OK. To abort the picture entirely, click Cancel. +If an inline picture was selected, click with the mouse in the appropriate location. The picture will be inserted. +If a framed picture was selected, the mouse cursor will change to crosshairs. Locate one corner of the location of the new picture +frame with the mouse. Click and hold the &LMB; down. Drag the cursor to adjust the size of the picture frame. When the size of the +picture frame is correct, release the &LMB;. &kword; will insert the picture into the frame, and resize the picture to fit within the +frame. + + +Using a picture from a scanner +A complete discussion of how to operate a scanner is beyond the scope of this documentation. This document will confine itself to the controls available in &kword; but will not +go into detail on the use of these controls. +To use a scanner to insert a picture into your kword document, begin by selecting +InsertScan Image... from +the menubar. + &kword; will open a dialog box for you to choose your scanner. Simply click on the radio button to the left of your scanner. Then click OK. This will bring up the scanning dialog: + + + + + + + + +You should begin by selecting the image type that you want to scan and the resolution. First determine the picture type using the drop down box labeled +Scan Mode. You can choose between Color, Greyscale or Binary image. +If you want to select a different scanner, click the Source... button. +If you have selected a Binary image, you can use the drop down box labeled Halftoning to select your halftone protocol. +Select your resolution using the drop down box labeled Resolution +Now place the object you want to scan in the scanner and click Preview Scan. Your scanner will take a low resolution +scan and preview it in the window in the far right of the dialog +Using your mouse, click on the upper left corner of he area you want to scan with the &LMB; and hold the button down. Drag the mouse down and +to the right to create a box for a high-resolution scan. When you have an appropriate sized box, release the &LMB;. Once the box is drawn, you +can adjust the selection box using the mouse. +You can refer to the box to the left of the preview window labeled Selection. This box will show you the height and +width of your selection and the amount of disk space you will need to store this image in the &kword; file. +Once you are satisfied with the size and position of the selection box, click Final Scan. The scanner will scan the selected area at the resolution you selected. +When the scanner is finished, click Close to close the dialog box. Your cursor will now be crosshairs. Using this cursor, draw the size and position you want your picture on the +page. The scanned image will be inserted in a separate frame. You can now adjust the size of the picture by changing the size of the frame +Adjusting the image prior to final scanning +You can use the lower left part of this dialog to adjust your image prior to scanning. +By moving the slider bar labeled Threshold you can adjust the cutoff point of white in the scanned image. +By moving the slider bars labeled Brightness and Sharpness you can adjust the relative brightness and the sharpness of the scanned image. +The preview window will not show you the effects of changes to your scanned image in the preview window. +You can select from one of three pre-defined gamma tables or you can select the User defined option from the drop +down box labeled Use custom gamma table. If you selected User defined you can click the Edit... +to alter the Brightness, Contrast and Gamma for your customized gamma table. + +Adjusting the preview scan size +If you know the size of the object you are scanning, you can select the preview area from the drop-down box labeled Scan size. You can also use the radio buttons +labeled Landscape and Portrait to change the orientation of the preview area. +Changing the orientation between portrait and landscape does not change the orientation of the scanned text or image. + +Using auto-selection +&kword; can try to automatically select the object you want to scan. It does this by looking for an area within the preview window that seems to +define an object in the picture. By default this option is disabled. You can enable autoselection in this dialog. +The autoselection area of the dialog is located just to the left of the preview window in the middle of the dialog box. It consists of three controls: + + +Checkbox +If a mark is placed in the checkbox, auto-selection is enabled. + If there is no mark in the checkbox, then auto-selection is disabled. + + +Drop down box +This drop down box contains two possible choices: Black and White. If +Black is chosen, then &kword; will look for an area surrounded by black to select automatically. +If White is chosen, then &kword; will look for an area surrounded by white to select automatically. + + + +Slider bar labeled Threshold +By adjusting this slider bar, you determine the threshold auto-selection uses to determine the area to select automatically. + + + +Miscellaneous scanning options +There are two additional options for scanning that are accessed by clicking on the Options tab. + + + + + +The checkbox labeled Ask for the scan device on plugin startup toggles the scanner selection dialog on and off. If there is a mark in this +checkbox, &kword; will ask you to select your scanner each time you insert a scanned image into your document. If there is no mark, then &kword; uses the previously +selected scanner. If you have access to only one scanner, or you only use one scanner, you should remove any mark from this box. +The checbox labled Query the network for scan devices is also used to select scanners. If there is a mark in this checkbox, +&kword; will check your local network for scanners that are avaialbe. If there is no mark in this box, &kword; will only look for scanners connected directly to +your machine. +To save these options, click Close. + + + + +Changing the size of a picture +graphicschange the size of + +Resizing a picture is done by changing the size of the frame that surrounds it. &kword; will automatically change the picture to fill the +entire frame. +For information on changing the size of a frame, see Resizing frames. + +Move Pictures +graphicsmoving + +The only way to move an inline image around on the page, is to alter the flow of the text that surrounds it. If this +is causing problems, the picture can always be changed to a framed picture. +To move a framed picture in &kword; is the same as moving any frame in &kword;. + + +Delete Graphics +graphicsdeleting + +To delete a graphic in &kword;, simply delete the frame around it. + +Saving Graphic in separate file +graphicssaving in a separate file + +You can save a picture or graph to a separate file (for use in another document or to archive the graphic). +Simply click once on the graphic with the &RMB;. A popup menu will appear. Select Save Picture.... +A dialog will appear that will allow you to specify where to save the graphic. +This does not remove the picture from the &kword; document file. It is simply a way to extract a picture from a +document so it can be archived or used in another application. + + +Switching between inline and framed pictures +graphicsswitching between inline and framed + +Switching between inline pictures and framed pictures is easy in &kword;. +Change an inline picture to a framed picture +To change in inline picture to a framed picture, click on the desired picture with the &LMB; once. This selects the frame +of the picture. +Now click and hold with the &RMB; and a popup menu will appear. In this menu, is an item labeled +Inline Frame, with a mark in front of it. Select this option by clicking with the &LMB;. +The frame is now +an independent and can be moved around freely. + +Change a framed picture to an inline picture +To change a framed picture into an inline picture, click on the desired picture with the &LMB; once. This selects the frame +of the picture. +Now click and hold with the &RMB; and a popup menu will appear. In this menu, is an item labeled +Inline Frame. Select this option by clicking with the &LMB;. +&kword; has now converted this to an inline frame. +&kword; tries to make a reasonable estimation of where in the text the inline image should be inserted. + + + + + diff --git a/doc/kword/headerfooter.docbook b/doc/kword/headerfooter.docbook new file mode 100644 index 000000000..25221cd66 --- /dev/null +++ b/doc/kword/headerfooter.docbook @@ -0,0 +1,57 @@ + + + + +Mike +McBride + + + + +Headers/Footers +headersusing +footersusing + +Introduction +With multi-page documents, you might want to provide certain +information at the top or bottom of each page throughout the document. +Headers or footers can provide the reader with important information and they tie your +documents together visually. + +Headers and footers are special frames. +You can edit the text and data within the headers and +footers just as you would any other text frame. What makes headers and footers +different from most other frames in &kword; is that they are automatically created at the top and bottom +of each page. + +Headers and footers are only available when using text oriented templates. + +Using headers and footers +You can toggle headers and footers on and off independently at any +time. + +You can toggle the headers by selecting +FormatEnable/Disable Document Headers +from the menubar. + +You can toggle the footers by selecting +FormatEnable/Disable Document Footers +from the menubar. + +The footers will be +added below the margins you set under page setup. The text within the +main frames will be moved so the headers and/or footers do not overlap +any text. + +Since headers and footers are simply text frames that are placed on each page, you can use all of the +tools and techniques you are familiar with to create your header and footer information. + +For more information on options for headers and footers, see the section on +Formatting the page. +For information on page numbers see the section on Page Numbering. +For information on formatting the frame, see the section on +Setting the Properties for a Frame. +For an example of how to place the page numbers on the outside of even and odd pages, see the +How do I? section. + + diff --git a/doc/kword/incindbut.png b/doc/kword/incindbut.png new file mode 100644 index 000000000..0ecefb2fc Binary files /dev/null and b/doc/kword/incindbut.png differ diff --git a/doc/kword/index.docbook b/doc/kword/index.docbook new file mode 100644 index 000000000..3a07e5c8e --- /dev/null +++ b/doc/kword/index.docbook @@ -0,0 +1,1852 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + +The &kword; Handbook + + +Mike +McBride + + +Gary +Cramblitt + +
    garycramblitt@comcast.net
    +
    +
    + +
    + +2000-2006 +Michael McBride + + +2006 +Gary Cramblitt + + +&FDLNotice; + +2006-04-23 +1.5 + + + +&kword; is a complete word-processing and simple desktop publishing program. It is part of the +&koffice; suite of utilities. + + +This manual describes &kword; 1.5. + + + + +KDE +KWord +KOffice +word processing + + +
    + + +Introduction + + +Introduction +introduction + +&kword;, is a full featured + +WYSIWYG (What You See Is What You Get) +Word-processor/Desktop Publishing Program. + + +&koffice;applications +&kword; is part of the &koffice; productivity suite for the K Desktop +Environment. Other applications in &koffice; include: + + + +&kspread; (A spreadsheet application.) +&kpresenter; (A presentation creator.) +&karbon14; (A vector drawing program.) +&kivio; (A flowchart creator) +&krita; (A pixel based drawing program.) +&kugar; (A report generation tool.) +&kexi; (An integrated environment for databases.) +&kchart; (A chart and graph creator.) +KPlato (An integrated project management and planning tool.) +and a simple integrated office desktop, to help organize your +work. + + + +All &koffice; applications were designed from the beginning to take +advantage of the features of &kde;. Because of this, &kword; (like +all of &koffice;), supports many advanced features you expect from todays desktop environment. + + + +&kword; is a word-processor which can work either as a traditional word +processor, or as a simple but powerful desktop publishing +application. This is possible because &kword; is a frame oriented word +processor, not a page oriented word processor (&Microsoft; +Word,&Wordperfect; +and Applixware are all page oriented word +processors). + + + +Frame oriented word processors work by creating one or more +frames per page. Each frame acts as a boundary (like +a frame which surrounds a photograph), which limits the text to the +boundaries of the frame. You can move and re-size boundaries to define +exactly where on the page the text will be placed. As you re-size +frames, the text is reworked to fit within these frames. + + + + + + +Button + + + +You can easily connect one frame to the next. When +you connect two frames, any text which does not fit within the first +frame, flows easily and automatically into the next. + + + + +Button + + + +In addition to text, you can include virtually anything inside a frame. +A frame can contain a spreadsheet, pictures, a database form, +or nearly any piece of data. Since each page can have any number of +frames, documents can appear quite sophisticated while still remaining +easy to edit. + + + +&kword; users also benefit from the auto wrap features of &kword;. When +you place one frame on top of part of another frame, the text from the +lowest frame can be automatically wrapped around +the newly created frame. This reformatting occurs in a +WYSIWYG Graphical User Interface, and happens +automatically while you edit. + + + + + + +Button + + +&kword;features + +As a word-processor, &kword; includes the most used options of many other +word processors, while maintaining a simple interface. In addition to +the features you expect from a modern word-processing package (text +entry, bold face, italics, text alignment, text printing, &etc;), +&kword; can: + + + + +Use predefined templates, to generate complex document layout with +one click of the mouse. As a user, you can build your own templates, +download templates from the web, or use the current document to create a +new template. + + +&kword; provides automatic numbering of lists and automatic bulleting of lists with any character or shape you want. + + +Define paragraph layout styles, frame layout styles and table layout styles, to shorten the editing time of +your document, and ensure consistency throughout a long document. + + +Edit headers and footers for your documents. You can have +different headers for even and odd pages, or the same headers +throughout. + + +Search through your document for text. You can further refine +your search by specifying font, format, font size and many other +features of the text. By adding wild-cards to your search, the search and +replace functions can become very powerful. + + +Footnotes and Endnotes. &kword; has all the tools necessary to manage footnotes or endnotes. + + +Tables. You can either use the table formatting capabilities of +&kword;, or you can import any spreadsheet from &kspread;. + + +&kword; has built in support for KParts. KParts allows you to +insert any spreadsheet, picture, chart, graph, document, or any other +data type from any &koffice; application. You are free to edit that +KPart using the tools designed for that task, without needing to start +the application at all. + + +&kword; can zoom in or out to make the editing of your documents +easier on any computer, and with any font size. + + +&kword; supports customizable toolbars and menus. + + +&kword; has extensive internationalization support including right-to-left and left-to-right text flow. + + +You can embed formulas directly into &kword; using the integrated +formula editor. + + +You can have &kword; auto-correct many of the most common spelling and punctuation mistakes. + + +&kword; can check the spelling of your document. &kword; can automatically mark misspelled words as you type. + + +You can access an on-line thesaurus (English only) to find the exact word you are looking for. + +&kword; can automatically create a table of contents, and keep it up to date. + + +&kword; has optional autocompletion for commonly used words. + + +&kword; has support for document bookmarks, to easily navigate large documents.. + + +&kword; has support for Internet hyperlinks and email addresses. + + +&kword; has the ability for proofreaders to make comments about portions of the text. These +comments are stored in the &kword; file, and can be changed or deleted easily. + + +&kword; can merge data from an outside database, spreadsheet, document or text file to create mailinglists, form letters, invoices, etc. + + +&kword; can load and save documents from other wordprocessing programs with an extensive list of filters. + +&kword; can create PDF files. + + +You can edit one document from multiple views. This allows you to have several windows open on +one document. Edits in one window are immediately updated in the other window. + + +&kword; can surround your frames with borders and you can set the background color of each frame separately if you want. + + +&kword; has several accessibility features, including the ability to speak all or part of +a document using Text-to-Speech (KTTS) and manipulate documents using the keyboard only. + + + + +The best part about &kword;, is the effort that has been placed to +make &kword; a productive tool for all your needs from the simplest +letter, to the most complex document you might need to work on. + + + + +What parts of this guide should I read? +getting started + +Anyone who has looked at the table of contents has surely come to +the conclusion that reading this manual from cover to cover, is an +unreasonable (and fortunately unnecessary) task. + +This user guide is designed to be helpful to a wide variety of +users, from the very experienced, to the novice user. Since different users will have different needs, each section of +this manual is self-contained. The user is not expected to have read all of +the previous sections of the manual to find the instructions +useful. + +To help determine what +should be read before starting to work with &kword;, a suggested +reading list for three levels of users is given below. + +If each of these sections is read before + starting to use &kword;, using &kword; will be easier. + + + +
    + +Experience Level +Previous Experience +What you should read + + + + + +Novice +No previous computer experience + + +Fundamentals +Step by Step Tutorial +The &kword; Screen +Document Storage and Printing +Editing Your Document +Introduction to Menu Bars and Toolbars +The difference between Text Oriented and Page Layout templates + + + + + +Intermediate +Comfortable with other page based word processors (&Microsoft; +Word, Word Perfect +or Applixware.) + +Fundamentals +Step by Step Tutorial +The difference between Text Oriented and Page Layout templates + + + + +Advanced User +Comfortable with other frames based word processors (Frame Maker, +&etc;). + +The difference between Text Oriented and Page Layout templates + + + + +These sections will help with the basic information. As other specific questions or situations arise, the +other sections of this manual can be used as a reference. + +Obviously this will not cover everyone's needs. Please use it as a guide to help +determine which parts of the manual will be helpful to read before you begin using &kword;. + + + + + + +&fundamentals; +&tutorial; +&basics; +&storeprint; +&editing; + + +Detailed Guides: Document Layout + +This section of the guide is designed to help the user with the format and layout of their +documents. The section will begin with information on changing the size and shape of the page +and the margins, and work progressively through smaller and smaller +blocks of text (frames, then paragraphs, then characters). At each level, all of the format and +layout options will be explained. + +After discussing the formatting of individual characters, the manual will elaborate on styles +(to provide consistent formatting through the document), lists, multi-column documents, tables and finally the use of headers +and footers in a document. + +The final part will show you how to save a document as a template for future documents. + +&pageformat; +&frames; +&formatframe; +&formatpara; +&tabstops; +&formatcharacters; +&styles; +&columns; +&lists; +&tabls; +&headersfooters; +&templatecreation; + + +Detailed Guides: More than just text +Up to this point in the documentation, we have been focusing on text. That is about to change! +This chapter will discuss inserting a table of contents, graphics, page numbers, links to web pages and how to +insert other types of &koffice; data into a document. +This chapter will also cover document information and its relationship to document variables. +Entering Document information +document information +&kword; can store information about the author and the document in the same file as the text and data of the document. +Entering this information into &kword; has two potential benefits: + +This information will always be available for reference. This is especially important in situations where +there are many possible authors (employees) and hundreds (or thousands) of documents. +The information supplied here, can be inserted automatically into the document as a +document variable. + +To enter document information, simply select +FileDocument Information... + from the menubar. This will bring up a dialog box with two tabs. +The first tab is labeled General. Enter a document Title, Subject lines, Keywords and an Abstract. +The bottom of this page displays the Type of the document, the date of the creation and modification, the last printing date, the Total editing time and the Revision number. Click on Reset to clear all data and set the actual date as creation date. +Both the document Title and the Abstract can be accessed throughdocument variables. +The second tab is labeled Author and has blanks to enter the authors name, Initials, Title, Position, Company and contact information (email address, telephone numbers and physical address). +Every value entered in this dialog can be inserted as a +document variables. +At the bottom of the dialog is a button labeled Load From Address Book. Clicking on this button will automatically insert your information contained in the &kde; address book into this &kword; document information dialog. +You must inform the &kde; address book which entry corresponds to your information. +To do this, open the &kde; address book, select the entry that contains your name and address. Now select +EditSet as Personal Contact Datafrom the menubar in the &kde; address book. This only needs to be performed once. +&kword; will now insert the entered information when the Load From Address Book button is clicked. +The second button Delete Personal Data allows you to remove all data of the entries on this page. +When finished entering the information, click OK to apply the changes. +If any document variables were changed, &kword; will update their values throughout the document. + +&graphics; +&toc; +&variables; +&expressions; +&links; +&comments; +&footend; +&parts; +&insfile; +&bookmarks; +&formulas; + + + + +&a11y; + + +Advanced Topics +The sections that are included in this chapter are for advanced users. The instructions for these sections +will assume you are familiar with the basic operation of &kword;. +&struct; + +&mmerge; + + + + + + +How do I... +The next part of &kword; documentation is designed to provide examples on how to solve specific +problems using &kword;. +Each section is a self contained list of steps, and refers the reader to other sections of the documentation +for more complete information on different aspects of &kword;. +These examples were selected to: + +Show how &kword; might function differently from other word processors you are used to. +Show how to combine several elements to create the desired document. +Illustrate the power of &kword;. + +You can use these examples as recipes for your document, or modify them to create the look or content +you desire. + +How do I get the pages numbers on the outsides of the pages and +the title in the middle of the header (like a novel)? +insert page numbers + +This first example shows how you can combine center tabs and variables in a header to create a common format to your document. +Your document must be at least 2 pages long before you begin this procedure. + +Select FileDocument Information +from the menubar. +Click on the General tab. +Click once in the text box labeled Title with the &LMB; and enter +the desired document title. +Click on the OK button. +Select FormatPage Layout... +from the menubar. +Click on the Header & Footer tab. +Select Different header for even and odd pages. +Then click OK. +Select FormatEnable Document Headers +from the menubar. +Move to an odd numbered page in your document, and click in the header box. +Select FormatParagraph... +from the menubar. +The Paragraph Settings dialog will appear. Click on the Tabulators tab. +Click the New button. +Using the arrows of the spinbox labeled Position enter a value that is exactly 1/2 the frame width. The frame width is + listed directly below the Position spin box. +Click the Center radio button in the section entitled Alignment. + +Click the New button again. +Using the arrows of the spinbox labeled Position enter a value that is slightly less than the frame width. The frame width is + listed directly below the Position spin box. +Click the Right radio button in the section entitled Alignment. + +Then click OK. +Click in the header again with the &LMB;. +Type the key. This will move the cursor to the center of the header. +Select InsertVariable +Document InformationDocument Title +from the menubar. +Type the key again. This will move the cursor near the right margin of the header. +Select InsertVariable +PagePage Number +from the menubar. +Move to an even numbered page in your document, and click in the header box. +Select FormatParagraph +from the menubar. +The Paragraph Settings dialog will appear. Click on the Tabulators tab. +Click the New button. +Using the arrows of the spinbox labeled Position enter a value that is exactly 1/2 the frame width. The frame width is + listed directly below the Position spin box. +Click the Center radio button in the section entitled Alignment. +Then click OK. +Click in the header again with the &LMB;. +Select InsertVariable +PagePage Number +from the menubar. +Type the key. This will move the cursor to the center of the header. +Select InsertVariable +Document InformationDocument Title +from the menubar. + +That completes the procedure. Your document now has the title of the document in the center along the top of each page, and +the page numbers on the outside corners of the pages. +If you want page numbers on the bottom of the pages, you can use Footers instead of +headers in your document. + + + +How do I create a <literal role="extension">.pdf</literal> file? +creating a PDF file +PDF, creating + +&kword; differs slightly from other word processors here. Instead of saving your file as a +.pdf file, you print your file to create the +.pdf file. +When you are ready to create a .pdf file from your document: + + +Select FilePrint +from the menubar. +This will bring up the Print dialog. +In the combo box labeled Name, select Print to File (PDF) +Enter your desired filename in the Output file: text box. +If you wish to make any changes to the PDF formatting, select Properties. +A complete explanation to all these properties, is beyond the scope of this document. +Click OK. + +Your PDF file will be created and saved at the location specified in Output file. +For more information on printing in &kde;, visit The &kde; Print web page. + + + + +How do I remove template categories from the startup dialog. + +Templates can only be removed using the Create Template dialog. For instructions, click +Removing template group. + + + + + + +&mbtb; +&opt; + + + +Questions and Answers +FAQ + + + + +When I try to load a document or picture, it does not appear in my dialog +box, but I know I saved it there. Why can I not see it? + + +Check to make sure that you have selected the correct file type in the open dialog box. +If you save a file in one format, but ask +&kword; to show you the files from another format, you will not see your saved file. + + + + + +What is a kwd file? +What is a kwt file? + + +A kwd file is a &kword; document. +A kwt file is a &kword; template file. + + + + + +Where can I get updates? + + +For updates to &kword; you should always check the following sites: +The &koffice; website (http://koffice.kde.org) is the first place to look for updates. +Any software updates, bug fixes or announcements of new releases of &koffice; will be found here. +Addons for &koffice; can be found at http://koffice.kde.org/addons/. + + + + + +How do themes affect &kword;? + + +&kword; (like all of &koffice;) is completely themeable. You can use any QT or &kde; theme to customize the look of &kword;. + + + + + +Can I use &kword; to read &Microsoft; Word files? + + +&kword; does have the ability to import &Microsoft; Word files. The conversion process is not perfect, +and some formatting information will be lost. For more details please refer to the +Import/Export Filters section of the documentation. + + + + + +Can I save my &kword; document as a &Microsoft; Word file? + + +At the moment, &kword; does not yet provide support for exporting to &Microsoft; Word +documents. If you need to exchange documents with MS Word, +you should use Rich Text Format as an intermediate file format. +Rich Text Format files +are converted well by both &Microsoft; Word and &kword;, + + + + + +Can I save my &kword; document as a PDF file? + + +Yes. Instructions on creating a PDF file are found +here. + + + + + +I have to exchange documents with a friend who does not have &kword;; what is +the best way to do this ? + + +What you and your friend need to do is agree on a file format that both word processors +can read and write effectively. Rich Text Format is probably a good choice. + + + + + + + + +Credits and Licenses +creditsoptions +licensesoptions + +&kword; Copyright 1999-2005 by The &kword; Team + + +&kword; Developers (Alphabetically) +Dag Andersen danders@get2net.dk +John Califf jcaliff@compuzone.net +Frank Dekervel frank.dekervel@student.kuleuven.ac.be +Krister Wicksell Eriksson krister.wicksell@spray.se +&David.Faure; &David.Faure.mail; +Nicolas Goutte goutte@kde.org +Shaheed Haque srhaque@iee.org +&Simon.Hausmann; &Simon.Hausmann.mail; +Nash Hoogwater nrhoogwater@wanadoo.nl +&Stephan.Kulow; &Stephan.Kulow.mail; +Sven Lüppken sven@kde.org> +Laurent Montel montel@kde.org +&Daniel.Naber; &Daniel.Naber.mail; +Reginald Stadlbauer reggie@kde.org +Werner Trobin trobin@kde.org +Torben Weis weis@kde.org +&Joseph.Wenninger; jowenn@kde.org +Thomas Zander zander@kde.org + + + + +&kword; Import/Export Filter Developers (Alphabetically) +Enno Bartels ebartels@nwn.de +Wolf-Michael Bolle +&Matthias.Kalle.Dalheimer; kalle@dalheimer.de +Clarence Dang dang@kde.org +Frank Dekervel frank.dekervel@student.kuleuven.ac.be +Nicolas Goutte goutte@kde.org +Tomasz Grobelny grotk@poczta.onet.pl +Shaheed Haque srhaque@iee.org +Ariya Hidayat ariya@kde.org +Robert Jacolin rjacolin@ifrance.com +Michael Johnson + +Ewald Snel ewald@rambo.its.tudelft.nl + + + +&kformula; developers +Andrea Rizzi rizzi@kde.org +Ulrich Kuettler ulrich.kuettler@mailbox.tu-dresden.de + + +Documentation by &Mike.McBride; + + +&underFDL; +This program is licensed under the terms of the &GNU; Library General +Public License v2. + + + + + + +Installation +&kword;installation + + +How to obtain &kword; + +&kword; is part of the &kde; project http://www.kde.org. &kword; is located +in the &koffice; package which can be obtained from &kde-ftp;, the +main ftp site of the &kde; project. + +Many distributions offer precompiled binaries on their ftp sites. Please check your distribution's web sites for more information. + +If you want to compile &kword; from source, then you should read through the next few sections for help on compilation. + + + + +Requirements +&kword;requirements + +In order to successfully use &kword;, you need: + + + +&Qt; Toolkit 3.2 or later. This can be obtained from Trolltech. +While &koffice; will compile and run with any version of &Qt; 3.2 or later, it is recommended that you compile and install +&Qt; 3.3.4 to take advantage of all the bug fixes (including some security fixes) that have occurred. + + + +&kde; 3.3.0 libraries (kdelibs) and the &kde; 3.3.0 base package +(kdebase). These can be obtained from the &kde; web page. +While &koffice; will compile and run with any version of &kde; 3.3.0 or later, it is recommended that you compile and install +&kde; 3.4 to take advantage of all the bug fixes that have occurred. +It is also recommended that you install the arts package 1.3.2 from the +&kde; &FTP; site. + + + +&GNU; c++ compiler or any c++ compiler that supports exceptions. For help on obtaining this, please refer to +your distribution's web site. + + + +autoconf 2.53 or later and automake 1.7 or later + + + +In order to use external databases for mail merging documents, you must have +the QT toolkit compiled with SQL support. To add SQL support (as a plugin), simply include + in your configure line. +driver should be replaced with mysql, odbc, +CVS, or psql as is appropriate for your database needs. + + + +Compilation and Installation + +Complete instructions on installing &koffice; from source are located at +http://www.koffice.org/download/source.php. + + + + + +&kword; Command Line Options +&kword;command line options + +You can specify some initial actions for &kword;. The most +commonly used options are discussed below with instructions on finding +help on the rest of the command line options. + +Specifying the file name + +Probably the most common command line option used is to specify +the file to edit. + +The format for specifying the file name is: + + +$ kword filename + + +Example: + +$ kword Resume.kwd + +This will cause &kword; to load Resume.kwd for editing. + +Show &kword; version + +To see the version numbers for the QT toolkit, &kde;, and &kword; type: + + +$ kword -v + + +Show the license for &kword; + +To see the license for &kword; type: + + +$ kword --license + + + +Show &kword; developer list + +To see the list of developers for &kword; type: + + +$ kword --author + + +Other command line options + +There are many other, rarely used, command line options. You can get detailed help on these options by typing: + +$ kword + + + + + +Import/Export Filters +&kword;filters +filters + +Introduction to Filters +&kword; has the ability (with varying success) to load data +from foreign (non-&koffice;) data files. &kword; also has the ability to +save data as non-&koffice; data files. This is provided to help users +of &kword; to interact more seamlessly with people who use other +operating systems and wordprocessors. + +&kword; does this by loading a non-&koffice; datafile into +memory and passing the data through a filter +to extract as much information as possible from the data file. Some +formatting information will be lost or changed by the filter in the +attempt. + +When &kword; reads data into +&kword; from a non-&koffice; file format, it is +importing the data. + + +When &kword; saves a &kword; document as a non-&koffice; +file format, it is exporting the data. + + +Filters included in &kword; + +&kword; comes with the following filters: + + + + +ApplicationImportExport + +AbiwordYesYes +AmiProYesYes +ApplixwordYesNo +&HTML;YesYes +&kpresenter;YesNo +Hancom WordYesNo +Magic Point PresentationYesNo +&Microsoft; PowerpointYesNo +&Microsoft; WordYesNo +&Microsoft; WriteYesYes +Oasis OpenDocumentYesYes +Openoffice.org PresentationYesNo +Openoffice.org Text DocumentYesYes +Palm DocumentYesYes +PDFYesNo +Plain TextYesYes +RTFYesYes +SGMLNoYes +TeX DocumentNoYes +WMLYesYes +WordperfectYesYes +&XML;YesNo + + + + +For details on each filter, please refer to the &koffice; filters web page. + + + + + + + + +Key Bindings Summary +keyboard shortcutstable of + +Keybindings for Working with Documents + + + +Start New +Document +&Ctrl;N + + + +Open +Document +&Ctrl;O + + + +Save +Document +&Ctrl;S + + + +Print +Document +&Ctrl;P + + + +Close +Document +&Ctrl;W + + + +Quit +&kword; +&Ctrl;Q + + + + + + +Keybindings for Character Selection + + +Move selection one character to the left.&Shift;Left Arrow +Move selection one word to the left.&Ctrl;&Shift;Left Arrow +Move selection one character to the right.&Shift;Right Arrow +Move selection one word to the right.&Ctrl;&Shift;Right Arrow + +Selects all characters from the start of the selection, to the character directly up one line.&Shift;Up Arrow +Selects all characters from the start of the selection, to the first character of the line directly above.&Ctrl;&Shift;Up Arrow + +Selects all characters from the start of the selection, to the character directly down one line.&Shift;Down Arrow +Selects all characters from the start of the selection, to the last character of the line directly below.&Ctrl;&Shift;Down Arrow + +Selects all characters from the start of the selection, to the beginning of the line.&Shift;Home +Selects all characters from the start of the selection, to the beginning of the document.&Ctrl;&Shift;Home + +Selects all characters from the start of the selection, to the end of the line.&Shift;End +Selects all characters from the start of the selection, to the end of the document.&Ctrl;&Shift;End + +Moves the current endpoint one screen up.&Shift;Page-Up +Moves the current endpoint one page up. The endpoint is located at the first character of this page.&Ctrl;&Shift;Page-Up + + +Moves the current endpoint down one screen.&Shift;Page-Down + +Moves the current endpoint down one page. The endpoint is located at the first character of this page.&Ctrl; &Shift;Page-Down +Select all text in the current frame.&Ctrl;A + + + + + +Keybindings for Character Formatting + + + + + +Toggle Boldface On/Off +&Ctrl;B + + + +Toggle Italics On/Off +&Ctrl;I + + + +Toggle Underline On/Off +&Ctrl;U + + + +Format Font +&Alt;&Ctrl;F + + + +Decrease Font Size +&Ctrl;< + + + +Increase Font Size +&Ctrl;> + + + + + + + + + +Keybindings for Paragraph Formatting + + + + + +Align Block (Justify) +&Ctrl;J + + + +Align Center +&Alt;&Ctrl;C + + + +Align Left +&Ctrl;L + + + +Align Right +&Alt;&Ctrl;R + + + +Format Paragraph +&Alt;&Ctrl;P + + + + + + + +Keybindings for Basic Editing Functions and Search and +Replace + + + + + + +Copy +&Ctrl;C (&Ctrl;Insert) + + + +Cut +&Ctrl;X (&Shift;Delete) + + + +Paste +&Ctrl;V (&Shift;Insert) + + + +Find +&Ctrl;F + + + +Replace +&Ctrl;R + + + +Undo +&Ctrl;Z + + + +Redo +&Ctrl;&Shift;Z + + + + + +Keybindings for Inserting + + + + + +Create Text +Frame +F10 + + + +Insert +Picture +&Shift;F5 + + + +Create +Formula Frame +F4 + + + +Create +Table +F5 + + + +Insert Special +Character +&Alt;&Shift;C + + + +Insert Non-breaking Space +&Ctrl;Space + + + +Insert Soft Hyphen +&Ctrl;- + + + +Insert Line +Break +&Shift;Return + + + +Insert Hard Frame +Break +&Ctrl;Return + + + + +Keybindings for Accessibility + + + +Popup Context Menu +Menu (see note below) + + +Resize Panel Forward +F8 + + +Resize Panel Reverse +&Shift;F8 + + +Set Focus to Widget +&Alt;F8 + + +Enter keyboard Mouse Emulation mode +&Alt;F12 + + +Click mouse in Mouse Emulation mode +spacebar + + +Go to Document Structure +&Alt;1 + + +Go to Document +&Alt;2 + + + + +On most keyboards, the Menu key is on the righthand side between +the &Windows; and &Ctrl; keys. It has a menu icon on it. + + +Keybindings for Mouse Navigation + + + + + + + +Miscellaneous Keyboard Shortcuts + + + + +&kword; Handbook +F1 + + + +Whats This? +&Shift;F1 + + + +Completion +&Ctrl;E + + + +Lower Frame +&Ctrl;&Shift;L + + + +Raise Frame +&Ctrl;&Shift;R + + + +Show Stylist +&Alt;&Ctrl;S + + + + + + + + + +&kword; Technical details + +&techstuff; + +Kword &MIME; types +&kword;&MIME; types + +The &kword; &MIME; type is : application/x-kword + + + + + + +Glossary + + +Aspect Ratio + +This is the ratio of the measurement of a screen, picture or document +horizontally compared to the vertical measurement. All standard +computer monitors have the same aspect ratio, regardless of their +resolution. Any &kword; document that conforms to the standard +screen will look good on any monitor. +For many images, it is important to maintain the aspect ratio. This prevents +distortion to the picture. + + + + +Binary code + +Binary code is the actual instructions for the computer. So if we +refer to binaries we mean the executable &kword; +program. While computers have no difficulties reading binary files, +they are not easily understood by people. Compare this distribution method to Source Code. For more information on compiling &kword;, see +the section entitled Installation + + + + +Bitmap Image + +Bit mapped images are composed of individual dots. This type of +file is very good for photographs and complex drawings. The downside of +using bitmap images, is that when you change the size of the image on +the page, there is a loss of detail. The file names of such pictures +often end in jpeg, png or +gif. + + + + +Cells + +Tables are made up of rows and columns of cells. Each cell is +defined by a combination of the row and column of a heading. + + + + +Clipboard + +The clipboard is a temporary storage area in memory. Whenever you +use the Cut or +Copy command, you are placing the object that +was selected into this memory location. Then when you use the +Paste command, you insert the information +from the clipboard into the document. For more information see the +section on Cut/Copy/Paste. + + + + +Compiling + +When you compile a program, you are converting it from +a source file (which is easily edited by a programmer) into a binary +file (which the computer uses). Compare this distribution method to Binary Code. +Compiling programs +is not as easy as installing binary versions. Users who are only interested in +using &kword; are encouraged to find a binary version of &kword; for their computer. For +users who want to learn more about programming, more information on compiling &kword; is +available in the section entitled Installation. + + + +Custom Variables + +Using custom variables you can store certain values (⪚ numbers +or text) for later use in your document or in a script. If you want to +find out more about custom variables, see Document Variables. + + + + +DEB + +This is a binary file format that is used by Debian and Debian-based +distributions. This will be the suffix of a file +specifically for +these distributions. An example would be +koffice-1.2.deb. For more information on installing +these files, refer to the Debian Web +Site. + + + + +Dialog Box + +A dialog box is a small window that appears on top of your working +document. This window usually has questions, information or +configuration options related to the task you are performing. When you +are finished with the dialog box, it will disappear and return you to +your document (possibly after making some changes to the +document). + + + + +DTP + +Stands for DeskTop Publishing. + + + + +FAQ + +Stands for Frequently Asked Questions and +normally means a document, where questions that arise many times are answered. If you +have a question to the developers of &koffice;, you should always have a +look at the FAQ first; you can find the latest version +here. + + + + +File Mask + +A file mask can be thought of as a strainer for you. On the +average computer, there are several thousand files. These files are +sorted into sub-directories, but it is not uncommon for many users to +have 100's of data files in a single sub-directory. +Fortunately for us, most applications use a suffix to their +filenames. By applying a file mask, &kword; will only show you the +files which are not filtered out by the mask. (That is to say &kword; +only shows the files that fit through the strainer). This can be +helpful if you have many files from many different applications. The +file mask is incorporated in the Filter: line of +the Save Document and Open Document dialog boxes. +As an example. If you use a file mask for &kword; files, the file +mask will try to filter out all files that are not for +&kword;. + + + +Filter + +A filter takes a document file from one program (⪚ &Microsoft; +Word), and filters out +the text and formatting information and converts that information into a +&kword; document. Filters are used to read and write files for other +programs. More information on the filters included with &kword; +is available in the section entitled Import/Export Filters. + + + + +Footer + +The footer of a page is an area below the normal text area. Often +it contains the page numbering and maybe some additional +information. The contents of the footer are normally the same for most +pages, and changing the footer on one page will change all other pages +as well. See Header. + + + + +Frame + +Nearly everything in &kword; is in a frame. Text is always in +a text frame. Pictures are in picture frames. Parts are in part +frames. A frame is basically just a rectangle that can contain some part +of your document. Frames can be moved, resized, deleted etc. + + + + +Frameset + +A frame-set is a group of frames which are connected together. If +you are writing text that does not fit into the first frame of a frame-set, +it will continue in the next frame belonging to that frame-set. + + + + +&FTP; + +&FTP; is the File Transfer Protocol; it is an +Internet protocol that allows you to retrieve files from so-called &FTP; +servers. If you want to download &koffice; from the Internet, you will +probably use &FTP;. + + + + +Hard Frame Break + +Normally, &kword; automatically adjusts text so it fits into a +text frame. By inserting a hard frame break you can force &kword; to +always start the next frame in the frameset with the text that follows +the break. + + + + +Hanging indention + +A paragraph where the first line of the paragraph extends outwards to +the left compared with other lines in the paragraph. + + + + + + +Header + +The header of a page is an area above the normal text area. Often +it contains the page numbering and maybe some additional +information. The contents of the header normally are the same for most +pages, and changing the header on one page will change all other pages +as well. See Footer. + + + + +&HTML; + +Stands for HyperText Markup Language. Most +web pages on the Internet are written in +&HTML;. &kword; can read and write +&HTML; documents for publishing on the World Wide +Web. + + + + +Hue + +Hue is a more technically correct term for what we generally refer to as color. +Examples of hues include red, green, blue and purple. + + + + +Inline frame + +An inline frame is a special frame type in &kword;. Inline frames are associated with a position in a text frame. +&kword; will keep the inline frame near the specified text. You will not be able to determine where exactly on a page the +frame will appear, but it will be located close to the specified text. +If you insert or delete text in front of the specified text, the inline image will move up or down the page to follow the +specified text +Inline frames are very useful when they contain a picture, graph or figure. Simply place the inline frame within the +text which describes the object, and &kword; will make sure both the text and the inline frame are always near each other. + + + + +&kde; + +Stands for the K Desktop Environment. Part of &kde; is +required for &kword; to operate. The K Desktop Environment is a user +interface which allows users to manipulate files and operate programs +graphically. For more information, please visit www.kde.org. + + + + +Key Binding + +All of the features of &kword; are available through the menubar. +You will find, however, that there are certain features of &kword; that +you use on a regular basis. You can bind a certain +key combination to that function. Once this combination is bound to the +function, you can use it as a shortcut to the function. &kword; comes +with several predefined key-bindings. For +more information on changing the default key-bindings, click here. + + + + +Landscape + +When you have a standard sheet of paper, you can either orient +your document with the long side vertically or horizontally. When the +horizontal dimension is greater than the vertical, this is termed +Landscape. +Example: + Compare +with Portrait. + + + + +Menubar + +The menubar is located at the top of the &kword; screen. You can +use it to access all features of &kword;. +Menubar: + + + + +Portrait + +When you have a standard sheet of paper, you can either orient +your document with the long side vertically or horizontally. When the +vertical dimension is greater than the horizontal, this is termed +Portrait. +Example: +Compare with Landscape. + + + + +RPM + +This is the binary file format for distributions based on the +&RedHat; package manager, a widely used packaging tool for the &Linux; +operating system. If you still have to get &koffice; and your system +supports RPM packages, you should get &koffice; +packages ending in .rpm. They are +very easy to use. + + + + +Saturation + +Saturation refers to the subjective quantity of a specific hue in a color. Colors with a low saturation appear more white. +Colors with high saturation appear more richly colored. +This is a set of four red dots which increase in saturation from left to right. + + + + + +Scaling Pictures + +Whenever you change the size of a graphics image, you are scaling +that image. In &kword; you scale the pictures by changing the shape of +the frame which surrounds the graphic. + + + + +Source Code + +Source code is the human readable version of an application (such +as &kword;). Computers cannot use source code directly. Instead, +source code must be compiled into +binary code, before use. + + + + +TAR + +Tar is a tool used for the archiving of files in so-called +tar-files which you recognize by their suffix +.tar. You can find &koffice; source +and binary distributions as gzipped +tar-files; however, you should not use them if there are special +packages for your system and package manager. See RPM, DEB. + + + + +tar.gz + +See TGZ. + + + + +TGZ + +Files ending in .tar.gz or +.tgz are tar-files compressed with the +gzip program. This makes the tar files smaller and +quicker to download. You can find &koffice; source and binary +distributions in this format; however, you should not use them if there +are special packages for your system and package manager. See RPM, DEB. + + + + +Toolbar + +A toolbar is a line of buttons which are shortcuts to more of the +commonly used features of &kword;. More information on toolbars can be +found here. +Example Toolbar: + + + + +&URL; + +&URL; is an abbreviation for Universal Resource Locater. A universal resource locater is +the technical term for what is commonly referred to as a websites address. +Examples of &URL;s include http://www.koffice.org and +http://www.kde.org + + + + +Value (color) + +Color value refers to how bright or dark a color is. Colors with low value are more black in appearance. Colors with high +value are more richly colored. +This is a set of four red dots which increase in value from left to right. + + + + + + +Vector Image + +A vector based graphic is described in terms of lines and shapes, +not in terms of dots. These files +scale better than bit-mapped images. + + + + +WYSIWYG + +Stands for What You See Is What You Get. +&kword; is a WYSIWYG word processor, which means that +the document will appear the same on the screen while you are editing +it, as it will on the printed page. + + + + +&X-Window; + +The &X-Window; (also known simply as X) is +required for &koffice; to operate. More information on &X-Window; for +&Linux; can be found at http://www.xfree86.org + + + + + +&documentation.index; + diff --git a/doc/kword/inscoldlg.png b/doc/kword/inscoldlg.png new file mode 100644 index 000000000..4af996944 Binary files /dev/null and b/doc/kword/inscoldlg.png differ diff --git a/doc/kword/insdate.png b/doc/kword/insdate.png new file mode 100644 index 000000000..12a11f354 Binary files /dev/null and b/doc/kword/insdate.png differ diff --git a/doc/kword/insertfile.docbook b/doc/kword/insertfile.docbook new file mode 100644 index 000000000..cf792062f --- /dev/null +++ b/doc/kword/insertfile.docbook @@ -0,0 +1,22 @@ + + + + +Mike +McBride + + + + +Inserting files +inserting files + +&kword; has the ability to insert a previously saved &kword; file into the current document. This is especially useful for +large documents that have multiple authors. +To insert a &kword; file into the current document, place the cursor at the desired insertion point of the document. +Selecting InsertFile... from +the menubar. You will be given a file selection dialog to select the &kword; file you want to insert. +When you have located the &kword; file, click OK, and the new &kword; file will be inserted into the +current document at the current cursor position. +&kword; will integrate the newly inserted document into the structure of the current document. + diff --git a/doc/kword/insgrph1.png b/doc/kword/insgrph1.png new file mode 100644 index 000000000..c404ae67c Binary files /dev/null and b/doc/kword/insgrph1.png differ diff --git a/doc/kword/insgrph2.png b/doc/kword/insgrph2.png new file mode 100644 index 000000000..d1ccc60e0 Binary files /dev/null and b/doc/kword/insgrph2.png differ diff --git a/doc/kword/insrowdlg.png b/doc/kword/insrowdlg.png new file mode 100644 index 000000000..32c55a380 Binary files /dev/null and b/doc/kword/insrowdlg.png differ diff --git a/doc/kword/instab1.png b/doc/kword/instab1.png new file mode 100644 index 000000000..7d4771b16 Binary files /dev/null and b/doc/kword/instab1.png differ diff --git a/doc/kword/instb.png b/doc/kword/instb.png new file mode 100644 index 000000000..72d4135a4 Binary files /dev/null and b/doc/kword/instb.png differ diff --git a/doc/kword/instime.png b/doc/kword/instime.png new file mode 100644 index 000000000..dc88fb44f Binary files /dev/null and b/doc/kword/instime.png differ diff --git a/doc/kword/intro1.png b/doc/kword/intro1.png new file mode 100644 index 000000000..a8d2261dc Binary files /dev/null and b/doc/kword/intro1.png differ diff --git a/doc/kword/intro2.png b/doc/kword/intro2.png new file mode 100644 index 000000000..0f4fe903e Binary files /dev/null and b/doc/kword/intro2.png differ diff --git a/doc/kword/intro3.png b/doc/kword/intro3.png new file mode 100644 index 000000000..04b6c138c Binary files /dev/null and b/doc/kword/intro3.png differ diff --git a/doc/kword/ital.png b/doc/kword/ital.png new file mode 100644 index 000000000..79a643539 Binary files /dev/null and b/doc/kword/ital.png differ diff --git a/doc/kword/joincell.png b/doc/kword/joincell.png new file mode 100644 index 000000000..ae9cd44c3 Binary files /dev/null and b/doc/kword/joincell.png differ diff --git a/doc/kword/kbd-focus-ext.png b/doc/kword/kbd-focus-ext.png new file mode 100644 index 000000000..541e124e5 Binary files /dev/null and b/doc/kword/kbd-focus-ext.png differ diff --git a/doc/kword/kformappcol.png b/doc/kword/kformappcol.png new file mode 100644 index 000000000..31083ce50 Binary files /dev/null and b/doc/kword/kformappcol.png differ diff --git a/doc/kword/kformapprow.png b/doc/kword/kformapprow.png new file mode 100644 index 000000000..df9b1389e Binary files /dev/null and b/doc/kword/kformapprow.png differ diff --git a/doc/kword/kforminscol.png b/doc/kword/kforminscol.png new file mode 100644 index 000000000..1c3391fbb Binary files /dev/null and b/doc/kword/kforminscol.png differ diff --git a/doc/kword/kforminsrow.png b/doc/kword/kforminsrow.png new file mode 100644 index 000000000..0d3273fc6 Binary files /dev/null and b/doc/kword/kforminsrow.png differ diff --git a/doc/kword/kformremcol.png b/doc/kword/kformremcol.png new file mode 100644 index 000000000..452eb974c Binary files /dev/null and b/doc/kword/kformremcol.png differ diff --git a/doc/kword/kformremrow.png b/doc/kword/kformremrow.png new file mode 100644 index 000000000..8dd870faf Binary files /dev/null and b/doc/kword/kformremrow.png differ diff --git a/doc/kword/kpart.png b/doc/kword/kpart.png new file mode 100644 index 000000000..f70b6b1d4 Binary files /dev/null and b/doc/kword/kpart.png differ diff --git a/doc/kword/kparts.docbook b/doc/kword/kparts.docbook new file mode 100644 index 000000000..67ac3357e --- /dev/null +++ b/doc/kword/kparts.docbook @@ -0,0 +1,56 @@ + + + + +Mike +McBride + + + + +KOffice Data +inserting &koffice; data +&koffice;inserting data into &kword; + +The applications which make up &koffice; are capable of a fine degree of integration between each other. +Because the actual process of inserting a component varies depending on the application, this chapter will not detail +every step of the process. You will need to be familiar with the basics of using the other application in order to correctly insert +a component from that application +Refer to the help files of the other applications for more specific information. +General instructions +There are two ways to insert a component (spreadsheet, presentation, graph, etc) from another application in &koffice;: + + + +Selecting +InsertObject Frame from +the menubar. +You will be given a list of &koffice; applications to choose from. Select the application you desire. + + + +or by clicking on the +toolbar. +A dialog box will appear with a list of &koffice; applications to choose from. Select the application you desire. + + + + +&kword; +will now ask you to define a frame for this object. Place the mouse pointer where you want the upper left corner of the frame to +be located. Click and hold with the &LMB;. Drag the mouse to draw a square for your new object. When you are happy with the size of the object frame, release the &LMB; +&kword; will now execute the application you selected from within &kword;. The details of each +application are different. Please see the application manuals for the specific &koffice; application for details on the use of that +application. (In other words, from this point on, if you insert a spreadsheet from &kspread;, then the windows will act the same +as &kspread;.) + +Working with the inserted component +To edit the data within the component, simply double click with the mouse pointer and &kword; will change the toolbars, menuitems and +application structure to match the &koffice; application. This way, you can use the application specific tools to refine your component. +The frame that contains the embedded data, can be manipulated +the same as any other frame in &kword;. +When you save your document, the component is saved within the &kword; document. + + diff --git a/doc/kword/landscape.png b/doc/kword/landscape.png new file mode 100644 index 000000000..c9c796110 Binary files /dev/null and b/doc/kword/landscape.png differ diff --git a/doc/kword/larrow.png b/doc/kword/larrow.png new file mode 100644 index 000000000..1da2e7386 Binary files /dev/null and b/doc/kword/larrow.png differ diff --git a/doc/kword/lbord.png b/doc/kword/lbord.png new file mode 100644 index 000000000..7814e3dc6 Binary files /dev/null and b/doc/kword/lbord.png differ diff --git a/doc/kword/linkdlg.png b/doc/kword/linkdlg.png new file mode 100644 index 000000000..620b2c6b0 Binary files /dev/null and b/doc/kword/linkdlg.png differ diff --git a/doc/kword/listdepth1.png b/doc/kword/listdepth1.png new file mode 100644 index 000000000..9f5ce1370 Binary files /dev/null and b/doc/kword/listdepth1.png differ diff --git a/doc/kword/listdepth2.png b/doc/kword/listdepth2.png new file mode 100644 index 000000000..8539363a1 Binary files /dev/null and b/doc/kword/listdepth2.png differ diff --git a/doc/kword/listdepth3.png b/doc/kword/listdepth3.png new file mode 100644 index 000000000..382f8e4b2 Binary files /dev/null and b/doc/kword/listdepth3.png differ diff --git a/doc/kword/lists.docbook b/doc/kword/lists.docbook new file mode 100644 index 000000000..4e7f8b18d --- /dev/null +++ b/doc/kword/lists.docbook @@ -0,0 +1,165 @@ + + + + +Mike +McBride + + + + +Lists +lists + +&kword; has a simple and flexible list creation system. +Using the same interface, &kword; can create bulleted or enumerated lists of nearly any depth. +For easy, simple lists, &kword; offers +a toolbar button for both enumerated and bulleted lists. + +An enumerating style is a series of letters or +numbers which proposes an order or hierarchy within the list. Bullets +simply mark the item as part of the list and usually consist of a symbol or shape. + +Simple lists + +To quickly create a single level list, &kword; provides two toolbar buttons. +To create a simple enumerated list, simply select from the +paragraph toolbar. +A small menu will list different enumerated list styles. Select the appropriate style and the selected +paragraphs are converted into a list of that style. +To create a simple bulleted list, select from the +paragraph toolbar. +A small menu will list different bulleted list styles. Select the appropriate style and the selected +paragraphs are converted into a bulleted list of that style. +You are still able to make changes to the list styles by using the dialog. + + +Complex lists +All complex list formatting is done through the Paragraph Settings dialog. To get to the Paragraph Settings dialog you can: + + + +Select +FormatParagraph... +from the menubar + + +Type &Alt;&Ctrl;P + + +Place the mouse pointer in the paragraphs that will become the list and click once +with the &RMB;. A small menu +will appear. Select Paragraph.... + + + +A dialog will appear. To find the tab specific to lists, click once on the tab labeled Bullets/Numbers. + + +List type + + + + + + + +To format the selected text as a list, select the radio button labeled List from the top section of the dialog box. + +There is a list of five bullets types and five enumerating styles along the left +side of the dialog box. Select the desired list style from the list on the left. + +Changing the look of the list + +The text box labeled Prefix text: allows the user to add text before +the enumeration or bullet. + +The text box labeled Suffix text: allows the user to add text after +the enumeration or bullet. + +For example: If Step is typed into the Prefix text: +box, and - is typed into the Suffix text: text box, the list will look like this: + + +Step 1 - Place 1 cup of flour in a large mixing bowl. +Step 2 - Add 1/4 tablespoon of yeast. +Step 3 - .... + + +If an enumerated list style is selected, the starting number/letter for the list can be set in the spin box +labeled Start at:. If you have selected a bulleted list style, this box will be inactive. + +Multi-level lists + +The spin box labled Depth: is used to add subsections to your list. By selecting a depth greater than one, +you are adding a subsection to the list. + +Example of a multilevel enumerated list: + + + + + + + + +An example of a multilevel bulleted list: + + + + + + + + +Adjust the depth setting to determine where in the list this text occurs. +By adjusting the spin box labeled Display levels: you can determine if previous levels are displayed. For example, with a list where Depth: is set to three and +Display levels: is set to one might be: + + +i. This is a step +ii. This is another step + + +If you change the Display levels: to two, it would change to: + + +A.i. This is a step +A.ii. This is another step + + + You can always refer to the preview section of the dialog for an example of how +your list will look. + + + + + +Custom Bullets +If you select Custom Bullet from the list of styles, you can click on the button labeled +Custom character: to choose the letter or symbol you want for your bulleted list. + +Restart new list +If you select the checkbox labeled Restart numbering at this paragraph &kword; will start +numbering your list at the beginning. + + Multiple paragraphs in one list element +Each new paragraph represents a new list element. Sometimes, however, it will be desireable to have multiple +paragraphs on a single list element. This is accomplished by inserting a New Line character instead of a Paragraph Break. + +To insert a New Line, type &Shift;Return. + + + + + + + + + + + + + diff --git a/doc/kword/ltab.png b/doc/kword/ltab.png new file mode 100644 index 000000000..60d29657b Binary files /dev/null and b/doc/kword/ltab.png differ diff --git a/doc/kword/ltab2.png b/doc/kword/ltab2.png new file mode 100644 index 000000000..f38b40f80 Binary files /dev/null and b/doc/kword/ltab2.png differ diff --git a/doc/kword/mailmerge.docbook b/doc/kword/mailmerge.docbook new file mode 100644 index 000000000..c0adac9d8 --- /dev/null +++ b/doc/kword/mailmerge.docbook @@ -0,0 +1,475 @@ + + + + +Mike +McBride + + + + +Mail Merge +mail mergeintroduction + +&kword; has the ability to use data from an outside database (or internal database) to personalize your +documents for individual members/clients/friends. +This section of the manual will cover all aspects of creating, merging and printing documents that are specific to &kword;. This +manual will not cover: + +Creating an external database. +Security issues regarding databases. +Detailed instructions on SQL. It is assumed you have some knowledge regarding SQL if you are using a +SQL database for your data source. +Accessing the network or Internet. + + +For answers to these questions, other documentation is available on the Internet that is specific to the software you have chosen. +You can retreive your mail-merge data from a number of sources: + +If you want to use an outside SQL database, click here for instructions. +If you want to use a &kspread; file for your data, click here. +If you want use information from your &kde; Address Book, click here. +If you want to use the internal database of &kword;, click here. + + + +Using an external SQL database as a data source +mail mergeSQL databases + +&kword; has the ability to use several of the most popular open source databases as a source of data for personalized documents. +In order to access an outside database using SQL, your machine needs to have the appropriate database module compiled +into your copy of QT. +For more information see the installation section of this documentation. +The database can be located on the same machine as &kword;, or on any computer which is accessable through your computer +network or the Internet. +In order to use the database, you must know the following information: + +Name of the database +Host name/IP address of the computer the database is located on +The port address on the specified computer granting SQL access +A valid user name for the database +A valid password for the user name + + +If you have all this information at your finger tips, you are ready to proceed. +Using an outside database to create personalized documents is a three step process: + +Connect to the database and select your query. +Insert the merge fields to tell &kword; +where to insert the database information. +Print the personalized documents. + + + +Locate the database and query the records. +To begin, select +ToolsConfigure Mail Merge... from +the menubar. A dialog box will appear. + + + + + + + + +Click on Open Existing.... Another small dialog will appear. + + + + + + + + +Select QT-SQL Source and click on +OK. A new dialog box will appear. + + + + + + + + +Enter the &URL; or IP address of the computer that holds the database in the text box labeled Hostname:. +Select the driver named QMYSQL3 from the combo box labeled Driver:. +Enter the database name you were provided in the text box labeled Database name: and a +user name in the text box labeled Username:. +If the database access is through a port other than the default port enter that port number in the text box labeled +Port:. +If you are going to be using this database at other times, you can click on the button labeled +Keep settings.... &kword; will ask for a descriptive name. +When you want to restore these settings on future sessions, simply select the descriptive name from the combo box in the +upper left of the dialog box. + +When all information is correct, click OK. &kword; will ask you for a password to that database. Enter +the password in the text box, and click OK. +&kword; will now ask if you want to replace your current data source with the source you have selected. Click Yes. +You are now connected to the database. Now you need to select the data from the database. This dialog box has re-appeared. + + + + + + + + +Click on Edit Current.... Another dialog will appear. + + + + + + + + +This dialog is designed to help you enter and test your database query. The dialog is divided into three +sections: Database information, Query information and Query line. +The database information section is labeled Information and consists of two combo boxes. The +left combo box (Available tables:) gives you a list of all available tables within the current database. +Select the desired table from the list by clicking on the table name with the &LMB;. +A list of all available fields from that table will appear in the right combo box. +The query line is a text box located near the bottom of the dialog labeled Query:. Simply type your +SQL query into this text box and click Execute. &kword; will query the database and return the specified query +in tabular format in the Query Result box. You can alter, or edit your query on the query line and each time you +click Execute, the new query results will appear. +&kword; does not limit your query strings. They can be simple and straight forward: +select * from Clients +Or complex multitable queries: +select Clients.FirstName, Clients.LastName, Clients.address, data.Birthday, +data.EyeColour from eMail, data where data.FirstName=Clients.FirstName and +data.LastName=Clients.LastName + + +Clicking Setup, will allow you to log into a different database. +When you have the correct query in the Query: text box, click OK to select that query. + +This will return you to the mail merge main dialog box. + + + + + + + + +Click Close. + +Now that you have selected your data query, it is time to insert the merge fields in the document. Click +here to continue. + + + + +Using a &kspread; file as a data source +mail mergeusing &kspread; file + +&kword; can use data in a &kspread; document for personalizing documents. +In order to use this data, you only need to know the location of the &kspread; document and the worksheet (page) number the data is located on. + +Using a &kspread; document to create personalized documents is a three step process: + +Select the file the data is located within. +Insert the merge fields to tell &kword; +where to insert the database information +Print the personalized documents. + + + +Selecting the file that contains the data. +To begin, select +ToolsConfigure Mail Merge... from +the menubar. A dialog box will appear. + + + + + + + + +Click on Open Existing.... Another small dialog will appear. + + + + + + + + +Select &kspread; Table Source from the drop down box labeled Available sources: and click on +OK. A new dialog box will appear. + + + + + + + + +Enter the &URL; or file name of the &kspread; document in the text box labeled URL:. You can type the file name +directly into the text box, or click on the button with the blue folder and use the file dialog to select the &kspread; file. +Once you have selected the &kspread; document, the drop down box labeled Page number: will show you all the available pages or worksheets +within the &kspread; document. Select the page (or worksheet) that contains the mail merge data. +When all information is correct, click OK. &kword; will ask you if you want to replace the current data source. Click Yes to continue. + + +You will again see the mail merge main dialog box. + + + + + + + + +Click Close. + +Now that you have selected your data query, it is time to insert the merge fields in the document. Click +here to continue. + + + + +Using your &kde; Address book as a data source +mail mergeusing &kde; Address Book + +&kword; can use data in your address book for personalizing documents. + +Using address book entries to create personalized documents is a three step process: + +Select the people you want included in the mail merge. +Insert the merge fields to tell &kword; +where to insert the database information +Print the personalized documents. + + + +Select the people you want included +To begin, select +ToolsConfigure Mail Merge... from +the menubar. A dialog box will appear. + + + + + + + + +Click on Open Existing.... Another small dialog will appear. + + + + + + + + +Select &kde; Addressbook Plugin from the drop down box labeled Available sources: and click on +OK. A new dialog box will appear. + + + + + + + + +The dialog consists of two listboxes labeled Address Book and Selected Addresses. By moving entries from your Address book to the Selected Addresses listbox, you will be including those entries in your merge document. +To add an entry, select the entry in the left listbox by clicking with the &LMB;. Then click Add. +To remove an entry, select the entry in the right listbox by clicking with the &LMB;. Then click Remove. +You can locate entries quickly by entering the first 2-3 letters of an entries name in the textbox labeled Filter on: +You can load the full address book application by clicking the Address Book... button. +You can also save a distribution list using the Save as Distribution List... button. For more information on distribution lists, see the documentation on the &kde; Addressbook. + +When you have selected all the entries and distribution lists you want, click OK. &kword; will ask you if you want to replace the current data source. Click Yes to continue. + + +You will again see the mail merge main dialog box. + + + + + + + + +Click Close. + +Now that you have selected your data query, it is time to insert the merge fields in the document. Click +here to continue. + + + + + +Using an internal representation of tabular data to create documents +mail mergeusing &kword; data tables + +For small sets of data, or when you do not currently have a database containing the merge data, &kword; +offers you the ability to enter the data directly into &kword; in tabular form. This internal data +structure can then be used to create documents with this data inserted at predefined locations. +Using an internal representation of the data to create personalized documents is a three step process: + +Enter the data into &kword; +Insert the merge fields to tell &kword; +where to insert the database information +Print the personalized documents. + +After the data has been created once, you can go back and change the data as needed, and produce another set of +personalized documents from that data. + + +Enter the data +To begin, select +ToolsConfigure Mail Merge... from +the menubar. A dialog box will appear. + + + + + + + + +Click on Create New.... Another small dialog will appear. +There is currently only one option in this dialog box Internal Storage. Click on +OK. A new dialog box will appear. + + + + + + + + +This is a record card for creating your tabular data file. Along the top is a toolbar and the main part of the dialog is space to hold +your entry/data pairs. +Defining the structure of your data table +First, we need to add one or more entries (merge fields). This is accomplished by clicking the + + +(Add entry) +button (third button from the right along the toolbar). A small dialog box will appear. Type a descriptive name of your entry +in the dialog box (Name, Address, Balance Due, etc....). +This is for the name of the entry, not the data that is contained within the entry. +Click OK, and the entry is added to the card. +Repeat this process until all needed entries are visible on this first card. +If you want to delete an entry, simply click once on the entry name with the &LMB; and select + +(Remove entry). +Be very sure you have selected the correct entry name. Once you tell &kword; to delete +the entry, the entry and all of the data within those entries will be deleted immediately. You will not be +given the option to stop or reverse the process once it is begun. + + +Entering the data into the table +Now that the structure of your data is defined, you can enter the data into your entries. +At the top of the dialog box, are 4 buttons surrounding a spin box. The spin box gives the current record number. All +records are numbered in the order they are added starting with number 1. You can use the spin box to go directly to +the desired record or you can use the arrows to graphically move +through the list of records. + + + + +ButtonAction + +Move directly to record one +Move back one record +Move forward one record +Move to the last record in the dataset + + + + +To enter the data, simply place the cursor in the text box to the right of the entry name, and type in the data. (&kword; uses +No Value as the default value for all entries in newly created records.) +To add a record, click the + + button. +To delete a record, click the + + button. +Be careful when you are deleting records. Once deleted, the record cannot be retrieved. +Continue to enter all data until your dataset is complete. +After your dataset is complete, click OK to +save the changes to your dataset. This will bring up the mail merge main dialog: + + + + + + + + +Click Close. Now it is time to insert the merge fields in the document. + + + + + + +Insert merge fields in document +Now that &kword; knows the entries available in your data source, you can insert the merge fields into your document. +A merge field is a placeholder within the document. This placeholder will be replaced in each personalized document with the +value of the entry for that individual record. + + +Insert a merge field +mail mergeinserting merge fields + +To insert a merge field, place the cursor at the desired place in the document. Select +InsertVariable +Mail Merge... from +the menubar. A list of available entries will appear. Select the desired entry, and click OK. +The merge field is inserted at the current cursor location. The merge field is surrounded by brackets. +You can place the cursor in a new location in the document and insert another placeholder. When you are done inserting placeholders, +you can proceed to printing your document. + + + +Delete a merge field +mail mergedeleting a merge field + +You can delete a merge field two ways. + + +Place the cursor at the end of the merge field, and press the &Backspace; key. +Place the cursor at the beginning of the merge field, and press the Delete key. + + + + + + +Previewing and printing the merged document +mail mergemerging data and text + +Once you have inserted all the merge fields you want, you are ready to preview and print the personalized documents. + +Preview your documents before printing +To preview your document select +ToolsConfigure Mail Merge... from +the menubar. A dialog box will appear. + + + + + + + + +Click Print Preview.... You will be able to see the final output of your personalized documents prior to +printing. + + +Print your personalized documents. +You print personalized documents using the same methods that you do to print traditional documents. For more information on printing +see the section on Printing a Document. + + + + diff --git a/doc/kword/mbtb.docbook b/doc/kword/mbtb.docbook new file mode 100644 index 000000000..e28f8dbc5 --- /dev/null +++ b/doc/kword/mbtb.docbook @@ -0,0 +1,2628 @@ + + + + + + +Mike +McBride + + + + +The Menu Items/Toolbars + + +Introduction to the Menubar and Toolbars + +The key to getting the most out of &kword;, is found in the menu +bars and the toolbars. + +The menubar is organized into groups of functions (⪚ file +functions, table functions, &etc;). Below each of these groups, is a +submenu of actions. Some of these submenus will have sub menus of +their own. + +The toolbars are also organized into groups. Each toolbar +consists of a set of buttons. Each button performs a specific +function. The toolbars are designed to act as shortcuts for more +commonly used functions. + +The first part of this section of the manual discusses the +manipulation of &kword;'s toolbars to suit your needs. + +The second part of this section, takes a detailed look at each +menubar function, and each standard toolbar button, and provides you with a +brief summary of its action. Many of these sections also provide you with a link to more detailed +information located elsewhere in the &kword; Handbook. + + + + +Hiding, Changing, and Moving Toolbars +toolbarshiding + +&kword; offers the user great flexibility when it comes to +toolbars. This first section will show you some of the many options +you have for relocating, reformatting and removing toolbars. + + +Hiding Toolbars + +When you start &kword; for the first time, several toolbars +are visible. If you don't think you will need a toolbar, and want to +reclaim that desktop space, you can hide any or all of the toolbars + +To hide a toolbar, Select +SettingsToolbars from +the menubar. This will bring up a submenu. All of the toolbars are +listed. Simply select the toolbar you want to hide or restore. + + + + +Moving Toolbars around +toolbarsmoving + +Toolbars can be located on the screen in 5 places. + + +Top +Bottom +Left +Right +Floating + + +Top, Bottom, +Left and Right refer to the +edges of the &kword; screen. + +By locating a toolbar in the Bottom +position, for example, you move the toolbar into a horizontal position +below the Document Area, and along the bottom of the &kword; +window. By locating a toolbar in the Left +position,however, you move the toolbar into a vertical position to the +left of the Document Area, and along the left edge of the &kword; +window. + +Multiple toolbars can be located at each of these points in the +screen. (You could, for instance, move all the toolbars to the top of +the screen). &kword; will shuffle toolbars around, to fit in the most +compact way at that location. + +There are two ways to move any toolbar. + + + + +Click on the striped area of the toolbar with the &LMB; and hold +the button down. Drag the toolbar to the desired location. You will +see a rectangular shape indicating the position and orientation of the +toolbar. When at the desired location, release the &LMB; and the +toolbar will be inserted there. + +or + + + +Click on the toolbar with the &RMB;. A +popup menu will appear. Select +Orientation. A small submenu will +appear. Select Top, +Bottom, Left, +Right, Floating or +Flat. + + + +If you select Floating for any toolbar, a new window will be created just for that toolbar. This window can be moved independently from the &kword; window. + +Finally, if you select Flat for any toolbar, the toolbar will be reduced to a horizontal section of lines located directly below the menubar. To restore this menubar, simply double click with the &LMB; on the flattened toolbar and the toolbar will be restored to its original size and position. + + + +Changing the look of your toolbars +toolbarsformatting + +Toolbars can have their buttons displayed different ways. Below +are examples of the four options for the File +toolbar. + + + + + +Icons Only + + + + +Text Only + + + + +Text Aside Icons + + + + +Text Under Icons + + + + + + +To change the appearance of a toolbar, place the cursor over on +the toolbar you want to change, and click with the &RMB;. + +A small menu will appear at the mouse cursor. Select +Text Position. This will open a submenu, +select your preference from the list. + + +Changing Icon Size +toolbarschanging size + +You can also select the size of the icons by clicking on the +toolbar with the &RMB;. A small popup menu will appear. Select +Icon Size and then your preferred icon +size. + + +Setting the look of one toolbar does not alter the look +of another toolbar. + + + + + + + + + +Menubar + +The Menubar contains all commands available to &kword;. It is +divided into 10 general categories. + + + + + + + + + +<guimenu>File</guimenu> Menu + +By clicking on the File menu, you can begin +new documents, load previously edited documents, print your documents, +close the current document (so you can load another document), or quit +&kword; entirely. + + + + + + + +&Ctrl;N + +FileNew + + Allows you to open new files for editing. For +Step by Step instructions see Beginning a New +Document. + +Typing &Ctrl;N or clicking + + is equivalent to +using the menubar. + + + + + + + +&Ctrl;O +FileOpen... + + + + For opening previously created &kword; files. +For Step by Step instructions see Retrieving a +Saved Document. +Typing &Ctrl;O or clicking + is equivalent to +using the menubar. + + + + + + +FileOpen +Recent + +For opening the most recently edited files. Once you +have clicked on this option, a list of recently edited files will +appear. Select the file you want and &kword; will open the +file. + + + + + + + +&Ctrl;S + +FileSave + +Saves your current file to disk. If you have +not saved the file yet, you will be prompted for a filename. For more +details, see Saving a Document. +Typing &Ctrl;S or clicking + + is equivalent to +using the menubar. + + + + + + +FileSave +As... + + + +Allows you to save your file under another name or another +format. For more details, see Saving a +Document. + + + + + + +FileReload + + + +Reloads the current file from disk, erasing any changes to the document since the last time it was saved. + + + + + + +FileImport... + + + +Will load a file from another application. &kword; attempts to decipher as much of the file as it can. For many files, some information will be lost. For more +information on the ability to import files from other applications, see the section on filters at the end of this documentation. + + + + + + +FileExport... + + + +Will save a file using the format of another application. &kword; attempts to save as much of the file as it can. For many files, some information will be lost. For more +information on the ability to export files to other applications, see the section on filters at the end of this documentation. + + + + + + +FileMail... + + + +Launches your email client so you can send the current file as an attachment. The file must have been saved once before this option can be selected. + + + + + + +FileCreate Template From +Document... + + + +Allows you to save your file as a template, to use as a +starting point for future documents. For more details, see +Creating a new template. + + + + + + +FileStatistics + + + + +Opens a window that counts the sentences, words, +characters and syllables in your document. The +number of sentences is not always absolutely correct, as &kword; has +to guess if a dot really starts a new sentence or not. The number of +syllables is estimated, &kword; therefore assumes that the text is +written in English. + +The Flesch reading ease: score is a number +between 0 and 100 which estimates how readable a text is. The higher +the number, the easier the text can be read. Text with a score of +70-80 should have fairly good readability. + +The Flesch formula uses the number of words per sentences and +the number of syllables per word. It assumes that the use of short +words and short sentences increases the readability of a text. It says +nothing about grammar or meaning. As both the number of sentences and +the number of syllables is estimated, the result is not absolutely +precise. The text should be at least 200 words long, if it isn't the +score will be marked as approximated. + +The Flesch score is defined for English text only, but the basic +idea should work for many other languages, too. + +Click OK to dismiss the +window. + + + + + + +&Ctrl;P +FilePrint... + + +Print the file. For an overview of printing +options see Printing a Document. + +Typing &Ctrl;P or clicking + + are equivalent to using +the menubar. + + + + + + +FilePrint Preview... + + + +Print the file, but sends the output to your postscript +viewer, for your confirmation before sending it to the printer. The +operation of your postscript viewer will vary depending on which viewer +you use. Refer to the help files for your viewer for +help. + +Clicking + is equivalent to using +the menubar. + + + + + + +FileDocument Information + + + +Opens a window that lets you enter information related to +the document (such as author's name, address, phone numbers, +document abstract, &etc;). This information is saved with the document for later +classification. +For more information, see Document Information. + + + + + + +&Ctrl;W +FileClose + + + +Close the file you are currently working on. If you have +not saved your most recent changes, you will be +prompted. +Typing &Ctrl;W +is equivalent to using the menubar. + + + + + + +&Ctrl;Q +FileQuit + + + +Quits &kword;. +Typing &Ctrl;Q is equivalent to +using the menubar. + + + + + + + +<guimenu>Edit</guimenu> Menu + +By clicking on the Edit menu, you can +cut/copy/paste text, undo or redo edits and perform searches and text +replacement. + + + + + +&Ctrl;Z +EditUndo + + + + +Reverses the last action you performed. Not all +actions can be reversed. If you are not able to Undo the last action, +the Undo option will be displayed gray and is +not accessible. For a more thourough +discussion of Undo/Redo, click +here. + +Typing &Ctrl;Z or clicking + + is equivalent to using +the menubar. + + + + + +&Ctrl;&Shift;Z +EditRedo + + + +Reverses the last Undo performed. If the Redo +option is unavailable, the Toolbar will display this items gray. For a more thourough discussion of Undo/Redo, +click here. +Typing &Ctrl;&Shift;Z +or clicking + + is +equivalent to using the menubar. + + + + + + + +&Ctrl;X + +EditCut + + + +Deletes the highlighted text from the document, and places +a copy in the clipboard. For a more complete directions on +cutting and pasting, and a full description of the clipboard, click here. + +Typing &Ctrl;X or clicking + + + + is equivalent to using the menubar. + + + + + + + +&Ctrl;C + +EditCopy + + + +Places a copy of the highlighted text in the clipboard, +without changing the text in the document. For a more complete +directions on cutting and pasting, and a full description of the +clipboard, click here. + +Typing &Ctrl;C or clicking + is equivalent to using +the menubar. + + + + + + + +&Ctrl;V + +EditPaste + + + +Inserts a copy of the clipboard into the current cursor +position. If there is highlighted text, &kword; replaces +replaces all highlighted text with the contents of the clipboard. The +clipboard is not altered. For a more complete directions on cutting and pasting, +and a full description of the clipboard, click here. + +Typing &Ctrl;V or clicking + is equivalent to using +the menubar. + + + + + + + +&Ctrl;A + +EditSelect All + + + +Immediately highlights all text of the current +frameset. + +Typing &Ctrl;A is equivalent to +using the menubar. + + + + + + + +EditSelect All Frames + + + +Immediately selects all frames in the current document. + + + + + + + +EditSelect Frame + + + +Selects the current text frame in the document. + + + + + + + + +&Ctrl;F + +EditFind... + + + +Allows you to search for a series of characters. +The find features of &kword; are covered in more detail under Searching for Text. + +Typing &Ctrl;F or clicking + is equivalent to +using the menubar. + + + + + +F3 + +EditFind Next + + + +Repeat the last search for characters starting at the current cursor position. +The find features of &kword; are covered in more detail under Searching for Text. + +Typing F3 is equivalent to +using the menubar. + + + + + +&Shift;F3 + +EditFind Previous + + + +Repeat the last search for characters starting at the current cursor position and moving backwards. +The find features of &kword; are covered in more detail under Searching for Text. + +Typing &Shift;F3 is equivalent to +using the menubar. + + + + + + +&Ctrl;R + +EditReplace... + + + +Allows you to replace one or more characters with +another set of characters. The find and replace features of &kword; are covered +in more detail under Replacing +Text. +Typing &Ctrl;R is equivalent to +using the menubar. + + + + + +EditDelete Page + + + +Delete the current page. + + + + + +<guimenu>View</guimenu> Menu + + + + +ViewNew View + + + +This will create a new view of your document. +For more information on views, refer to the section entitled Using Multiple Views. + + + + + + + +&Ctrl;&Shift;W + +ViewClose All Views + + + +This will close all views including the current view. This will also quit &kword;. +For more information on views, refer to the section +entitled Using Multiple Views. + + + + + + +ViewSplit View + + + +This will split the current view. The orientation of the +split is determined by the Splitter +Orientation. For more information on views, refer to the +section entitled Using Multiple +Views. + + + + + + +ViewRemove View + + + +This will close the current view. For more +information on views, refer to the section entitled Using Multiple Views. + + + + + + +ViewSplitter Orientation + + + +This determines whether split views are oriented +horizontally or vertically. Click on this option, and you are +presented with a submenu with 2 options: +Vertical and +Horizontal. For more information on views, +refer to the section entitled Using Multiple +Views. + + + + + + +ViewDisplay Mode + + + +When this option is selected, a submenu opens with 3 options: + +Page Mode - &kword; will show you how your page looks in a WYSIWYG environment. This is the standard view +for editing your document. +Preview Mode - This changes &kword; from a single page view, to a multiple page view suitable for evaluating document flow and formatting. +The number of pages shown in preview mode can be adjusted. +Text Mode - When this option is selected, &kword; will only show the text of your document. + + + + + + +ViewFormatting Characters + + + +Clicking on this option toggles the display of formatting +characters. Selecting this option will display non-printable characters +(spaces, character returns, and tab stops). Selecting this option again +will turn the display of these characters off. +Which formatting characters are visible can be configured in the +&kword; configuration dialog. + + + + + + +ViewFrame Borders + + + +Clicking on this option toggles the display of the borders +to frames. Normally, &kword; draws a gray line around each frame, so +you can see the borders of the frames. If you want this option turned +off, you can select this option. Selecting this option again will turn +the borders back on. + + + + + + +ViewShow/Hide Doc Structure + + + +Clicking on this option toggles the display of the document +structure window. For more information, refer to the section entitled +Document Structure. + + + + + + +ViewShow/Hide Rulers + + + +Selecting this option will toggle the rulers off. +Selecting this option again will turn rulers on. More +information on rulers can be found under Using rulers. + + + + + + +ViewShow/Hide Grid + + + +Selecting this option will toggle the grid on. +Selecting this option again will turn grid off. + + + + + + +ViewSnap to Grid + + + +Selecting this option will toggle the snap to grid on. +Selecting this option again will turn snap to grid off. A checkmark before +the menu entry will show you the current status of this option. + + + + + + + +ViewZoom + + + +Selecting this option will let you increase or decrease +the page magnification. Selecting a zoom value larger than 100 percent +causes the text and pictures to appear larger. Selecting a zoom value +smaller than 100 percent will cause the text and pictures to appear +smaller. + + +The zoom value does not affect the final output of the text or +pictures. This option is intended to help you edit and layout your +documents. + + + + + + + +<guimenu>Insert</guimenu> Menu + + + + + +&Alt; &Shift; C + +InsertSpecial Character... + + + +Opens a dialog box which allows you to select characters +not found on the keyboard. +Typing &Alt; &Shift; +C is equivalent to using the menubar. + + + + + + + +&Ctrl;Return + +InsertPage Break + + + +This will enter a special character which will force text +into the next connected text frame (Page Layout Templates) or the next page (Text Oriented Templates). More information can be +found at Page Breaks located in the Working with Frames +section. + +Typing &Ctrl;Return is equivalent to +using the menubar. + + + + + + +InsertPage + + + +This option will insert a new page at the current cursor position. + + + + + +InsertFootnote/Endnote... + + + +This will insert a footnote or endnote at the current cursor +position. More detailed information can be found in Footnotes and Endnotes. + + + + + + +InsertTable of Contents + + + +This will insert or update a table of contents at the current cursor +position. More detailed information can be found in Table of Contents. + + + + + + +InsertVariable + + + +Selecting this option will allow you to insert page +numbers, date, time, author information, &etc; You can find +specific information about page numbers here. More information about Date and +Times can be found under Inserting the Date +and Time. More information on other variables can be found in Document Variables. + + + + + + +InsertExpression + + + +Selecting this option will allow you to insert common +phrases. The phrases are organized into categories. For +information on using and adding expressions refer to the section +entitled Expressions. + + + + + + +InsertLink... + + + +Allows you to connect text to an external web page, +email address or files +For more information refer to the section entitled +Document Links. + + + + + + +InsertComment... + + + +Allows you to add comments to selected text. +For more information refer to the section entitled +Document Comments. + + + + + + +InsertFile... + + + +Allows you to insert another &kword; file within the document. +For more information refer to the section entitled +Inserting Files. + + + + + + +InsertBookmark... + + + +Allows you to mark your place in the document for easy retrieval. +For more information refer to the section entitled +Document Bookmarks. + + + + + + + +F5 + +InsertTable... + + + +This will allow you to create a table in the current +cursor location. For more information, please see the section entitled Tables. + +Typing F5 or +clicking are +equivalent to using the +menubar. + + + + + + + +&Shift;F5 + +InsertPicture... + + + + This option will let you create a new frame, and +automatically insert a picture from a file into the new frame. +After selecting this menu item or toolbar button, a dialog box will be +opened, so you may select the picture file from your system. (For help +with this dialog box, please see Inserting Graphics.) Once you have +selected the file you want, click on the OK +button. &kword; will close the dialog box, and your cursor will change +to cross hairs. Locate the cursor on the page where you would like to +locate one corner of your picture. Click and hold the +&LMB;, then drag the mouse. +This will create a border which represents the final size of the picture +in your document. When you are happy with the size of the picture, +release the mouse button and the picture will be inserted in your new +frame. +Typing &Shift;F5 or +clicking +is equivalent to using the menubar. + + + + + + + +F10 + +InsertText Frame + + + +To create a new text frame. After selecting this +option, your cursor will change to cross hairs. Choose the location of +one corner of your new text frame. Click on the +&LMB; and hold the button down. +Drag the mouse, until you have the desired text frame. When you have +the correct shape and size, release the mouse button. &kword; will now +bring up a dialog box with options to connect this text frame to other +frames in your document. For more information on this subject, see +Working with Frames. + +Typing F10 or +clicking is equivalent to using the +menubar. + + + + + + + +F4 + +InsertFormula + + + +Insert a formula into the document. More +information on formulas in &kword; can be found here. + +Typing F4 or +clicking are +equivalent to using +the menubar. + + + + + + +InsertObject Frame + + + +Creates a new frame, and opens a dialog box listing each +of the &koffice; applications. This will allow you to insert any data +into your &kword; document. +Clicking is equivalent to +using the menubar. + + + + + + +InsertScan Image... + + + +Allows you to access your scanner for inserting pictures into your document. For more information see +the section entitled Using a picture from a scanner. + + + + + + + +<guimenu>Format</guimenu> Menu + + + + + +FormatDefault Format + + + + Automatically changes all formating back to the +default settings for the selected text. +The default format can be set with the Document Configuration options. + + + + + + + + +&Alt;&Ctrl;F + +FormatFont... + + + + Allows you to change the formatting characteristics of +the selected text. For more details, go to Formating Characters + +Typing &Alt;&Ctrl;F is equivalent to +using the menubar. + + + + + + + +&Alt;&Ctrl;P + +Format +Paragraph... + + + +To change the indenting, spacing between paragraphs, text flow, +tab stops, numbering and borders. For more details, go to Formating Paragraphs. +Typing &Alt;&Ctrl;P is equivalent to +using the menubar. + + + + + + +FormatFootnote... + + + +Allows you to change the look of your footnotes. +For more information see +Footnotes. + + + + + + +FormatFormula + + + +Allows you to format the selected formula. For +more information go to Formulas + + + + + + +FormatStyle + + + +Allows you to select a style for the selected text. Selecting this option shows a submenu +listing all available paragraphs styles. Select the correct style and the paragraph style will be changed. +For more +information go to Text Styles. + + + + + + + +&Alt;&Ctrl;S + +FormatStyle Manager... + + + +Opens a dialog to allow you to format, add and delete +styles. For more information go to StylesTyping &Alt;&Ctrl;S is equivalent to +using the menubar. + + + + + + +FormatImport Styles... + + + +Allows you to import a style. For more information go to Text Styles. + + + + + + +FormatCreate Style From Selection... + + + +Uses the currently selected text to create a new style. +For more +information go to Text Styles. + + + + + + +FormatPage Layout... + + + +Use this to alter the properties of the printed page, +including size, headers and footers. For more details, go to +Formating the Page + + + + + + +FormatEnable/Disable Document Headers + + + +Selecting this option will toggle headers on. +Selecting this option again will turn headers off. More +information on headers and footers can be found under Headers and Footers. + + + + + + +FormatEnable/Disable Document Footers + + + +Selecting this option will toggle footers on. +Selecting this option again will turn footers off. More +information on headers and footers can be found under Headers and Footers. + + + + + + + + + + +<guimenu>Frames</guimenu> Menu + + + + + +FramesFrame/Frameset Properties... + + + +Allows you to configure basic formating options for the +frameset. More information on this subject can be found in +Setting properties for +frames. + + + + + + +FramesDelete Frame + + + +This will allow you to delete the entire frame, and all of +the text and objects contained within the frame. + + + + + + + +&Ctrl;&Shift;R + +FramesRaise Frame + + + +This will allow you to raise the frame up one level. For more information see the section entitled +Raise and Lower frames. +Typing &Ctrl;&Shift;R is equivalent to +using the menubar. + + + + + + + +&Ctrl;&Shift;L + +FramesLower Frame + + + +This will allow you to lower the frame down one level. For more information see the section entitled +Raise and Lower frames. +Typing &Ctrl;&Shift;L is equivalent to +using the menubar. + + + + + + +FramesBring to Front + + + +This raises the currently selected frame to the top of all overlapping frames. For more information see the section entitled +Raise and Lower frames. + + + + + + +FramesSend to Back + + + +This lowers the currently selected frame to the bottom of all overlapping frames. For more information see the section entitled +Raise and Lower frames. + + + + + + +FramesCreate Linked Copy + + + +Creates a duplicate frame. The contents of the new frame will automatically be updated to match the contents of the old frame. As you continue to edit the document, changes to one of these frames will result in the same changes to the other frame. + + + + + + +FramesConvert to Text Box + + + +Selected text is removed from the current frame. A new frame is created to allow the selected text to be inserted, and the new text frame is inserted into the current document. This is an easy way to remove a section of text and place it in a text box of its own. + + + + + + +FramesFrame Style Manager... + + + +Allows you to edit the frame styles. For more information see the section entitled +Using frame styles. + + + + + + +FramesCreate Framestyle From Frame... + + + +Create a new framestyle based on the currently selected frame. For more information see the section entitled +Using Framestyles. + + + + + + +FramesFramestyle + + + +Allows you to format the selected frame(s) with a predefined framestyle. For more information see the section entitled +Using frame styles. + + + + + + +FramesFrame Background Color... + + + +This will allow you to change the background color of the current frame. + + + + + + +FramesConfigure Frame Border + + + +This will allow you to change the border surrounding the current frame. When selected, a submenu will +appear with all available border styles. Select the correct style and the borders are instantly changed. + + + + + + + + + + + + +<guimenu>Table</guimenu> Menu + + + + + + +TableProperties + + + +Allows you to change the number of rows and columns in a table. For more +on tables, click here. + + + + + + +TableRowInsert Row... + + + +Allows you to insert a row into a table. For more +on tables, click here. +Clicking is +equivalent to using the menubar. + + + + + + +TableRowDelete Selected Rows... + + + +Delete a row from a table. For more on tables, +click here. + +Clicking +is equivalent to using the menubar. + + + + + + +TableColumnInsert Column... + + + +Allows you to insert a column into a table. For +more on tables, click here. +Clicking is +equivalent to using the menubar. + + + + + + +TableColumnDelete Selected Columns... + + + +Delete a column from a table. For more on tables, +click here. +Clicking +is equivalent to using the menubar. + + + + + + +TableColumnResize Column... + + + +Change the width of the currently selected column. For more on changing column widths, +click here. + + + + + + +TableCellJoin Cells + + + +This will convert two (or more) separate cells into a +single cell. For more on tables, click +here. + + + + + + +TableCellSplit Cell... + + + +This will split one cell into multiple smaller cells. For more on tables, click +here. + + + + + + +TableCellProtect Cells + + + +This prevent changes to the data in the selected cells. For more on tables, click +here. + + + + + + +TableUngroup Table + + + +Converts a table into a grid of individual frames. These individual frames are not connected and can be moved independently around the page. For more on tables, click here. + + + + + + +TableDelete Table + + + +Deletes the table the cursor is in. You can +find more about tables in the section entitled Tables. + + + + + + +TableTable Style Manager... + + + +Lets you edit tablestyles. You can +find more about tables in the section entitled Using Tablestyle. + + + + + + +TableTablestyle + + + +Lets you format the currently selected table using a preformatted template. You can +find more about tables in the section entitled Using Tablestyle. + + + + + + +TableConvert Table to Text + + + +Converts data that is currently in the selected table to regular text.. + + + + + + + +<guimenu>Tools</guimenu> Menu + + + + + + +ToolsSpellcheckAutospellcheck + + + +Will toggle automatic spellchecking of the document on and off. + + + + + + +ToolsSpellcheckSpelling... + + + +Will check the spelling of the document. +Clicking is +equivalent to using the menubar. + + + + + + +ToolsAutocorrectionDisable/Enable Autocorrection + + + +Toggles autocorrection on and off. +For more information see the section entitled +Autocorrection. + + + + + + +ToolsAutocorrectionApply Autocorrection + + +&kword; will format your document according to specific rules. +For more information see Manually Applying Autocorrection. + + + + + +ToolsChange Case... + + + +Allows you to set the case of all selected text. +For more information see +Changing Font Case. + + + + + + +ToolsSort Text... + + + +Alphabetizes the selected paragraphs. You will be given the option to sort in ascending or decending order. + + + + + + +ToolsEdit Personal Expressions... + + + +This is for adding and editing expressions. +For information on using and adding expressions +refer to the section entitled Expressions. + + + + + + +ToolsAdd Expression + + + +Creates a new personal expression with the selected text. For more information on personal expresions, +refer to the section entitled Expressions. + + + + + + +ToolsCustom Variables... + + + +This is for editing custom document variables. +For information on using and adding expressions +refer to the section entitled Document variables. + + + + + + +ToolsSelect Bookmark... + + + +Jump to, rename or delete bookmarks. For more information see the section entitled +Document Bookmarks. + + + + + + +ToolsConfigure Mail Merge... + + + +Displays the Mail Merge Setup Dialog. + + + + + + + + +<guimenu>Settings</guimenu> Menu + + + + + + +SettingsToolbars + + + +Allows you to hide or reveal toolbars individually. For more information see +the section entitled Hiding, Changing and Moving Toolbars. + + + + + + +SettingsConfigure Autocorrection... + + + +Allows you to modify the autocorrection options. +For more on Autocorrection, click +here. + + + + + + +SettingsConfigure Completion... + + + +Allows you to modify the autocompletion options. +For more see the section on Autocompletion. + + + + + + +SettingsConfigure Shortcuts... + + + +Allows you to change the keyboard shortcuts. For +details, click here + + + + + + +SettingsConfigure Toolbars... + + + +Allows you to change the toolbars. For details, +click here + + + + + + +SettingsConfigure &kword;... + + + +Allows you to change miscellaneous &kword; +options.For details, click here. + + + + + + + + +<guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + + + + + +<guilabel>File</guilabel> Toolbar + +The File toolbar consists of 5 buttons. Each button performs a +task from the menubar. Click on that task for more details. + + + + + + + + + + +ButtonCommand + + + + + +Open New File + + + + +Open Saved File + + + + +Save File + + + + +Print File + + + + +Print Preview + + + + + + +<guilabel>Format</guilabel> ToolBar + +The Format toolbar consists of 9 buttons. Each button +performs a task from the format +character dialog. + + + + + + + + + + +ButtonCommand + + +Select Font Face +Character Size +Toggle Bold Text +Toggle Italics +Toggle Underline +Toggle Strikeout +Toggle Superscript Text +Toggle Subscript Text +Change Font Color +Clicking on the letter changes the selected text to the color previewed in the underline. Clicking the arrow to the right of the letter will let you select a new color. + + + + + + +<guilabel>Insert</guilabel> Toolbar + +The Insert toolbar consists of 5 buttons. Each button performs a +task from the menubar. Click on that task for more details. + + + + + + + + + + +ButtonCommand + + + + + +Insert Table + + + + +Insert Picture + + + + +Insert Text Frame + + + +Insert Formula Frame + + + +Insert Object Frame + + + + + + + + +<guilabel>Edit</guilabel> Toolbar + +The Edit toolbar consists of 8 buttons. Each +button performs a task from the menubar. Click on that +task for more details. + + + + + + + + + + + +ButtonCommand + + + + + +Undo + + + + +Redo + + + + +Cut + + + + +Copy + + + + +Paste + + + + +Spell Check + + + + +Find + + + + +Zoom + + + + + + + +<guilabel>Paragraph</guilabel> Toolbar + +The Paragraph toolbar consists of 9 buttons. Each button performs +a task from the menubar. + + + + + + + + + + + +ButtonCommand + + +Select Character Style +Left Text Align +Center Text Align +Right Text Align +Justify Text +Numbered Text paragraphs +Bulleted Text paragraphs +Reduce paragraph indent +Increase Paragraph Indent + + + + + +<guilabel>Table</guilabel> Toolbar + +The Table toolbar consists of 5 buttons. Each button +performs a task from the menubar. Click on that task for more +details. + + + + + + + + + + + +ButtonCommand + + + + + +Set tablestyle + + + + +Insert Row + + + + +Insert Column + + + + +Delete Row + + + + +Delete Column + + + + + + +<guilabel>Border</guilabel> Toolbar + +The Border toolbar consists of 10 buttons. Each button performs a +task from the menubar. Click on that task for more details. + + + + + + + + + + + +ButtonCommand + + +Set framestyle +Toggle border outline +Toggle Left Frame Border +Toggle Right Frame Border +Toggle Top Frame Border +Toggle Bottom Frame Border +Select Border Size +Select Border Style +Select Border Color +Select Background Color + + + + + +<guilabel>Formula</guilabel> Toolbar + +The Formula toolbar consists of 26 buttons. + + + + + + + + + + + +ButtonCommand + + +Add or Change Square Root +Add Fraction +Add to Brackets +Add to Square Brackets +Add to Curly Brackets +Absolute Value +Add Overline +Add Underline +Integral +Change to Sum +Change to Product +Add Matrix +Add Upper Left Index +Add Lower Left Index +Add Upper Right Index +Add Lower Right Index +-Right Facing Characters +-Left Facing Characters +Special Symbols +Insert Column +Append Column +Remove Column +Insert Row +Append Row +Remove Row + + + + + +Selecting Colors from a <guilabel>Select Color</guilabel> dialog +selecting a color + +&kword; uses a common dialog box any time the user needs to select a color for an object (text, backgrounds, borders, etc.). +This section will go into some detail on how to use this color dialog to choose the best color for your object. +When it is necessary to select a color, a dialog box appears. + + + + + + +The color dialog is an incredibly flexible dialog box, which makes it possible to select colors in one of six different methods: + + +Spectrum selectors +The spectrum selectors consists of a square to adjust Hue and +Saturation, and a tall narrow box to adjust Value. +The white cross hairs in the box show the currently selected color on the spectrum. Drag the cross hairs up to increase +saturation. Drag down to decrease saturation. Move the +cross hairs left or right to change the hue. +To adjust the value of the color, use the tall, narrow box to move the black arrow. Sliding the +arrow up increases the color's value. Sliding the arrow down decreases the color's +value. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + +Hue, Saturation and Value +Using the three spin boxes labeled H,S and V, a user can +specify the Hue (Range 0-359), Saturation (Range 0-255) +and Value (Range 0-255) +respectively. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + + +Red, Green and Blue +Using the three spin boxes labeled R,G and B, a user can +specify the amount of Red, Green and Blue to be mixed to form the current color. All three boxes can be set to any value from 0-255. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + + +Palettes +A palette is a group of related colors. These colors are all made available for easy selection according to a meaningful +association. +To select a new palette, click on the combo box at the top of the palette selection area. +You will be presented with several choices: +Recent Colors - This is a list of the most recently used colors in your document. You can use this palette to +maintain consistency. As each new color is selected, it is automatically added to the recent colors palette. +Custom Colors - You can create your own custom palette. This is done by selecting a +color using one of the other +color selection options, and clicking on Add to Custom Colors. +That color is now added to your custom color palette. +Forty Colors - This is a list of 40 commonly used colors. This is a good palette to choose from if some of the people +viewing your document will be on machines with limited color capability. +Web Colors - This is a predefined palette of colors that you might find useful for designing web pages. +Royal Colors - This is a predefined palette of colors including numerous shades of purple and yellow. +Named Colors - This is a list of color names. The names are based on standard X server color +names. The names are designed to give descriptive names to each color. Simply select the name you want. +Once you have selected a palette, you will be presented with a small square showing each color available in the palette. To +select a color from the palette, simply click on the square of the desired color. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + + +Eye dropper +The eye dropper can be used to sample a color from the screen. +When the eye dropper button is clicked, the cursor becomes crosshairs. Simply place the crosshairs over any spot on the screen +and click once. &kword; will detect the selected color and automatically change the current color to match the selection. +This is especially useful for matching color elements between previously created elements and new items. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + +HTML code +If you know the HTML color code you want to use, you can enter it into the text box labeled +HTML:. +For more information on HTML color codes, visit the +Web monkey color code page. +The currently selected color is visible in the colored square below the Add to Custom Colors button. + + + +Once the color is selected, click OK to make that the current color for your text, border, etc. +Click Cancel to abort the color selection. + + +Selecting files using the file dialog +using file dialog + +&kword; uses a common dialog box for all file related actions (saving, loading, or selecting new files +for insertion into the document). An example is shown below. + + + + + + +This section will look more closely at this dialog and provided detailed information on its use. + +We will begin at the top of the dialog. + +Toolbar + +The current location on the drive is listed at the top-center of the dialog. This example dialog shows the current folder is /home/mmcbride/kword. If you click on this drop +down box, you will see common and recently visited folders. By +selecting one of these folders, you will be immediately moved to +that folder and the dialog box will update the file list. + +In the upper left corner, is a blue arrow pointed up. This +arrow will take you up one level in the folder structure. + +The next two buttons are back and forward buttons. These +buttons work just like those in an Internet browser. You can use the Back +button to travel to the previous folder, and the Forward button to +advance into a folder you just came from. + +Next to the arrow buttons, is a Reload button. Clicking this +button, causes &kword; to reload the current folder if new files have been +added or deleted. + +To the right of the Reload button, is a blue file folder with a starburst. This button +will let you create a new folder and name it. + +Next to the new folder button, is a button with a star on it. +This button allows you to set and navigate through bookmarks. This is +a quick way to jump to commonly accessed folders. By clicking +this button, a submenu appears which allows you to add bookmarks or +jump to a new bookmark. + +Next to the bookmark button, is a button with a wrench on it. +Clicking this button brings up a sub menu with several entries: + + + +Sorting + +If this option is selected, a submenu will appear allowing you to sort your files by name, date or size. You can sort them forward or reversed. You can also determine if +folders should be listed before files, or mixed within the files. + + + + +Short View + +If this option is selected, only the names of the files and folders will be shown. +Compare this to detailed view. + + + + +Detailed View + +If this option is selected, the names, sizes, dates, permisions, file owners and group ownerships are shown. +Compare this to short view. + + + + +Show Hidden Files + +This will toggle between revealing and hiding normally hidden files. In most cases you will want to leave this option off. + + + + +Show/Hide Quick Access Navigation Panel + +The tall box along the left side of the dialog with a dark grey backround is the Quick Navigation Panel. You can use this option to toggle whether it is visible or not. +More detailed information about hte Quick Navigation Panel is avialable further down this page. + + + + +Show/Hide Preview + +You can use this option to toggle whether the preview panel is visible or not. Typically, the preview panel is left off, but it can be useful when looking for a picture to insert into a document. + + + + +Separate Folders + +Use this option to toggle between a 2 pane view of the filesystem and a one pane view of the filesystem. +Most people will not need to worry about this option as most people prefer the one pane view. + + + + + +Quick Navigation Bar + +Along the left side of the dialog box, is a column that contains +several icons. You can think of each of these icons as a shortcut to +another subfolder. If you click on an icon, you will be immediately +moved to that location. + +You can add/edit or delete entries from the Location Bar. +Simply click with the &RMB; and a small popup menu will appear. + +File Name and Filters + + +The text box labeled Location: contains the current filename Resume.kwd. This text box will contain the +filename of the currently selected file when loading new documents or files into +&kword;. When saving a file, you will enter the desired filename in this text box. + +The text box labeled Filter: shows we are only looking +at &kword; files. By clicking on the combo box, you can select from several +different file formats. You can also select All Supported Files to display +all files that are supported by &kword;. The file types available will change depending on +the specific task at hand. + +If there is a mark in the checkbox labeled Automatically select filename extension, +then &kword; will add the correct filename extension based on your selection in the Filter: +drop down box. If there is no mark in this box, you are responsible for providing an extension. Most users +will leave this box marked. + +There is a Cancel button, if you click this +button, the action will be aborted, and you will return to editing the +document. + +There is an OK button, which will be used +when we have selected the correct filename. + +Using this dialog, you can move through the folder tree to find +any location on your computer. + +To enter a folder click on that folder. To exit that folder, +click the blue up arrow button. + +This dialog box is used in many different tasks in &kword;. The task will determine the exact effect +of the information you have entered into this dialog box. For more information on the exact effect, see the documentation on that task. + + + diff --git a/doc/kword/migrating.docbook b/doc/kword/migrating.docbook new file mode 100644 index 000000000..c224b1f83 --- /dev/null +++ b/doc/kword/migrating.docbook @@ -0,0 +1,15 @@ + + + + +Mike +McBride + + + + +Migrating to &kword; +migrating to &kword; + +To be written + diff --git a/doc/kword/mmerge1.png b/doc/kword/mmerge1.png new file mode 100644 index 000000000..db14e0b88 Binary files /dev/null and b/doc/kword/mmerge1.png differ diff --git a/doc/kword/mmerge1a.png b/doc/kword/mmerge1a.png new file mode 100644 index 000000000..f6aca0c49 Binary files /dev/null and b/doc/kword/mmerge1a.png differ diff --git a/doc/kword/mmerge2.png b/doc/kword/mmerge2.png new file mode 100644 index 000000000..481d2d09b Binary files /dev/null and b/doc/kword/mmerge2.png differ diff --git a/doc/kword/mmergeab1.png b/doc/kword/mmergeab1.png new file mode 100644 index 000000000..cd3306027 Binary files /dev/null and b/doc/kword/mmergeab1.png differ diff --git a/doc/kword/mmergekspread1.png b/doc/kword/mmergekspread1.png new file mode 100644 index 000000000..d187ab964 Binary files /dev/null and b/doc/kword/mmergekspread1.png differ diff --git a/doc/kword/mmergesql1.png b/doc/kword/mmergesql1.png new file mode 100644 index 000000000..67f5b99ff Binary files /dev/null and b/doc/kword/mmergesql1.png differ diff --git a/doc/kword/mmergesql2.png b/doc/kword/mmergesql2.png new file mode 100644 index 000000000..05d7df32d Binary files /dev/null and b/doc/kword/mmergesql2.png differ diff --git a/doc/kword/mousenav.png b/doc/kword/mousenav.png new file mode 100644 index 000000000..462c6051f Binary files /dev/null and b/doc/kword/mousenav.png differ diff --git a/doc/kword/numtxtbut.png b/doc/kword/numtxtbut.png new file mode 100644 index 000000000..dcccf5eff Binary files /dev/null and b/doc/kword/numtxtbut.png differ diff --git a/doc/kword/opendlg.png b/doc/kword/opendlg.png new file mode 100644 index 000000000..ede758e55 Binary files /dev/null and b/doc/kword/opendlg.png differ diff --git a/doc/kword/opt.docbook b/doc/kword/opt.docbook new file mode 100644 index 000000000..7fb0b5881 --- /dev/null +++ b/doc/kword/opt.docbook @@ -0,0 +1,654 @@ + + + + +Mike +McBride + + + + +&kword; Options +&kword;options +configuring &kword; + +This section of the documentation will show you how to configure &kword; to suit your personal work style and preferences. +&kword; can be modified in three separate ways: + +Configure shortcuts +Configure toolbars +Miscellaneous options + + +Configure Key Bindings (keyboard shortcuts) +configuring keyboard shortcuts +keyboard shortcutschanging +configuring key binding +keyboard key bindingchanging + +To configure the keyboard shortcuts select +SettingsConfigure Shortcuts... + from the menubar. + +This will bring up a dialog box. + + + + + + + + +To edit the shortcuts, the first thing you need to do is find +the action you want to edit. All of the possible actions are listed in +the combo box labeled Action. By using the +scrollbar, locate the action you are interested in and click once with +the &LMB;. + +Once you have selected the action, you can turn your attention to +the bottom half of the dialog box. You use the bottom half of the dialog +box to change the shortcuts. + + + +None + +By selecting this option, the currently selected action will not +have any keyboard shortcut. + + + + +Default + +By selecting this option, the currently selected action will use +the default shortcut. Once this option is clicked, the default keyboard shortcut +is listed below. + + + + +Custom + +By selecting this option, you can choose any keyboard combination +as a shortcut for this action. + + + + + +Defining custom keyboard shortcuts +You determine the key combination by clicking on the button with the current +keyboard combination in it. A second dialog will appear: + + + + + + + + +This dialog box allows you to determine two different key combinations +which will trigger the desired action: Primary shortcut: and Alternate shortcut:. + +Defining simple keyboard shortcuts +Begin by deciding if you want to specify the Primary shortcut: or Alternate shortcut: +, by placing a mark in the appropriate radiobutton. + +The button will clear the current keyboard shortcut. + +Now type the keyboard shortcut into the keyboard. &kword; will use this keyboard combination as the new +keyboard shortcut. The window will close automatically. + +Once you have completed your entries, simply click on OK +to accept the changes or Cancel to cancel your changes. + + +Defining multi-key keyboard shortcuts + +Multi-key keyboard shortcuts can be used when you run out of simple keyboard shortcuts. + +Multi-key shortcuts are edited the same as simple keyboard shortcuts, except a mark is placed in the +check box labeled Multi-key mode prior to entering the keyboard shortcut. + +You can now enter multiple keyboard characters for the keyboard shortcut. + +It is important to understand that keyboard combinations +(i.e.: &Alt; &Shift; +P) are still a single character because all the keys are +depressed at the same time. + +An example of a multi-key combination would be if you press &Alt; +X, release both characters then type a +W. This is a multi-key combination. + +Once you have completed your entries, simply click on OK +to accept the changes or Cancel to cancel your changes. + + + + + +Configure Toolbars +configuring toolbars + +To configure &kword;'s toolbars +select SettingsConfigure +Toolbars... from the menubar. + +This will bring up a dialog box. You can add or remove as many +toolbar buttons to as many toolbars as you like. You can also move the +buttons around on the toolbar using this dialog. + + + + + + + + + +Adding a button to a toolbar + +To add a button to a toolbar, you move it from the +Available actions: box to the Current +actions: column. + +First select the toolbar you want to add a button to by selecting +the toolbar from the combo box labeled +Toolbar: + +Now select the action you want to add from the combo box labeled +Available actions: by clicking once with the left +mouse button. + +Click the blue arrow pointing to the +right. + +Once the OK button or the Apply button has been clicked, the toolbars +will change. + + + + +Deleting a button from a toolbar + +To delete a button from a toolbar, you move it from the +Current actions: box to the Available +actions: column. + +First select the toolbar you want to delete a button from by selecting +the toolbar from the combo box labeled +Toolbar: + +Select the toolbar button you want to remove the button from +the combo box labeled Current actions:. + +Click the blue arrow pointing to the +left. + +Once the OK button or the Apply button has been clicked, the toolbars +will change. + + + + +Moving a button on a toolbar + +First select the toolbar you want to move a button on by selecting +the toolbar from the combo box labeled +Toolbar: + +To move a button, simply click on the button you want to move with +the left mouse button. + +Click the up or down arrows to move the button up or down the +toolbar respectively. + +Once the OK button or the Apply button has been clicked, the toolbars +will change. + + + + + +&kword; Options +&kword;options + +To configure options regarding spelling and the user interface +select SettingsConfigure +&kword;... from the menubar. + +This will bring up a dialog box. + + + +Configure &kword; User Interface + +Clicking Interface will allow you to change +the following. + + + + + + + + + +Units: +Select your preferred unit of measurement. &kword; will use these units for all measurements. See +Using Rulers for more information. + + + + +Show status bar +Placing a mark in this check box makes the status bar visible in &kword;. See +The &kword; Screen for more information. + + + + +Show scrollbar +Placing a mark in this check box makes the scrollbar visible in &kword;. See +The &kword; Screen for more information. + + + + +PageUp/PageDown moves the caret +If this check box has a mark, then when you press the PageUp and PageDown keys +on the keyboard, &kword; moves the text cursor (the caret) down one page. If there is no mark in this check box +then &kword; moves the view, but does not change the position of the text cursor. + + + +Number of recent files: + +This determines the maximum number of files that are listed under + FileOpen +Recent command. You can adjust this value +from 1-20. + + + + +Horizontal grid size: +Determines the horizontal size of the grid. When frames and tab stops are placed on the page, they +are placed on a point in the grid. This gives your document a more professional look because elements are effectively +aligned. You can reduce the grid size if you need finer control of your layout. + + + +Vertical grid size: +Determines the vertical size of the grid. When frames are placed on the page, they +are placed on a point in the grid. This gives your document a more professional look because elements are effectively +aligned. You can reduce the grid size if you need finer control of your layout. + + + +Paragraph indent by toolbar buttons: +Use this spin box to determine how far the paragraph is indented when using the increase indent button +() and the decrease indent button +(). + + + +Number of pages per row in preview mode: +Determines the number of pages per row in preview mode. +This determines the size of the pages in preview mode. + + + +When you are happy with the changes, simply click +OK. + +If you click on Cancel, all changes will be +lost. + +Clicking on the Defaults button restores all +values to their default values. + + + +Configure document options + + + + + + + +Document defaults + + +Default column spacing + +Use this to adjust the default spacing between columns. For more information on columns see +Columns. + + + + +Default font: + +Click on the Choose... button, and a new dialog will appear. Use this dialog to +choose the default font. This setting determines the default font used by &kword; until further formatting is done. You can +revert any text to this default by selecting + FormatDefault Format from +the menubar. + + + + +Global language: + +Use this drop down box to determine the default language for the document. This setting is used by the +hyphenation and spelling tools. + + + + +Automatic hyphenation + +Place a mark in this checkbox if you want &kword; to automatically hyphenate long words when it determines the word wrap +in text frames. + + + + + + +Document settings + + +Autosave every (min): + +You can use this to adjust how often &kword; saves a temporary +file. If you set this value to No autosave, &kword; will not autosave. +You can adjust the autosave from 1 minute to 60 minutes. + + + + +Create backup file + +If there is a mark in this checkbox, &kword; will automatically create a backup file everytime you save your document. + + + + +Starting page number: + +Use this text box to determine the starting page number. For more information on page numbering see +Page Numbering. +This is helpful if you have split a single document into multiple files. + + + + +Tab stop: + +Each &kword; document has a default set of tab stops. If you add tab stops to your document, the newly added +tab stops override the default tabstops. You can use this text box to define the spacing between default tab stops. +As an example. If you enter 1.5 in this text box, and the unit of measure is in centimeters, then the +first default tab stop will be located 1.5 cm to the right of the left margin of the frame. The second default tab stop will be located at 3 cm from the +left margin, etc.... + + + + + +Cursor settings + + +Cursor in protected area + +When there is a mark in this check box, and you click in a protected frame of your document, a cursor appears. When the +mark is removed from this check box, and you click in a protected frame, there is no cursor visible. + + + + + + +When you are happy with the changes, simply click +OK. + +If you click on Cancel, all changes will be +lost. + +Clicking on the Defaults button restores all +values to their default values. + + + + + + +Configure Spelling. + +To configure the options for the speller, click on the button +labeled Spelling. + + + + + + + +Each option is detailed below. + + + +Default language: +Used by the spelling application to choose the correct dictionary. + + + + +Enable background spellchecking +If a mark is placed in this checkbox, &kword; will check the spelling of words in your document as you type them. Words that +&kword; believes are misspelled will have a red line drawn under them. + + + + +Skip all uppercase words +If a mark is placed in this checkbox, &kword; will not check the spelling of any word which consists of all capital letters. +This is useful if the document you are working on uses a large number of acronyms. If this box is left unchecked, most of those acronyms +will be incorrectly marked. By placing a mark in this checkbox, &kword; will not mark the acronyms as misspelled. + + + +Skip run-together words +If this box is not checked, and &kword; finds a two words in its dictionary that are placed next to each other, it will be +marked as misspelled. If this box is checked, the combined word will be ignored. +Examples of such words are shutout, +cannot, and blackout. + +Checking this box will help prevent &kword; from +flagging website and email addresses for spelling errors. These +addresses often contain words run together. + + + +Ignoring words +The bottom half of the dialog box allows you to designate specific words (they may be specialized terminology, proper names, etc) which +should be ignored by the spelling program. + +Adding a word to the ignore list +To add a word, type the word in the text box directly below the words Ignore +These Words and click the Add button. + + +Deleteing a word from the ignore list +To remove a word, select the word in the listbox containing all the currently ignored words by clicking on it with +the &LMB;. Now click the Remove button. + + +Changing the order a word appears in the list +To move a word in the list, select the word in the listbox containing all the currently ignored words by clicking on it with +the &LMB;. Now click the Move Up button or the Move Up button to move the word +within the list. + +When you are happy with the changes, simply click +OK. + +If you click on Cancel, all changes will be +lost. + +Clicking on the Defaults button restores all +values to their default values. + + + + + + +Configure formula options + + + + + + +Use this dialog to format the appearance of formulas in &kword;. See the formula documentation for further details. +When you are happy with the changes, simply click +OK. + +If you click on Cancel, all changes will be +lost. + +Clicking on the Defaults button restores all +values to their default values. + + +Configure miscellaneous options + + + + + + + +Misc + + + +Undo/redo limit: +Use this spin box or slider to determine how many actions &kword; keeps in its Undo buffer. Any action that exceeds +this number will be forgotten. + + + + +Display links +Placing a mark in this check box makes document links visible in &kword;. If there is no mark in this check box, +document links will be hidden. See +Document links for more information. + + + + +Underline all links +Placing a mark in this check box will have &kword; automatically underline a document link when it is created. See +Document links for more information. + + + + +Display comments +Placing a mark in this check box makes document comments visible in &kword;. See +Document comments for more information. + + + + +Display field code +If there is a mark in this check box, &kword; shows the variable name of document variables, +rather than the content of the variable in the &kword; +screen. If this check box does not have a mark, then &kword; shows the contents of the variables. +This option does not affect the printed output. The contents of the variables are printed regardless of the state of this +check box. + + + + + +View Formatting + +You can use these four check boxes to determine what formatting characters are displayed when you have asked &kword; to +show formatting characters. + + + +View formatting end paragraph +Toggles the display of paragraph marks (new-line characters) on and off. + + + + +View formatting space +Toggles the display of individual spaces on and off. + + + + +View formatting tabs +Toggles the display of tab stops on and off. + + + + +View formatting break +Toggles the display of frame breaks on and off. + + + + + +When you are happy with the changes, simply click +OK. + +If you click on Cancel, all changes will be +lost. + +Clicking on the Defaults button restores all +values to their default values. + + + +Configure path options + + + + + + +Use this dialog to set the Backup Path and the directory +for your Personal Expression in &kword;. + + +Configure Text-To-Speech options + +See the Text-to-Speech section +in the accessibility chapter for further details. + + + + diff --git a/doc/kword/opt1.png b/doc/kword/opt1.png new file mode 100644 index 000000000..cf32ccc1a Binary files /dev/null and b/doc/kword/opt1.png differ diff --git a/doc/kword/opt2.png b/doc/kword/opt2.png new file mode 100644 index 000000000..45cbf78d0 Binary files /dev/null and b/doc/kword/opt2.png differ diff --git a/doc/kword/opt3.png b/doc/kword/opt3.png new file mode 100644 index 000000000..b866c8a23 Binary files /dev/null and b/doc/kword/opt3.png differ diff --git a/doc/kword/opt4.png b/doc/kword/opt4.png new file mode 100644 index 000000000..26de4bed8 Binary files /dev/null and b/doc/kword/opt4.png differ diff --git a/doc/kword/opt5.png b/doc/kword/opt5.png new file mode 100644 index 000000000..35b59a3eb Binary files /dev/null and b/doc/kword/opt5.png differ diff --git a/doc/kword/opt6.png b/doc/kword/opt6.png new file mode 100644 index 000000000..05decd5d0 Binary files /dev/null and b/doc/kword/opt6.png differ diff --git a/doc/kword/optkb.png b/doc/kword/optkb.png new file mode 100644 index 000000000..cf574a404 Binary files /dev/null and b/doc/kword/optkb.png differ diff --git a/doc/kword/optkb2.png b/doc/kword/optkb2.png new file mode 100644 index 000000000..6628c2a97 Binary files /dev/null and b/doc/kword/optkb2.png differ diff --git a/doc/kword/opttb.png b/doc/kword/opttb.png new file mode 100644 index 000000000..833c4afc0 Binary files /dev/null and b/doc/kword/opttb.png differ diff --git a/doc/kword/pageformat.docbook b/doc/kword/pageformat.docbook new file mode 100644 index 000000000..395003049 --- /dev/null +++ b/doc/kword/pageformat.docbook @@ -0,0 +1,253 @@ + + + + +Mike +McBride + + + + +Formatting the Page + +Before delving into the specifics of formatting a page in &kword;, remember that +&kword; has two separate types of documents: Text Oriented and Page Layout. +Please review The difference between Text Oriented and Page Layout Documents, +if the differences are still unclear. + +This section of the manual is divided into two sub-parts, one for +Text Oriented, the other for Page Layout. + + + Formatting the Page (Text Oriented Document) +text oriented documentformatting the page size +formatting the page size (text oriented document) +text oriented documentformatting the margins +formatting the margins (text oriented document) +headersformatting +footersformatting the page + +When you are working with a Text Oriented Document, you control +the size and shape of the main frame by setting the paper size and the margins. + +Formatting the page is usually done by selecting: +FormatPage Layout... +from the menubar. + + +You can also go straight to the +Page Layout options by selecting the main frame of the document and then double clicking on either of the +rulers. + + +A dialog box will appear with three tabs, labeled Page Size & Margins, Columns and Header & and Footer. + +The Page Size & Margins tab is for altering +the paper size, and changing the margins. + + + + + + + + +First you will notice, that a preview box appears on the right +half of this dialog. This will approximate the +final look of your document. It is updated with each change, and should +be used as a guide for your changes. + +On the left, the dialog displays the current unit of measurement. +This unit of measurement is the same unit of measurement +you use for your document rulers. (In this example, we are using +inches.) To change the units, follow the instructions in the section entitled +Using Rulers. + +The dialog section labled Page Size is used to specify +the paper size for the document. +&kword; includes many predefined paper sizes. Select the appropriate paper size with the drop down +box labeled Size. + +In addition to standard paper sizes, there are two selections that +deserve special mention. + + +Screen +This format is used to generate a document where +each page has an aspect +ratio (shape) which matches the aspect ratios of computer +monitors. This might be useful for documents which will never be printed, but will appear only on a computer screen. + + + +Custom +You can select this option to specify a unique paper size. +Once selected, two text +entry boxes (labeled Width: and +Height:) become active. Enter the height and width of your desired paper size in these text boxes. + + + +Below the page size, are two radio boxes in the section labeled +Orientation you can select either Portrait or Landscape layout for +your document. + +Below the page orientation, is the Margins subsection, which +consists of 4 spin boxes. + +The Margins define the +white-space surrounding the text in your main frame. You can enter any +number from 0 to the maximum size of the page in these boxes. The units +are the same for all four boxes, and is the same as the measurement +listed at the top of the dialog. + +Clicking on the Columns tab allows you to +change the number of columns on each page. Details on multi-column documents +can be found here. + +Clicking on the Header & Footer tab allows the user to +specify header and footer information. + + + + + + + + +This dialog can be broken into two major sections. + +If you are not familiar with Headers and Footers yet, you should +first read the section entitled Headers/Footers + +Headers + +This section lets you determine the placement of headers, and +which pages have which headers on them. + +If you place a mark in front of Different header for the first page, you +will be able to specify a different format for the header on the first page. + +If you place a mark in front of Different header for even and odd pages, +the even pages will use one header, the odd +pages use another header. +You can use this to ensure the page numbers +are always on the outside of the page, or to list the title of the +document on odd pages and the chapter number on the even pages. + +In the spin box labeled Spacing between header and +body:, you can specify how much empty space should be placed +between the bottom of the header, and the top of the main frame. + +Footers + +This section lets you determine the placement of footers, and +which pages have which footers on them. + +If you place a mark in front of Different footer for the first page, you +will be able to specify a different format for the footer on the first page. + +If you place a mark in front of Different footer for even and odd pages, +the even pages will use one footer, the odd +pages use another footer. + +In the spin box labeled Spacing between footer and +body:, you can specify how much empty space should be placed +between the top of the footer, and the bottom of the main frame. + +Footnote/Endnote + +The bottom spin box is labeled Spacing between footnote and body:. As the label +suggests, you can use this text +box to specify the distance between the bottom edge of the main frame, and the top edge of the footnotes. For more information on +footnotes, see the section entitled footnotes. + +When you are satisfied with the changes you are ready to make, +click OK. + +If you click Cancel, all your changes will +be ignored. + + + + + Formatting the Page (Page Layout Document) +page layout documentformatting the page size +formatting the page size (page layout document) + +When you are working with a Page Layout Document, you control the +size and shape of all the frames individually. + +Formatting the page is usually done by selecting: +FormatPage Layout... +from the menubar. + + +You can also go straight to the Page +Layout options by double clicking on either of the +rulers. + + +A dialog box will appear. + +The Page Size & Margins tab is for altering +the paper size, and changing the margins. + + + + + + + + +First you will notice, that a preview box appears on the right +half of this dialog. This will approximate the +final look of your document. It is updated with each change, and should +be used as a guide for your changes. + +On the left, the dialog displays the current unit of measurement. +This unit of measurement is the same unit of measurement +you use for your document rulers. (In this example, we are using +inches.) To change the units, follow the instructions in the section entitled +Using Rulers. + +The dialog section labled Page Size is used to specify +the paper size for the document. +&kword; includes many predefined paper sizes. Select the appropriate paper size with the drop down +box labled Size. + +In addition to standard paper sizes, there are two selections that +deserve special mention. + + +Screen +This format is used to generate a document where +each page has an aspect +ratio (shape) which matches the aspect ratios of computer +monitors. This might be useful for documents which will never be printed, but will appear only on a computer screen. + + + +Custom +You can select this option to specify a unique paper size. +Once selected, two text +entry boxes (labeled Width: and +Height:) become active. Enter the height and width of your desired paper size in these text boxes. + + + +Next to the paper format, in the section labeled +Orientation you can select either Portrait or Landscape layout for +your document. + +Below the page format options, is the Margins subsection, which +consists of 4 entry boxes. All options in this subsection are disabled in Page Oriented documents. + + + diff --git a/doc/kword/paratb.png b/doc/kword/paratb.png new file mode 100644 index 000000000..cbdd6667c Binary files /dev/null and b/doc/kword/paratb.png differ diff --git a/doc/kword/part-kformula.png b/doc/kword/part-kformula.png new file mode 100644 index 000000000..7f38e7bd7 Binary files /dev/null and b/doc/kword/part-kformula.png differ diff --git a/doc/kword/part-kspread.png b/doc/kword/part-kspread.png new file mode 100644 index 000000000..93fb35034 Binary files /dev/null and b/doc/kword/part-kspread.png differ diff --git a/doc/kword/picture.png b/doc/kword/picture.png new file mode 100644 index 000000000..eba247ce7 Binary files /dev/null and b/doc/kword/picture.png differ diff --git a/doc/kword/pntdlg.png b/doc/kword/pntdlg.png new file mode 100644 index 000000000..9a90d6fc3 Binary files /dev/null and b/doc/kword/pntdlg.png differ diff --git a/doc/kword/pntdlg1.png b/doc/kword/pntdlg1.png new file mode 100644 index 000000000..d70273f03 Binary files /dev/null and b/doc/kword/pntdlg1.png differ diff --git a/doc/kword/portrait.png b/doc/kword/portrait.png new file mode 100644 index 000000000..f1541de9a Binary files /dev/null and b/doc/kword/portrait.png differ diff --git a/doc/kword/rarrow.png b/doc/kword/rarrow.png new file mode 100644 index 000000000..11a8ada57 Binary files /dev/null and b/doc/kword/rarrow.png differ diff --git a/doc/kword/rbord.png b/doc/kword/rbord.png new file mode 100644 index 000000000..207091661 Binary files /dev/null and b/doc/kword/rbord.png differ diff --git a/doc/kword/redo.png b/doc/kword/redo.png new file mode 100644 index 000000000..934e58716 Binary files /dev/null and b/doc/kword/redo.png differ diff --git a/doc/kword/repldlg.png b/doc/kword/repldlg.png new file mode 100644 index 000000000..2efdfc02a Binary files /dev/null and b/doc/kword/repldlg.png differ diff --git a/doc/kword/rowin.png b/doc/kword/rowin.png new file mode 100644 index 000000000..fefbcd166 Binary files /dev/null and b/doc/kword/rowin.png differ diff --git a/doc/kword/rowout.png b/doc/kword/rowout.png new file mode 100644 index 000000000..b82f870f5 Binary files /dev/null and b/doc/kword/rowout.png differ diff --git a/doc/kword/rtab.png b/doc/kword/rtab.png new file mode 100644 index 000000000..8fc40bcfc Binary files /dev/null and b/doc/kword/rtab.png differ diff --git a/doc/kword/rtab2.png b/doc/kword/rtab2.png new file mode 100644 index 000000000..9ce5569f3 Binary files /dev/null and b/doc/kword/rtab2.png differ diff --git a/doc/kword/ruler.png b/doc/kword/ruler.png new file mode 100644 index 000000000..e1479538b Binary files /dev/null and b/doc/kword/ruler.png differ diff --git a/doc/kword/saturation.png b/doc/kword/saturation.png new file mode 100644 index 000000000..444758214 Binary files /dev/null and b/doc/kword/saturation.png differ diff --git a/doc/kword/saved1.png b/doc/kword/saved1.png new file mode 100644 index 000000000..ce392844f Binary files /dev/null and b/doc/kword/saved1.png differ diff --git a/doc/kword/saved2.png b/doc/kword/saved2.png new file mode 100644 index 000000000..05d9647ef Binary files /dev/null and b/doc/kword/saved2.png differ diff --git a/doc/kword/savedlg.png b/doc/kword/savedlg.png new file mode 100644 index 000000000..ee5966a6f Binary files /dev/null and b/doc/kword/savedlg.png differ diff --git a/doc/kword/savetmpl1.png b/doc/kword/savetmpl1.png new file mode 100644 index 000000000..3bfccf0f6 Binary files /dev/null and b/doc/kword/savetmpl1.png differ diff --git a/doc/kword/scan.png b/doc/kword/scan.png new file mode 100644 index 000000000..0746bfa49 Binary files /dev/null and b/doc/kword/scan.png differ diff --git a/doc/kword/scan2.png b/doc/kword/scan2.png new file mode 100644 index 000000000..caec3df8d Binary files /dev/null and b/doc/kword/scan2.png differ diff --git a/doc/kword/screen.png b/doc/kword/screen.png new file mode 100644 index 000000000..e6f199c19 Binary files /dev/null and b/doc/kword/screen.png differ diff --git a/doc/kword/select1.png b/doc/kword/select1.png new file mode 100644 index 000000000..b35002130 Binary files /dev/null and b/doc/kword/select1.png differ diff --git a/doc/kword/spell.png b/doc/kword/spell.png new file mode 100644 index 000000000..0a3cb23e9 Binary files /dev/null and b/doc/kword/spell.png differ diff --git a/doc/kword/spelldlg.png b/doc/kword/spelldlg.png new file mode 100644 index 000000000..727b86dd2 Binary files /dev/null and b/doc/kword/spelldlg.png differ diff --git a/doc/kword/stkout.png b/doc/kword/stkout.png new file mode 100644 index 000000000..b7b7e0145 Binary files /dev/null and b/doc/kword/stkout.png differ diff --git a/doc/kword/storeprint.docbook b/doc/kword/storeprint.docbook new file mode 100644 index 000000000..1289f39a8 --- /dev/null +++ b/doc/kword/storeprint.docbook @@ -0,0 +1,476 @@ + + + + +Mike +McBride + + + + +Detailed Guides: Document Creation, Storage, and Printing + +This section of the documentation will cover everything you need +to know about starting a new document, saving a document, retrieving a +saved document and printing a document. + + +Beginning a New Document +create new document +Starting a new document can be done 5 ways: + + + +You can start &kword; from the +&kde; Panel. + + + +You can start &kword; from the +command line by typing$kword & + + + + +You can begin a new document in &kword; by selecting +FileNew from +the menubar. + + + +You can use the keyboard shortcut: &Ctrl;N + + + +or by clicking on the +toolbar. + + + + +However you begin a new document, a dialog box appears: + + + + + + + +This dialog box allows you to: + + + +Start a new document from a +template + + +Open an existing +document + + +Open a recent +document + + +&kword; remembers your previous choice. That previous choice will be the current default option. + + + +Starting a new document from a template + +In order to start a new document based on a template, you must +first choose which template you want to use. + + +Use the icons located along the left edge of the dialog box to select your template group. Simply click with the &LMB; to select that group and +display all the available templates of that group. + + +Remember templates are either Text Oriented (Blank Document) or Page Layout +templates. If you need to review the differences, click here. + +Once you have selected the icon, you are shown all the available +templates, each with a title and a small icon which shows you the +general layout of the template. + + +&kword; comes with four standard template groups. You can add +new icons by installing outside templates, or creating templates of your +own. + + +To select your template, click on it with the &LMB;. The +selected template will be highlighted. +Confirm your choice by clicking +the Use This Template button. This will begin a new document +with that template. + + + +For faster access to a template, simply double click on the +template, and &kword; will immediately load that template. + + + + +Opening an existing document + +Click on the Open Existing Document... button, and an new +dialog box is revealed. For more details on this dialog box refer to +Using the file selection dialog. + + +Open a Recent Document +&kword; keeps track of the most recently edited documents. You can select one of these documents by clicking on the icon labeled +Recent Documents. This will list the most recently edited files on the system. Simply click on the icon of the desired file with the +&LMB; and click Open This Document. + + + + + + + + + +Saving a Document +saving a document +Once you have entered text and data into a document, you will +usually want to save this to a file on your hard drive. + +&kword; can create a .pdf file for you. For instructions see +How do I create a .pdf file? + + + +The <guimenuitem>Save</guimenuitem> Command +The Save command can be invoked 3 ways: + + + +By selecting +FileSave from +the Menubar + + + +You can use the keyboard shortcut: &Ctrl;S + + + +or by clicking on the toolbar. + + + +Any of these methods results in the same action by &kword;. + +By selecting the Save command, you are +instructing &kword; to save the file under the current filename. You +will not be given the option to change the filename or its location. If +you want to change the name of the file, or where it is saved, you must +select +FileSave +As... from the Menubar. + +If you have not saved this file before, it does not have a +filename. &kword; automatically executes the Save As... +command so you can provide a file name. + +&kword; does not report a successful save. Therefore, if the file +was saved without incident, &kword; will return you to editing your +document. + +You can verify that the file was saved, by checking the titlebar. +If there are unsaved changes, the titlebar will have +[modified] in the titlebar. + + + + + + + + + + If the save was +successful, only the filename will be in the titlebar. If there is a +problem with the save, an error box will appear. + + + + + + + + + + + + + +The <guimenuitem>Save As...</guimenuitem> Command +saving a document with new name + +General +The Save As... command can be invoked 2 +ways: + + + +By selecting FileSave +As... from the Menubar + + +or by trying to Save a file which does +not yet have a filename. + + + +The difference between the Save and the +Save As... command, is the Save +As... command prompts you for a filename, and lets you +select a different file format or location. The +Save command simply saves the file in the +previous location. + + +Using the dialog box + +When you select Save As... a dialog appears. + + + + + + + + +For more information on using this dialog, see the section entitled +Using the file selection dialog. + +When you are in the folder you want to save the file in, type a filename into the +Location: box. +&kword; can create a .pdf file for you. For instructions see +How do I create a .pdf file. + + There is no need to put a .kwd at the end of your filename, &kword; +will do this for you. + + +&UNIX; filenames are more flexible than many other operating +systems. Filenames can: + + +be of nearly any length +be any combination of upper and lowercase letters +include spaces and punctuation + + +Filenames should not: + + + +begin with a space or period +end with a common file extension (.ps,.pdf,etc). + + + + +Once you have entered the correct information you can click on +Save to complete the save. + +&kword; does not report a successful save. Therefore, if the file +was saved without incident, &kword; will return you to editing your +document. If there is a problem with the save, an error box will +appear. + + +&kword; will only allow you to save your file where you are +allowed to by the permissions listed by the operating system. If you try +to save outside that area, &kword; will report an error. + + + + + + + +Retrieving a Saved Document +loading a &kword; file + +The Open... command can be invoked 4 ways: + + + + +By clicking the Open Existing Document +tab when Opening a New Document + + + +By selecting +FileOpen... from +the menubar + + + +You can use the keyboard shortcut: +&Ctrl;O + + + +or by clicking +on the toolbar. + + + +Any of these methods results in the same action by &kword;. + +Using the dialog box +When trying to open a file, a dialog appears. + + + + + + + + +For more information on using this dialog, see the section entitled +Using the file dialog. + +Use this dialog to locate the document you want to load. Once located, click +once with the &LMB; on the filename. Once the filename is selected click OK. The file will be loaded. + +There is a Cancel button, if you click this +button, the load will be aborted. + + + + +Printing A Document +printing a document +The Print... command can be invoked 3 ways: + + + +By selecting +FilePrint... +from the menubar + + +You can use the keyboard shortcut: +&Ctrl;P + + +or by clicking +on the toolbar. + + + +No matter how you do this, the &kde; print dialog will +appear. + + + + + + + + +The top combo box labeled Name: shows the +currently selected printer. To configure this printer click on the +Properties button. + +To select a different printer, click on the combo box and +select the desired printer. + +If you want to print your output into a postscript file, to a PDF file, +a fax modem (to send it as a fax) or email the file as a PDF file, select +the appropriate option from the combo box labeled Name. Once that option has been selected, enter +the filename into the text box labled Output file:. + +The line labled State tells you if your printer is currently connected and if it is printing another page. You can not change any information on this line. + +The lines labled Type and Location tells you what type of printer is currently selected and where that printer is located. You can not change any information on these lines. + + + +The line labled Comment describes how +&kword; interacts with your computer (what driver and print system it is using). You can not change anything on this line. Complete setup of the &kde; +printing system is beyond the scope of this document. For more information see the &kde; +print web site at http://printing.kde.org. + +If you want to print all pages of your document and only one copy, you can click +Print. If you want to change the number of copies or only print selected +pages, click the Options >> button. + +The System Options button allows a user to change the setup of the printers and &kde; print system. This is also beyond the scope of this manual. +If you need to make changes please refer to the &kde; print web site at http://printing.kde.org. + +Depending on which printing system your computer uses, you may find that you have +more printing options then those described below. What is described here, is available on +most systems. + +Once you click Options >>, the dialog box changes to: + + + + + + + + +Under Page Selection, you can select either +to print the whole document (select All), print the page the cursor is +located on (simply select Current), or print a range of pages. If you select the +Range option, enter your page range in the text box +provided. (Example: 3-13) + +In the combo box labeled Page set: you can tell &kword; to +print the Even Pages, the Odd Pages or +All Pages. + +In the box on the right labeled Copies:, you should set the number of copies +you want printed. You can either enter the number directly into the +box, or use the arrows to adjust the number. &kword; can print a maximum +of 999 copies at once. + +You can have &kde; collate your documents by clicking on the +Collate check box. If selected, &kde; will print +all of the pages for copy 1, then print all the pages for copy 2, &etc; +If not selected, &kde; will print all of the copies of the first page, +then all of the copies of the second page, &etc; + +You can also determine if the document is printed in forward order +(print first page first), or reverse order (print last page +first). + +If you click on Options <<, the print dialog will +compress down to the previous view. + +Depending on your systems setup, you may have additional options available to you. These options are discussed at http://printing.kde.org. + +When you are satisfied with your selections, you can click +OK to print. + +If you click on Cancel, the printing will +be aborted. + + + + diff --git a/doc/kword/styldlg1.png b/doc/kword/styldlg1.png new file mode 100644 index 000000000..8b8d13948 Binary files /dev/null and b/doc/kword/styldlg1.png differ diff --git a/doc/kword/styleimport.png b/doc/kword/styleimport.png new file mode 100644 index 000000000..80e10f42c Binary files /dev/null and b/doc/kword/styleimport.png differ diff --git a/doc/kword/styles.docbook b/doc/kword/styles.docbook new file mode 100644 index 000000000..3f0043a65 --- /dev/null +++ b/doc/kword/styles.docbook @@ -0,0 +1,351 @@ + + + + +Mike +McBride + + + + +Text styles +text stylesintroduction + +Introduction to text styles +When you build documents that are more complex than a business +letter, such as a book, newsletter, or resume, the document is often +broken down into sections. Each of these sections may have a similar +appearance. + +You can use text styles to easily keep a consistent look throughout +your document. + + +If you are familiar with Styles in &Microsoft; +Word, &kword; text styles perform similar functions in &kword;. +You can skip to the next section. + + +Lets look at a section of a document and try to identify appropriate text styles: + + + + + + + + +In this example, you can see several different text styles at work: + + +The title is centered, underlined and in bold text +The section title (Income) is boldfaced. +The caption for figure 1-1 is smaller than normal text and boldface. +The rest of the document is in a standard font. + + + +We do not need to know exactly how we want the text and paragraphs +of these sections to look yet. All we need to do is identify these +sections of text as Section Titles, Normal +Text, etc. + +Once we have finished the document, you can change the look of all +the text labeled Section Title all at once. + +This will ensure that all section titles appear consistent +throughout your document. + +&kword; has 8 predefined text styles. + +Text styles should not be confused with table styles or +frame styles. +Text styles determine how the characters and paragraphs appear. Framestyles, control the borders and background color for the +frame. Tablestyles determine how tables appear in the finished document. + + + +Changing the text style of text +text styleschanging text style of selected text + +To change the text style of text, first, select +the text you want the changes to apply to. + +You can now change the text style in one of two ways: + + + +Select +FormatStyle +from the menubar. This will show the list of available text styles, select +the text style from the list. + + + +You can select the text style using the combo box on the Paragraph toolbar. +This combo box looks like this: . + + +Simply select the new text style from the list provided. + +You can change the text style of an entire paragraph. Simply place the cursor in a paragraph (making sure that +no characters are selected) and select a new style. Every character in the paragraph will be converted to the new text style. + + + +Creating a text style +text stylescreating + +If you plan on using text styles extensively in a large document, you +will probably want to create new text styles specific for your needs. + + +There are two ways to create a new text style: + + +Create a text style based on another text style using a dialog. +Format a block of text to the desired format, +then create a text style based on that text. + + + + +Creating a new text style based on a current text style +To create a new text style select +FormatStyle Manager... +from the menubar.This will bring up a dialog box. + + + + + + + +In the list box on the left, is a list of all the currently defined text styles. Select the current style that most closely resembles the new +text style. Click on that text style once with the &LMB;. + +Click the New button. + +&kword; will create a new text style based on the selected text style. It will assign it a temporary name [New Style Template (8)]. + +Type a descriptive name in the box labeled +Name. This will be the name of the text style. + +The rest of the dialog is used to make the alterations needed to create the new +text style. + +The preview box will show you what your new text style will look +like. + +Use the tabs labeled Font, +Indent & Spacing, General Layout, Decorations, Bullets/Numbers, and Tabulators, to format the text style. + +Click OK to create your new text style. +Click Cancel to abort the creation of the +text style. + + +Changing the Font Size, Type etc. + +The tab labeled Font is used to set the font type, font style, formatting, etc. + +This tab functions identically to the change font dialog used to edit general text. +Changes to this tab affect to +all text formated with this text style. + + + + +Changing Paragraph Spacing and Indents + +The tab labeled Indents & Spacing is used to adjust +spacing between lines, and paragraph indentation. + +This tab functions identically to the same tab in the Format Paragraph dialog. +Changes to this tab affect to +all text formated with this text style. + + + +Changing Paragraph Alignment + +The tab labeled General Layout determines how the text is placed within +the line. With other applications, you may have referred to +this as Alignment, or +Justification. + +This tab functions identically to the same tab in the Format Paragraph dialog. +Changes to this tab affect to +all text formated with this text style. + + + + +Changing Paragraph Borders + +The tab labeled Decorations is used to define and configure graphical borders +around your paragraphs. + +This tab functions identically to the same tab in the Format Paragraph dialog. +Changes to this tab affect to +all text formated with this text style. + + + + +Changing Paragraph Numbering/Bullets + +The tab labeled Bullets/Numbers is used to make all text formatted with this text style into a list. + +This tab functions identically to the same tab in the Format Paragraph dialog. +For more information see the section entitled Lists. + + + + + +Changing Tab-stops. + +Using the tab labeled Tabulators it is possible to define tab stops for the new text style. + +This tab functions identically to the same tab in the Format Paragraph dialog. +For more information see the section entitled Using Tab Stops. + + + + + +Creating a text style based on formatted text +If you have text that is already formatted correctly for a new text style: + +Select the text and select + +FormatCreate Style From Selection... +from the menubar. + +&kword; will prompt you for a name for your text style. Enter the name in the text box. +Click the +OK button. + + A new text style is created with the font, paragraph spacing, paragraph alignment, borders and shadows of the +currently selected text. +Future formatting changes to this selected text will not automatically change the text style you just created. If you want the changes +to become part of the text style, you must edit the text style. + + + + +Deleting a text style +text stylesdeleting + +Deleting an unneeded text style is easy. + + +Select +FormatStyle Manager... +from the menubar.This will bring up a dialog box. + + + + + + + + +From the list of available text styles, select the style you want to +delete by clicking once with the &LMB;. + + +Be sure you have selected the correct text style before you click +Delete. &kword; will not ask for confirmation, +so you will not be given an opportunity to back out. + +Click Delete. +The text style is now deleted. + + + + +Editing a text style +text stylesediting + +The true power of text styles, is the ability to edit the formatting +options of that text style after the text style is defined. +By changing the formatting of the text style, &kword; will immediately change +every paragraph with that text style, and maintain a consistent look to +the document. + +&kword; uses the same interfaces to edit the formatting options of a +text style, that it used to create the text style in the first +place. + +To edit a current text style: + +Select +FormatStyle Manager... +from the menubar.This will bring up a dialog box. + + + + + + + +Select the text style you want to edit from the list on the left by clicking once with the &LMB;. +Now you can make the changes you want to this text style. + +The preview box will show you what your new text style will look +like. + + +Do not change the name of your text style. + +Doing so will delete your current text style from the list (and create +a new one with the new name). + +Any paragraphs which were originally formatted with this text style, +will revert to Standard. + + +Use the tabs labeled Font, +Indent & Spacing, General Layout, Decorations, Bullets/Numbers, and Tabulators to alter the look of the text style. + +Click OK to commit your changes. + +Click Cancel to abort all changes to this +text style. + + + + +Import a text style +text stylesimporting + +&kword; has the ability to import a text style from one &kword; document and include it in the +list of text text styles in another &kword; document. +To import a text style, select FormatImport Style... +from the menubar.This will bring up an empty dialog box. +Click on the Load button. This will bring up a +file selection dialog. Choose the &kword; file you want to import the text style from and click +OK. +The dialog box will now fill with all available text text styles available for import. +If &kword; encounters a duplicate text style name in the selected file, it will append a number to the end of the +text style name to identify the imported style. +As an example, if you import the Standard text style from another &kword; file, &kword; will change +the text style name to Standard-1. +Select all the text style you want to import. Then click +OK. + + + diff --git a/doc/kword/subscbut.png b/doc/kword/subscbut.png new file mode 100644 index 000000000..6d0e55ce7 Binary files /dev/null and b/doc/kword/subscbut.png differ diff --git a/doc/kword/sum.png b/doc/kword/sum.png new file mode 100644 index 000000000..440c6a952 Binary files /dev/null and b/doc/kword/sum.png differ diff --git a/doc/kword/supscbut.png b/doc/kword/supscbut.png new file mode 100644 index 000000000..043100660 Binary files /dev/null and b/doc/kword/supscbut.png differ diff --git a/doc/kword/table.docbook b/doc/kword/table.docbook new file mode 100644 index 000000000..55faf3295 --- /dev/null +++ b/doc/kword/table.docbook @@ -0,0 +1,653 @@ + + + + +Mike +McBride + + + + +Tables +tablesusing + +&kword; has the built in ability to generate tables for the display of data. + +These tables can consist of up to 128 rows and 128 columns, +with text centered or justified differently in different cells. Text flows easily around in the +table and cells are resized (if specified by the user) automatically to fit comfortably around the data. + +Tables in &kword; are for the display of data only. No calculations can be performed. + +Remember, if you need the functions of a spreadsheet, you can embed a &kspread; Table in your +document. + +This section of the document will cover the formatting of tables +created in &kword; only. + +Adding a new Table +tablesadding + +You can create a table in &kword; in one of three ways: + + + + +Select Insert +Table... from the menubar. + + +You can use the keyboard shortcut: F5. + + + +or by clicking +on the toolbar. + + + + +This will open a dialog box. The dialog box has two tabs: Geometry and Templates. + + + + + + + + +This dialog box is divided into two halves. + +The right half of the dialog box provides you a quick visual guide +to how many rows and columns will be created in the table. This is +useful for laying out your table. You cannot edit +your table layout here. + +The left half of the dialog box consists of two combo boxes. + +The spin box labeled Number of +rows:, allows you to specify from 1 to 128 rows in the +table. + +The spin box labeled Number of +columns:, allows you to specify from 1 to 128 columns in the +table. + +While adjusting either of these two options, the preview box +adjusts to your new settings. + + +If you click on the tab labeled Templates, you can use predefined table looks to format the look of your table. +For more information see the section on Using formatting templates. + +Click OK to insert the table. +Click Cancel to cancel this action and return to editing your document. + + + +Moving between cells in a table +tablesnavigating + +You can navigate between cells of the table by using the mouse (simply click in the cell you want to edit), +or by using the keyboard (use the arrow keys to move up, down, left or right one cell at a time). + + + +Deleting a Table +tablesdeleting + +To delete a table in &kword;: + +Place the mouse pointer over the frame of any cell of the table you want to +delete and click once with the &LMB;. + +Be sure you have selected the correct table before continuing. +&kword; will not ask for confirmation. + + +Select TableDelete +Table from the menubar + + +The table will be immediately deleted. + + + +Insert Row in Table +tablesinserting a row + +You can insert a row into any place in a table. + +To insert a row into a table, place the mouse pointer over the border of any cell of the table you want to add +a row to. Using your mouse, select either Table +Row +Insert Row... + from the menubar or +click on the +toolbar. + + +This will bring up a dialog box. + + + + + + + +The spin box labeled Row:, allows +you to select any row within the table. This number selection box +limits you to the rows currently in the table. +Select the row you want to use as a reference. + +Now select either Before or +After as is appropriate. + +Click OK to add the row or click +Cancel to not add any rows. + + + + +Insert Column in Table +tablesinserting a column + +To insert a column into a table, place the mouse pointer over the border of any cell of the table you want to add +a column to. Select either TableColumn +Insert Column... from the menubar or click + on the +toolbar. + +This will bring up a dialog box. + + + + + + + + +The number selection box labeled Column:, +allows you to select any column within the table. This number selection +box limits you to the columns currently in the table. + +Select the column you want to use as a reference. + +Now select either Before or +After as is appropriate. + +Click OK to add the column or click +Cancel to not add any columns. + + + + +Delete Row in Table +tablesdeleting a row + +To delete a row from a table: + +Click once with the &LMB; in any cell in the row you want to delete Then: + + + +select TableRow +Delete Selected +Rows... from the menubar + + +or click on the +toolbar. + + +This will bring up a dialog box confirming that your have selected the correct row(s). + + +Make sure you have selected the correct row(s) before +continuing. +&kword; will delete any data contained within the selected rows. + +Click Delete to delete the row, or click Cancel to not +delete any rows. + + + + +Delete Column in Table +tablesdeleting a column + +To delete a column from a table: + +Click once with the &LMB; in any cell in the column you want to delete Then: + + + +select TableColumn +Delete Selected +Columns... from the menubar + + +or click on the +toolbar. + + + +This will bring up a dialog box confirming that your have selected the correct column(s). + + + +Make sure you have selected the correct column(s) before +continuing. +&kword; will delete any data contained within these columns. + + +Click Delete to delete the column(s), or click +Cancel to not delete any columns. + + + + +Change column width +tableschange column width + +When a table is created, all columns are equal in width. You can change the width of individual columns by using +the mouse or the keyboard. +Using the mouse +First select any cell in the column you want to change, by holding down the &Ctrl; key and clicking once with the &LMB;. +The cell is now surrounded by 8 colored boxes. Place the mouse over the box in the middle of the +right vertical border of the cell. The mouse pointer changes to a double-headed arrow. Click on the box and drag the right edge of the +cell to the desired width. When you release the &LMB;, the entire column will assume the width of this cell. + + +Using the dialog box +First, select any cell in the column you want to change, by holding down the &Ctrl; key and clicking once with the &LMB;. +You can select any cell in the table to change column widths. By selecting a cell in the column you want to change +the dialog box will default to the correct column automatically. +Select TableColumn +Resize +Column... from the menubar. +A dialog box will appear. In the spin box labeled Column:, you can chose a different column to set. +In the spin box labeled Width:, enter the desired width of the column. +Click OK to change the width, or click Cancel to leave the column +width unchanged. + + + + +Join Cells in Table +tablesjoin cells + +A table is traditionally made of a grid of rows and columns, with +equal sized cells throughout the table. + +Sometimes you would like to spread text out over several cells in +a table. This is especially common with titles. + +&kword; allows you to do this by Joining two (or +more) adjacent cells of a table together. + + + + + + + +This is an example of three cells joined together in the middle of +a table. + + +You can join cells vertically, as well as horizontally. + + +To join several cells you must first select the cells. To select the cells, hold down the &Ctrl; key +and click once with the &LMB; +in a cell. Click on the next cell with the &LMB;. Continue +this until you have selected all the cells you want to join together. + + +If you have a number of cells in a row that you want to select, +you can select them in two quick steps: +First hold down the &Ctrl; key and click on one of the end cells. +Now hold down the &Shift; key and click on the cell at the other +end of the row or column you want to join. +All cells between these two cells will be selected. + + + +Once you have selected all the cells you want to join, +select TableCell +Join Cells from the menubar + +The cells will now be joined. + +Any text in the left most frame will now be located in the joined +frame. Any text from any other frames will be deleted. + + + +Split Cells in Table +tablessplit cells + +In addition to combining two or more cells into a single cell, it is easy to split one cell into many cells. + +If you decide that you do not want the previously joined cells to +be joined any longer, you can split them back into individual cells +again. You can also split cells within a column or row. They do not need +to have been previously joined. + +To split a cell, select the cell you want to split by holding the &Ctrl; button down and +clicking on it with the +&LMB;. Select TableCell +Split Cell... from the menubar. + +This will bring up a small dialog box which allows you to set the number of rows and +the number of columns you want to split this cell into. + +Once you have set the correct number of rows and columns in the spin boxes, click +OK to split the cells. Click Cancel to abort. + + + + +Ungroup a Table +tablesungrouping + +If you select a cell in a table and then choose Table +Ungroup Table from the menubar, &kword; will convert each cell in your table +into an individual frame. You can then move these frames around independently on the page. + + + + +Protecting a cell in a table. +tablesprotecting cells + +You can protect any or all cells in a table from accidental modification or deletion. +Simply select the cell(s) you want to protect, then: +Select Table +CellProtect Cells +from the menubar or hold down the &Ctrl; button, click in the cell once with the &RMB; and select + CellProtect Cells +from the popup menu. +You will not be able to change the contents or formatting of that cell. + +To disable the protection, simply repeat the steps above, and the cells will no longer be protected. + + + + +Formating a Table +tablesformating + +There are many aspects of a table that can be formatted. + +For information of formatting text with a table see Format characters. +For information on formatting borders between frames in individual cells, see Borders +For information on formatting background color of individual cells, see Frame background +For information on changing the width of columns, see Resizing Columns + +&kword; also provides the user with a set of tools to help speed up the formatting of tables. + + +Altering the number of rows and columns in a table. +tableschanging geometry + +Previously in the manual, we have discussed how to individually add or delete rows and/or columns. &kword; also provides the +user the ability to make major changes to the number of rows and columns in a table. +Select Table +Properties... +from the menubar. A dialog will appear. + + + + + + + + +You can use this dialog to change the number of rows in your table by using the spin box labeled +Number of rows:. +If you reduce the number of rows using this dialog box, &kword; will delete the bottom row(s) +including the data within the rows.Be sure you do not have any data in these rows +that you need to preserve. +You can use this dialog to change the number of columns in your table by using the spin box labeled +Number of columns:. +If you reduce the number of columns using this dialog box, &kword; will delete the right most column(s) +including the data within the columns.Be sure you do not have any data in these columns +that you need to preserve. +Placing a mark in the check box labeled Reapply template to table, will cause &kword; to re-apply the +template to the table after adding or deleting the specified number of rows and/or columns. +Click OK to make changes permenant, or click Cancel to abort all +changes. + + + + +Selecting an entire column for formatting +To select an entire column for formatting, move the mouse pointer to the white space directly above +the desired column. The mouse pointer will turn from an arrow to a hand. If you click with the &LMB;, the entire column will be selected. + + + +Selecting an entire row for formatting +To select an entire row for formatting, move the mouse pointer to the white space directly to the left of +the desired row. The mouse pointer will turn from an arrow to a hand. If you click with the &LMB;, the entire row will be selected. + + + +Using table templates to format an entire table +tablestemplates + +&kword; has templates for many commonly used table formatting options. Table templates provide +the same formatting functionality for tables that +document templates provide you for formating your documents. +Select Table +Properties... +from the menubar. A dialog will appear. Click on the tab labeled Templates. + + + + + + + + +Along the left of the dialog box, is a list of table templates. + +On the right is a preview box that +gives an example of what a table template will look like when applied to your table. + +Below the preview box, are 5 check boxes. + + +First row +This check box will toggle formatting of all cells in the top row. + + + +Last row +This check box will toggle formatting of all cells in the bottom row. + + + +Body +This check box will toggle formatting of all cells in the body. The body of the table is any cells which are not formatted +by any of the other four options. + + + +First column +This check box will toggle formatting of all cells in the left column. + + + +Last column +This check box will toggle formatting of all cells in the right column. + + + + + +Placing a mark in the check box labeled Reapply template to table, will cause &kword; to re-apply the +template to the table after adding or deleting the specified number of rows and/or columns. + +Click OK to make changes permenant, or click Cancel to abort all +changes. + + + + + +Using table styles +tablesstyles +table styles + +Table styles are a rapid way for you to format individual cells of your table to common formats. You can add or remove +table styles, and change predefined table styles to suit your needs. A table style consists of a frame style and a text style +which are grouped together and named. + +Formatting a cell with a table styles +table stylesformatting a cell with + +To format a cell using a predefined table style simply: +Select the cell(s) by holding down &Ctrl; and clicking within the cell with the &LMB;. You can also +select columns and rows. +Select +TableTablestyle +from the menubar. A submenu will appear, listing all the currently defined table styles. Select the name of the table style +you want and all selected cells will automatically be formatting using the options of that table style. + + + +Editing a table style +table stylesediting + +To change the options of a table style, you will use the Table Style Manager. +Select +TableTable Style Manager... +from the menubar. A dialog box will appear. + + + + + + + + +All of the currently defined table styles are listed in the listbox on the left. The currently selected table style is highlighted, and +the name of the currently selected table style is listed in the text box labeled Name. (In this example, +the currently selected table style is Header 1.) +Select the name of the table style you want to change by clicking on the name of the table style in the listbox on the left. + +In the section labeled Adjust is a combo box labeled Framestyle which is used to select the desired frame style. +If you want to add or alter a frame style, click the Change... button, and you will be taken to the +Framestylist to make those changes. +Below that, is a combo box labeled Textstyle: which is used to select the desired text style for this table style. +If you want to add or alter a text style, click on the Change... button, and you will be taken directly to the +Stylelist to make those changes. + +Once all changes have been made, click OK to save your changes. All of the affected table styles will +be changed to reflect the new options. + + + +Creating a new table style +table stylescreating + +To create a new table style, select +TableTable Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Select a table style from the list at the left which most closely matches your new desired table style. +The selected table style will be used as a template for the new table style. Select the table style by clicking +once with the &LMB; in the list on the left. +Click on the New button. &kword; will generate a new table style, which is a copy +of the previously selected table style. +Choose a name for your new table style, and type it in the text box labeled Name. +You can now change your table style options to customize your newly created table style. For details, see +Editing a table style. + + + +Deleting a table style +table stylesdeleting + +To delete table style, select +TableTable Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Select the table style you want to delete +by clicking once with the &LMB; on the name of the table style you want to delete. +Click on the Delete button. +&kword; will not allow you to delete the Plain table style. + + + +Changing the order of the table style in the list +table stylesreordering + +To change the order that the table style are listed, select +TableTable Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +The order the table styles are listed in the menu is determined by the order of the table styles in the list on the left. +Select the table style you want to move from the list at the left by clicking once with the &LMB;. +Now click on the Up Arrow and Down Arrow located at the bottom of the list of table styles. +This will move theselected table style up or down in the list of table styles. +When you are satisfied with the order of the list, select OK. + + + +Importing a table style from another &kword; file +table stylesimporting + +To import a table style from another &kword; file, select +TableTable Style Manager... +from the menubar. A dialog box will appear. + + + + + + + +Click the button labeled Import From File. You can +select the &kword; file using the file selection dialog. Choose your file, and click +OK. +A new dialog box will appear listing all available table styles for importing. +If &kword; encounters a duplicate table style name in the selected file, it will append a number to the end of the +table style name to identify the imported style. +As an example, if you import the Plain table style from another &kword; file, &kword; will change +the name to Plain-1. +Select all the table styles you want to import. Then click +OK. +The table styles will now appear at the bottom of your list of table styles. Click OK +to save the table styles in the new document. + + + + diff --git a/doc/kword/tableprop1.png b/doc/kword/tableprop1.png new file mode 100644 index 000000000..c581ec77d Binary files /dev/null and b/doc/kword/tableprop1.png differ diff --git a/doc/kword/tableprop2.png b/doc/kword/tableprop2.png new file mode 100644 index 000000000..8941d0d62 Binary files /dev/null and b/doc/kword/tableprop2.png differ diff --git a/doc/kword/tablestylist.png b/doc/kword/tablestylist.png new file mode 100644 index 000000000..e00625547 Binary files /dev/null and b/doc/kword/tablestylist.png differ diff --git a/doc/kword/tabstops.docbook b/doc/kword/tabstops.docbook new file mode 100644 index 000000000..01fa83f18 --- /dev/null +++ b/doc/kword/tabstops.docbook @@ -0,0 +1,324 @@ + + + + +Mike +McBride + + + + +Using Tab Stops +tab stopsusing +paragraphsetting tab stops + +Tab stops are a (very useful) holdover from the days of +typewriters. They allow you to align text into columns quickly and +easily. + +When a tab stop is in place, you can immediately jump to a +horizontal position on the page by pressing the Tab key. Tab stops +are most commonly used to align columns in a table, or to automatically +indent paragraphs. + +Tab stops are part of the properties of a paragraph. Each +paragraph keeps track of its own set of tab stops. To view the tab +stops of a particular paragraph, place the mouse pointer within a +paragraph, click once, and check the top ruler. The tab stops are +marked as symbols in black. + +&kword; recognizes 4 types of tab stops. Each of these types has +a corresponding symbol to help you identify the type in the +ruler. + + + +TypeExampleSymbolDescription + + +Right Tab Stop + + +With a right tab stop, the right edge of the next set of words is aligned at the tab stop. + +Center Tab Stop + + +With a center tab stop, the text is centered at the tab stop. + +Left Tab Stop + + +With a left tab stop, the left edge of the next set of words is aligned at the tab stop. + +Decimal Tab Stop + + +With a decimal tab stop, the decimal points of the text are aligned at the tab stop. + + + + +Setting Tab Stops +tab stopssetting a new tab stop + +Tab stops can be set one of two ways: + + + +Using the rulers of +&kword; + + +Using a specialized dialog +panel. + + + + +Using the Ruler + +You can use the top ruler of &kword; to interactively insert tab +stops. + +First, you should select the type of tab stop you want to +use. + +Place the mouse cursor over the current tab character (located +directly to the left of the top ruler). Click once with the &RMB;. A small popup menu +will appear. You can select the tab stop you want from the sub +menu. + + +You can also use the left mouse button to cycle through the +different types of tab stops. + +Click once on the current tab character, and the tab stop changes +from left tab stop, to center tab stop. +If you continue to click with the left mouse button, you will change to +right tab stop, then to decimal tab stop, +then back to left tab stop. + + +Once you have the correct type of tab stop, you can simply place +the mouse pointer on the top ruler bar at the desired position, and click once with the +&LMB;. This will place a tab +stop at that position. + + + + +Using the Dialog Box + +The fastest way to get to the tab stop dialog panel, is to select +FormatParagraph... +from the menubar or type &Ctrl;&Alt;P. +This will bring up a dialog box with 5 tabs. Click on the tab +labeled Tabulators. + + + + + + + + +You can now add tab stops by: + + + +Click the New button at the bottom of the list of tab stops. + + +Type the horizontal location of the tab stop in the space +labeled Position. The units used and the current frame width +are listed below the text box. + + +Select the type of tab stop from the list of radio buttons labeled +Alignment. + +Determine what you want to fill the empty space to the tab stop with. +In most cases this should be left as Blank. For information on other options in this section, see +Tab filling. + + + +You can now add another tab stop. When you are done adding tab stops, you can click +OK to finish. + + + + + +Moving Tab Stops +tab stopsmoving + +Tab stops can be moved one of two ways: + + + +Using the rulers of +&kword; + + +Using a specialized dialog +panel. + + + + +Using the Ruler + + + +To move a tab stop with the ruler, place the mouse over the +desired tab stop. The mouse pointer will change to a double +arrow. + + + +Click and hold down the &LMB;. Drag the tab +stop to its new location + + + +When the tab stop is where you want it, release the mouse +button. + + + + + + +Using the Dialog Box + +Select FormatParagraph... +from the menubar or type &Ctrl;&Alt;P. +This will bring up a dialog box with 5 tabs. + +Click on the tab labeled Tabulators + +A very fast way to edit existing tab stops is to simply double click on the +tab stop you want to edit in the top ruler of &kword;. This will also bring up +the Tabulators dialog box with the desired tab stop already selected. + + + + + + + + + +Click on the tab stop you want moved. The list of all tab stops +is in the box on the left side of the dialog panel. + + +Type the horizontal location of the tab stop in the space +labeled Position. The units used and the current frame width +are listed below the text box. + + + +If you need to make changes, select the type of tab stop from the +list labeled Alignment or change the white space character +under Tab Leader. + + +Click OK when you are done moving all tab stops around. + + + + + + +Removing Tab Stops +tab stopsremoving +tab stopsdeleting + + +Tab stops can be removed one of two ways: + + + + +Using the rulers of +&kword; + + +Using a specialized dialog +panel. + + + + +Using the Ruler + + + +To delete a tab stop with the ruler, place the mouse over the +desired tab stop. The mouse pointer will change to a double +arrow. + + +Click and hold down the &RMB; on +the mouse. A popup menu will appear. Select Remove Tabulator. + + + + + +Using the Dialog Box + +Select FormatParagraph... +from the menubar or type &Ctrl;&Alt;P. +This will bring up a dialog box with 5 tabs. + +Click on the tab labeled Tabulators + +A very fast way to edit existing tab stops is to simply double click on the +tab stop you want to edit in the top ruler of &kword;. This will also bring up +the Tabulators dialog box with the desired tab stop already selected. + + + + + + + + + + +Click on the tab stop you want removed. The list of all tab stops +is in the box on the left side of the dialog panel + + +Click the Delete button. + + + +You can delete all tab stops at once by clicking Delete All. +&kword; will not prompt you prior to deleting all tabs, so make sure that is your intention prior to selecting the +Delete All button. + + +When you are done deleting tab stops, you can click +OK to finish. + + + + +Tab filling +tab stopstab filling + +By default, &kword; uses the standard tab function that you are familiar with when using a typewriter or most wordprocessing programs. +You can, however, have &kword; insert dots or lines to fill the tab space. +To change the way the tab fills work in &kword; you change the combo box labeled Filling:. This combo box +gives you many different line styles to choose from. +You can change the thickness of the lines by using the Width: spin box. + + + + + diff --git a/doc/kword/tb1.png b/doc/kword/tb1.png new file mode 100644 index 000000000..7a02c80f7 Binary files /dev/null and b/doc/kword/tb1.png differ diff --git a/doc/kword/tb2.png b/doc/kword/tb2.png new file mode 100644 index 000000000..efa6d8a4c Binary files /dev/null and b/doc/kword/tb2.png differ diff --git a/doc/kword/tb3.png b/doc/kword/tb3.png new file mode 100644 index 000000000..a17c16b7d Binary files /dev/null and b/doc/kword/tb3.png differ diff --git a/doc/kword/tb4.png b/doc/kword/tb4.png new file mode 100644 index 000000000..a2dde5f5b Binary files /dev/null and b/doc/kword/tb4.png differ diff --git a/doc/kword/tblsty.png b/doc/kword/tblsty.png new file mode 100644 index 000000000..e9beb7d6f Binary files /dev/null and b/doc/kword/tblsty.png differ diff --git a/doc/kword/tbord.png b/doc/kword/tbord.png new file mode 100644 index 000000000..557370bd6 Binary files /dev/null and b/doc/kword/tbord.png differ diff --git a/doc/kword/techinfo.docbook b/doc/kword/techinfo.docbook new file mode 100644 index 000000000..a2a7dd85b --- /dev/null +++ b/doc/kword/techinfo.docbook @@ -0,0 +1,246 @@ + + + + +Mike +McBride + + + + +&kword; file format +&kword;file format + +&kword; uses two open source, independently developed standards for +its file format. The combination was chosen for its balance between +convenience and open development models. + +First, it should be noted that all &kword; files are multiple &XML; +files that are compressed to reduce their space requirements. + +Select the &kword; version you are interested in: + +&kword; 1.1 and earlier. +&kword; 1.2. +&kword; 1.3. + + + + +&kword; 1.1 and earlier + +The &XML; files are compressed into a single file using the same +algorithm as used by tar. + +You can uncompress the files with the following command: + + +% tar -xzvf filename + + +This will expand the &kword; document file into its component +files. + +The text portion of all &kword; files are &XML; (eXtensible Markup +Language) files. + +For more information on &XML; documents, processors and +technology, please visit World Wide Web Consortium &XML; +pages XML.org Resource +Guide The &XML; +FAQ + +All &kword; documents consist of at least two &XML; files: + + + +maindoc.xml + +This file contains the bulk of the &kword; text, tables and formula +information. It is marked with &XML; tags according to the official DTD. A +copy of the &kword; 1.1 DTD is located at: http://www.koffice.org/DTD/kword-1.1.dtd. + + + +documentinfo.xml + +This file contains the document information. This is information +entered into the dialog boxes when selecting +FileDocument +Information from the menubar. This information +is useful for tracking authors, contact information &etc; +The DTD for &koffice; 1.1 is located at: http://www.koffice.org/DTD/document-info-1.1.dtd. + + + + +In addition, there may be other files included in the &kword; document +file. Pictures, embedded documents and other binary information are stored +within the &kword; document as separate files. + +For more specific information on &kword; file storage or other +internal information, please see The KOffice API and the +General &kde; developer information +pages. + + + +&kword; 1.2 + +The text files are compressed into a single file using the same +algorithm as used by zip. +This change was made because of its broad use in other open source office +suites and its improved performance with lower memory requirements. +You can uncompress the files with the following command: + + +% unzip filename + + +This will expand the &kword; document file into its component +files. + +The text portion of all &kword; files are &XML; +(eXtensible Markup Language) files. + +For more information on &XML; documents, processing and +technology, please visit World Wide Web Consortium &XML; +pages XML.org Resource +Guide The &XML; +FAQ + +All &kword; documents consist of at least three files: + + + +maindoc.xml + +This file contains the bulk of the &kword; text, tables and formula +information. It is marked with &XML; tags according to the official +DTD. A copy of the &kword; 1.2 DTD is located at: http://www.koffice.org/DTD/kword-1.2.dtd. + + + +documentinfo.xml + +This file contains the document information. This is information +entered into the dialog boxes when selecting +FileDocument +Information from the menubar. This information +is useful for tracking authors, contact information etc. +The DTD for &koffice; 1.2 is located at: http://koffice.kde.org/DTD/document-info-1.2.dtd. + + + + +mimetype + +This file contains the mimetype for &kword; files. This information +is used by &kde; to determine that this is a &kword; file. +This file always contains: +application/x-kword + + + + + +In addition, there may be other files included in the &kword; document +file. Pictures, embedded documents and other binary information are stored +within the &kword; document as separate files. + +For more specific information on &kword; file storage or other +internal information, please see The KOffice API and the +General &kde; developer information +pages. + + + +&kword; 1.3 (current version) + +The text files are compressed into a single file using the same +algorithm as used by zip. +This change was made because of its broad use in other open source office +suites and its improved performance with lower memory requirements. +You can uncompress the files with the following command: + + +% unzip filename + + +This will expand the &kword; document file into its component +files. + +The text portion of all &kword; files are &XML; +(eXtensible Markup Language) files. + +For more information on &XML; documents, processing and +technology, please visit World Wide Web Consortium &XML; +pages XML.org Resource +Guide The &XML; +FAQ + +All &kword; documents consist of at least three files: + + + +maindoc.xml + +This file contains the bulk of the &kword; text, tables and formula +information. It is marked with &XML; tags according to the official +DTD. A copy of the &kword; 1.3 DTD is located at: http://www.koffice.org/DTD/kword-1.3.dtd. + + + +documentinfo.xml + +This file contains the document information. This is information +entered into the dialog boxes when selecting +FileDocument +Information from the menubar. This information +is useful for tracking authors, contact information etc. +The DTD for &koffice; 1.3 is located at: http://koffice.kde.org/DTD/document-info-1.3.dtd. + + + + +mimetype + +This file contains the mimetype for &kword; files. This information +is used by &kde; to determine that this is a &kword; file. +This file always contains: +application/x-kword + + + + + +In addition, there may be other files included in the &kword; document +file. Pictures, embedded documents and other binary information are stored +within the &kword; document as separate files. + +For more specific information on &kword; file storage or other +internal information, please see The KOffice API and the +General &kde; developer information +pages. + + + + diff --git a/doc/kword/tedittb.png b/doc/kword/tedittb.png new file mode 100644 index 000000000..f8c9ae5c2 Binary files /dev/null and b/doc/kword/tedittb.png differ diff --git a/doc/kword/templatecreation.docbook b/doc/kword/templatecreation.docbook new file mode 100644 index 000000000..13023f763 --- /dev/null +++ b/doc/kword/templatecreation.docbook @@ -0,0 +1,115 @@ + + + + +Mike +McBride + + + + +Creating Templates, Saving a document as a template and Deleting Templates + +&kword; comes with several predefined templates (both +Page Layout and Text Oriented templates), which are designed +to provide initial formatting of documents. + +If, however, the same format for a custom document is used over and +over, &kword; can create a template which more +exactly matches the needs of the document. + +An unlimited number of templates can be created in &kword;, and +they can be organized into categories for easy recall. + +Creating a new template +templatescreating + +Templates are created by first generating the layout in +&kword; based on one of the predefined templates, and then saving the +file. Instead of saving it as a traditional file, it is saved as a +template. + +What follows, is a step by step process to save the current +document as a template. + + + +When the document is a completed template, Select +FileCreate Template From +Document... from the menubar. + +This brings up a dialog: + + + + + + + +This dialog helps organize the templates into +groups (categories). + +Select the group to place the new template into. +To create a new group to place templates in, simply click the button +labeled Add Group. A dialog box will appear asking for the +name of the new group. Click OK and the new group is created. + + +Type in a name for the template in the text box labeled Name. + + +Select the icon for your new template by +using the radio buttons on the right +&kword; has a default icon, which is shown below both options. +To change the icon, select Custom and a dialog box will appear. +Simply select the desired icon using the dialog box. Click OK when the icon is selected. + + +Click OK. + + + +Once you have saved the template, the next time you open a +document, your new category/new template will appear in the open file +dialog. + + +Removing a template +templatesdeleting +To delete a template, follow these steps: + + +Select +FileCreate Template From +Document... from the menubar. +This will bring up a dialog + +Click on the small plus sign (+) in front of the template group where the template can be found. + +Click once on the template name +Click on the button labeled Remove. +A small dialog box will appear verifying that you do intend to delete +the template. Simply click Yes. + +The template is now deleted. + +Removing a template group +templatesdeleting template group + +To delete a group of templates, follow these steps: + + +Select +FileCreate Template From +Document... from the menubar. +This will bring up a dialog + +Click once on the group name +Click on the button labeled Remove. +A small dialog box will appear verifying that you do intend to delete +the group of templates. Simply click Yes. + +The group and all of the templates within the group are now deleted. + + + diff --git a/doc/kword/textstyex.png b/doc/kword/textstyex.png new file mode 100644 index 000000000..d6189dbed Binary files /dev/null and b/doc/kword/textstyex.png differ diff --git a/doc/kword/tfcreatebut.png b/doc/kword/tfcreatebut.png new file mode 100644 index 000000000..753eb01b2 Binary files /dev/null and b/doc/kword/tfcreatebut.png differ diff --git a/doc/kword/thesaurus.png b/doc/kword/thesaurus.png new file mode 100644 index 000000000..6ed9fbc99 Binary files /dev/null and b/doc/kword/thesaurus.png differ diff --git a/doc/kword/toc.docbook b/doc/kword/toc.docbook new file mode 100644 index 000000000..e8cab6a38 --- /dev/null +++ b/doc/kword/toc.docbook @@ -0,0 +1,67 @@ + + + + +Mike +McBride + + + + +Table of Contents +table of contentsintroduction + +When writing a large document, it is useful to include a table of contents. This can be done automatically +with &kword;. +To begin creating a table of contents &kword; needs to know what to include in the table of contents. +The first part of this chapter describes how to prepare the document to generate an accurate table of contents. +The second part of this section, discusses the actual generation and updating of the table of contents. +The final part of this section provides pointers on changing the look of the table of contents. +Preparing the document +table of contentspreparing document for + +&kword; uses a style-based method of creating table of contents entries. +For more information on styles, see the Styles section of this documentation. +To mark each level of the document, use the paragraph styles Head 1, +Head 2 and Head 3. +Major subjects should be marked with the Head 1 style. +Sub-headings under the Head 1 subjects should be marked with Head 2. +Sub-headings under the Head 2 subject headings should be marked with Head 3 +Once this is done, proceed to the next section. + +Creating the table of contents +table of contentscreating +table of contentsupdating + +To create the table of contents is easy. Simply place the cursor in a text frame where the table of contents should be inserted. +Select +InsertTable of Contents from +the menubar. +&kword; locates all entries labeled with the appropriate paragraph styles, and their corresponding page numbers. +It assembles this into the +table of contents. +Once the table of contents is created, it will remain unchanged until &kword; is instructed to update it. +To update the table of contents, click once with the &LMB; in the current table of contents. Then select + +InsertUpdate Table of Contents from +the menubar. +&kword; will replace the old table of contents with a newly updated one. + +Changing the look of the table of contents. +table of contentsformatting + +The look of the table of contents is also adjusted by using the paragraph styles in &kword;. +The table of contents title is formated with the Contents Title paragraph style. +All major subject headings (those marked with the Head 1 style), are now formatted +using Contents Head 1 paragraph style. All sub-headings (those marked with the +Head 2 style), are now formatted +using Contents Head 2 paragraph style. Finally, all sub-headings (those marked with +the Head 3 style), are now formatted +using Contents Head 3 paragraph style. +By changing the look of those three styles, +the appearance of the +table of contents can be radically changed. + + + + diff --git a/doc/kword/tts.png b/doc/kword/tts.png new file mode 100644 index 000000000..3b95737b6 Binary files /dev/null and b/doc/kword/tts.png differ diff --git a/doc/kword/tutorial.docbook b/doc/kword/tutorial.docbook new file mode 100644 index 000000000..6d9bc502d --- /dev/null +++ b/doc/kword/tutorial.docbook @@ -0,0 +1,356 @@ + + + + +Mike +McBride + + + + +Step by Step Tutorial +tutorial +This section is a step by step +walk through of the most important functions needed to understand how +to create and manipulate a complex document. This tutorial will generate the start of a +newsletter as an example document. + +It is recommend that you go through the tutorial in order at +least once if you are new to frame based word processors. + + +Tutorial: Choosing the initial template + +The steps to this tutorial are numbered from 1 to 23. +Beneath each step, is text in italics which further elaborates or explains the changes. + +When you first start &kword; (or start a new +document after &kword; is running), &kword; asks for a document template. + + + + +Screen shot + + +Here you can either: + + +Select the initial template for your new +document. + + +Open a &kword; document saved to your hard +drive or network. + + + + +Step 1: Click on Page Layout. + +Screen shot + +This will list the Page Layout templates available on +your system. For information on the differences between Page Layout and Text Oriented templates, see the section entitled +The difference between Text Oriented and Page Layout +templates. + +Step 2: Now select the Simple Layout icon by +clicking once with the left button of your mouse. + +Screen shot + +This is the template we will use for the +tutorial. + +Step 3: Now confirm your selection by clicking on +Use This Template. + +Screen shot + +To complete your selection. + +&kword; will open a new document with three frames. The +frames are outlined on the white background, as gray boxes. Each box is +a separate frame. + + + + +Tutorial: Selecting a frame and entering text into that frame + +To begin entering text (or adding any sort of data for +that matter) into a document, its important to let &kword; know which +frame to put the data in. + + +In order to keep both editing and formatting of your document efficient and simple, +the command executed with a mouse click changes depending on where in the &kword; window the pointer +is located. + +When the pointer is located over toolbars, scrollbars, menu buttons or other areas +outside the document, the pointer is an arrow. You should already be +familiar with this type of pointer when using other &kde; programs. +When inside the document, there are two separate pointers which alternate automatically +based on how close to a frame edge the pointer is currently located. +When the mouse pointer is near the edge of a frame, the pointer will change into two intersecting lines +with arrows on all four points. Clicking the left mouse button now will select the nearest frame. +As you move the pointer away from the edge of the frame, the pointer will change into the text entry pointer. +Clicking the left mouse button at this time will tell &kword; to insert text into this frame. + + + +Step 4: Place the mouse pointer over the upper-left frame. +Make sure you do not see the frame select pointer +Step 5: Click once with the left mouse button. + + +Screen shot + +This tells &kword; to insert text into this frame. Click in the upper left corner of the frame to position the cursor in the upper left corner of the frame. + +Step 6: Enter the following text using the keyboard: KWord Press Release. + +This is some sample text for our +newsletter. + +Step 7: Select KWord Press Release by placing +the mouse cursor on the right end of the text. Click once with the +&LMB; and drag the mouse cursor +to the left. Selected text will be white text on a colored +background. When all the text has been selected, release the &LMB;. + + +Screen shot +This defines what text is going to be altered with Step 8. +Step 8: Click inside the Text Size combo box. Change this +number to 26. + + +Screen shot + +This changes the size of the selected text to one more +appropriate for a title. + + + + Tutorial: Changing the size of a frame + +Now that we have entered some text, we can see that the +frame should extend across the entire width of the page for a title. We need to change +the size and shape of the frame. + +Step 9: Place the mouse pointer over the frame border (you will notice the cursor +changes to two intersecting lines with arrows), and click +once with the &LMB;. + +This will select this frame, so it can be +re-shaped. + +You will now notice the frame is outlined in black, with +8 squares on the outline. These squares are used for re-sizing the +frame. + +Step 10: Place the mouse pointer over the square in the lower +right corner of the frame. Click with the &LMB; and hold it +down. Drag the mouse up and to the right. + + +Screen shot + +Notice how the frame changes shape. Adjust the size and +shape of the frame until it looks similar to the example below: + + +Screen shot + +When it does, release the mouse button. + + + + +Tutorial: Moving a frame on the page and layering frames + +Now that we have created a title block, we will center it at the +top of the page. + +Step 11: Place the mouse pointer over the border of the frame (but +not on any of the squares). + +The pointer will now change to a 4 way arrow. This +indicates &kword; is ready to move the frame on the +page. + +Step 12: Click and hold with the &LMB;. Drag the +mouse, and the frame will follow it. Position the frame in the center +of the page near the top. When you are satisfied with its final +location, release the mouse button. + + +Screen shot + +Notice how the right side of the title block has slid behind the empty frame on the right. This is easily corrected. + +Step 13: Select FramesBring to Front. + + +Screen shot + +This will place the title on top of the other frame. You can raise and lower frames to give you the look you need. + + + +Tutorial: Adding a new frame/Making text flow between two frames +Now we will add a new text frame to our document for our first article. +Step 14: Begin by selecting +InsertText +Frame from the menubar. + + +Screen shot + +The pointer has changed to cross-hairs. You can draw +your new text box with this cursor. Start by placing the pointer at one +corner. Click and hold the left mouse +button. Drag the mouse diagonally. An outline will appear which +represents your new text frame. When you have a text frame of +reasonable size, release the left mouse +button. + + +Screen shot + +It is not important if your text box does not resemble +the example for the purposes of this tutorial. + +When you release the left +mouse button, a new dialog box appears. + + +This dialog box lists all the current frame sets and has a radio button to create a +new frame set (default value). By selecting the default value, you will +create a new frame set (text will not flow from any other frame into this +frame). + +Notice that the default name for this frameset is +Text Frameset 3 + +Step 15: For the purposes of this tutorial, the default value of +Create a new frameset is good. Simply select +OK. + + +Screen shot + +Now you can see your new frame has been created. It is called +Text Frameset 3 + +Now we are going to create another small frame right next to this one. + +Step 16: Select InsertText +Frame. + + +Screen shot + +Again using the crosshair pointer, draw another small frame near the first one. + + +Screen shot + +A dialog box will appear. + +Step 17: Select Text Frameset 3 by clicking with the &LMB;. + + +Screen shot + +Step 18: Select OK. + + +Screen shot + +What you have just done, is connect this new textframe, to the last frame you created. + To test this: + +Step 19: Click once inside the leftmost frame with the &LMB;. + + +Screen shot + +Step 20: Begin typing. You will need to type quite a bit, but +keep typing. When you run out of space in the text frame, you will see +your new text is moved immediately into your new text frame. + + +Screen shot + + + + +Tutorial: Deleting a frame + +Now we will delete an unneeded frame. We will delete +the long text frame on the right side of the page. + +Step 21: Place the mouse pointer over the frame border of the right +hand text frame (Remember: watch for the pointer to change), and click with the &LMB;. + + +Screen shot + +This selects the frame. + +Step 22: Select +FramesDelete +Frame. + + +Screen shot + +A small dialog box appears, checking that you really intended to delete this frame. +Step 23: Select Delete. + +This deletes the frame. + + + +Tutorial: Summary + +Hopefully this tutorial has introduced you to the most basic tasks in &kword;. + +At this point, you have : + + +Started a new document using a template +Added text to a frame. +Resized text. +Created, moved, resized and deleted frames. + +The purpose of this tutorial was not to explore every aspect of &kword;, but to +introduce you to the bare essentials. Hopefully you understand the basic manipulation +of frames. From this point, you can refer to the specific sections of the manual for +help, tips and advanced features of &kword;. + + diff --git a/doc/kword/undl.png b/doc/kword/undl.png new file mode 100644 index 000000000..601137756 Binary files /dev/null and b/doc/kword/undl.png differ diff --git a/doc/kword/undo.png b/doc/kword/undo.png new file mode 100644 index 000000000..6fa539ea1 Binary files /dev/null and b/doc/kword/undo.png differ diff --git a/doc/kword/value.png b/doc/kword/value.png new file mode 100644 index 000000000..3cc80d139 Binary files /dev/null and b/doc/kword/value.png differ diff --git a/doc/kword/viewsize.png b/doc/kword/viewsize.png new file mode 100644 index 000000000..ac2fdc48e Binary files /dev/null and b/doc/kword/viewsize.png differ diff --git a/doc/kword/wbw.png b/doc/kword/wbw.png new file mode 100644 index 000000000..62f4daa53 Binary files /dev/null and b/doc/kword/wbw.png differ diff --git a/doc/kword/wpfmtpg1.png b/doc/kword/wpfmtpg1.png new file mode 100644 index 000000000..97710feb4 Binary files /dev/null and b/doc/kword/wpfmtpg1.png differ diff --git a/doc/kword/wpfmtpg2.png b/doc/kword/wpfmtpg2.png new file mode 100644 index 000000000..51ce12a1a Binary files /dev/null and b/doc/kword/wpfmtpg2.png differ diff --git a/doc/kword/wpfmtpg3.png b/doc/kword/wpfmtpg3.png new file mode 100644 index 000000000..d4e3f9e3c Binary files /dev/null and b/doc/kword/wpfmtpg3.png differ diff --git a/doc/kword/zoom.png b/doc/kword/zoom.png new file mode 100644 index 000000000..694455ec1 Binary files /dev/null and b/doc/kword/zoom.png differ diff --git a/doc/thesaurus/Makefile.am b/doc/thesaurus/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/thesaurus/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/thesaurus/index.docbook b/doc/thesaurus/index.docbook new file mode 100644 index 000000000..bd799022f --- /dev/null +++ b/doc/thesaurus/index.docbook @@ -0,0 +1,150 @@ + + + + + +]> + + + +&kthesaurus; + + + +Daniel +Naber +
    daniel.naber@t-online.de
    +
    + +
    + +2003-04-12 +0.95.00 + + +2002 +2003 +Daniel Naber + + + + +&kthesaurus; lists words related to a given term and offers a user interface +to &wordnet;, a powerful lexical reference system. By default, only the +English language is supported. + + + + +KDE +thesaurus +WordNet +synonyms +dictionary +lexicon +English +words + + +
    + + + +The Thesaurus Tab + +The Thesaurus tab offers a small thesaurus, +built from a subset of &wordnet;. +The results are listed in three +categories: Synonyms, More General +Words (hypernyms), More Specific +Words (hyponyms). Synonyms are words with a very similar meaning. +They do not necessarily apply to all senses of each word, so you cannot +always replace a word with any synonym. + +You can double click on a word to search for its synonyms &etc;. +You can also type a word directly into the Search for: +box at the top and press +Return. The word which is currently visible in the +Replace with: box at the bottom is the one that will +be used if you click on Replace. + +&kthesaurus; can be used as a standalone application, but it can also be +used from other applications (like &kword;, typically by right clicking +on a word and selecting Show related words). +The Replace button will only be visible +on a word and selecting Show Related Words). +The Replace with: button will only be visible +if &kthesaurus; is called from another application. + +We have to keep the data file small so that it can be +included in &koffice; — this introduces several limitations +(compared to &wordnet;): + + +Only exact matches are found, ⪚ if you search for a plural +form nothing will be found. +Many not so common words have been removed. +It doesn't distinguish between parts of speech, e.g. verbs and +nouns are mixed up in the lists of words. +It won't separate the different meanings words can have. +Adjectives don't really have a more general / more specific +meaning, so one word may appear in more than one list at the same time. + + +On the other hand, a few words have been added (function words like if +and very few words specific to &kde;). + +Please do not report bugs in the thesaurus +to the &wordnet; project, but to &kde;. + + + + + +Using languages besides English + +By default, only the English language is supported +in &kthesaurus;. You can check out +the +KOffice download page to see which other languages +are available. + + + + + +The &wordnet; tab + +The &wordnet; tab provides a user interface +to a local installation of &wordnet; 1.7. +&wordnet; is an online lexical reference +system whose design is inspired by current psycholinguistic theories +of human lexical memory. The &kthesaurus; user interface offers nearly all options +which are available on the command line. It calls the wn binary, +which has to be in your PATH. + +To learn more about &wordnet;, please see the &wordnet; man pages +or have a look at the &wordnet; homepage. + + + + + + +Copyright and Licensing + + +&kthesaurus; and this documentation is copyrighted by Daniel Naber. + + + +&underFDL; +&underGPL; + + + + +&documentation.index; + +
    diff --git a/example/Makefile.am b/example/Makefile.am new file mode 100644 index 000000000..55b98290f --- /dev/null +++ b/example/Makefile.am @@ -0,0 +1,38 @@ + +INCLUDES = $(KOFFICE_INCLUDES) $(all_includes) + +## The part +kde_module_LTLIBRARIES = libexamplepart.la +libexamplepart_la_SOURCES = example_part.cc \ + example_view.cc example_factory.cc +libexamplepart_la_LDFLAGS = $(KDE_PLUGIN) +libexamplepart_la_LIBADD = $(LIB_KOFFICEUI) + +## The kdeinit loadable module and executable +kdeinit_LTLIBRARIES = example.la +lib_LTLIBRARIES = +bin_PROGRAMS = +example_la_SOURCES = main.cc +example_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +example_la_LIBADD = $(LIB_KOFFICEUI) + +METASOURCES = AUTO + +kdelnk_DATA = example.desktop +kdelnkdir = $(kde_appsdir)/Office + +# Note: for your application, the mime type should be defined in +# kdelibs CVS HEAD and a compatibility entry should be added in +# the directory koffice/mimetypes/kde?? +# where ?? is the version number of the last stable kde(libs) release. +kdemime_DATA = x-vnd.kde.example.desktop +kdemimedir = $(kde_mimedir)/application + +rc_DATA = example.rc example_readonly.rc +rcdir = $(kde_datadir)/example + +messages: rc.cpp + $(XGETTEXT) rc.cpp *.cc example_aboutdata.h -o $(podir)/example.pot +kde_services_DATA = examplepart.desktop + +include $(top_srcdir)/admin/Doxyfile.am diff --git a/example/README b/example/README new file mode 100644 index 000000000..8b3933fc4 --- /dev/null +++ b/example/README @@ -0,0 +1,2 @@ +If you want this example to be compiled (or if you want to compile your app +based on that example), remove the 'configure.in.in' file! \ No newline at end of file diff --git a/example/configure.in.in b/example/configure.in.in new file mode 100644 index 000000000..904df8069 --- /dev/null +++ b/example/configure.in.in @@ -0,0 +1,4 @@ +dnl This is here so that example isn't compiled and intalled by default. +dnl Do NOT put this file in your application, if you want it compiled ! + +DO_NOT_COMPILE="$DO_NOT_COMPILE example" diff --git a/example/configure.in.in.koffice b/example/configure.in.in.koffice new file mode 100644 index 000000000..69d9f75ba --- /dev/null +++ b/example/configure.in.in.koffice @@ -0,0 +1,108 @@ +dnl Rename this file configure.in.in to have a check for KOffice in during configure + +dnl +dnl Check for koffice. Argument is the minimum required version, in the form a.b.c. +dnl This check *aborts* if koffice wasn't found or was too old. +dnl If you only have an optional koffice requirement you'll have to change the test. +dnl +AC_DEFUN(AC_PATH_KOFFICE, +[ + dnl TODO: use AC_CACHE_VAL + + if test -z "$1"; then + koffice_minver_maj=1 + koffice_minver_min=2 + koffice_minver_pat=94 + else + koffice_minver_maj=`echo "$1" | sed -e "s/^\(.*\)\..*\..*$/\1/"` + koffice_minver_min=`echo "$1" | sed -e "s/^.*\.\(.*\)\..*$/\1/"` + koffice_minver_pat=`echo "$1" | sed -e "s/^.*\..*\.\(.*\)$/\1/"` + fi + + AC_REQUIRE([AC_PATH_QT]) + + AC_MSG_CHECKING([for KOffice]) + + koffice_incdir=$kde_includes + koffice_libdir=$kde_libraries + + AC_ARG_WITH(koffice-includes, + [ --with-koffice-includes=DIR where include files for KOffice are installed ], + [ koffice_incdir="$withval"] ) + AC_ARG_WITH(koffice-libs, + [ --with-koffice-libs=DIR where libs for KOffice are installed ], + [ koffice_libdir="$withval"] ) + + if ! test -f "$koffice_incdir/kofficeversion.h"; then + AC_MSG_ERROR([Cannot find KOffice headers in $ac_koffice_includes. Please check your installation, or use --with-koffice-includes.]) + fi + + AC_LANG_SAVE + AC_LANG_CPLUSPLUS + + ac_cxxflags_safe="$CXXFLAGS" + ac_ldflags_safe="$LDFLAGS" + ac_libs_safe="$LIBS" + CXXFLAGS="$CXXFLAGS -I$koffice_incdir $KDE_INCLUDES $all_includes" + LDFLAGS="$LDFLAGS $KDE_LDFLAGS $QT_LDFLAGS $all_libraries $USER_LDFLAGS $KDE_MT_LDFLAGS" + LIBS="$LIBS -lkofficeui $LIBQT" + + AC_TRY_COMPILE( + [ +#include "confdefs.h" +#include +#if ! KOFFICE_IS_VERSION($koffice_minver_maj,$koffice_minver_min,$koffice_minver_pat) +#error 1 +#endif + ], + [], + [ have_koffice="yes" ], + [ + have_koffice="no"; dnl in case someone wants to turn the error below into a warning + AC_MSG_ERROR("Your KOffice version is too old. Please upgrade to at least $koffice_minver_maj.$koffice_minver_min.$koffice_minver_pat") + ]) + + dnl Ok it's the right version. Now, does it link ok? + + cat > conftest.$ac_ext < +int main( int, char ** ) +{ + KoApplication app; + return 0; +} +EOF + + if AC_TRY_EVAL(ac_link) && test -s conftest; then + rm -f conftest* + else + have_koffice="no" + rm -f conftest* + AC_MSG_ERROR([Cannot link small KOffice application. For more details look at config.log]) + fi + + CXXFLAGS="$ac_cxxflags_safe" + LDFLAGS="$ac_ldflags_safe" + LIBS="$ac_libs_safe" + + AC_LANG_RESTORE + + dnl Success, prepare the variables for the Makefile.am + + KOFFICE_INCLUDES="" + if test "$koffice_incdir" != "/usr/include"; then + KOFFICE_INCLUDES="-I$koffice_incdir" + fi + KOFFICE_LDFLAGS="" + if test "$koffice_libdir" != "/usr/lib"; then + KOFFICE_LDFLAGS="-L$koffice_libdir" + fi + AC_SUBST(KOFFICE_LDFLAGS) + + LIB_KOFFICE="-lkofficeui" + AC_SUBST(LIB_KOFFICE) + + AC_MSG_RESULT([libraries $koffice_libdir, headers $koffice_incdir]) +]) + +AC_PATH_KOFFICE diff --git a/example/example.desktop b/example/example.desktop new file mode 100644 index 000000000..e8c401563 --- /dev/null +++ b/example/example.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Name=KOffice Example Application +Name[ar]=تطبيق مثالي لِــ KOffice +Name[bg]=Примерна програма за KOffice +Name[br]=Meziant skouer KOffice +Name[ca]=Aplicació KOffice d'exemple +Name[cs]=Příklad KOffice aplikace +Name[cy]=Cymhwysiad Enghreifftiol KOffice +Name[da]=KOffice eksempel-program +Name[de]=KOffice-Beispielprogramm +Name[el]=Παράδειγμα εφαρμογής του KOffice +Name[eo]=KOffice Ekzempla Aplikaĵo +Name[es]=Aplicación de ejemplo de KOffice +Name[et]=KOffice'i näidisrakendus +Name[eu]=KOffice-en adibidezko aplikazioa +Name[fa]=کاربرد نمونۀ KOffice +Name[fi]=KOfficen esimerkkiohjelma +Name[fr]=Application-exemple KOffice +Name[fy]=Foarbyldapplikaasje foar KOffice +Name[ga]=Feidhmchlár Samplach KOffice +Name[gl]=Aplicación Exemplo de KOffice +Name[he]=תוכנית לדוגמה של KOffice +Name[hi]=के-ऑफ़िस उदाहरण अनुप्रयोग +Name[hr]=Primjer aplikacije za KOffice +Name[hu]=KOffice mintaalkalmazás +Name[is]=KOffice sýniforrit +Name[it]=Applicazione KOffice di esempio +Name[ja]=KOffice サンプルアプリケーション +Name[km]=កម្មវិធី​ឧទាហរណ៍​សម្រាប់ KOffice +Name[lv]=KOffice programmas piemērs +Name[ms]=Aplikasi Contoh KOffice +Name[nb]=Eksempelprogram for KOffice +Name[nds]=Bispeelprogramm för KOffice +Name[ne]=केडीई कार्यालय उदाहरण अनुप्रयोग +Name[nl]=Voorbeeldtoepassing voor KOffice +Name[nn]=Dømeprogram for KOffice +Name[pa]=KOffice ਉਦਾਹਰਨ ਕਾਰਜ +Name[pl]=Przykładowy program KOffice +Name[pt]=Aplicação Exemplo do KOffice +Name[pt_BR]=Aplicativo de Exemplo do KOffice +Name[ro]=Exemplu de aplicaţie KOffice +Name[ru]=Пример приложения KOffice +Name[se]=KOffice-ovdamearkaprográmma +Name[sk]=Príklad aplikácie KOffice +Name[sl]=Vzorčni program KOffice +Name[sr]=Пример KOffice-овог програма +Name[sr@Latn]=Primer KOffice-ovog programa +Name[sv]=Koffice-exempelprogram +Name[ta]=K office எடுத்துக்காட்டு பயன்பாடுகள் +Name[tg]=Нусхаи Барномаи KOffice +Name[tr]=Koffice Örnek Uygulama +Name[uk]=Приклад програми KOffice +Name[uz]=KOffice namuna dasturi +Name[uz@cyrillic]=KOffice намуна дастури +Name[wa]=Programe di mostraedje di KOffice +Name[zh_CN]=KOffice 应用程序范例 +Name[zh_TW]=KOffice 範例應用程式 +Exec=example +MimeType=application/x-example +Type=Application +Icon=example +X-KDE-NativeMimeType=application/x-example diff --git a/example/example.rc b/example/example.rc new file mode 100644 index 000000000..b3339591f --- /dev/null +++ b/example/example.rc @@ -0,0 +1,12 @@ + + + Edit + + + + +Edit + + + + diff --git a/example/example_aboutdata.h b/example/example_aboutdata.h new file mode 100644 index 000000000..a4ed180d0 --- /dev/null +++ b/example/example_aboutdata.h @@ -0,0 +1,42 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef EXAMPLE_ABOUTDATA +#define EXAMPLE_ABOUTDATA + +#include +#include + +static const char* description=I18N_NOOP("Example KOffice Program"); +static const char* version="0.1"; + +KAboutData * newExampleAboutData() +{ + // Change this, of course + // The first argument of the KAboutData constructor is the instance name. + // It is very important, it's what's used for many things, like the subdir in share/apps, etc. + // It must also match the name of the application's .desktop file. + KAboutData * aboutData=new KAboutData( "example", I18N_NOOP("Example"), + version, description, KAboutData::License_GPL, + "(c) 1998-2000, Torben Weis"); + aboutData->addAuthor("Torben Weis",0, "weis@kde.org"); + return aboutData; +} + +#endif diff --git a/example/example_factory.cc b/example/example_factory.cc new file mode 100644 index 000000000..e3b46cf31 --- /dev/null +++ b/example/example_factory.cc @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +K_EXPORT_COMPONENT_FACTORY( libexamplepart, ExampleFactory ) + +KInstance* ExampleFactory::s_global = 0L; +KAboutData* ExampleFactory::s_aboutData = 0L; + +ExampleFactory::ExampleFactory( QObject* parent, const char* name ) + : KoFactory( parent, name ) +{ + global(); +} + +ExampleFactory::~ExampleFactory() +{ + delete s_aboutData; + s_aboutData = 0L; + delete s_global; + s_global = 0L; +} + +KParts::Part* ExampleFactory::createPartObject( QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name, const char* classname, const QStringList & ) +{ + // If classname is "KoDocument", our host is a koffice application + // otherwise, the host wants us as a simple part, so switch to readonly and single view. + bool bWantKoDocument = ( strcmp( classname, "KoDocument" ) == 0 ); + + // parentWidget and widgetName are used by KoDocument for the "readonly+singleView" case. + ExamplePart *part = new ExamplePart( parentWidget, widgetName, parent, name, !bWantKoDocument ); + + if ( !bWantKoDocument ) + part->setReadWrite( false ); + + return part; +} + +KAboutData* ExampleFactory::aboutData() +{ + if ( !s_aboutData ) + s_aboutData = newExampleAboutData(); + return s_aboutData; +} + +KInstance* ExampleFactory::global() +{ + if ( !s_global ) + { + s_global = new KInstance( aboutData() ); + // Add any application-specific resource directories here + + // Tell the iconloader about share/apps/koffice/icons + s_global->iconLoader()->addAppDir("koffice"); + } + return s_global; +} + +#include diff --git a/example/example_factory.h b/example/example_factory.h new file mode 100644 index 000000000..1df863252 --- /dev/null +++ b/example/example_factory.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef EXAMPLE_FACTORY_H +#define EXAMPLE_FACTORY_H + +#include + +class KInstance; +class KAboutData; + +class ExampleFactory : public KoFactory +{ + Q_OBJECT +public: + ExampleFactory( QObject* parent = 0, const char* name = 0 ); + ~ExampleFactory(); + + virtual KParts::Part *createPartObject( QWidget *parentWidget = 0, const char *widgetName = 0, QObject *parent = 0, const char *name = 0, const char *classname = "KoDocument", const QStringList &args = QStringList() ); + + static KInstance* global(); + + // _Creates_ a KAboutData but doesn't keep ownership + static KAboutData* aboutData(); + +private: + static KInstance* s_global; + static KAboutData* s_aboutData; +}; + +#endif diff --git a/example/example_part.cc b/example/example_part.cc new file mode 100644 index 000000000..e459040a4 --- /dev/null +++ b/example/example_part.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "example_part.h" +#include "example_factory.h" +#include "example_view.h" + +#include + +ExamplePart::ExamplePart( QWidget *parentWidget, const char *widgetName, QObject* parent, const char* name, bool singleViewMode ) + : KoDocument( parentWidget, widgetName, parent, name, singleViewMode ) +{ + setInstance( ExampleFactory::global(), false ); +} + +bool ExamplePart::initDoc(InitDocFlags flags, QWidget* parentWidget) +{ + // If nothing is loaded, do initialize here + // Most KOffice applications use the template dialog here, with code like: +/* + KoTemplateChooseDia::DialogType dlgtype; + if (initDocFlags() != KoDocument::InitDocFileNew ) + dlgtype = KoTemplateChooseDia::Everything; + else + dlgtype = KoTemplateChooseDia::OnlyTemplates; + + KoTemplateChooseDia::ReturnType ret = KoTemplateChooseDia::choose( + .... ) +*/ + return TRUE; +} + +KoView* ExamplePart::createViewInstance( QWidget* parent, const char* name ) +{ + return new ExampleView( this, parent, name ); +} + +bool ExamplePart::loadXML( QIODevice *, const QDomDocument & ) +{ + // TODO load the document from the QDomDocument + return true; +} + +QDomDocument ExamplePart::saveXML() +{ + // TODO save the document into a QDomDocument + return QDomDocument(); +} + +bool ExamplePart::loadOasis( const QDomDocument & doc, KoOasisStyles& oasisStyles, + const QDomDocument & settings, KoStore* store ) +{ + // TODO load the document from the QDomDocument + return true; +} + +bool ExamplePart::saveOasis( KoStore* store, KoXmlWriter* manifestWriter ) +{ + // TODO save the document to the KoStore; + return true; +} + +void ExamplePart::paintContent( QPainter& painter, const QRect& rect, bool /*transparent*/, + double /*zoomX*/, double /*zoomY*/ ) +{ + // ####### handle transparency + + // Need to draw only the document rectangle described in the parameter rect. + int left = rect.left() / 20; + int right = rect.right() / 20 + 1; + int top = rect.top() / 20; + int bottom = rect.bottom() / 20 + 1; + + for( int x = left; x < right; ++x ) + painter.drawLine( x * 20, top * 20, x * 20, bottom * 20 ); + for( int y = left; y < right; ++y ) + painter.drawLine( left * 20, y * 20, right * 20, y * 20 ); +} + +#include "example_part.moc" diff --git a/example/example_part.h b/example/example_part.h new file mode 100644 index 000000000..5945f8e4d --- /dev/null +++ b/example/example_part.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef EXAMPLE_PART_H +#define EXAMPLE_PART_H + +#include + +class ExamplePart : public KoDocument +{ + Q_OBJECT +public: + ExamplePart( QWidget *parentWidget = 0, const char *widgetName = 0, QObject* parent = 0, const char* name = 0, bool singleViewMode = false ); + + virtual void paintContent( QPainter& painter, const QRect& rect, bool transparent = FALSE, double zoomX = 1.0, double zoomY = 1.0 ); + + virtual bool initDoc(InitDocFlags flags, QWidget* parentWidget=0); + + virtual bool loadXML( QIODevice *, const QDomDocument & ); + virtual QDomDocument saveXML(); + + virtual bool loadOasis( const QDomDocument & doc, KoOasisStyles& oasisStyles, + const QDomDocument & settings, KoStore* store ); + virtual bool saveOasis( KoStore* store, KoXmlWriter* manifestWriter ); + +protected: + virtual KoView* createViewInstance( QWidget* parent, const char* name ); +}; + +#endif diff --git a/example/example_readonly.rc b/example/example_readonly.rc new file mode 100644 index 000000000..fab57057d --- /dev/null +++ b/example/example_readonly.rc @@ -0,0 +1,7 @@ + + + &Edit + + + + diff --git a/example/example_view.cc b/example/example_view.cc new file mode 100644 index 000000000..2e97a2065 --- /dev/null +++ b/example/example_view.cc @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "example_view.h" +#include "example_factory.h" +#include "example_part.h" + +#include +#include +#include +#include +#include +#include + +ExampleView::ExampleView( ExamplePart* part, QWidget* parent, const char* name ) + : KoView( part, parent, name ) +{ + setInstance( ExampleFactory::global() ); + if ( !part->isReadWrite() ) // readonly case, e.g. when embedded into konqueror + setXMLFile( "example_readonly.rc" ); // simplified GUI + else + setXMLFile( "example.rc" ); + KStdAction::copy(this, SLOT( copy() ), actionCollection(), "copy" ); + KStdAction::cut(this, SLOT( cut() ), actionCollection(), "cut" ); + // Note: Prefer KStdAction::* to any custom action if possible. + //m_cut = new KAction( i18n("&Cut"), "editcut", 0, this, SLOT( cut() ), + // actionCollection(), "cut"); +} + +void ExampleView::paintEvent( QPaintEvent* ev ) +{ + QPainter painter; + painter.begin( this ); + + // ### TODO: Scaling + + // Let the document do the drawing + koDocument()->paintEverything( painter, ev->rect(), FALSE, this ); + + painter.end(); +} + +void ExampleView::updateReadWrite( bool /*readwrite*/ ) +{ +#ifdef __GNUC__ +#warning TODO +#endif +} + +void ExampleView::copy() +{ + kdDebug(31000) << "ExampleView::copy(): COPY called" << endl; +} + +void ExampleView::cut() +{ + kdDebug(31000) << "ExampleView::cut(): CUT called" << endl; +} + +#include "example_view.moc" diff --git a/example/example_view.h b/example/example_view.h new file mode 100644 index 000000000..932af33aa --- /dev/null +++ b/example/example_view.h @@ -0,0 +1,49 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999, 2000 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef EXAMPLE_VIEW +#define EXAMPLE_VIEW + +#include + +class KAction; +class QPaintEvent; + +class ExamplePart; + +class ExampleView : public KoView +{ + Q_OBJECT +public: + ExampleView( ExamplePart* part, QWidget* parent = 0, const char* name = 0 ); + +protected slots: + void cut(); + void copy(); + +protected: + void paintEvent( QPaintEvent* ); + + virtual void updateReadWrite( bool readwrite ); + +private: + //KAction* m_cut; +}; + +#endif diff --git a/example/examplepart.desktop b/example/examplepart.desktop new file mode 100644 index 000000000..a96fa13e1 --- /dev/null +++ b/example/examplepart.desktop @@ -0,0 +1,59 @@ +[Desktop Entry] +Name=KOffice Example Component +Name[ar]=مكوّن KOffice مثالي +Name[bg]=Примерен модул за KOffice +Name[ca]=Component KOffice d'exemple +Name[cs]=Ukázková KOffice komponenta +Name[cy]=Cydran Enghreifftiol KOffice +Name[da]=KOffice eksempel-komponent +Name[de]=KOffice-Beispielkomponente +Name[el]=Παράδειγμα συστατικού του KOffice +Name[eo]=KOffice Ekzempla Komponanto +Name[es]=Componente de ejemplo de KOffice +Name[et]=KOffice'i näidiskomponent +Name[eu]=KOffice-en adibidezko osagaia +Name[fa]=مؤلفۀ نمونۀ KOffice +Name[fi]=KOfficen esimerkkikomponentti +Name[fr]=Composant-exemple KOffice +Name[fy]=Foarbyldkomponint foar KOffice +Name[ga]=Comhpháirt Shamplach KOffice +Name[gl]=Componente Exemplo de KOffice +Name[he]=רכיב לדוגמה של KOffice +Name[hi]=के-ऑफ़िस उदाहरण अवयव +Name[hr]=Primjer komponente za KOffice +Name[hu]=KOffice mintakomponens +Name[is]=KOffice sýnihluti +Name[it]=Componente di esempio di KOffice +Name[ja]=KOffice サンプルコンポーネント +Name[km]=សមាសភាគ​ឧទាហរណ៍​សម្រាប់ KOffice +Name[lv]=KOffice piemēra komponents +Name[ms]=Komponen Contoh KOffice +Name[nb]=Eksempelkomponent for KOffice +Name[nds]=Bispeelmodulen för KOffice +Name[ne]=केडीई कार्यालय उदाहरण अवयव +Name[nl]=Voorbeeldcomponent voor KOffice +Name[nn]=Dømekomponent for KOffice +Name[pa]=KOffice ਉਦਾਹਰਨ ਭਾਗ +Name[pl]=Przykładowy komponent KOffice +Name[pt]=Componente Exemplo do KOffice +Name[pt_BR]=Componente de Exemplo do KOffice +Name[ru]=Пример компонента KOffice +Name[se]=KOffice-ovdamearkaoassi +Name[sk]=Príklad modulu KOffice +Name[sl]=Vzorčna komponenta KOffice +Name[sr]=Пример KOffice-ове компоненте +Name[sr@Latn]=Primer KOffice-ove komponente +Name[sv]=Koffice-exempelkomponent +Name[ta]=K office எடுத்துக்காட்டு பயன்பாடுகள் +Name[tg]=Мисоли Барномаи KOffice +Name[tr]=KOffice Örnek Bileşeni +Name[uk]=Приклад компонента KOffice +Name[wa]=Componint di mostraedje di KOffice +Name[zh_CN]=KOffice 组件范例 +Name[zh_TW]=KOffice 範例元件 +X-KDE-Library=libexamplepart +MimeType=application/x-example +Type=Service +ServiceTypes=KOfficePart,KParts/ReadOnlyPart,KParts/ReadWritePart +X-KDE-NativeMimeType=application/x-example +Icon=example diff --git a/example/main.cc b/example/main.cc new file mode 100644 index 000000000..e12a1242d --- /dev/null +++ b/example/main.cc @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 1998, 1999 Torben Weis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include "example_aboutdata.h" +#include + +static const KCmdLineOptions options[]= +{ + {"+[file]", I18N_NOOP("File to open"),0}, + KCmdLineLastOption +}; + +extern "C" EXAMPLE_EXPORT int kdemain( int argc, char **argv ) +{ + KCmdLineArgs::init( argc, argv, newExampleAboutData() ); + KCmdLineArgs::addCmdLineOptions( options ); + KoApplication app; + + if (!app.start()) // parses command line args, create initial docs and shells + return 1; + return app.exec(); +} + diff --git a/example/x-vnd.kde.example.desktop b/example/x-vnd.kde.example.desktop new file mode 100644 index 000000000..9140b74f8 --- /dev/null +++ b/example/x-vnd.kde.example.desktop @@ -0,0 +1,10 @@ +# KDE Config File +[Desktop Entry] +MimeType=application/x-vnd.kde.example +#Comment=... +Type=MimeType +Patterns=*.xmpl; +X-KDE-AutoEmbed=false +[Property::X-KDE-NativeExtension] +Type=QString +Value=.xmpl diff --git a/filters/Makefile.am b/filters/Makefile.am new file mode 100644 index 000000000..4e18acc72 --- /dev/null +++ b/filters/Makefile.am @@ -0,0 +1,48 @@ + +if compile_filter_KARBON +KARBONDIR = karbon +endif + +if include_XSLTFILTERS +XSLTFILTERDIR = xsltfilter +endif + +if compile_filter_KWORD +KWORDDIR = kword +endif + +if compile_filter_KPRESENTER +KPRESENTERDIR = kpresenter olefilters +endif + +if compile_filter_KSPREAD +KSPREADDIR = kspread +endif + +if compile_filter_KCHART +KCHARTDIR = kchart +endif + +if compile_filter_KFORMULA +KFORMULADIR = kformula +endif + +if compile_filter_KUGAR +KUGARDIR = kugar +endif + +if compile_filter_KRITA +KRITADIR = krita +endif + +if compile_filter_KIVIO +KIVIODIR = kivio +endif + +SUBDIRS = generic_wrapper libdialogfilter liboofilter $(KSPREADDIR) $(KCHARTDIR) $(KWORDDIR) $(KPRESENTERDIR) $(XSLTFILTERDIR) $(KFORMULADIR) $(KARBONDIR) $(KUGARDIR) $(KRITADIR) $(KIVIODIR) + +messages: + $(EXTRACTRC) `find . -name \*.ui` > rc.cpp + $(XGETTEXT) `find . -name \*.cpp -o -name \*.cc` -o $(podir)/kofficefilters.pot + +include $(top_srcdir)/admin/Doxyfile.am diff --git a/filters/configure.in.mid b/filters/configure.in.mid new file mode 100644 index 000000000..a996cfb73 --- /dev/null +++ b/filters/configure.in.mid @@ -0,0 +1,58 @@ +AC_MSG_CHECKING([for filters to be compiled]) + +if test -s $srcdir/inst-apps ; then + SUBDIRLIST=`cat $srcdir/inst-apps` +else + SUBDIRLIST=`cat $srcdir/subdirs` +fi + +# fallback (KDE_CREATE_SUBDIRLIST has this fallback, so I have put it here too.) +if test -z "$SUBDIRLIST" ; then + SUBDIRLIST=`ls -1 $srcdir` +fi + +# first check which main apllication we could compile +for args in $SUBDIRLIST ; do + case $args in + kword) COMPILE_FILTER_KWORD="$args " ;; + kspread) COMPILE_FILTER_KSPREAD="$args " ;; + kchart) COMPILE_FILTER_KCHART="$args " ;; + karbon) COMPILE_FILTER_KARBON="$args " ;; + kpresenter) COMPILE_FILTER_KPRESENTER="$args " ;; + kformula) COMPILE_FILTER_KFORMULA="$args " ;; + kugar) COMPILE_FILTER_KUGAR="$args " ;; + krita) COMPILE_FILTER_KRITA="$args " ;; + kivio) COMPILE_FILTER_KIVIO="$args " ;; + kexi) COMPILE_FILTER_KEXI="$args " ;; + esac +done + +# now remove the applications the user has asked not to compile +for args in $DO_NOT_COMPILE ; do + case $args in + kword) COMPILE_FILTER_KWORD= ;; + kspread) COMPILE_FILTER_KSPREAD= ;; + kchart) COMPILE_FILTER_KCHART= ;; + karbon) COMPILE_FILTER_KARBON= ;; + kpresenter) COMPILE_FILTER_KPRESENTER= ;; + kformula) COMPILE_FILTER_KFORMULA= ;; + kugar) COMPILE_FILTER_KUGAR= ;; + krita) COMPILE_FILTER_KRITA= ;; + kivio) COMPILE_FILTER_KIVIO= ;; + kexi) COMPILE_FILTER_KEXI= ;; + esac +done + +USERFEEDBACKCOMPILE="$COMPILE_FILTER_KWORD$COMPILE_FILTER_KSPREAD$COMPILE_FILTER_KCHART$COMPILE_FILTER_KARBON$COMPILE_FILTER_KPRESENTER$COMPILE_FILTER_KFORMULA$COMPILE_FILTER_KUGAR" +AC_MSG_RESULT([$USERFEEDBACKCOMPILE]) + +AM_CONDITIONAL(compile_filter_KWORD, test -n "$COMPILE_FILTER_KWORD") +AM_CONDITIONAL(compile_filter_KSPREAD, test -n "$COMPILE_FILTER_KSPREAD") +AM_CONDITIONAL(compile_filter_KCHART, test -n "$COMPILE_FILTER_KCHART") +AM_CONDITIONAL(compile_filter_KARBON, test -n "$COMPILE_FILTER_KARBON") +AM_CONDITIONAL(compile_filter_KPRESENTER, test -n "$COMPILE_FILTER_KPRESENTER") +AM_CONDITIONAL(compile_filter_KFORMULA, test -n "$COMPILE_FILTER_KFORMULA") +AM_CONDITIONAL(compile_filter_KUGAR, test -n "$COMPILE_FILTER_KUGAR") +AM_CONDITIONAL(compile_filter_KRITA, test -n "$COMPILE_FILTER_KRITA") +AM_CONDITIONAL(compile_filter_KIVIO, test -n "$COMPILE_FILTER_KIVIO") +AM_CONDITIONAL(compile_filter_KEXI, test -n "$COMPILE_FILTER_KEXI") diff --git a/filters/filterstatus.xml b/filters/filterstatus.xml new file mode 100644 index 000000000..6dc476802 --- /dev/null +++ b/filters/filterstatus.xml @@ -0,0 +1,453 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +]> + + + + + + + Five Stars + The filter is stable and works well. + + + Four Stars + The filter generally works well. + + + Three Stars + The filter generally works well, however some features might be missing or might not work correctly yet. + + + Two Stars + The filter generally works although it is not finished, and it may suffer from some instability. + + + One Star + Work has begun on the filter although the code is still at an early stage of development, and does not work properly. + + + Planned + An author has volunteered to work on the filter, although the code does not actually exist yet, or is at a very early stage of development. + + + None + The filter does not currently exist, and nobody is working on it. + + + Abandoned + The status of this filter is unknown, as its development has been abandoned. + + + + KOffice SVN + KOffice Development Version + + + Generic (for all KOffice applications) + + + XSLT + + + + + + KWord + + + AbiWord + + + + + AmiPro + Lotus word processor + + + + + Applix Word + + + + + DocBook + SGML DocBook only + + + + + HTML + HTML 4.01 / XHTML 1.0 + + + + + LaTeX + + + + + MS Write + + + + OpenOffice.org Writer + + + + + Palmdoc + Palm documents + + + + + PDF + Portable Document Format + + + + + Plain text + + + + + RTF + Rich Text Format + + + + + StarWriter + Ariya Hidayat + Marco Zanon + + + + + WML + Wireless markup language + + + + + WordPerfect + WP 5.x and WP 6/7/8 documents, text only + + + + + + KSpread + + + Applix Spreadsheet + + + + + CSV + Comma Separated Values + + + + + dBase + dBase 3 only + + + + + Gnumeric + Part of GNOME Office + + + + + HTML + + + + + LaTeX + + + + + Quattro Pro + + + + + OpenOffice.org Calc + Norbert Andres + + + + + + KPresenter + + Magicpoint + Lukas Tinkl + + + + + OpenOffice.org Impress + + + + + KWord + + + + + + Karbon 14 + + Adobe Illustrator + + + + Kontour + + + + EPS + Encapsulated PostScript + + + + SVG + Scalable Vector Graphics (W3C) + + + + WMF + Windows MetaFile + + + + PNG + + + + Applix Graphics + + + + + MSOD + Microsoft Office Drawing + + + + Xfig + + + + LaTeX + + + + OpenOffice.org Draw + + + + + + Krita Krita can use <a + href="http://imagemagick.org/">ImageMagick</a> + for importing and exporting images. This means that, in + addition to the file formats listed below, Krita can work + with all images that your installation of ImageMagick + supports. This includes all common image file formats, + including the native formats of Photoshop and the Gimp. + <br /> <a + href="http://imagemagick.org/script/formats.php">More + information on file formats supported by + ImageMagick.</a> + + + + PNG + Portable Network Graphics + + + + + JPEG + + + + + TIFF + + + + + RAW + + + + + OpenEXR + + <a href="http://www.openexr.com/">OpenEXR</a> is a high dynamic-range (HDR) format <br /> + developed by <a href="http://www.ilm.com">Industrial Light & Magic</a> + + + + + + PDF + Portable Document Format + + + + + Gimp (XCF) + Native file format of the + <a href="http://www.gimp.org/">Gimp</a> + + + + + + KChart + + Text + Text file (e.g. CSV or tab-delimited) + + + + + PNG + Portable Network Graphics (most graphics programs) + + + + + SVG + Scalable Vector Graphics (W3C) + + + + + + Kexi + + Text + Text file (e.g. CSV or tab-delimited) + + + + Microsoft Access (MDB) + + Available as a + <a href="kexi/mdb.php" + >separate plugin</a> + + + + + + + diff --git a/filters/generic_wrapper/Makefile.am b/filters/generic_wrapper/Makefile.am new file mode 100644 index 000000000..ecb0bf0cf --- /dev/null +++ b/filters/generic_wrapper/Makefile.am @@ -0,0 +1,18 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libgenerickofilter.la + + +libgenerickofilter_la_SOURCES = generic_filter.cc +libgenerickofilter_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libgenerickofilter_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KIO) + +METASOURCES = AUTO + +noinst_HEADERS = generic_filter.h + +service_DATA = generic_filter.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/generic_wrapper/README b/filters/generic_wrapper/README new file mode 100644 index 000000000..102f7a30f --- /dev/null +++ b/filters/generic_wrapper/README @@ -0,0 +1,40 @@ +KOffice Filter Wrapper +====================== + +This is a generic framework for developing KOffice import and export +filters in a scripting language of your choice (Python, Perl, etc). + +Requirements for your filter: +----------------------------- +- do whatever you want with your script, it just has to take two + parameters, the input file and the output file +- provide a .desktop files, containing these mandatory fields: + +Name=My cool filter in Perl +Type=Service +ServiceTypes=KOfficeGenericFilter +Exec=my_filter.pl +X-KDE-Wrapper-Export= +X-KDE-Wrapper-Import= + +- write a suitable Makefile.am + +bin_SCRIPTS = my_filter.pl +service_DATA = my_filter.desktop +servicedir = $(kde_servicesdir) + +- if not already present, write a .desktop file for the external MIME + type + +In doubt, have a look at an example filter in +filters/kpresenter/magicpoint. + +The only shortcoming at the moment is that you have to add these MIME +types to filters/generic_wrapper/generic_filter.desktop file (in the +fields X-KDE-Export resp. X-KDE-Import). + +--- +That's it, have fun :-) + +Lukas Tinkl +SuSE Labs, Czech Republic diff --git a/filters/generic_wrapper/generic_filter.cc b/filters/generic_wrapper/generic_filter.cc new file mode 100644 index 000000000..14830762a --- /dev/null +++ b/filters/generic_wrapper/generic_filter.cc @@ -0,0 +1,127 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "generic_filter.h" + +typedef KGenericFactory GenericFilterFactory; +K_EXPORT_COMPONENT_FACTORY( libgenerickofilter, GenericFilterFactory ) + + +GenericFilter::GenericFilter(KoFilter *, const char *, const QStringList&) : + KoFilter() { +} + +KoFilter::ConversionStatus GenericFilter::convert( const QCString &from, const QCString &to ) +{ + + //find the right script to use + KTrader::OfferList offers = KTrader::self()->query("KOfficeGenericFilter", + "(Type == 'Service') and ('KOfficeGenericFilter' in ServiceTypes) and (exist Exec)"); + + if (offers.isEmpty()) + return KoFilter::NotImplemented; + + KTrader::OfferList::ConstIterator it; + for (it=offers.begin(); it!=offers.end(); ++it) + { + kdDebug() << "Got a filter script, exec: " << (*it)->exec() << + ", imports: " << (*it)->property("X-KDE-Wrapper-Import").toString() << + ", exports: " << (*it)->property("X-KDE-Wrapper-Export").toString() << endl; + if ((*it)->property("X-KDE-Wrapper-Import").toCString()==from + && (*it)->property("X-KDE-Wrapper-Export").toCString()==to) + { + m_exec=(*it)->exec(); + m_from=from; + m_to=to; + break; + } + } + + //decide between import/export + if( m_to == "application/x-kword" || m_to == "application/x-karbon" || + m_to == "application/x-kspread" || m_to == "application/x-kivio" || + m_to == "application/x-kchart" || m_to == "application/x-kpresenter" ) + return doImport(); + else if ( m_from == "application/x-kword" || m_from == "application/x-karbon" || + m_from == "application/x-kspread" || m_from == "application/x-kivio" || + m_from == "application/x-kchart" || m_from == "application/x-kpresenter" ) + return doExport(); + else + return KoFilter::NotImplemented; +} + +KoFilter::ConversionStatus GenericFilter::doImport() +{ + KTempFile temp(QString("genericfilter-")); + temp.setAutoDelete(true); + + QFile tempFile(temp.name()); + + m_out = KoStore::createStore(&tempFile, KoStore::Write); + + if (!m_out || !m_out->open("root")) + { + kdError() << "Unable to create output store!" << endl; + m_out->close(); + return KoFilter::StorageCreationError; + } + else + { + QString exec = m_exec + " " + KProcess::quote(m_chain->inputFile()) + " " + + KProcess::quote(m_chain->outputFile()); + system(QFile::encodeName(exec)); + + kdDebug() << "Executing: " << exec << endl; + + QFile outFile(m_chain->outputFile()); + outFile.open(IO_ReadOnly); + QByteArray outData = outFile.readAll(); + if (outData.size()==0) { + m_out->close(); + return KoFilter::UnexpectedEOF; + } + else { + m_out->write(outData); + m_out->close(); + } + } + + return KoFilter::OK; +} + +KoFilter::ConversionStatus GenericFilter::doExport() +{ + return KoFilter::NotImplemented; +} + +#include "generic_filter.moc" diff --git a/filters/generic_wrapper/generic_filter.desktop b/filters/generic_wrapper/generic_filter.desktop new file mode 100644 index 000000000..1a7c6961d --- /dev/null +++ b/filters/generic_wrapper/generic_filter.desktop @@ -0,0 +1,58 @@ +[Desktop Entry] +Name=Generic KOffice Filter +Name[ar]=مِرْشَح نوعيّ لـ KOffice +Name[bg]=Общ филтър за KOffice +Name[br]=Sil KOffice rummel +Name[ca]=Filtre genèric de KOffice +Name[cs]=Obecný filtr KOffice +Name[cy]=Hidlen generig KOffice +Name[da]=Generisk KOffice-filter +Name[de]=Generischer KOffice-Filter +Name[el]=Γενικευμένο φίλτρο του KOffice +Name[eo]=Komuna KOffice-Filtrilo +Name[es]=Filtro genérico de KOffice +Name[et]=KOffice'i üldine filter +Name[eu]=KOffice-en iragazki generikoa +Name[fa]=پالایۀ عمومی KOffice +Name[fi]=Yleinen KOffice-suodin +Name[fr]=Filtre générique de KOffice +Name[fy]=Algemiene KOffice filter +Name[ga]=Scagaire Ginearálta KOffice +Name[gl]=Filtro xenérico de KOffice +Name[he]=מסנן גנרי של KOffice +Name[hr]=Generički KOffice filtar +Name[hu]=Általános KOffice-szűrő +Name[is]=Almenn KOffice sía +Name[it]=Filtro generico di KOffice +Name[ja]=KOffice ジェネリックフィルタ +Name[km]=តម្រង KOffice ទូទៅ +Name[lt]=Bendras KOffice filtras +Name[lv]=Vispārējs KOffice filtrs +Name[ms]=Penapis KOffice Biasa +Name[nb]=Alment KOffice-filter +Name[nds]=Allgemeen KOffice-Filter +Name[ne]=जेनेरिक केडीई कार्यालय फिल्टर +Name[nl]=Generiek KOffice-filter +Name[nn]=Generelt KOffice-filter +Name[pl]=Ogólny filtr KOffice +Name[pt]=Filtro Genérico do KOffice +Name[pt_BR]=Filtro genérico do KOffice +Name[ro]=Filtru generic KOffice +Name[ru]=Фильтр KOffice +Name[se]=Oppalaš KOffice-silli +Name[sk]=Všeobecný filter KOffice +Name[sl]=Generični filter za KOffice +Name[sr]=KOffice-ов генерички филтер +Name[sr@Latn]=KOffice-ov generički filter +Name[sv]=Generellt Koffice-filter +Name[uk]=Загальний фільтр KOffice +Name[uz]=KOffice umumiy filteri +Name[uz@cyrillic]=KOffice умумий филтери +Name[zh_CN]=KOffice 通用过滤器 +Name[zh_TW]=通用 KOffice 過濾器 +X-KDE-Export=application/x-kpresenter +X-KDE-Import=application/x-magicpoint +X-KDE-Weight=1 +Type=Service +ServiceTypes=KOfficeFilter +X-KDE-Library=libgenerickofilter diff --git a/filters/generic_wrapper/generic_filter.h b/filters/generic_wrapper/generic_filter.h new file mode 100644 index 000000000..21cc73118 --- /dev/null +++ b/filters/generic_wrapper/generic_filter.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __GENERICFILTER_H__ +#define __GENERICFILTER_H__ + +#include +#include + +#include +#include +#include + +class GenericFilter : public KoFilter +{ + Q_OBJECT + +public: + GenericFilter(KoFilter *parent, const char *name, const QStringList&); + virtual ~GenericFilter() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, + const QCString& to ); +private: + KoFilter::ConversionStatus doImport(); + KoFilter::ConversionStatus doExport(); + QString m_to, m_from, m_exec; + KoStore* m_out; +}; + +#endif /* __GENERICFILTER_H__ */ diff --git a/filters/karbon/Makefile.am b/filters/karbon/Makefile.am new file mode 100644 index 000000000..f62023863 --- /dev/null +++ b/filters/karbon/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = eps ai svg png wmf kontour xcf msod oodraw + diff --git a/filters/karbon/ai/Makefile.am b/filters/karbon/ai/Makefile.am new file mode 100644 index 000000000..761feaffd --- /dev/null +++ b/filters/karbon/ai/Makefile.am @@ -0,0 +1,44 @@ +kde_module_LTLIBRARIES = libkarbonaiimport.la + +libkarbonaiimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonaiimport_la_LDFLAGS = \ + $(all_libraries) \ + $(KDE_RPATH) \ + -module -avoid-version -no-undefined + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + $(all_includes) + +service_DATA = karbon_ai_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + aicolor.h \ + aielement.h \ + aiimport.h \ + ailexer.h \ + aiparserbase.h \ + ai88handler.h \ + ai3handler.h \ + karbonaiparserbase.h + +libkarbonaiimport_la_SOURCES = \ + aicolor.cc \ + aielement.cc \ + aiimport.cc \ + ailexer.cc \ + aiparserbase.cc \ + ai88handler.cc \ + ai3handler.cc \ + karbonaiparserbase.cc + +libkarbonaiimport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/ai/ai3handler.cc b/filters/karbon/ai/ai3handler.cc new file mode 100644 index 000000000..ae0252a3a --- /dev/null +++ b/filters/karbon/ai/ai3handler.cc @@ -0,0 +1,74 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "ai3handler.h" + +AI3Handler::AI3Handler(AIParserBase *delegate){ + m_delegate = delegate; +} +AI3Handler::~AI3Handler(){ +} + +bool AI3Handler::handleAIOperation (AIOperation op) { +// PathElement pathElement; +// double fval; + int ival; + + switch (op) { + case AIO_SetWindingOrder : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotWindingOrder (ival); + return true; + break; + case AIO_BeginGroupNoClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (false); + return true; + break; + case AIO_EndGroupNoClip : + if (m_delegate->m_debug) qDebug ("got end group noclip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (false); + if (m_delegate->m_debug) qDebug ("/got end group noclip"); + return true; + break; + case AIO_BeginCombination : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginCombination (); + return true; + break; + case AIO_EndCombination : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndCombination (); + return true; + break; + case AIO_BeginGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (true); + return true; + break; + case AIO_EndGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); + return true; + break; + case AIO_SetFillMode : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillMode((FillMode) m_delegate->getIntValue()); + return true; + break; + default : + return false; + } + return false; +} + diff --git a/filters/karbon/ai/ai3handler.h b/filters/karbon/ai/ai3handler.h new file mode 100644 index 000000000..27f23cec7 --- /dev/null +++ b/filters/karbon/ai/ai3handler.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AI3HANDLER_H +#define AI3HANDLER_H + +#include "aiparserbase.h" + +/** + *@author Dirk Schoenberger + */ + +class AI3Handler { +private: + AIParserBase *m_delegate; +public: + AI3Handler(AIParserBase *delegate); + ~AI3Handler(); + + bool handleAIOperation (AIOperation op); +}; + +#endif diff --git a/filters/karbon/ai/ai88handler.cc b/filters/karbon/ai/ai88handler.cc new file mode 100644 index 000000000..f3cf53a7a --- /dev/null +++ b/filters/karbon/ai/ai88handler.cc @@ -0,0 +1,564 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include "ai88handler.h" + +AI88Handler::AI88Handler(AIParserBase *delegate){ + m_delegate = delegate; +} +AI88Handler::~AI88Handler(){ +} + +bool AI88Handler::handleAIOperation (AIOperation op) { + PathElement pathElement; + double fval; + int ival; + + switch (op) { + case AIO_SetFillColorCMYK : + _handleSetFillColorCMYK(); + return true; + break; + case AIO_SetStrokeColorCMYK : + _handleSetStrokeColorCMYK(); + return true; + break; + case AIO_SetFillColorGray : + _handleSetFillColorGray(); + return true; + break; + case AIO_SetStrokeColorGray : + _handleSetStrokeColorGray(); + return true; + break; + case AIO_SetFillColorCustom : + _handleSetFillColorCustom(); + return true; + break; + case AIO_SetStrokeColorCustom : + _handleSetStrokeColorCustom(); + return true; + break; + case AIO_SetFillPattern : + _handleSetFillPattern(); + return true; + break; + case AIO_SetStrokePattern : + _handleSetStrokePattern(); + return true; + break; + case AIO_SetFillOverprinting : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotFillOverprinting (m_delegate->getBoolValue()); + return true; + break; + case AIO_SetStrokeOverprinting : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotStrokeOverprinting (m_delegate->getBoolValue()); + return true; + break; + case AIO_LockElement : + if (m_delegate->m_miscGStateHandler) m_delegate->m_miscGStateHandler->gotLockNextObject (m_delegate->getBoolValue()); + return true; + break; + case AIO_SetFlatness : + fval = m_delegate->getDoubleValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFlatness (fval); + return true; + break; + case AIO_SetLineCap : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineCaps (ival); + return true; + break; + case AIO_SetLineJoin : + ival = m_delegate->getIntValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineJoin (ival); + return true; + break; + case AIO_SetLineWidth : + fval = kMax(0.2, m_delegate->getDoubleValue()); // Use thinnest pen stroke possible for 0 (Rob) + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotLineWidth (fval); + return true; + break; + case AIO_SetMiterLimit : + fval = m_delegate->getDoubleValue(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotMiterLimit (fval); + return true; + break; + case AIO_SetDash : + _handleSetDash(); + return true; + break; + case AIO_BeginGroupClip : + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotBeginGroup (true); + return true; + break; + case AIO_EndGroupClip : + if (m_delegate->m_debug) qDebug ("got end group clip"); + if (m_delegate->m_structureHandler) m_delegate->m_structureHandler->gotEndGroup (true); + if (m_delegate->m_debug) qDebug ("/got end group clip"); + return true; + + break; + case AIO_MoveTo : + pathElement.petype = PET_MoveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_LineToCorner : + pathElement.petype = PET_LineTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_LineToSmooth : + pathElement.petype = PET_LineTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.pointdata.y = m_delegate->getDoubleValue(); + pathElement.pevalue.pointdata.x = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToCorner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToSmooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC1Corner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC1Smooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y2 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x2 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC2Corner : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Corner; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + case AIO_CurveToOmitC2Smooth : + pathElement.petype = PET_CurveTo; + pathElement.pttype = PT_Smooth; + pathElement.pevalue.bezierdata.y3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x3 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.y1 = m_delegate->getDoubleValue(); + pathElement.pevalue.bezierdata.x1 = m_delegate->getDoubleValue(); + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotPathElement (pathElement); + return true; + break; + + case AIO_PathIgnoreReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(false, true); + return true; + break; + case AIO_PathIgnoreResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(true, true); + return true; + break; + case AIO_PathIgnoreNoReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(false, false); + return true; + break; + case AIO_PathIgnoreNoResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotIgnorePath(true, false); + return true; + break; + case AIO_PathClipPath : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotClipPath(false); + return true; + break; + case AIO_PathFillNonZero : + if (m_delegate->m_pathHandler) + { + m_delegate->m_pathHandler->gotFillMode (FM_NonZero); + m_delegate->m_pathHandler->gotFillPath(false, true); + } + return true; + break; + case AIO_PathFillNonZeroClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(true, true); + return true; + break; + case AIO_PathFillNoReset : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(false, false); + return true; + break; + case AIO_PathFillNoResetClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotFillPath(true, false); + return true; + break; + case AIO_PathStroke : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotStrokePath(false); + return true; + break; + case AIO_PathStrokeClose : + if (m_delegate->m_pathHandler) m_delegate->m_pathHandler->gotStrokePath(true); + return true; + break; + case AIO_PatternDefinition : + _handlePatternDefinition(); + return true; + break; + case AIO_GsaveIncludeDocument : + _handleGsaveIncludeDocument(); + return true; + break; + case AIO_Grestore : + if (m_delegate->m_embeddedHandler) m_delegate->m_embeddedHandler->gotGrestore(); + return true; + break; + case AIO_FontEncoding : + _handleFontEncoding(); + return true; + break; + case AIO_SetCurrentText : + _handleSetCurrentText(); + return true; + break; + case AIO_TextBlockFillStroke : + _handleTextBlock (TO_FillStroke); + return true; + break; + case AIO_TextBlockFill : + _handleTextBlock (TO_Fill); + return true; + break; + case AIO_TextBlockAppend : + _handleTextBlock (TO_Append); + return true; + break; + case AIO_TextBlockIgnore : + _handleTextBlock (TO_Ignore); + return true; + break; + case AIO_TextBlockStroke : + _handleTextBlock (TO_Stroke); + return true; + break; + case AIO_TextOutput : + _handleTextOutput (); + return true; + break; + case AIO_TextBlockEnd : + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextBlockEnd(); + return true; + break; + default : + return false; + } + return false; +} + + +void AI88Handler::_handleSetFillColorCMYK() +{ + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + + if (m_delegate->m_debug) qDebug ("values 1 are %f %f %f %f",c,m,y,k); + AIColor color (c,m,y,k); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetFillPattern() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = m_delegate->getDoubleValue(); + double k = m_delegate->getDoubleValue(); + double r = m_delegate->getDoubleValue(); + double rf = m_delegate->getDoubleValue(); + double angle = m_delegate->getDoubleValue(); + double sy = m_delegate->getDoubleValue(); + double sx = m_delegate->getDoubleValue(); + double py = m_delegate->getDoubleValue(); + double px = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillPattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} + +void AI88Handler::_handleSetStrokePattern() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = m_delegate->getDoubleValue(); + double k = m_delegate->getDoubleValue(); + double r = m_delegate->getDoubleValue(); + double rf = m_delegate->getDoubleValue(); + double angle = m_delegate->getDoubleValue(); + double sy = m_delegate->getDoubleValue(); + double sx = m_delegate->getDoubleValue(); + double py = m_delegate->getDoubleValue(); + double px = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokePattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} + + +void AI88Handler::_handleSetStrokeColorCMYK() +{ + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 2 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} + +void AI88Handler::_handleSetFillColorGray() +{ + double g = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 3 are %f",g); + + AIColor color (g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetStrokeColorGray() +{ + double g = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 4 are %f",g); + + AIColor color (g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} + +void AI88Handler::_handleSetFillColorCustom() +{ + double g = m_delegate->getDoubleValue(); + const QString name = m_delegate->getStringValue(); + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 5 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotFillColor (color); +} + +void AI88Handler::_handleSetDash() +{ +// qDebug ("found dash operation"); + double fval = m_delegate->getDoubleValue(); + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotDash (aval, fval); +// qDebug ("dash operation finished"); +} + +void AI88Handler::_handlePatternDefinition() +{ + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ury = m_delegate->getDoubleValue(); + double urx = m_delegate->getDoubleValue(); + double lly = m_delegate->getDoubleValue(); + double llx = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + + if (m_delegate->m_documentHandler) m_delegate->m_documentHandler->gotPatternDefinition (name.latin1(), aval, llx, lly, urx, ury); +} + +void AI88Handler::_handleGsaveIncludeDocument() { + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &name = elem2.toString(); + + int ury = m_delegate->getIntValue(); + int urx = m_delegate->getIntValue(); + int lly = m_delegate->getIntValue(); + int llx = m_delegate->getIntValue(); + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_delegate->m_embeddedHandler) m_delegate->m_embeddedHandler->gotGsaveIncludeDocument (aval, llx,lly,urx,ury,name.latin1()); +} + +void AI88Handler::_handleSetCurrentText() { + int iAlign = m_delegate->getIntValue(); + TextAlign ta = TA_HLeft; + + switch (iAlign) + { + case 0 : ta = TA_HLeft; break; + case 1 : ta = TA_HCenter; break; + case 2 : ta = TA_HRight; break; + case 3: ta = TA_VTop; break; + case 4 : ta = TA_VCenter; break; + case 5 : ta = TA_VBottom; break; + } + + double kerning = m_delegate->getDoubleValue(); + double leading = m_delegate->getDoubleValue(); + double size = m_delegate->getDoubleValue(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &fontname = elem2.toReference(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotFontDefinition (fontname.latin1(), size, leading, kerning, ta); + +} + +void AI88Handler::_handleTextBlock (TextOperation to) { + AIElement elem (m_delegate->m_stack.top()); + qDebug ("to element is (%s)",elem.typeName()); + m_delegate->m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextBlockBegin (aval, to); +} + +void AI88Handler::_handleTextOutput () { + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + + const QString &text = elem.toString(); + + int length = -1; + + if (m_delegate->m_stack.empty()) + { + AIElement elem2 (m_delegate->m_stack.top()); + if (elem2.type() == AIElement::Int) + { + length = elem2.asInt(); + m_delegate->m_stack.pop(); + } + } + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotTextOutput (text.latin1(), length); +} + +void AI88Handler::_handleFontEncoding() +{ + while (m_delegate->m_stack.top().type() != AIElement::Reference) { + m_delegate->m_stack.pop(); + } + + AIElement elem (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QString &oldFont = elem.toReference(); + + AIElement elem2 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QString &newFont = elem2.toReference(); + + AIElement elem3 (m_delegate->m_stack.top()); + m_delegate->m_stack.pop(); + const QValueVector encodingData = elem3.toElementArray(); + + if (m_delegate->m_textHandler) m_delegate->m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); +} + +void AI88Handler::_handleSetStrokeColorCustom() +{ + double g = m_delegate->getDoubleValue(); + const QString name = m_delegate->getStringValue(); + double k = m_delegate->getDoubleValue(); + double y = m_delegate->getDoubleValue(); + double m = m_delegate->getDoubleValue(); + double c = m_delegate->getDoubleValue(); + if (m_delegate->m_debug) qDebug ("values 6 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_delegate->m_gstateHandler) m_delegate->m_gstateHandler->gotStrokeColor (color); +} diff --git a/filters/karbon/ai/ai88handler.h b/filters/karbon/ai/ai88handler.h new file mode 100644 index 000000000..be031113e --- /dev/null +++ b/filters/karbon/ai/ai88handler.h @@ -0,0 +1,56 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AI88HANDLER_H +#define AI88HANDLER_H + +#include "aiparserbase.h" + +/** + *@author Dirk Schoenberger + */ + +class AI88Handler { +private: + AIParserBase *m_delegate; + + void _handleSetDash(); + void _handleSetStrokeColorCMYK(); + void _handleSetFillColorCMYK(); + void _handleSetStrokeColorGray(); + void _handleSetFillColorGray(); + void _handleSetStrokeColorCustom(); + void _handleSetFillColorCustom(); + void _handleSetFillPattern(); + void _handleSetStrokePattern(); + void _handlePatternDefinition(); + void _handleGsaveIncludeDocument(); + void _handleSetCurrentText(); + void _handleTextBlock (TextOperation to); + void _handleTextOutput (); + void _handleFontEncoding(); + +public: + AI88Handler(AIParserBase *delegate); + ~AI88Handler(); + + bool handleAIOperation (AIOperation op); +}; + +#endif diff --git a/filters/karbon/ai/aicolor.cc b/filters/karbon/ai/aicolor.cc new file mode 100644 index 000000000..673841676 --- /dev/null +++ b/filters/karbon/ai/aicolor.cc @@ -0,0 +1,100 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "aicolor.h" +#include + +AIColor::AIColor(){ + ctype = AIColor::CT_CMYK; + cdata.cmykdata.cvalue = 0; + cdata.cmykdata.mvalue = 0; + cdata.cmykdata.yvalue = 0; + cdata.cmykdata.kvalue = 0; +} + +AIColor::AIColor( const AIColor& value ){ + ctype = value.ctype; + memcpy (&cdata, &value.cdata, sizeof (cdata)); +} +AIColor::AIColor( double c, double m, double y, double k ){ + ctype = AIColor::CT_CMYK; + cdata.cmykdata.cvalue = c; + cdata.cmykdata.mvalue = m; + cdata.cmykdata.yvalue = y; + cdata.cmykdata.kvalue = k; +} +AIColor::AIColor( double c, double m, double y, double k, const char* colorname, double gray ){ + ctype = AIColor::CT_CMYK_Key; + cdata.cmykdata.cvalue = c; + cdata.cmykdata.mvalue = m; + cdata.cmykdata.yvalue = y; + cdata.cmykdata.kvalue = k; + cdata.cmykdata.colorname = strdup (colorname); +} +AIColor::AIColor( double gray ){ + ctype = AIColor::CT_Gray; + cdata.graydata = gray; +} + +AIColor::~AIColor(){ +} + +void AIColor::toRGB (double &r, double &g, double &b) +{ + switch (ctype) + { + case CT_CMYK : + case CT_CMYK_Key : + r = 1 - cdata.cmykdata.cvalue - cdata.cmykdata.kvalue; + g = 1 - cdata.cmykdata.mvalue - cdata.cmykdata.kvalue; + b = 1 - cdata.cmykdata.yvalue - cdata.cmykdata.kvalue; + break; + case CT_Gray : + r = cdata.graydata; + g = cdata.graydata; + b = cdata.graydata; + break; + default : + qDebug ("unknown colortype %d", ctype); + } +} + +void AIColor::toCMYK (double &c, double &m, double &y, double &k) +{ + switch (ctype) + { + case CT_CMYK : + case CT_CMYK_Key : + c = cdata.cmykdata.cvalue; + m = cdata.cmykdata.mvalue; + y = cdata.cmykdata.yvalue; + k = cdata.cmykdata.kvalue; + break; + case CT_Gray : + c = 0; + m = 0; + y = 0; + k = cdata.graydata; + break; + default : + qDebug ("unknown colortype %d", ctype); + } +} + + diff --git a/filters/karbon/ai/aicolor.h b/filters/karbon/ai/aicolor.h new file mode 100644 index 000000000..b8cc14149 --- /dev/null +++ b/filters/karbon/ai/aicolor.h @@ -0,0 +1,57 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AICOLOR_H +#define AICOLOR_H + +#include + +/** + *@author + */ + +class AIColor { + public: + typedef enum { CT_CMYK, CT_CMYK_Key, CT_Gray } ColorType; + + private: + ColorType ctype; + + union { + struct { + double cvalue, mvalue, yvalue, kvalue; + char *colorname; + double graydata; + } cmykdata; + double graydata; + } cdata; +public: + AIColor(); + ~AIColor(); + AIColor( const AIColor& ); + AIColor( double c, double m, double y, double k ); + AIColor( double c, double m, double y, double k, const char *colorname, double gray ); + AIColor( double gray ); + + void toRGB (double &r, double &g, double &b); + void toCMYK (double &c, double &m, double &y, double &k); + +}; + +#endif diff --git a/filters/karbon/ai/aielement.cc b/filters/karbon/ai/aielement.cc new file mode 100644 index 000000000..13887b50f --- /dev/null +++ b/filters/karbon/ai/aielement.cc @@ -0,0 +1,804 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "aielement.h" +#include + +AIElement::Private::Private() +{ + typ = AIElement::Invalid; +} + +AIElement::Private::Private( Private* d ) +{ + switch( d->typ ) + { + case AIElement::Invalid: + break; + case AIElement::String: + case AIElement::Reference: + case AIElement::Operator: + value.ptr = new QString( *((QString*)d->value.ptr) ); + break; + case AIElement::CString: + // QCString is explicit shared + value.ptr = new QCString( *((QCString*)d->value.ptr) ); + break; +/* case AIElement::List: + value.ptr = new QValueList( *((QValueList*)d->value.ptr) ); + break; */ + case AIElement::ElementArray: + value.ptr = new QValueVector( *((QValueVector*)d->value.ptr) ); + break; + case AIElement::Block: + value.ptr = new QValueVector( *((QValueVector*)d->value.ptr) ); + break; + case AIElement::ByteArray: + value.ptr = new QByteArray( *((QByteArray*)d->value.ptr) ); + break; + case AIElement::Int: + value.i = d->value.i; + break; + case AIElement::UInt: + value.u = d->value.u; + break; + case AIElement::Double: + value.d = d->value.d; + break; + case AIElement::Byte: + value.b = d->value.b; + break; + default: + Q_ASSERT( 0 ); + } + + typ = d->typ; +} + +AIElement::Private::~Private() +{ + clear(); +} + +void AIElement::Private::clear() +{ + switch( typ ) + { + case AIElement::String: + case AIElement::Operator: + case AIElement::Reference: + delete (QString*)value.ptr; + break; + case AIElement::CString: + delete (QCString*)value.ptr; + break; +/* case AIElement::List: + delete (QValueList*)value.ptr; + break; */ + case AIElement::ElementArray: + delete (QValueVector*)value.ptr; + break; + case AIElement::Block: + delete (QValueVector*)value.ptr; + break; + case AIElement::ByteArray: + delete (QByteArray*)value.ptr; + break; + case AIElement::Invalid: + case AIElement::Int: + case AIElement::UInt: + case AIElement::Double: + case AIElement::Byte: + break; + } + + typ = AIElement::Invalid; +} + +/*! + Constructs an invalid aielement. +*/ +AIElement::AIElement() +{ + d = new Private; +} + +/*! + Destroys the AIElement and the contained object. + + Note that subclasses that reimplement clear() should reimplement + the destructor to call clear(). This destructor calls clear(), but + because it is the destructor, AIElement::clear() is called rather than + a subclass's clear(). +*/ +AIElement::~AIElement() +{ + if ( d->deref() ) + delete d; +} + +/*! + Constructs a copy of the aielement, \a p, passed as the argument to this + constructor. Usually this is a deep copy, but a shallow copy is made + if the stored data type is explicitly shared, as e.g. QImage is. +*/ +AIElement::AIElement( const AIElement& p ) +{ + d = new Private; + *this = p; +} + +/*! + Constructs a new aielement with a string value, \a val. +*/ +AIElement::AIElement( const QString& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new QString( val ); +} + +/*! + Constructs a new aielement with a C-string value, \a val. + + If you want to modify the QCString after you've passed it to this + constructor, we recommend passing a deep copy (see + QCString::copy()). +*/ +AIElement::AIElement( const QCString& val ) +{ + d = new Private; + d->typ = CString; + d->value.ptr = new QCString( val ); +} + +/*! + Constructs a new aielement with a C-string value of \a val if \a val + is non-null. The aielement creates a deep copy of \a val. + + If \a val is null, the resulting aielement has type Invalid. +*/ +AIElement::AIElement( const char* val ) +{ + d = new Private; + if ( val == 0 ) + return; + d->typ = CString; + d->value.ptr = new QCString( val ); +} + +/*! + Constructs a new aielement with an integer value, \a val. +*/ +AIElement::AIElement( int val ) +{ + d = new Private; + d->typ = Int; + d->value.i = val; +} + +/*! + Constructs a new aielement with an unsigned integer value, \a val. +*/ +AIElement::AIElement( uint val ) +{ + d = new Private; + d->typ = UInt; + d->value.u = val; +} + +/*! + Constructs a new aielement with an byte value, \a val. +*/ +AIElement::AIElement( uchar val ) +{ + d = new Private; + d->typ = Byte; + d->value.b = val; +} + + +/*! + Constructs a new aielement with a floating point value, \a val. +*/ +AIElement::AIElement( double val ) +{ + d = new Private; + d->typ = Double; + d->value.d = val; +} + +/*! + Constructs a new aielement with a list value, \a val. +*/ +/* AIElement::AIElement( const QValueList& val ) +{ + d = new Private; + d->typ = List; + d->value.ptr = new QValueList( val ); +} */ + +AIElement::AIElement( const QValueVector& val, Type type ) +{ + d = new Private; + d->typ = type; + d->value.ptr = new QValueVector( val ); +} + +AIElement::AIElement( const QByteArray& val ) +{ + d = new Private; + d->typ = ByteArray; + d->value.ptr = new QByteArray( val ); +} + +/*! + Assigns the value of the aielement \a aielement to this aielement. + + This is a deep copy of the aielement, but note that if the aielement + holds an explicitly shared type such as QImage, a shallow copy + is performed. +*/ +AIElement& AIElement::operator= ( const AIElement& aielement ) +{ + AIElement& other = (AIElement&)aielement; + + other.d->ref(); + if ( d->deref() ) + delete d; + + d = other.d; + + return *this; +} + +/*! + \internal +*/ +void AIElement::detach() +{ + if ( d->count == 1 ) + return; + + d->deref(); + d = new Private( d ); +} + +/*! + Returns the name of the type stored in the aielement. + The returned strings describe the C++ datatype used to store the + data: for example, "QFont", "QString", or "QValueList". + An Invalid aielement returns 0. +*/ +const char* AIElement::typeName() const +{ + return typeToName( d->typ ); +} + +/*! Convert this aielement to type Invalid and free up any resources + used. +*/ +void AIElement::clear() +{ + if ( d->count > 1 ) + { + d->deref(); + d = new Private; + return; + } + + d->clear(); +} + +static const int ntypes = 11; +static const char* const type_map[ntypes] = +{ + 0, +// "QValueList", + "QString", + "int", + "uint", + "double", + "QCString", + "Operator", + "Reference", + "QValueVector", + "QByteArray", + "uchar", +}; + +/*! + Converts the enum representation of the storage type, \a typ, to its + string representation. +*/ +const char* AIElement::typeToName( Type typ ) +{ + if ( typ >= ntypes ) + return 0; + return type_map[typ]; +} + +/*! + Converts the string representation of the storage type gven in \a + name, to its enum representation. + + If the string representation cannot be converted to any enum + representation, the aielement is set to \c Invalid. +*/ +AIElement::Type AIElement::nameToType( const char* name ) +{ + for ( int i = 0; i < ntypes; i++ ) { + if ( !qstrcmp( type_map[i], name ) ) + return (Type) i; + } + return Invalid; +} + +/*! + Returns the aielement as a QString if the aielement has type() + String, CString, ByteArray, Int, Uint, Double, + or QString::null otherwise. + + \sa asString() +*/ +const QString AIElement::toString() const +{ + if ( d->typ == CString ) + return QString::fromLatin1( toCString() ); + if ( d->typ == Int ) + return QString::number( toInt() ); + if ( d->typ == UInt ) + return QString::number( toUInt() ); + if ( d->typ == Double ) + return QString::number( toDouble() ); + if ( d->typ == Byte ) + return QString::number( toByte() ); + if ( d->typ != String ) + return QString::null; + return *((QString*)d->value.ptr); +} + +const QString AIElement::toReference() const +{ + if ( d->typ != Reference ) + return QString::null; + return *((QString*)d->value.ptr); +} + +const QString AIElement::toOperator() const +{ + if ( d->typ != Operator ) + return QString::null; + return *((QString*)d->value.ptr); +} + +/*! + Returns the aielement as a QCString if the aielement has type() + CString or String, or a 0 otherwise. + + \sa asCString() +*/ +const QCString AIElement::toCString() const +{ + if ( d->typ == CString ) + return *((QCString*)d->value.ptr); + if ( d->typ == String ) + return ((QString*)d->value.ptr)->latin1(); + if ( d->typ == Operator ) + return ((QString*)d->value.ptr)->latin1(); + if ( d->typ == Reference ) + return ((QString*)d->value.ptr)->latin1(); + + return 0; +} + + +/*! + Returns the aielement as an int if the aielement has type() + String, CString, Int, UInt, Double, Byte, or 0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to an int and FALSE otherwise. + + \sa asInt() canCast() +*/ +int AIElement::toInt( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toInt( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toInt( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Int ) + return d->value.i; + if( d->typ == UInt ) + return (int)d->value.u; + if( d->typ == Byte ) + return (int)d->value.b; + if ( d->typ == Double ) + return (int)d->value.d; + return 0; +} + +uchar AIElement::toByte( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toShort( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toShort( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Byte ) + return d->value.b; + if( d->typ == Int ) + return (uchar)d->value.i; + if( d->typ == UInt ) + return (uchar)d->value.u; + if ( d->typ == Double ) + return (uchar)d->value.d; + return 0; +} + + +/*! + Returns the aielement as an unsigned int if the aielement has type() + String, CString, UInt, Int, Double, Byte, or 0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to a uint and FALSE otherwise. + + \sa asUInt() +*/ +uint AIElement::toUInt( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toUInt( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toUInt( ok ); + if ( ok ) + *ok = canCast( UInt ); + if( d->typ == Int ) + return d->value.i; + if( d->typ == UInt ) + return (int)d->value.u; + if( d->typ == Byte ) + return (int)d->value.b; + if ( d->typ == Double ) + return (int)d->value.d; + + return 0; +} + +/*! + Returns the aielement as a double if the aielement has type() + String, CString, Double, Int, UInt, Byte, or 0.0 otherwise. + + If \a ok is non-null, \a *ok is set to TRUE if the value could be + converted to a double and FALSE otherwise. + + \sa asDouble() +*/ +double AIElement::toDouble( bool * ok ) const +{ + if( d->typ == String ) + return ((QString*)d->value.ptr)->toDouble( ok ); + if ( d->typ == CString ) + return ((QCString*)d->value.ptr)->toDouble( ok ); + if ( ok ) + *ok = canCast( Double ); + if ( d->typ == Double ) + return d->value.d; + if ( d->typ == Int ) + return (double)d->value.i; + if ( d->typ == UInt ) + return (double)d->value.u; + if ( d->typ == Byte ) + return (double)d->value.b; + return 0.0; +} + +/*! + Returns the aielement as a QValueList if the aielement has type() + List or StringList, or an empty list otherwise. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QValueList list = myAIElement.toList(); + QValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode + + \sa asList() +*/ +/* const QValueList AIElement::toList() const +{ + if ( d->typ == List ) + return *((QValueList*)d->value.ptr); + return QValueList(); +} */ + +const QValueVector AIElement::toElementArray() const +{ + if ( d->typ == ElementArray ) + return *((QValueVector*)d->value.ptr); + return QValueVector(); +} + +const QValueVector AIElement::toBlock() const +{ + if ( d->typ == Block ) + return *((QValueVector*)d->value.ptr); + return QValueVector(); +} + + +const QByteArray AIElement::toByteArray() const +{ + if ( d->typ == ByteArray ) + return *((QByteArray*)d->value.ptr); + return QByteArray(); +} + +#define Q_VARIANT_AS( f ) Q##f& AIElement::as##f() { \ + if ( d->typ != f ) *this = AIElement( to##f() ); else detach(); return *((Q##f*)d->value.ptr);} + +Q_VARIANT_AS(String) +Q_VARIANT_AS(CString) + +/*! + Returns the aielement's value as int reference. +*/ +int& AIElement::asInt() +{ + detach(); + if ( d->typ != Int ) { + int i = toInt(); + d->clear(); + d->value.i = i; + d->typ = Int; + } + return d->value.i; +} + +/*! + Returns the aielement's value as unsigned int reference. +*/ +uint& AIElement::asUInt() +{ + detach(); + if ( d->typ != UInt ) { + uint u = toUInt(); + d->clear(); + d->value.u = u; + d->typ = UInt; + } + return d->value.u; +} + +/*! + Returns the aielement's value as double reference. +*/ +double& AIElement::asDouble() +{ + if ( d->typ != Double ) { + double dbl = toDouble(); + d->clear(); + d->value.d = dbl; + d->typ = Double; + } + return d->value.d; +} + +/*! + Returns the aielement's value as byte reference. +*/ +uchar& AIElement::asByte() +{ + detach(); + if ( d->typ != Byte ) { + uchar b = toByte(); + d->clear(); + d->value.b = b; + d->typ = Byte; + } + return d->value.b; +} + + +/*! + Returns the aielement's value as aielement list reference. + + Note that if you want to iterate over the list, you should + iterate over a copy, e.g. + \code + QValueList list = myAIElement.asList(); + QValueList::Iterator it = list.begin(); + while( it != list.end() ) { + myProcessing( *it ); + ++it; + } + \endcode +*/ +/* QValueList& AIElement::asList() +{ + if ( d->typ != List ) + *this = AIElement( toList() ); + return *((QValueList*)d->value.ptr); +} */ + +QValueVector& AIElement::asElementArray() +{ + if ( d->typ != ElementArray ) + *this = AIElement( toElementArray() ); + return *((QValueVector*)d->value.ptr); +} + +QValueVector& AIElement::asBlock() +{ + if ( d->typ != Block ) + *this = AIElement( toBlock() ); + return *((QValueVector*)d->value.ptr); +} + + +QByteArray& AIElement::asByteArray() +{ + if ( d->typ != ByteArray ) + *this = AIElement( toByteArray() ); + return *((QByteArray*)d->value.ptr); +} + +/*! + Returns TRUE if the aielement's type can be cast to the requested + type, \p t. Such casting is done automatically when calling the + toInt(), ... or asInt(), ... methods. + + The following casts are done automatically: +
      +
    • CString => String +
    • Double => String, Int, UInt +
    • Int => String, Double, UInt +
    • String => CString, Int, Uint, Double +
    • UInt => String, Double, Int +
    +*/ +bool AIElement::canCast( Type t ) const +{ + if ( d->typ == t ) + return TRUE; + if ( t == Int && ( d->typ == String || d->typ == Double || d->typ == UInt || d->typ == Byte) ) + return TRUE; + if ( t == UInt && ( d->typ == String || d->typ == Double || d->typ == Int || d->typ == Byte) ) + return TRUE; + if ( t == Double && ( d->typ == String || d->typ == Int || d->typ == UInt || d->typ == Byte) ) + return TRUE; + if ( t == CString && d->typ == String ) + return TRUE; + if ( t == String && ( d->typ == CString || d->typ == Int || d->typ == UInt || d->typ == Double || d->typ == Byte) ) + return TRUE; + + return FALSE; +} + +/*! + \brief Casts the aielement to the requested type. + + If the cast cannot be + done, the aielement is set to the default value of the requested type + (e.g. an empty string if the requested type \p t is + AIElement::String, an empty point array if the requested type \p t is + AIElement::PointArray, etc). + + \returns TRUE if the current type of the + aielement was successfully casted; otherwise returns FALSE. + + \see canCast() +*/ + +bool AIElement::cast( Type t ) +{ + switch ( t ) { +/* case AIElement::List: + asList(); + break; */ + case AIElement::ElementArray: + asElementArray(); + break; + case AIElement::Block: + asBlock(); + break; + case AIElement::String: + asString(); + break; + case AIElement::Int: + asInt(); + break; + case AIElement::UInt: + asUInt(); + break; + case AIElement::Double: + asDouble(); + break; + case AIElement::CString: + asCString(); + break; + case AIElement::Byte: + asByte(); + break; + case AIElement::ByteArray: + asByteArray(); + break; + default: + case AIElement::Invalid: + (*this) = AIElement(); + } + return canCast( t ); +} + +/*! Compares this AIElement with \a v and returns TRUE if they are + equal; otherwise returns FALSE. +*/ + +bool AIElement::operator==( const AIElement &v ) const +{ + if ( !v.canCast( type() ) ) + return FALSE; + switch( d->typ ) { +/* case List: + return v.toList() == toList(); */ + case ElementArray: + return v.toElementArray() == toElementArray(); + case Block: + return v.toBlock() == toBlock(); + case ByteArray: + return v.toByteArray() == toByteArray(); + + case String: + return v.toString() == toString(); + case Operator: + return v.toOperator() == toOperator(); + case Reference: + return v.toReference() == toReference(); + case CString: + return v.toCString() == toCString(); + case Int: + return v.toInt() == toInt(); + case UInt: + return v.toUInt() == toUInt(); + case Byte: + return v.toByte() == toByte(); + case Invalid: + break; + } + return FALSE; +} + +/*! Compares this AIElement with \a v and returns TRUE if they are + not equal; otherwise returns FALSE. +*/ + +bool AIElement::operator!=( const AIElement &v ) const +{ + return !( v == *this ); +} diff --git a/filters/karbon/ai/aielement.h b/filters/karbon/ai/aielement.h new file mode 100644 index 000000000..5c6ab0458 --- /dev/null +++ b/filters/karbon/ai/aielement.h @@ -0,0 +1,151 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AIELEMENT_H +#define AIELEMENT_H + +// #include +#include + +class QString; +class QCString; + +/** + *@author + */ + +class AIElement { +public: + enum Type { + Invalid, +// List, + String, + Int, + UInt, + Double, + CString, + // Custom Types + Operator, + Reference, + ElementArray, + Block, + ByteArray, + Byte + }; + + AIElement(); + ~AIElement(); + AIElement( const AIElement& ); + AIElement( const QString&, Type type = String ); + AIElement( const QCString& ); + AIElement( const char* ); +// AIElement( const QValueList& ); + AIElement( const QValueVector&, Type type = ElementArray); + AIElement( int ); + AIElement( uint ); + AIElement( double ); + AIElement( const QByteArray& ); + AIElement( uchar ); + + AIElement& operator= ( const AIElement& ); + bool operator==( const AIElement& ) const; + bool operator!=( const AIElement& ) const; + + Type type() const; + const char* typeName() const; + + bool canCast( Type ) const; + bool cast( Type ); + + bool isValid() const; + + void clear(); + + const QString toString() const; + const QCString toCString() const; + int toInt( bool * ok=0 ) const; + uint toUInt( bool * ok=0 ) const; + double toDouble( bool * ok=0 ) const; +// const QValueList toList() const; + const QValueVector toElementArray() const; + const QValueVector toBlock() const; + + // Custom types + const QString toReference() const; + const QString toOperator() const; + const QByteArray toByteArray() const; + uchar toByte( bool * ok=0 ) const; + +// QValueListConstIterator listBegin() const; +// QValueListConstIterator listEnd() const; + QString& asString(); + QCString& asCString(); + int& asInt(); + uint& asUInt(); + double& asDouble(); +// QValueList& asList(); + QValueVector& asElementArray(); + QValueVector& asBlock(); + + // Custom types + QString& asReference(); + QString& asToken(); + QByteArray& asByteArray(); + uchar& asByte(); + + static const char* typeToName( Type typ ); + static Type nameToType( const char* name ); + +private: + void detach(); + + class Private : public QShared + { + public: + Private(); + Private( Private* ); + ~Private(); + + void clear(); + + Type typ; + union + { + uint u; + int i; + double d; + uchar b; + void *ptr; + } value; + }; + + Private* d; +}; + +inline AIElement::Type AIElement::type() const +{ + return d->typ; +} + +inline bool AIElement::isValid() const +{ + return (d->typ != Invalid); +} + +#endif diff --git a/filters/karbon/ai/aiimport.cc b/filters/karbon/ai/aiimport.cc new file mode 100644 index 000000000..a5e24f5b1 --- /dev/null +++ b/filters/karbon/ai/aiimport.cc @@ -0,0 +1,101 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "aiimport.h" +#include "karbonaiparserbase.h" + +class AiImportFactory : KGenericFactory +{ +public: + AiImportFactory( void ) + : KGenericFactory( "karbonaiimport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonaiimport, AiImportFactory() ) + +AiImport::AiImport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +AiImport::~AiImport() +{ +} + +KoFilter::ConversionStatus +AiImport::convert( const QCString& from, const QCString& to ) +{ + if ( from != "application/illustrator" || to != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + QFile fileIn( m_chain->inputFile() ); + if( !fileIn.open( IO_ReadOnly ) ) + { + fileIn.close(); + return KoFilter::FileNotFound; + } + + QDomDocument doc ("DOC"); + KarbonAIParserBase parser; + + if (!parser.parse (fileIn, doc)) + { + fileIn.close(); + return KoFilter::CreationError; + } + QString result = doc.toString(); + + kdDebug() << result << endl; + KoStoreDevice* storeOut = m_chain->storageFile( "root", KoStore::Write ); + if( !storeOut ) + { + fileIn.close(); + return KoFilter::StorageCreationError; + } + + QCString cStr = result.latin1(); + storeOut->writeBlock( cStr, cStr.size() - 1 ); + + return KoFilter::OK; +} + + +#include "aiimport.moc" + + + diff --git a/filters/karbon/ai/aiimport.h b/filters/karbon/ai/aiimport.h new file mode 100644 index 000000000..2ec2d19bc --- /dev/null +++ b/filters/karbon/ai/aiimport.h @@ -0,0 +1,47 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __AIIMPORT_H__ +#define __AIIMPORT_H__ + +#include + +#include "karbonaiparserbase.h" + +class QDomElement; +class QTextStream; + +class AiImport : public KoFilter +{ + Q_OBJECT + +public: + AiImport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~AiImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +/* private: + QString m_result; */ + + +}; + +#endif + + diff --git a/filters/karbon/ai/ailexer.cc b/filters/karbon/ai/ailexer.cc new file mode 100644 index 000000000..7b660f7f6 --- /dev/null +++ b/filters/karbon/ai/ailexer.cc @@ -0,0 +1,514 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include "ailexer.h" + +#define CATEGORY_WHITESPACE -1 +#define CATEGORY_ALPHA -2 +#define CATEGORY_DIGIT -3 +#define CATEGORY_SPECIAL -4 +#define CATEGORY_LETTERHEX -5 +#define CATEGORY_INTTOOLONG -6 + +#define CATEGORY_ANY -127 + +#define MAX_INTLEN 9 +#define MIN_HEXCHARS 6 + +#define STOP 0 + +int iswhitespace(char c){ + return (c==' ')||(c=='\n')||(c=='\t')||(c=='\r'); +} + +int isSpecial(char c){ + return (c=='*')||(c=='_')||(c=='?')||(c=='~')||(c=='-')||(c=='^')||(c=='`')||(c=='!')||(c=='.')||(c=='@')||(c=='&')||(c=='$')||(c=='='); +} + +int isletterhex(char c){ + return (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F'); +} + +const char*statetoa (State state){ + switch (state) + { + case State_Comment : return "comment"; + case State_Integer : return "integer"; + case State_Float : return "float"; + case State_String : return "string"; + case State_Token : return "token"; + case State_Reference : return "reference"; + case State_Start : return "start"; + case State_BlockStart : return "block start"; + case State_BlockEnd : return "block end"; + case State_ArrayStart : return "array start"; + case State_ArrayEnd : return "array end"; + case State_Byte : return "byte"; + case State_ByteArray : return "byte array"; + case State_StringEncodedChar : return "encoded char (string)"; + case State_CommentEncodedChar : return "encoded char (comment)"; + case State_ByteArray2 : return "byte array (mode 2)"; + default : return "unknown"; + } +} + +typedef struct { + State oldState; + char c; + State newState; + Action action; +} Transition; + +static Transition transitions[] = { + { State_Comment, '\n', State_Start, Action_Output}, + { State_Comment, '\r', State_Start, Action_Output}, + { State_Comment, '\\', State_CommentEncodedChar, Action_InitTemp}, + { State_Comment, CATEGORY_ANY, State_Comment, Action_Copy}, + { State_Integer, CATEGORY_DIGIT, State_Integer, Action_Copy}, + { State_Integer, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Integer, '.', State_Float, Action_Copy}, + { State_Integer, ']', State_Start, Action_OutputUnget}, + { State_Integer, '}', State_Start, Action_OutputUnget}, + { State_Integer, '#', State_Byte, Action_Copy }, + { State_Integer, '/', State_Start, Action_OutputUnget }, + { State_Integer, '{', State_Start, Action_OutputUnget }, + { State_Integer, '%', State_Start, Action_OutputUnget }, + { State_Integer, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy }, + { State_Integer, CATEGORY_INTTOOLONG, State_ByteArray2, Action_Copy }, + { State_Integer, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Float, CATEGORY_DIGIT, State_Float, Action_Copy}, + { State_Float, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Float, ']', State_Start, Action_OutputUnget}, + { State_Float, '}', State_Start, Action_OutputUnget}, + { State_Float, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Token, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_Token, CATEGORY_DIGIT, State_Token, Action_Copy}, + { State_Token, CATEGORY_SPECIAL, State_Token, Action_Copy}, + { State_Token, '}', State_Start, Action_OutputUnget}, + { State_Token, ']', State_Start, Action_OutputUnget}, + { State_Token, '{', State_BlockStart, Action_Output}, + { State_Token, '}', State_BlockEnd, Action_Output}, + { State_Token, '/', State_Start, Action_OutputUnget}, + { State_Token, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Token, CATEGORY_ANY, State_Start, Action_Abort}, + { State_String, ')', State_Start, Action_Output}, + { State_String, '\\', State_StringEncodedChar, Action_InitTemp}, + { State_String, CATEGORY_ANY, State_String, Action_Copy}, +// { State_Array, CATEGORY_ALPHA, State_Array, Action_Copy}, +// { State_Array, CATEGORY_DIGIT, State_Array, Action_Copy}, +// { State_Array, ' ', State_Array, Action_Copy}, + { State_BlockStart, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_BlockEnd, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_ArrayStart, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_ArrayEnd, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_Reference, '#', State_Reference, Action_Copy }, + { State_Reference, CATEGORY_ALPHA, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_DIGIT, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_SPECIAL, State_Reference, Action_Copy }, + { State_Reference, CATEGORY_ANY, State_Start, Action_OutputUnget }, + { State_Byte, '/', State_Start, Action_OutputUnget }, + { State_Byte, CATEGORY_DIGIT, State_Byte, Action_Copy}, + { State_Byte, CATEGORY_ALPHA, State_Byte, Action_Copy}, + { State_Byte, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_ByteArray, '>', State_Start, Action_Output }, + { State_ByteArray, CATEGORY_ALPHA, State_ByteArray, Action_Copy }, + { State_ByteArray, CATEGORY_DIGIT, State_ByteArray, Action_Copy }, + { State_ByteArray, CATEGORY_WHITESPACE, State_ByteArray, Action_Ignore }, + { State_ByteArray, CATEGORY_ANY, State_Start, Action_Abort }, + { State_StringEncodedChar, '\\', State_String, Action_Copy}, + { State_StringEncodedChar, CATEGORY_DIGIT, State_StringEncodedChar, Action_CopyTemp}, + { State_StringEncodedChar, CATEGORY_ANY, State_String, Action_DecodeUnget}, + { State_CommentEncodedChar, '\\', State_Comment, Action_Copy}, + { State_CommentEncodedChar, CATEGORY_DIGIT, State_CommentEncodedChar, Action_CopyTemp}, + { State_CommentEncodedChar, CATEGORY_ANY, State_Comment, Action_DecodeUnget}, + { State_ByteArray2, '\n', State_Start, Action_Output}, + { State_ByteArray2, '\r', State_Start, Action_Output}, + { State_ByteArray2, '}', State_Start, Action_ByteArraySpecial}, + { State_ByteArray2, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_ByteArray2, CATEGORY_DIGIT, State_ByteArray2, Action_Copy}, + { State_ByteArray2, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy}, + { State_ByteArray2, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_ByteArray2, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Start, '%', State_Comment, Action_Ignore}, + { State_Start, CATEGORY_DIGIT, State_Integer, Action_Copy}, + { State_Start, '-', State_Integer, Action_Copy}, + { State_Start, '+', State_Integer, Action_Copy}, + { State_Start, '.', State_Float, Action_Copy}, + { State_Start, '/', State_Reference, Action_Ignore }, + { State_Start, '(', State_String, Action_Ignore}, + { State_Start, '{', State_BlockStart, Action_Copy}, + { State_Start, '}', State_BlockEnd, Action_Copy}, + { State_Start, '[', State_ArrayStart, Action_Copy}, + { State_Start, ']', State_ArrayEnd, Action_Copy}, + { State_Start, '<', State_ByteArray, Action_Ignore}, + { State_Start, CATEGORY_ALPHA, State_Token, Action_Copy}, + { State_Start, CATEGORY_WHITESPACE, State_Start, Action_Output}, + { State_Start, CATEGORY_SPECIAL, State_Token, Action_Copy}, + { State_Start, CATEGORY_LETTERHEX, State_ByteArray2, Action_Copy}, + { State_Start, CATEGORY_ANY, State_Start, Action_Abort}, + { State_Start, STOP, State_Start, Action_Abort} +}; + +AILexer::AILexer(){ +} +AILexer::~AILexer(){ +} + +bool AILexer::parse (QIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// qDebug ("got %c", c); + + State newState; + Action action; + + nextStep (c, &newState, &action); + + switch (action) + { + case Action_Copy : + m_buffer.append (c); + break; + case Action_CopyOutput : + m_buffer.append (c); + doOutput(); + break; + case Action_Output : + doOutput(); + break; + case Action_OutputUnget : + doOutput(); + fin.ungetch(c); + break; + case Action_Ignore : + /* ignore */ + break; + case Action_Abort : + qWarning ( "state %s / %s char %c (%d)" , statetoa(m_curState), statetoa(newState), c, c ); + parsingAborted(); + return false; + break; + case Action_InitTemp : + m_temp.clear(); + break; + case Action_CopyTemp : + m_temp.append (c); + break; + case Action_DecodeUnget : + m_buffer.append (decode()); + fin.ungetch(c); + break; + // in Postscript Quelltext: Kombination F} + case Action_ByteArraySpecial : + m_curState = State_Token; + doOutput(); + fin.ungetch(c); + break; + default : + qWarning ( "unknown action: %d ", action); + } + + m_curState = newState; + } + + parsingFinished(); + return true; +} + +void AILexer::doOutput () +{ + if (m_buffer.length() == 0) return; + switch (m_curState) + { + case State_Comment : + gotComment (m_buffer.latin1()); + break; + case State_Integer : + gotIntValue (m_buffer.toInt()); + break; + case State_Float : + gotDoubleValue (m_buffer.toFloat()); + break; + case State_String : + gotStringValue (m_buffer.latin1()); + break; + case State_Token : + gotToken (m_buffer.latin1()); + break; + case State_Reference : + gotReference (m_buffer.latin1()); + break; + case State_BlockStart : + gotBlockStart (); + break; + case State_BlockEnd : + gotBlockEnd (); + break; + case State_Start : + break; + case State_ArrayStart : + gotArrayStart (); + break; + case State_ArrayEnd : + gotArrayEnd (); + break; + case State_Byte : + gotByte (getByte()); + break; + case State_ByteArray : + case State_ByteArray2 : + doHandleByteArray (); + break; + default: + qWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void AILexer::gotComment (const char *value) { + qDebug ( "gotComment: %s ", value ); +} + +void AILexer::gotIntValue (int value) { + qDebug ( "gotInt: %d ", value ); +} + +void AILexer::gotDoubleValue (double value) { + qDebug ( "gotDouble: %f ", value ); +} + +void AILexer::gotStringValue (const char *value) { + qDebug ( "gotString: %s ", value ); +} + +void AILexer::gotToken (const char *value) { + qDebug ( "gotToken: %s ", value ); +} + +void AILexer::gotReference (const char *value) { + qDebug ( "gotReference: %s ", value ); +} + +void AILexer::gotBlockStart (){ + qDebug ( "gotBlockStart" ); +} + +void AILexer::gotBlockEnd (){ + qDebug ( "gotBlockEnd" ); +} + +void AILexer::gotArrayStart (){ + qDebug ( "gotArrayStart" ); +} + +void AILexer::gotArrayEnd (){ + qDebug ( "gotArrayEnd" ); +} + +void AILexer::parsingStarted() { + qDebug ( "parsing started" ); +} + +void AILexer::parsingFinished() { + qDebug ( "parsing finished" ); +} + +void AILexer::parsingAborted() { + qDebug ( "parsing aborted" ); +} + +void AILexer::gotByte (uchar value) { + qDebug ( "got byte %d" , value ); +} + +void AILexer::gotByteArray (const QByteArray &data) { + qDebug ( "got byte array" ); +/* for ( uint i = 0; i < data.size(); i++ ) + { + uchar value = data[i]; + qDebug( "%d: %x", i, value ); + } + qDebug ( "/byte array" ); */ + +} + + +void AILexer::nextStep (char c, State *newState, Action *newAction) { + int i=0; + + while (true) { + Transition trans = transitions[i]; + + if (trans.c == STOP) { + *newState = trans.newState; + *newAction = trans.action; + return; + } + + bool found = false; + + if (trans.oldState == m_curState) { + switch (trans.c) { + case CATEGORY_WHITESPACE : found = isspace(c); break; + case CATEGORY_ALPHA : found = isalpha(c); break; + case CATEGORY_DIGIT : found = isdigit(c); break; + case CATEGORY_SPECIAL : found = isSpecial(c); break; + case CATEGORY_LETTERHEX : found = isletterhex(c); break; + case CATEGORY_INTTOOLONG : found = m_buffer.length() > MAX_INTLEN; break; + case CATEGORY_ANY : found = true; break; + default : found = (trans.c == c); + } + + if (found) { + *newState = trans.newState; + *newAction = trans.action; + + return; + } + } + + + i++; + } +} + +void AILexer::doHandleByteArray () +{ + // Special case - too short + if (m_buffer.length () < MIN_HEXCHARS) + { + gotToken (m_buffer.latin1()); + return; + } + + uint strIdx = 0; + uint arrayIdx = 0; + + QByteArray data (m_buffer.length() >> 1); + + while (strIdx < m_buffer.length()) + { + const QString &item = m_buffer.mid (strIdx, 2); + uchar val = item.toShort(NULL, 16); + data[arrayIdx] = val; + strIdx += 2; + arrayIdx++; + } + + gotByteArray (data); +} + +uchar AILexer::getByte() +{ +// qDebug ("convert string to byte (%s)", m_buffer.latin1()); + + QStringList list = QStringList::split ("#", m_buffer.toString()); + int radix = list[0].toShort(); + uchar value = list[1].toShort (NULL, radix); + + return value; +} + +uchar AILexer::decode() +{ + uchar value = m_temp.toString().toShort(NULL, 8); +// qDebug ("got encoded char %c",value); + return value; +} + +/* StringBuffer implementation */ + +int initialSize = 20; +int addSize = 10; + +StringBuffer::StringBuffer () { + m_buffer = (char*)calloc (initialSize, sizeof(char)); + m_length = 0; + m_capacity = initialSize; +} + +StringBuffer::~StringBuffer (){ + free(m_buffer); +} + +void StringBuffer::append (char c){ + ensureCapacity(m_length + 1); + m_buffer[m_length] = c; + m_length++; +} + +void StringBuffer::clear(){ + for (uint i=0; i= p_capacity) return; + + int newSize = m_capacity + addSize; + if (p_capacity > newSize) newSize = p_capacity; + + char* oldBuffer = m_buffer; + char *newBuffer = (char*)calloc (newSize, sizeof(char)); + strcpy (newBuffer, m_buffer); + free(oldBuffer); + m_buffer = newBuffer; + m_capacity = newSize; +} + +uint StringBuffer::length() { + return m_length; +} + +double StringBuffer::toFloat() { + QString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + QString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +QString StringBuffer::mid( uint index, uint len) const { + QString data = toString(); + return data.mid(index,len); +} diff --git a/filters/karbon/ai/ailexer.h b/filters/karbon/ai/ailexer.h new file mode 100644 index 000000000..c53aab66d --- /dev/null +++ b/filters/karbon/ai/ailexer.h @@ -0,0 +1,123 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AILEXER_H +#define AILEXER_H + +#include +#include + +/** + *@author Dirk Schnberger + */ +typedef enum { + State_Comment=0, + State_Integer, + State_Float, + State_String, + State_Token, + State_Reference, + State_Start, + State_BlockStart, + State_BlockEnd, + State_ArrayStart, + State_ArrayEnd, + State_Byte, + State_ByteArray, + State_StringEncodedChar, + State_CommentEncodedChar, + State_ByteArray2 +} State; + +typedef enum { + Action_Copy=1, + Action_CopyOutput, + Action_Output, + Action_Ignore, + Action_Abort, + Action_OutputUnget, + Action_InitTemp, + Action_CopyTemp, + Action_DecodeUnget, + Action_ByteArraySpecial +} Action; + +class StringBuffer { +public: + StringBuffer (); + virtual ~StringBuffer (); + + void append (char c); + void clear(); + QString toString() const; + uint length(); + double toFloat(); + int toInt(); + const char *latin1(); + QString mid( uint index, uint len=0xffffffff) const; +private: + char *m_buffer; + uint m_length; + int m_capacity; + + void ensureCapacity (int p_capacity); +}; + +class AILexer { +public: + AILexer(); + virtual ~AILexer(); + + virtual bool parse (QIODevice& fin); +private: + State m_curState; + StringBuffer m_buffer; + StringBuffer m_temp; + +/* State nextState (char c); + Action nextAction (char c); */ + + void nextStep (char c, State* newState, Action* newAction); + + void doOutput (); + void doHandleByteArray (); + uchar getByte(); + uchar decode(); + +protected: + virtual void parsingStarted(); + virtual void parsingFinished(); + virtual void parsingAborted(); + + virtual void gotComment (const char *value); + virtual void gotIntValue (int value); + virtual void gotDoubleValue (double value); + virtual void gotStringValue (const char *value); + virtual void gotToken (const char *value); + virtual void gotReference (const char *value); + virtual void gotBlockStart (); + virtual void gotBlockEnd (); + virtual void gotArrayStart (); + virtual void gotArrayEnd (); + virtual void gotByte (uchar value); + virtual void gotByteArray (const QByteArray &data); +}; + +#endif + diff --git a/filters/karbon/ai/aiparserbase.cc b/filters/karbon/ai/aiparserbase.cc new file mode 100644 index 000000000..63ace7343 --- /dev/null +++ b/filters/karbon/ai/aiparserbase.cc @@ -0,0 +1,1337 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schönberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "aiparserbase.h" +#include "ai88handler.h" +#include "ai3handler.h" +#include +#include + +typedef struct { + char* op; + AIOperation action; +} AIOperationMapping; + +typedef struct { + char* op; + PSOperation action; +} PSOperationMapping; + +typedef struct { + char* op; + CommentOperation action; +} CommentOperationMapping; + +static AIOperationMapping aiMappings[] = { + { "k", AIO_SetFillColorCMYK }, + { "K", AIO_SetStrokeColorCMYK }, + { "g", AIO_SetFillColorGray }, + { "G", AIO_SetStrokeColorGray }, + { "x", AIO_SetFillColorCustom }, + { "X", AIO_SetStrokeColorCustom }, + { "p", AIO_SetFillPattern }, + { "P", AIO_SetStrokePattern }, + { "O", AIO_SetFillOverprinting }, + { "R", AIO_SetStrokeOverprinting }, + { "i", AIO_SetFlatness }, + { "J", AIO_SetLineCap }, + { "j", AIO_SetLineJoin }, + { "M", AIO_SetMiterLimit }, + { "w", AIO_SetLineWidth }, + { "d", AIO_SetDash }, + { "q", AIO_BeginGroupClip }, + { "Q", AIO_EndGroupClip }, + { "m", AIO_MoveTo }, + { "l", AIO_LineToSmooth }, + { "L", AIO_LineToCorner }, + { "c", AIO_CurveToSmooth }, + { "C", AIO_CurveToCorner }, + + { "v", AIO_CurveToOmitC1Smooth }, + { "V", AIO_CurveToOmitC1Corner }, + { "y", AIO_CurveToOmitC2Smooth }, + { "Y", AIO_CurveToOmitC2Corner }, + + { "H", AIO_PathIgnoreNoReset }, + { "h", AIO_PathIgnoreNoResetClose }, + { "W", AIO_PathClipPath }, + { "N", AIO_PathIgnoreReset }, + { "n", AIO_PathIgnoreResetClose }, + { "F", AIO_PathFillNonZero }, + { "f", AIO_PathFillNonZeroClose }, + { "B", AIO_PathFillNoReset }, + { "b", AIO_PathFillNoResetClose }, + { "S", AIO_PathStroke }, + { "s", AIO_PathStrokeClose }, + { "D", AIO_SetWindingOrder }, + { "Z", AIO_FontEncoding }, + { "E", AIO_PatternDefinition }, + { "A", AIO_LockElement }, + + { "z", AIO_SetCurrentText }, + { "a", AIO_TextBlockFillStroke }, + { "e", AIO_TextBlockFill }, + { "I", AIO_TextBlockAppend }, + { "o", AIO_TextBlockIgnore }, + { "r", AIO_TextBlockStroke }, + { "t", AIO_TextOutput }, + { "T", AIO_TextBlockEnd }, + { "`", AIO_GsaveIncludeDocument }, + { "~", AIO_Grestore }, + + { "u", AIO_BeginGroupNoClip }, + { "U", AIO_EndGroupNoClip }, + { "*u", AIO_BeginCombination }, + { "*U", AIO_EndCombination }, + + { "XR", AIO_SetFillMode }, + + { NULL, AIO_Other } +}; + +static PSOperationMapping psMappings[] = { + { "get", PSO_Get }, + { "exec", PSO_Exec }, + { "string", PSO_String }, + { "bind", PSO_Bind }, + { "def", PSO_Def }, + { "userdict", PSO_Userdict }, + { "dict", PSO_Dict }, + { "dup", PSO_Dup }, + { "begin", PSO_Begin }, + { "put", PSO_Put }, + { NULL, PSO_Other }, +}; + +static CommentOperationMapping commentMappings[] = { + { "BeginProlog", CO_BeginProlog }, + { "BeginSetup", CO_BeginSetup }, + { "BeginProcSet", CO_BeginProcSet }, + { "BeginResource", CO_BeginResource }, + { "BeginEncoding", CO_BeginEncoding }, + { "BeginPattern", CO_BeginPattern }, + { "BeginDocument", CO_BeginPattern }, + { "Trailer", CO_Trailer }, + { "EndProlog", CO_EndProlog }, + { "EndSetup", CO_EndSetup }, + { "EndProcSet", CO_EndProcSet }, + { "EndResource", CO_EndResource }, + { "EndEncoding", CO_EndEncoding }, + { "EndPattern", CO_EndPattern }, + { "EndDocument", CO_EndDocument }, + + { "Title", CO_Title }, + { "Creator", CO_Creator }, + + { "EOF", CO_Ignore }, + { "Note", CO_Ignore }, + { "EndComments", CO_Ignore }, + { "PS-Adobe", CO_Ignore }, + + { "BoundingBox", CO_BoundingBox }, + { "TemplateBox", CO_TemplateBox }, + { "AI3_Margin", CO_Margin }, + + { "For", CO_For }, + { "CreationDate", CO_CreationDate }, + { "DocumentFonts", CO_DocumentFonts }, + { "DocumentFiles", CO_DocumentFiles }, + { "ColorUsage", CO_ColorUsage }, + { "DocumentProcSets", CO_DocumentProcSets }, + { "DocumentSuppliedProcSets", CO_DocumentSuppliedProcSets }, + + { "DocumentProcessColors", CO_DocumentProcessColors }, + { "DocumentCustomColors", CO_DocumentCustomColors }, + { "CMYKCustomColor", CO_CMYKCustomColor }, + { "TileBox", CO_TileBox }, + { "%+", CO_Continuation }, + + { "Template", CO_Template }, + { "PageOrigin", CO_PageOrigin }, + { "PrinterName", CO_PrinterName }, + { "PrinterRect", CO_PrinterRect }, + { "Note", CO_Note }, + + { "DocumentNeededResources", CO_DocumentNeededResources }, + + + { "IncludeFont", CO_IncludeFont }, + { "BeginBrushPattern", CO_BeginBrushPattern }, + { "EndBrushPattern", CO_EndBrushPattern }, + { "BeginGradient", CO_BeginGradient }, + { "EndGradient", CO_EndGradient }, + { "BeginPalette", CO_BeginPalette }, + { "EndPalette", CO_EndPalette }, + + { "IncludeFile", CO_IncludeFile }, + { "IncludeResource", CO_IncludeResource }, + + { NULL, CO_Other } +}; + +AIParserBase::AIParserBase() : m_debug(false), m_ignoring(false), m_sink (DS_Other), m_continuationMode(CM_None) + { + m_gstateHandler = NULL; + m_structureHandler = NULL; + m_pathHandler = NULL; + m_miscGStateHandler = NULL; + m_documentHandler = NULL; + m_moduleHandler = NULL; + m_embeddedHandler = NULL; + m_ai88Handler = new AI88Handler(this); + m_ai3Handler = new AI3Handler(this); +} + +AIParserBase::~AIParserBase(){ + delete m_ai88Handler; + delete m_ai3Handler; + +} + +bool AIParserBase::parse (QIODevice& fin){ + return AILexer::parse (fin); +} + +void AIParserBase::gotComment (const char *value) { + int llx, lly, urx, ury; + + CommentOperation cop = getCommentOperation (value); + switch (cop) { + case CO_BeginDocument : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Document, value); + break; + case CO_EndDocument : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Document, value); + break; + case CO_BeginPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Pattern, value); + break; + case CO_EndPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Pattern, value); + break; + case CO_BeginProlog : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Prolog, value); + break; + case CO_BeginProcSet : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_ProcSet, value); + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginResource : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Resource, value); + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginEncoding : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Encoding, value); + m_ignoring = false; + break; + case CO_IncludeFont : + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginBrushPattern : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_BrushPattern, value); + break; + case CO_BeginGradient : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Gradient, value); + break; + case CO_Trailer : + if (m_debug) qDebug ("start ignoring"); + m_ignoring = true; + break; + case CO_BeginPalette : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Palette, value); + break; + case CO_BeginSetup : + if (m_moduleHandler) m_moduleHandler->gotBeginSection (ST_Setup, value); + break; + case CO_EndSetup : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Setup, value); + break; + case CO_EndProlog : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Prolog, value); + break; + case CO_EndProcSet : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_ProcSet, value); + if (m_debug) qDebug ("stop ignoring"); + m_ignoring = false; + break; + case CO_EndResource : + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Resource, value); + if (m_debug) qDebug ("stop ignoring"); + m_ignoring = false; + break; + case CO_EndEncoding : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Encoding, value); + break; + case CO_EndBrushPattern : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_BrushPattern, value); + break; + case CO_EndGradient : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Gradient, value); + break; + case CO_EndPalette : + cleanupArrays(); + if (m_moduleHandler) m_moduleHandler->gotEndSection (ST_Palette, value); + break; + case CO_Ignore : + break; + case CO_BoundingBox : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotBoundingBox (llx, lly, urx, ury); + } + break; + case CO_TemplateBox : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotTemplateBox (llx, lly, urx, ury); + } + break; + case CO_Margin : + if (getRectangle (value, llx, lly, urx, ury)) + { + if (m_documentHandler) m_documentHandler->gotMargin (llx, lly, urx, ury); + } + break; + case CO_Title : + if (m_documentHandler) m_documentHandler->gotTitle (getValue (value)); + break; + case CO_Creator : + if (m_documentHandler) m_documentHandler->gotCreator (getValue (value)); + break; + case CO_DocumentFonts : + _handleDocumentFonts (value); + m_continuationMode = CM_DocumentFonts; + break; + case CO_DocumentFiles : + _handleDocumentFiles (value); + m_continuationMode = CM_DocumentFiles; + break; + case CO_DocumentCustomColors : + _handleDocumentCustomColors (value); + m_continuationMode = CM_DocumentFiles; + break; + case CO_CMYKCustomColor : + _handleCMYKCustomColor (value); + m_continuationMode = CM_CMYKCustomColor; + break; + case CO_DocumentNeededResources : + _handleDocumentNeededResources (value); + m_continuationMode = CM_DocumentNeededResources; + break; + case CO_DocumentProcessColors : + _handleDocumentProcessColors (value); + break; + case CO_CreationDate : + _handleCreationDate (value); + break; + case CO_IncludeFile : + break; + case CO_IncludeResource : + _handleIncludeResource (value); + break; + case CO_Continuation : + switch (m_continuationMode) { + case CM_DocumentFonts : _handleDocumentFonts (value); break; + case CM_DocumentFiles : _handleDocumentFiles (value); break; + case CM_DocumentCustomColors : _handleDocumentCustomColors (value); break; + case CM_CMYKCustomColor : _handleCMYKCustomColor (value); break; + case CM_DocumentNeededResources : _handleDocumentNeededResources (value); break; + + default : qWarning ("unknown continuation mode %d",m_continuationMode); + } + break; + + default : + qWarning( "unhandled comment: %s", value ); + } +} + +void AIParserBase::handleElement (AIElement &element) +{ + if (m_ignoring) return; + + if (m_sink == DS_Array) + { + if (m_debug) qDebug ("in mode array"); + QValueVector &elementArray = m_arrayStack.top(); + elementArray.push_back(element); + } + if (m_sink == DS_Block) + { + if (m_debug) qDebug ("in mode block"); + QValueVector &elementArray = m_blockStack.top(); + elementArray.push_back(element); + } + else + { + if (m_debug) qDebug ("in mode stack"); + m_stack.push (element); + } +} + +void AIParserBase::gotIntValue (int value) { + if (m_debug) qDebug ("got int value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got int value"); +} + +void AIParserBase::gotDoubleValue (double value) { + if (m_debug) qDebug ("got double value"); + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got double value"); +} + +void AIParserBase::gotStringValue (const char *value) { + if (m_debug) qDebug ("got string value"); + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) qDebug ("string: %s", value); + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got string value"); + +} + +void AIParserBase::gotReference (const char *value) { + if (m_debug) qDebug ("got reference value"); + + if (m_ignoring) return; + if (value == NULL) value = ""; + if (m_debug) qDebug ("reference: %s", value); + QString string(value); + AIElement element (string, AIElement::Reference); + handleElement (element); + if (m_debug) qDebug ("/got reference value"); + +} + +void AIParserBase::gotByte (uchar value) { + if (m_debug) qDebug ("got byte value"); + + if (m_ignoring) return; + AIElement element (value); + handleElement (element); + if (m_debug) qDebug ("/got byte value"); +} + +void AIParserBase::gotByteArray (const QByteArray &data) { + if (m_ignoring) return; + AIElement element (data); + handleElement (element); +} + + +void AIParserBase::gotArrayStart () { + if (m_ignoring) return; + if (m_debug) qDebug ("got array start"); + + QValueVector array; + m_arrayStack.push (array); + + m_sink = DS_Array; +} + +void AIParserBase::gotBlockStart () { + if (m_ignoring) return; + if (m_debug) qDebug ("got block start"); + + QValueVector array; + m_blockStack.push (array); + + m_sink = DS_Block; +} + +void AIParserBase::gotArrayEnd () { + if (m_ignoring) return; + if (m_debug) qDebug ("got array end"); + + QValueVector stackArray = m_arrayStack.pop(); + + if (m_arrayStack.empty()) + { + if (m_debug) qDebug ("put elements to stack"); + AIElement realElement (stackArray); + + if (m_debug) { + qDebug ("going to stack"); + elementtoa (realElement); + qDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) qDebug ("put elements to nest stack level"); + QValueVector currentTOS = m_arrayStack.top(); + currentTOS.push_back (stackArray); + } +} + +void AIParserBase::gotBlockEnd () { + if (m_ignoring) return; + if (m_debug) qDebug ("got block end"); + + QValueVector stackArray = m_blockStack.pop(); + + if (m_blockStack.empty()) + { + if (m_debug) qDebug ("put elements to stack"); + AIElement realElement (stackArray, AIElement::Block); + + if (m_debug) { + qDebug ("going to stack"); + elementtoa (realElement); + qDebug ("done"); + } + m_stack.push (realElement); + + m_sink = DS_Other; + } + else + { + if (m_debug) qDebug ("put elements to nest stack level"); + QValueVector currentTOS = m_blockStack.top(); + currentTOS.push_back (stackArray); + } +} + +/*Ai88*/ /* void AIParserBase::_handleSetDash() +{ + double fval = getDoubleValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + if (m_gstateHandler) m_gstateHandler->gotDash (aval, fval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorCMYK() +{ + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + + if (m_debug) qDebug ("values 1 are %f %f %f %f",c,m,y,k); + AIColor color (c,m,y,k); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillPattern() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = getDoubleValue(); + double k = getDoubleValue(); + double r = getDoubleValue(); + double rf = getDoubleValue(); + double angle = getDoubleValue(); + double sy = getDoubleValue(); + double sx = getDoubleValue(); + double py = getDoubleValue(); + double px = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_gstateHandler) m_gstateHandler->gotFillPattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokePattern() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ka = getDoubleValue(); + double k = getDoubleValue(); + double r = getDoubleValue(); + double rf = getDoubleValue(); + double angle = getDoubleValue(); + double sy = getDoubleValue(); + double sx = getDoubleValue(); + double py = getDoubleValue(); + double px = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + if (m_gstateHandler) m_gstateHandler->gotStrokePattern (name.latin1(), px, py, sx, sy, angle, rf, r, k, ka, aval); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorCMYK() +{ + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 2 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorGray() +{ + double g = getDoubleValue(); + if (m_debug) qDebug ("values 3 are %f",g); + + AIColor color (g); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorGray() +{ + double g = getDoubleValue(); + if (m_debug) qDebug ("values 4 are %f",g); + + AIColor color (g); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetFillColorCustom() +{ + double g = getDoubleValue(); + const QString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 5 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_gstateHandler) m_gstateHandler->gotFillColor (color); +} */ + +void AIParserBase::_handlePSGet() { + m_stack.pop(); + m_stack.pop(); + + QString name ("xxx"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSExec() { + m_stack.pop(); +} + +void AIParserBase::_handlePSString() { + m_stack.pop(); + + QString name ("stringval"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSBind() { + m_stack.pop(); + + QString name ("bindentry"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSUserdict() { + QString name ("userdict"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSDict() { + m_stack.pop(); + m_stack.pop(); + m_stack.pop(); + + QString name ("dict"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSDup() { + AIElement &tos = m_stack.top(); + + AIElement copy (tos); + m_stack.push (copy); +} + +void AIParserBase::_handlePSBegin() { + m_stack.pop(); + + QString name ("dictionary begin"); + AIElement ref (name,AIElement::Reference); + m_stack.push (ref); +} + +void AIParserBase::_handlePSPut() { + m_stack.pop(); + m_stack.pop(); +} + +/*Ai88*/ /* void AIParserBase::_handlePatternDefinition() +{ + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + double ury = getDoubleValue(); + double urx = getDoubleValue(); + double lly = getDoubleValue(); + double llx = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + + if (m_documentHandler) m_documentHandler->gotPatternDefinition (name.latin1(), aval, llx, lly, urx, ury); +} */ + +void AIParserBase::_handlePSDef() { + // name ref + m_stack.pop(); + + // impl + m_stack.pop(); +} + +/*Ai88*/ /* void AIParserBase::_handleSetStrokeColorCustom() +{ + double g = getDoubleValue(); + const QString &name = getStringValue(); + double k = getDoubleValue(); + double y = getDoubleValue(); + double m = getDoubleValue(); + double c = getDoubleValue(); + if (m_debug) qDebug ("values 6 are %f %f %f %f",c,m,y,k); + + AIColor color (c,m,y,k,name.latin1(),g); + + if (m_gstateHandler) m_gstateHandler->gotStrokeColor (color); +} */ + +void AIParserBase::_handleDocumentFonts(const char *) { +} + +void AIParserBase::_handleDocumentFiles(const char *) { +} + +void AIParserBase::_handleDocumentCustomColors(const char *) { +} + +void AIParserBase::_handleDocumentNeededResources(const char *data) { + if (!data) return; + QStringList items = QStringList::split (' ', data); + + QString itemType = items[1]; + QString name = items[2]; + QString version = items[3]; + QString release = items[4]; +} + +void AIParserBase::_handleIncludeResource(const char *data) { + if (!data) return; + QStringList items = QStringList::split (' ', data); + + QString itemType = items[1]; + QString name = items[2]; + QString version = items[3]; + QString release = items[4]; + + m_modules.push_back (name); +} + +void AIParserBase::_handleDocumentProcessColors(const char *data) { + if (!data) return; + + int colorSet = 0; + QString tmp (data); + + signed int index; + + index = tmp.find ("Cyan"); + if (index > 0) colorSet |= PC_Cyan; + + index = tmp.find ("Magenta"); + if (index > 0) colorSet |= PC_Magenta; + + index = tmp.find ("Yellow"); + if (index > 0) colorSet |= PC_Yellow; + + index = tmp.find ("Black"); + if (index > 0) colorSet |= PC_Black; + + if (m_documentHandler) m_documentHandler->gotProcessColors (colorSet); +} + +void AIParserBase::_handleCMYKCustomColor(const char *) { +} + +/*Ai88*/ /* void AIParserBase::_handleGsaveIncludeDocument() { + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &name = elem2.toString(); + + int ury = getIntValue(); + int urx = getIntValue(); + int lly = getIntValue(); + int llx = getIntValue(); + + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_embeddedHandler) m_embeddedHandler->gotGsaveIncludeDocument (aval, llx,lly,urx,ury,name.latin1()); +} */ + +/*Ai88*/ /* void AIParserBase::_handleSetCurrentText() { + int iAlign = getIntValue(); + TextAlign ta = TA_HLeft; + + switch (iAlign) + { + case 0 : ta = TA_HLeft; break; + case 1 : ta = TA_HCenter; break; + case 2 : ta = TA_HRight; break; + case 3: ta = TA_VTop; break; + case 4 : ta = TA_VCenter; break; + case 5 : ta = TA_VBottom; break; + } + + double kerning = getDoubleValue(); + double leading = getDoubleValue(); + double size = getDoubleValue(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + + const QString &fontname = elem2.toReference(); + + if (m_textHandler) m_textHandler->gotFontDefinition (fontname.latin1(), size, leading, kerning, ta); +} */ + +/*Ai88*/ /* void AIParserBase::_handleTextBlock (TextOperation to) { + AIElement elem (m_stack.top()); + qDebug ("to element is (%s)",elem.typeName()); + m_stack.pop(); + + const QValueVector aval = elem.toElementArray(); + + if (m_textHandler) m_textHandler->gotTextBlockBegin (aval, to); +} */ + +/*Ai88*/ /* void AIParserBase::_handleTextOutput () { + AIElement elem (m_stack.top()); + m_stack.pop(); + + const QString &text = elem.toString(); + + int length = -1; + + if (m_stack.empty()) + { + AIElement elem2 (m_stack.top()); + if (elem2.type() == AIElement::Int) + { + length = elem2.asInt(); + m_stack.pop(); + } + } + if (m_textHandler) m_textHandler->gotTextOutput (text.latin1(), length); +} */ + +void AIParserBase::_handleCreationDate (const char *data) +{ + if (!data) return; + + QRegExp test ("\\((.+)\\) \\((.+)\\)"); + if (test.search (data)) + { + QString val1 = test.cap(1); + QString val2 = test.cap(2); + + if (m_documentHandler) m_documentHandler->gotCreationDate (val1.latin1(),val2.latin1()); + } +} + +void AIParserBase::gotToken (const char *value) { + if (m_debug) qDebug ("got token"); + + if (m_ignoring) return; + if (m_debug) qDebug ("token: %s", value); + + if (m_sink == DS_Array) + { + if (m_debug) qDebug ("token in array"); + QString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + if (m_sink == DS_Block) + { + if (m_debug) qDebug ("token in block"); + QString op (value); + AIElement realElement (op, AIElement::Operator); + handleElement (realElement); + + return; + } + + if (m_debug) qDebug ("get ai operation"); + + AIOperation op = getAIOperation (value); +// PathElement pathElement; +// double fval; +// int ival; + + bool handled = false; + + handled = m_ai88Handler->handleAIOperation (op); + if (!handled) handled = m_ai3Handler->handleAIOperation (op); + + if (!handled) + { + if (m_sink == DS_Other) + { + if (handlePS (value)) return; + } + qWarning ( "unknown operator: %s", value ); + + QString string(value); + + if (m_modules.findIndex(string) != -1) + { + AIElement element (string, AIElement::Reference); + handleElement (element); + return; + } + + if (m_debug) stacktoa (m_stack); + qWarning ( "pushing %s to stack", value ); + AIElement element (string, AIElement::Operator); + handleElement (element); + } + + if (m_debug) qDebug ("/got token value"); +} + +bool AIParserBase::handlePS (const char *operand){ + if (m_ignoring) return false; + + PSOperation psop = getPSOperation (operand); + + switch (psop) + { + case PSO_Get : + _handlePSGet (); + return true; + case PSO_Exec : + _handlePSExec (); + return true; + case PSO_Def : + _handlePSDef (); + return true; + case PSO_String : + _handlePSString (); + return true; + case PSO_Bind : + _handlePSBind (); + return true; + case PSO_Userdict : + _handlePSUserdict (); + return true; + case PSO_Dict : + _handlePSDict (); + return true; + case PSO_Dup : + _handlePSDup (); + return true; + case PSO_Begin : + _handlePSBegin (); + return true; + case PSO_Put : + _handlePSPut (); + return true; + default: break; + } + return false; +} + +const double AIParserBase::getDoubleValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toDouble(); +} + +const int AIParserBase::getIntValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toInt(); +} + +const bool AIParserBase::getBoolValue(void) { + return getIntValue() == 1; +} + +const QString AIParserBase::getStringValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toString(); +} + +const QString AIParserBase::getOperatorValue(void) { + const AIElement &elem = m_stack.pop(); + + return elem.toOperator(); +} + +AIOperation AIParserBase::getAIOperation (const char *operand) +{ + int i=0; + QString cmpValue (operand); + + for(;;) { AIOperationMapping map = aiMappings[i]; + if (map.op == NULL) return AIO_Other; + if (cmpValue.compare (map.op) == 0) return map.action; + + i++; + } +} + +PSOperation AIParserBase::getPSOperation (const char *operand) +{ + int i=0; + QString cmpValue (operand); + + for(;;) { PSOperationMapping map = psMappings[i]; + if (map.op == NULL) return PSO_Other; + if (cmpValue.compare (map.op) == 0) return map.action; + + i++; + } +} + +CommentOperation AIParserBase::getCommentOperation (const char *command) { + QString data (command); + + signed int index; + + int i=0; + + for(;;) { + CommentOperationMapping map = commentMappings[i]; + if (map.op == NULL) return CO_Other; + index = data.find (map.op); + if (index >= 0) return map.action; + i++; + } +} + +void GStateHandlerBase::gotFillPattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData) { + qDebug ( "got fill pattern %s %f %f %f %f %f %f %f %f %f", pname, px, py, sx, sy, angle, rf, r, k, ka); + arraytoa (transformData); + qDebug ("/got fill pattern"); +} + +void GStateHandlerBase::gotStrokePattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData) { + qDebug ( "got stroke pattern %s %f %f %f %f %f %f %f %f %f", pname, px, py, sx, sy, angle, rf, r, k, ka); + arraytoa (transformData); + qDebug ("/got stroke pattern"); +} + +const char *AIParserBase::getValue (const char *input) { + QString data(input); + + signed int index = data.find (':'); + if (index < 0) return ""; + index++; + while (data.at(index) == ' ') index++; + return data.mid(index).latin1(); +} + +bool AIParserBase::getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury) { + if (input == NULL) return false; + + QString s(input); + if (s.contains ("(atend)")) return false; + QStringList values = QStringList::split (" ", input); + if (values.size() < 5) return false; + llx = values[1].toInt(); + lly = values[2].toInt(); + urx = values[3].toInt(); + ury = values[4].toInt(); + + return true; +} + +bool AIParserBase::getPoint (const char* input, int &x, int &y) { + if (input == NULL) return false; + + QString s(input); + QStringList values = QStringList::split (" ", input); + + if (values.size() < 3) return false; + + x = values[1].toInt(); + y = values[2].toInt(); + + return true; +} + +void AIParserBase::cleanupArrays() +{ + if (m_sink == DS_Array) qDebug ("unclosed array(s)."); + while (m_sink == DS_Array) gotArrayEnd (); + stacktoa (m_stack); +} + +/*Ai88*/ /* void AIParserBase::_handleFontEncoding() +{ + while (m_stack.top().type() != AIElement::Reference) { + m_stack.pop(); + } + + AIElement elem (m_stack.top()); + m_stack.pop(); + const QString &oldFont = elem.toReference(); + + AIElement elem2 (m_stack.top()); + m_stack.pop(); + const QString &newFont = elem2.toReference(); + + AIElement elem3 (m_stack.top()); + m_stack.pop(); + const QValueVector encodingData = elem3.toElementArray(); + + if (m_textHandler) m_textHandler->gotFontEncoding (encodingData, oldFont.latin1(), newFont.latin1()); +} */ + +void TextHandlerBase::gotFontEncoding (const QValueVector& encodingData, const char*oldFontName, const char*newFontName) +{ + qDebug ("font encoding %s to %s",oldFontName, newFontName); + arraytoa (encodingData); + qDebug ("/font encoding"); +} + +void TextHandlerBase::gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align) +{ + qDebug ("font definition: name %s size %f leading %f kerning %f align %d", fontName, size, leading, kerning, align); +} + +void TextHandlerBase::gotTextBlockBegin (const QValueVector& transData, TextOperation mode) +{ + qDebug ("text block begin %d",mode); + arraytoa (transData); + qDebug ("/text block begin"); +} + +void TextHandlerBase::gotTextOutput (const char*text, int length) +{ + qDebug ("text output (%s) %d",text,length); +} + +void TextHandlerBase::gotTextBlockEnd () +{ + qDebug ("text block end"); +} + +const void elementtoa (const AIElement &/*data*/) +{ +/* AIElement::Type type = data.type(); + qDebug ("type: %s", AIElement::typeToName (type)); + + switch (type) + { + case AIElement::String : + case AIElement::CString : + case AIElement::Int : + case AIElement::UInt : + case AIElement::Double : + qDebug ("string value : %s",data.toString().latin1()); + break; + case AIElement::Reference : + qDebug ("string value : %s",data.toReference().latin1()); + break; + case AIElement::Operator : + qDebug ("string value : %s",data.toOperator().latin1()); + break; + case AIElement::ElementArray : + arraytoa (data.toElementArray()); + break; + case AIElement::Block : + arraytoa (data.toBlock()); + break; + + default : + qDebug ("could not fetch data"); + } */ +} + +const void arraytoa (const QValueVector &/*data*/) +{ +/* qDebug ("array size is %d ",data.size()); + if (data.size() > 0) + { + qDebug ("[[[[[[[[[[[[[[[[[[[["); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + qDebug ("]]]]]]]]]]]]]]]]]]]]"); + } */ +} + +const void stacktoa (const QValueStack &/*data*/) +{ +/* qDebug ("stack size is %d",data.size()); + if (data.size() > 0) + { + qDebug ("<<<<<<<<<<<<<<<<<<"); + for (uint i=0; i< data.size(); i++) + { + elementtoa (data[i]); + } + } + qDebug (">>>>>>>>>>>>>>>>>>"); */ +} + +const void stacktoa2 (const QValueStack >&/*data*/) +{ +/* qDebug ("stack size is %d",data.size()); + + if (data.size() > 0) + { + qDebug ("((((((((((((((((((((((("); + for (uint i=0; i< data.size(); i++) + { + arraytoa (data[i]); + } + qDebug (")))))))))))))))))))))))"); + } */ +} + +const void aiotoa (AIOperation &data) +{ + switch (data) + { + case AIO_SetFillColorCMYK : qDebug ("AIO_SetFillColorCMYK"); break; + case AIO_SetStrokeColorCMYK : qDebug ("AIO_SetStrokeColorCMYK"); break; + case AIO_SetFillColorGray : qDebug ("AIO_SetFillColorGray"); break; + case AIO_SetStrokeColorGray : qDebug ("AIO_SetStrokeColorGray"); break; + case AIO_SetFillColorCustom : qDebug ("AIO_SetFillColorCustom"); break; + case AIO_SetStrokeColorCustom : qDebug ("AIO_SetStrokeColorCustom"); break; + case AIO_SetFillPattern : qDebug ("AIO_SetFillPattern"); break; + case AIO_SetStrokePattern : qDebug ("AIO_SetStrokePattern"); break; + case AIO_SetFillOverprinting : qDebug ("AIO_SetFillOverprinting"); break; + case AIO_SetStrokeOverprinting : qDebug ("AIO_SetStrokeOverprinting"); break; + case AIO_SetFlatness : qDebug ("AIO_SetFlatness"); break; + case AIO_SetLineCap : qDebug ("AIO_SetLineCap"); break; + case AIO_SetLineJoin : qDebug ("AIO_SetLineJoin"); break; + case AIO_SetLineWidth : qDebug ("AIO_SetLineWidth"); break; + case AIO_SetMiterLimit : qDebug ("AIO_SetMiterLimit"); break; + case AIO_SetDash : qDebug ("AIO_SetDash"); break; + case AIO_BeginGroupClip : qDebug ("AIO_BeginGroupClip"); break; + case AIO_EndGroupClip : qDebug ("AIO_EndGroupClip"); break; + case AIO_MoveTo : qDebug ("AIO_MoveTo"); break; + case AIO_LineToCorner : qDebug ("AIO_LineToCorner"); break; + case AIO_LineToSmooth : qDebug ("AIO_LineToSmooth"); break; + case AIO_CurveToSmooth : qDebug ("AIO_CurveToSmooth"); break; + case AIO_CurveToCorner : qDebug ("AIO_CurveToCorner"); break; + case AIO_CurveToOmitC1Smooth : qDebug ("AIO_CurveToOmitC1Smooth"); break; + case AIO_CurveToOmitC1Corner : qDebug ("AIO_CurveToOmitC1Corner"); break; + case AIO_CurveToOmitC2Smooth : qDebug ("AIO_CurveToOmitC2Smooth"); break; + case AIO_CurveToOmitC2Corner : qDebug ("AIO_CurveToOmitC2Corner"); break; + case AIO_PathIgnoreNoReset : qDebug ("AIO_PathIgnoreNoReset"); break; + case AIO_PathIgnoreNoResetClose : qDebug ("AIO_PathIgnoreNoResetClose"); break; + case AIO_PathClipPath : qDebug ("AIO_PathClipPath"); break; + case AIO_PathIgnoreReset : qDebug ("AIO_PathIgnoreReset"); break; + case AIO_PathIgnoreResetClose : qDebug ("AIO_PathIgnoreResetClose"); break; + case AIO_PathFillNonZero : qDebug ("AIO_PathFillNonZero"); break; + case AIO_PathFillNonZeroClose : qDebug ("AIO_PathFillNonZeroClose"); break; + case AIO_PathStroke : qDebug ("AIO_PathStroke"); break; + case AIO_PathStrokeClose : qDebug ("AIO_PathStrokeClose"); break; + case AIO_PathFillNoReset : qDebug ("AIO_PathFillNoReset"); break; + case AIO_PathFillNoResetClose : qDebug ("AIO_PathFillNoResetClose"); break; + case AIO_FontEncoding : qDebug ("AIO_FontEncoding"); break; + case AIO_PatternDefinition : qDebug ("AIO_PatternDefinition"); break; + case AIO_SetCurrentText : qDebug ("AIO_SetCurrentText"); break; + case AIO_TextBlockFillStroke : qDebug ("AIO_TextBlockFillStroke"); break; + case AIO_TextBlockFill : qDebug ("AIO_TextBlockFill"); break; + case AIO_TextBlockAppend : qDebug ("AIO_TextBlockAppend"); break; + case AIO_TextBlockIgnore : qDebug ("AIO_TextBlockIgnore"); break; + case AIO_TextBlockStroke : qDebug ("AIO_TextBlockStroke"); break; + case AIO_TextOutput : qDebug ("AIO_TextOutput"); break; + case AIO_TextBlockEnd : qDebug ("AIO_TextBlockEnd"); break; + case AIO_GsaveIncludeDocument : qDebug ("AIO_GsaveIncludeDocument"); break; + case AIO_Grestore : qDebug ("AIO_Grestore"); break; + case AIO_LockElement : qDebug ("AIO_LockElement"); break; + case AIO_SetWindingOrder : qDebug ("AIO_SetWindingOrder"); break; + default : qDebug ("unknown"); + } +} + +const void sttoa (SectionType &data, bool begin) +{ + switch (data) + { + case ST_Setup : begin ? qDebug ("start setup") : qDebug ("end setup"); break; + case ST_Prolog : begin ? qDebug ("start prolog") : qDebug ("end prolog"); break; + case ST_ProcSet : begin ? qDebug ("start procset") : qDebug ("end procset"); break; + case ST_Encoding : begin ? qDebug ("start encoding") : qDebug ("end encoding"); break; + case ST_Pattern : begin ? qDebug ("start pattern") : qDebug ("end pattern"); break; + case ST_Document : begin ? qDebug ("start document") : qDebug ("end document"); break; + case ST_BrushPattern : begin ? qDebug ("start brush pattern") : qDebug ("end brush pattern"); break; + case ST_Gradient : begin ? qDebug ("start gradient") : qDebug ("end gradient"); break; + case ST_Palette : begin ? qDebug ("start palette") : qDebug ("end palette"); break; + case ST_Resource : begin ? qDebug ("start resource") : qDebug ("end resouce"); break; + + default : begin ? qDebug ("unknown") : qDebug ("end unknown"); + } +} + diff --git a/filters/karbon/ai/aiparserbase.h b/filters/karbon/ai/aiparserbase.h new file mode 100644 index 000000000..8d2633f3f --- /dev/null +++ b/filters/karbon/ai/aiparserbase.h @@ -0,0 +1,440 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schönberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef AIPARSERBASE_H +#define AIPARSERBASE_H + +#include "ailexer.h" + +#include +#include +#include +#include + +#include "aielement.h" +#include "aicolor.h" + + +const void arraytoa (const QValueVector &data); +const void elementtoa (const AIElement &data); +const void stacktoa (const QValueStack &data); +const void stacktoa2 (const QValueStack >&data); + +class GStateHandlerBase; +class StructureHandlerBase; +class PathHandlerBase; +class MiscGStateHandlerBase; +class DocumentHandlerBase; +class ModuleHandlerBase; +class EmbeddedHandlerBase; +class TextHandlerBase; +class AI88Handler; +class AI3Handler; + +/** + *@author Dirk Schönberger + */ + +typedef enum { PET_MoveTo, PET_LineTo, PET_CurveTo, PET_CurveToOmitC1, PET_CurveToOmitC2 } PathElementType; +typedef enum { PT_Smooth, PT_Corner } PointType; +typedef enum { TO_FillStroke, TO_Fill, TO_Append, TO_Ignore, TO_Stroke } TextOperation; +typedef enum { FM_NonZero=0, FM_EvenOdd=1 } FillMode; +typedef enum { FS_Roman, FS_Kanji } FontScript; + +typedef enum { DS_Array, DS_Block, DS_Other } DataSink; +typedef enum { ST_Setup, ST_Prolog, ST_ProcSet, ST_Encoding, ST_Pattern, ST_Document, ST_BrushPattern, ST_Gradient, ST_Palette, ST_Resource } SectionType; + +typedef enum { TA_HLeft, TA_HCenter, TA_HRight, TA_VTop, TA_VCenter, TA_VBottom } TextAlign; + +#define PC_Cyan 0x0001 +#define PC_Magenta 0x0002 +#define PC_Yellow 0x0004 +#define PC_Black 0x0008 + +typedef enum { + /* AI 88 */ + AIO_SetFillColorCMYK, AIO_SetStrokeColorCMYK, + AIO_SetFillColorGray, AIO_SetStrokeColorGray, + AIO_SetFillColorCustom, AIO_SetStrokeColorCustom, + AIO_SetFillPattern, AIO_SetStrokePattern, + AIO_SetFillOverprinting, AIO_SetStrokeOverprinting, + AIO_SetFlatness, AIO_SetLineCap, AIO_SetLineJoin, + AIO_SetLineWidth, AIO_SetMiterLimit, AIO_SetDash, + AIO_BeginGroupClip, AIO_EndGroupClip, + AIO_MoveTo, + AIO_LineToCorner, + AIO_LineToSmooth, + AIO_CurveToSmooth, + AIO_CurveToCorner, + AIO_CurveToOmitC1Smooth, + AIO_CurveToOmitC1Corner, + AIO_CurveToOmitC2Smooth, + AIO_CurveToOmitC2Corner, + + AIO_PathIgnoreNoReset, AIO_PathIgnoreNoResetClose, + AIO_PathClipPath, + AIO_PathIgnoreReset, AIO_PathIgnoreResetClose, + AIO_PathFillNonZero, AIO_PathFillNonZeroClose, + AIO_PathStroke, AIO_PathStrokeClose, + AIO_PathFillNoReset, AIO_PathFillNoResetClose, + + AIO_FontEncoding, + AIO_PatternDefinition, + + AIO_SetCurrentText, + AIO_TextBlockFillStroke, + AIO_TextBlockFill, + AIO_TextBlockAppend, + AIO_TextBlockIgnore, + AIO_TextBlockStroke, + AIO_TextOutput, + AIO_TextBlockEnd, + + AIO_GsaveIncludeDocument, + AIO_Grestore, + + AIO_LockElement, + + /* AI 3 */ + AIO_SetWindingOrder, + AIO_SetFillMode, + + AIO_BeginGroupNoClip, AIO_EndGroupNoClip, + AIO_BeginCombination, AIO_EndCombination, + + AIO_Other +} AIOperation; + +typedef enum { + PSO_Get, + PSO_Exec, + PSO_Def, + PSO_String, + PSO_Bind, + PSO_Userdict, + PSO_Dict, + PSO_Dup, + PSO_Begin, + PSO_Put, + PSO_Other +} PSOperation; + +typedef enum { + CU_BlackWhite, + CU_Color, + CU_Unknown +} ColorUsage; + +typedef enum { + CO_BeginSetup, CO_EndSetup, + CO_BeginProlog, CO_EndProlog, + CO_BeginProcSet, CO_EndProcSet, + CO_BeginEncoding, CO_EndEncoding, + CO_BeginPattern, CO_EndPattern, + CO_IncludeFile, + CO_BeginDocument, CO_EndDocument, + + CO_Trailer, + CO_BoundingBox, + CO_TemplateBox, + CO_Margin, + CO_Title, + CO_Creator, + CO_Other, +/**/ CO_For, + CO_CreationDate, +/**/ CO_DocumentFonts, +/**/ CO_DocumentFiles, +/**/ CO_ColorUsage, +/**/ CO_DocumentProcSets, +/**/ CO_DocumentSuppliedProcSets, + CO_DocumentProcessColors, +/**/ CO_DocumentCustomColors, +/**/ CO_CMYKCustomColor, +/**/ CO_TileBox, + CO_Continuation, +/**/ CO_Note, + + // AI88 Win +/**/ CO_Template, +/**/ CO_PageOrigin, +/**/ CO_PrinterName, +/**/ CO_PrinterRect, + + // AI8 + CO_BeginBrushPattern, CO_EndBrushPattern, + CO_BeginGradient, CO_EndGradient, + CO_BeginPalette, CO_EndPalette, + + // other + CO_BeginResource, CO_EndResource, + CO_IncludeFont, + CO_IncludeResource, + CO_DocumentNeededResources, + + CO_Ignore +} CommentOperation; + +typedef enum { + CM_DocumentFonts = 1, + CM_DocumentFiles = 2, + CM_DocumentCustomColors = 3, + CM_CMYKCustomColor = 4, + CM_DocumentNeededResources = 5, + CM_None = -1 +} ContinuationMode; + +typedef enum { +/**/ PDO_ColorDefinition, +/**/ PDO_TileDefinition +} PatternDefinitionOperation; + +/**/ +#define PatternTileFilledDefiniton "_" +#define TextSizeUnknown -1 + +/* typedef QValueVector ElementArray; +typedef QValueStack ElementStack; +typedef QValueStack ElementArrayStack; */ + +typedef struct { + PathElementType petype; + union { + struct { + float x, y; + } pointdata; + struct { + float x1, y1, x2, y2, x3, y3; + } bezierdata; + } pevalue; + PointType pttype; +} PathElement; + +class AIParserBase : protected AILexer { + friend class AI88Handler; + friend class AI3Handler; + +protected: + bool m_debug; +private: + bool m_ignoring; + QValueStack m_stack; + QValueStack > m_arrayStack; + QValueStack > m_blockStack; + DataSink m_sink; + QValueList m_modules; + ContinuationMode m_continuationMode; + + const double getDoubleValue(void); + const int getIntValue(void); + const bool getBoolValue(void); + const QString getStringValue(void); + const QString& getReferenceValue(void); + const QString getOperatorValue(void); + +/*Ai88*/ // void _handleSetDash(); +/*Ai88*/ // void _handleGsaveIncludeDocument(); +/*Ai88*/ // void _handleSetStrokeColorCMYK(); +/*Ai88*/ // void _handleSetFillColorCMYK(); +/*Ai88*/ // void _handleSetStrokeColorGray(); +/*Ai88*/ // void _handleSetFillColorGray(); +/*Ai88*/ // void _handleSetStrokeColorCustom(); +/*Ai88*/ // void _handleSetFillColorCustom(); +/*Ai88*/ // void _handleSetFillPattern(); +/*Ai88*/ // void _handleSetStrokePattern(); + +/*Ai88*/ // void _handlePatternDefinition(); +/*Ai88*/ // void _handleFontEncoding(); + + void _handlePSGet(); + void _handlePSExec(); + void _handlePSDef(); + void _handlePSString(); + void _handlePSBind(); + void _handlePSUserdict(); + void _handlePSDict(); + void _handlePSDup(); + void _handlePSBegin(); + void _handlePSPut(); + + void _handleDocumentFonts(const char *data); + void _handleDocumentFiles(const char *data); + void _handleDocumentCustomColors(const char *data); + void _handleCMYKCustomColor(const char *data); + void _handleDocumentProcessColors(const char *data); + void _handleDocumentNeededResources(const char *data); + void _handleIncludeResource(const char *data); + +/*Ai88*/ // void _handleSetCurrentText(); +/*Ai88*/ // void _handleTextBlock (TextOperation to); +/*Ai88*/ // void _handleTextOutput (); + + void _handleCreationDate (const char *data); + + AIOperation getAIOperation (const char *operand); + PSOperation getPSOperation (const char *operand); + CommentOperation getCommentOperation (const char *command); + + bool handlePS (const char *operand); + + const char *getValue (const char *input); + bool getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury); + bool getPoint (const char* input, int &x, int &y); +protected: + void gotComment (const char *value); + void gotIntValue (int value); + void gotDoubleValue (double value); + void gotStringValue (const char *value); + void gotToken (const char *value); + void gotReference (const char *value); + void gotBlockStart (); + void gotBlockEnd (); + void gotArrayStart (); + void gotArrayEnd (); + void gotByte (uchar value); + void gotByteArray (const QByteArray &data); + + GStateHandlerBase *m_gstateHandler; + StructureHandlerBase *m_structureHandler; + PathHandlerBase *m_pathHandler; + MiscGStateHandlerBase *m_miscGStateHandler; + DocumentHandlerBase *m_documentHandler; + ModuleHandlerBase *m_moduleHandler; + EmbeddedHandlerBase *m_embeddedHandler; + TextHandlerBase *m_textHandler; + AI88Handler *m_ai88Handler; + AI3Handler *m_ai3Handler; + +private: + void handleElement (AIElement &element); + void cleanupArrays(); +public: + AIParserBase(); + ~AIParserBase(); + + bool parse (QIODevice& fin); +}; + +const void aiotoa (AIOperation &data); +const void sttoa (SectionType &data, bool begin); + +class GStateHandlerBase +{ + public: + GStateHandlerBase() {} + virtual ~GStateHandlerBase() {} + + virtual void gotFillColor (AIColor &) {} + virtual void gotStrokeColor (AIColor &) {} + virtual void gotFillPattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData); + virtual void gotStrokePattern (const char *pname, double px, double py, double sx, double sy, double angle, double rf, double r, double k, double ka, const QValueVector& transformData); + virtual void gotFlatness (double) {} + virtual void gotLineWidth (double) {} + virtual void gotLineCaps (int) {} + virtual void gotLineJoin (int) {} + virtual void gotMiterLimit (double) {} + virtual void gotWindingOrder (int) {} + virtual void gotDash (const QValueVector& /*dashData*/, double /*phase*/) {} +}; + +class StructureHandlerBase { + public: + StructureHandlerBase() {} + virtual ~StructureHandlerBase() {} + + virtual void gotBeginGroup (bool /*clipping*/) {} + virtual void gotEndGroup (bool /*clipping*/) {} + virtual void gotBeginCombination () {} + virtual void gotEndCombination () {} +}; + +class PathHandlerBase { + public: + PathHandlerBase() {} + virtual ~PathHandlerBase() {} + + virtual void gotPathElement (PathElement &) {} + virtual void gotFillPath (bool /*closed*/, bool /*reset*/) {} + virtual void gotStrokePath (bool /*closed*/) {} + virtual void gotIgnorePath (bool /*closed*/, bool /*reset*/) {} + virtual void gotClipPath (bool /*closed*/) {} + virtual void gotFillMode (FillMode) {} +}; + +class MiscGStateHandlerBase { + public: + MiscGStateHandlerBase() {} + virtual ~MiscGStateHandlerBase() {} + + virtual void gotLockNextObject (bool /*value*/) {} + virtual void gotFillOverprinting (bool /*value*/) {} + virtual void gotStrokeOverprinting (bool /*value*/) {} +}; + +class DocumentHandlerBase { + public: + DocumentHandlerBase() {} + virtual ~DocumentHandlerBase() {} + + virtual void gotBoundingBox (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotTemplateBox (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotMargin (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotPrinterRect (int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/) {} + virtual void gotPrinterName (const char *) {} + virtual void gotPageOrigin (int /*x*/, int /*y*/) {} + virtual void gotTemplate (const char *) {} + virtual void gotTitle (const char *) {} + virtual void gotCreator (const char *) {} + virtual void gotPatternDefinition (const char */*name*/, const QValueVector& /*layerData*/, double /*llx*/, double /*lly*/, double /*urx*/, double /*ury*/) {} + virtual void gotCreationDate (const char */*val1*/,const char */*val2*/) {} + virtual void gotProcessColors (int /*colors*/) {} +}; + +class ModuleHandlerBase { + public: + ModuleHandlerBase() {} + virtual ~ModuleHandlerBase() {} + + virtual void gotBeginSection (SectionType, const char *) {} + virtual void gotEndSection (SectionType, const char *) {} +}; + +class EmbeddedHandlerBase { + public: + EmbeddedHandlerBase() {} + virtual ~EmbeddedHandlerBase() {} + + virtual void gotGsaveIncludeDocument (const QValueVector& /*transData*/, int /*llx*/, int /*lly*/, int /*urx*/, int /*ury*/, const char*/*fileName*/) {} + virtual void gotGrestore () {} +}; + +class TextHandlerBase { + public: + TextHandlerBase() {} + virtual ~TextHandlerBase() {} + + virtual void gotFontEncoding (const QValueVector& encodingData, const char*oldFontName, const char*newFontName); + virtual void gotFontDefinition (const char*fontName, double size, double leading, double kerning, TextAlign align); + virtual void gotTextBlockBegin (const QValueVector& transData, TextOperation mode); + virtual void gotTextOutput (const char*text, int length=-1); + virtual void gotTextBlockEnd (); +}; + +#endif + diff --git a/filters/karbon/ai/karbon_ai_import.desktop b/filters/karbon/ai/karbon_ai_import.desktop new file mode 100644 index 000000000..bec797b29 --- /dev/null +++ b/filters/karbon/ai/karbon_ai_import.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 Illustrator Import Filter +Name[af]=Karbon14 Illustreerder In voer Filter +Name[ar]=مِرْشَح استيراد Illustrator لدى Karbon14 +Name[bg]=Филтър за импортиране от Illustrator в Karbon14 +Name[br]=Sil enporzh Illustrator evit Karbon14 +Name[ca]=Filtre d'importació Illustrator per a Karbon14 +Name[cs]=Importní filtr souborů aplikace Illustrator pro Karbon14 +Name[cy]=Hidlen Fewnforio Illustrator Karbon14 +Name[da]=Karbon14 Illustrator-importfilter +Name[de]=Karbon14 Illustrator-Importfilter +Name[el]=Φίλτρο εισαγωγής Illustrator του Karbon14 +Name[eo]=Importfiltrilo por Karbon-Ilustrilo +Name[es]=Filtro de importación Karbon14 Illustrator +Name[et]=Karbon14 Illustrator'i impordifilter +Name[eu]=Karbon14 ilustratzailearen inportaziorako iragazkia +Name[fa]=پالایۀ واردات تصویرگر Karbon14 +Name[fi]=Karbon14 Illustrator -tuontisuodin +Name[fr]=Filtre d'importation Illustrator vers Karbon 14 +Name[fy]=Illustrator-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iompórtála Karbon14 Illustrator +Name[gl]=Filtro de Importación de Illustrator para Karbon14 +Name[he]=מסנן ייבוא מ־Illustrator ל־Karbon14 +Name[hi]=कार्बन 14 इलस्ट्रेटर आयात छननी +Name[hr]=Karbon14 Illustrator filtar uvoza +Name[hu]=Karbon14 Illustrator importszűrő +Name[is]=Karbon14 Illustrator innflutningssía +Name[it]=Filtro di importazione Illustrator per Karbon14 +Name[ja]=Karbon14 Illustrator インポートフィルタ +Name[km]=តម្រង​នាំចូល​វិចិត្រសាល​សម្រាប់ Karbon ១៤ +Name[lo]=ຕົວຕອງການນຳເຂົ້າ Illustrator +Name[lt]=Karbon14 Illustrator importavimo filtras +Name[lv]=Karbon14 Ilustratora importa filtrs +Name[ms]=Penapis Import Karbon14 Illustrator +Name[mt]=Filtru għall-importazzjoni Illustrator għal Karbon14 +Name[nb]=Illustrator-importfilter for Karbon14 +Name[nds]=Illustrator-Importfilter för Karbon14 +Name[ne]=कार्बन१४ ब्याख्याकर्ता आयात फिल्टर +Name[nl]=Illustrator-importfilter voor Karbon14 +Name[nn]=Illustrator-importfilter for Karbon14 +Name[pl]=Filtr importu formatu Illustrator do Karbon14 +Name[pt]=Filtro de Importação de Illustrator para o Karbon14 +Name[pt_BR]=Filtro de Importação Illustrator do Karbon14 +Name[ro]=Filtru importare Karbon14 pentru Illustrator +Name[ru]=Фильтр импорта файлов Illustrator в Karbon14 +Name[se]=Karbon14:a Illustrator-sisafievrridansilli +Name[sk]=Illustrator filter pre import do Karbon14 +Name[sl]=Uvozni filter Illustrator za Karbon14 +Name[sr]=Karbon14-ов филтер за увоз из Illustrator-а +Name[sr@Latn]=Karbon14-ov filter za uvoz iz Illustrator-a +Name[sv]=Karbon14 Illustrator-importfilter +Name[ta]=Karbon 14 Illustrator இறக்குமதி வடிகட்டி +Name[tg]=Karbon14 EPS Филтри Воридоти Иллюстратор +Name[th]=ตัวกรองการนำเข้า Illustrator ของคาร์บอน14 +Name[tr]=Karbon14 Illustrator Alma Filtresi +Name[uk]=Фільтр імпорту Illustrator для Karbon14 +Name[uz]=Karbon14 Illustrator import filteri +Name[uz@cyrillic]=Karbon14 Illustrator импорт филтери +Name[xh]=Isihluzi Sokurhweba Somzobi we Karbon 14 +Name[zh_CN]=Karbon14 Illustrator 导入过滤器 +Name[zh_TW]=Karbon14 Illustrator 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/illustrator +X-KDE-Weight=1 +X-KDE-Library=libkarbonaiimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/ai/karbonaiparserbase.cc b/filters/karbon/ai/karbonaiparserbase.cc new file mode 100644 index 000000000..8c2b5a5f5 --- /dev/null +++ b/filters/karbon/ai/karbonaiparserbase.cc @@ -0,0 +1,637 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schönberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "karbonaiparserbase.h" + +#include +#include +#include +#include +#include +#include "aicolor.h" +#include +#include + +#include + +const void pottoa (PathOutputType &data); + +// generic +KarbonAIParserBase::KarbonAIParserBase() : m_pot(POT_Other), m_ptt (PTT_Output), m_bbox(0,0,612,792), m_emptyFill(), m_emptyStroke() +/* , m_strokeColor(), m_fillColor() */ { + + // A4, 70 dpi +/* m_bbox.llx = 0; + m_bbox.lly = 0; + m_bbox.urx = 612; + m_bbox.ury = 792; */ + +/* m_lineWidth = 0; + m_flatness = 0; + m_lineCaps = 0; + m_lineJoin = 0; + m_miterLimit = 10; */ + m_windingOrder = 0; + + m_fm = FM_NonZero; + + m_curKarbonPath = new VPath( 0L ); + + m_document = new VDocument(); + m_layer = NULL; + m_combination = NULL; + + m_emptyFill.setType (VFill::none); + m_emptyStroke.setType (VStroke::none); + + setupHandlers(); +} + +// generic +KarbonAIParserBase::~KarbonAIParserBase(){ + teardownHandlers(); + delete m_curKarbonPath; + + delete m_document; +} + +// generic +void KarbonAIParserBase::parsingStarted(){ +// qDebug ( getHeader().latin1() ); +} + +// generic +void KarbonAIParserBase::parsingFinished(){ +// qDebug ( getFooter().latin1() ); + + // handle bounding box + if (m_document) + { + kdDebug() << "bbox 1 is " << m_bbox << endl; + + if (m_bbox.width() > 0. ) + m_document->setWidth (m_bbox.width()); + if (m_bbox.height() > 0. ) + m_document->setHeight (m_bbox.height()); + +/* QWMatrix matrix; + matrix.translate (-m_bbox.x(),-m_bbox.y()); + + VTransformNodes translator (matrix); + m_document->accept (translator); */ + VTranslateCmd cmd (0L, -m_bbox.x(), -m_bbox.y()); + m_document->accept (cmd); + } +} + +// generic +QString KarbonAIParserBase::getParamList(Parameters& params){ + QString data(""); + + Parameter *param; + + if (params.count() > 0) + { + + for ( param=params.first(); param != 0; param=params.next() ) { + data += " " + param->first + "=\"" + param->second + "\""; + } + } + + return data; +} + +// generic +void KarbonAIParserBase::gotStartTag (const char *tagName, Parameters& params){ + qDebug ("<%s%s>", tagName, getParamList (params).latin1() ); +} + +// generic +void KarbonAIParserBase::gotEndTag (const char *tagName){ + qDebug ("", tagName ); +} + +// generic +void KarbonAIParserBase::gotSimpleTag (const char *tagName, Parameters& params){ + qDebug ("<%s%s/>", tagName, getParamList (params).latin1() ); +} + +// generic +void KarbonAIParserBase::gotPathElement (PathElement &element){ + switch (element.petype) + { + case PET_MoveTo : + m_curKarbonPath->moveTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y)); + break; + case PET_LineTo : + m_curKarbonPath->lineTo (KoPoint (element.pevalue.pointdata.x,element.pevalue.pointdata.y)); + break; + case PET_CurveTo : + m_curKarbonPath->curveTo (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1), + KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + case PET_CurveToOmitC1 : + m_curKarbonPath->curve1To (KoPoint (element.pevalue.bezierdata.x2,element.pevalue.bezierdata.y2), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + case PET_CurveToOmitC2 : + m_curKarbonPath->curve2To (KoPoint (element.pevalue.bezierdata.x1,element.pevalue.bezierdata.y1), + KoPoint (element.pevalue.bezierdata.x3,element.pevalue.bezierdata.y3)); + break; + } +} + +// generic +void KarbonAIParserBase::gotFillPath (bool closed, bool reset, FillMode /*fm*/){ +// qDebug ("found fill path"); +// if (!reset) qDebug ("retain filled path"); + + if (closed) m_curKarbonPath->close(); + + if (!reset) + m_pot = POT_Filled; + else + { + doOutputCurrentPath2 (POT_Filled); + m_pot = POT_Other; + } +} + +// generic +void KarbonAIParserBase::gotIgnorePath (bool closed, bool reset){ +// qDebug ("found ignore path"); + + if (closed) m_curKarbonPath->close(); + + if (! reset) + m_pot = POT_Other; + else + { + doOutputCurrentPath2 (POT_Ignore); + m_pot = POT_Other; + } +} + +// generic +void KarbonAIParserBase::gotStrokePath (bool closed) { +// qDebug ("found stroke path"); + + if (closed) m_curKarbonPath->close(); + + PathOutputType pot = POT_Stroked; + if (m_pot != POT_Other) + { + pot = POT_FilledStroked; + } + + doOutputCurrentPath2 (pot); + + m_pot = POT_Other; +} + +// generic +void KarbonAIParserBase::gotClipPath (bool /*closed*/){ + + doOutputCurrentPath2 (POT_Clip); +} + +// generic +void KarbonAIParserBase::gotFillColor (AIColor &color){ +// double r, g, b; +// color.toRGB (r,g,b); +// qDebug ("set fillcolor to %f %f %f",r,g,b); +// m_fillColor = color; + + VColor karbonColor = toKarbonColor (color); + m_fill.setColor (karbonColor); +} + +// generic +void KarbonAIParserBase::gotStrokeColor (AIColor &color){ +// double r, g, b; +// color.toRGB (r,g,b); +// qDebug ("set strokecolor to %f %f %f",r,g,b); +// m_strokeColor = color; + + VColor karbonColor = toKarbonColor (color); + m_stroke.setColor (karbonColor); +} + +// generic +void KarbonAIParserBase::gotBoundingBox (int llx, int lly, int urx, int ury){ +/* m_bbox.llx = llx; + m_bbox.lly = lly; + m_bbox.urx = urx; + m_bbox.ury = ury; */ + m_bbox.setCoords(llx,lly,urx,ury); +} + +void KarbonAIParserBase::gotLineWidth (double val){ +// m_lineWidth = val; + m_stroke.setLineWidth (val); +} + +void KarbonAIParserBase::gotFlatness (double /*val*/) +{ +// m_flatness = val; +// m_stroke.setFlatness (val); +} + +void KarbonAIParserBase::gotLineCaps (int val) +{ +// m_lineCaps = val; + VStroke::VLineCap lineCap = VStroke::capButt; + + switch (val) + { + case 0 : lineCap = VStroke::capButt; break; + case 1 : lineCap = VStroke::capRound; break; + case 2 : lineCap = VStroke::capSquare; break; + } + + m_stroke.setLineCap (lineCap); +} + +void KarbonAIParserBase::gotLineJoin (int val) +{ +// m_lineJoin = val; + + VStroke::VLineJoin lineJoin = VStroke::joinMiter; + + switch (val) + { + case 0 : lineJoin = VStroke::joinMiter; break; + case 1 : lineJoin = VStroke::joinRound; break; + case 2 : lineJoin = VStroke::joinBevel; break; + } + + m_stroke.setLineJoin (lineJoin); + +} + +void KarbonAIParserBase::gotMiterLimit (double val) +{ +// m_miterLimit = val; + m_stroke.setMiterLimit (val); +} + +void KarbonAIParserBase::gotWindingOrder (int val) +{ + m_windingOrder = val; +} + +void KarbonAIParserBase::gotBeginGroup (bool clipping) +{ +// qDebug ("start begin group"); + if (clipping) + { + VClipGroup *group = new VClipGroup( 0L ); + m_groupStack.push (group); + } + else + { + VGroup *group = new VGroup( 0L ); + m_groupStack.push (group); + } + +// qDebug ("end begin group"); + +} + +void KarbonAIParserBase::gotEndGroup (bool /*clipping*/) +{ +// qDebug ("start end group"); + + if (m_debug) qDebug ("got end group"); + + if (m_groupStack.isEmpty()) return; + + if (m_debug) qDebug ("got end group 2"); + + VGroup *group = m_groupStack.pop(); + + if (m_debug) qDebug ("got end group 3"); + + if (m_debug) + { + if (!group) qDebug ("group is NULL"); + } + + if (m_groupStack.isEmpty()) + { + if (m_debug) qDebug ("insert object"); + ensureLayer(); + m_layer->append (group); + if (m_debug) qDebug ("/insert object"); + } + else + { + if (m_debug) qDebug ("insert object to group"); + + m_groupStack.top()->append (group); + if (m_debug) qDebug ("/insert object to group"); + } + + if (m_debug) qDebug ("/got end group"); + +// qDebug ("end end group"); +} + +void KarbonAIParserBase::gotBeginCombination () { + m_ptt = PTT_Combine; +} + +void KarbonAIParserBase::gotEndCombination () { +// qDebug ( "got end combination" ); + + m_ptt = PTT_Output; + + if (m_combination != NULL) + { + m_curKarbonPath = m_combination; + doOutputCurrentPath2 (POT_Leave); + } + + m_combination = NULL; +} + + +const VColor KarbonAIParserBase::toKarbonColor (const AIColor &color) +{ + AIColor temp (color); + VColor value; + + double v1, v2, v3, v4; + temp.toCMYK (v1, v2, v3, v4); + + float cv1 = v1; + float cv2 = v2; + float cv3 = v3; + float cv4 = v4; + + value.setColorSpace (VColor::cmyk); + value.set (cv1, cv2, cv3, cv4); + + return value; +} + +void KarbonAIParserBase::doOutputCurrentPath2(PathOutputType type) +{ + ensureLayer(); + + if (type != POT_Leave) + { +// pottoa(type); + + m_curKarbonPath->setStroke(m_emptyStroke); + m_curKarbonPath->setFill(m_emptyFill); + + if ((type != POT_Filled) && (type != POT_Stroked) && (type != POT_FilledStroked)) return; + if ((type == POT_Filled) || (type == POT_FilledStroked)) + { +/* VFill fill; + fill.setColor (toKarbonColor (m_fillColor)); + m_curKarbonPath->setFill(fill); */ +// qDebug ("set filled"); + m_curKarbonPath->setFill(m_fill); + } + + if ((type == POT_Stroked) || (type == POT_FilledStroked)) + { +/* VStroke stroke; + stroke.setColor (toKarbonColor (m_strokeColor)); + m_curKarbonPath->setStroke (stroke); */ +// qDebug ("set stroked"); + m_curKarbonPath->setStroke (m_stroke); + } + } + + if (m_ptt == PTT_Combine) + { +// m_pot |= type; + if (m_combination == NULL) + m_combination = m_curKarbonPath; + else + m_combination->combine (*m_curKarbonPath); + + m_curKarbonPath = new VPath( 0L ); + + return; + } + + ensureLayer(); + + if (m_groupStack.isEmpty()) + { + m_layer->append( m_curKarbonPath ); + } + else + { + m_groupStack.top()->append( m_curKarbonPath ); + } + + m_curKarbonPath = new VPath( 0L ); +} + +bool KarbonAIParserBase::parse (QIODevice& fin, QDomDocument &doc) +{ + + bool res = AIParserBase::parse (fin); + +// qDebug ("document is %s",doc.toString().latin1()); + if (res) + { + qDebug ("before save document"); + doc = m_document->saveXML(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = doc.createElement( "PAPER" ); + doc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document->width() ); + paper.setAttribute( "height", m_document->height() ); + + qDebug ("after save document"); + } + else + { + QDomDocument tempDoc; + doc = tempDoc; + } + + return res; +} + +void KarbonAIParserBase::ensureLayer () +{ + if (!m_layer) + { + m_layer = new VLayer( 0 ); + m_document->insertLayer (m_layer); + } +} + + +void KarbonAIParserBase::setupHandlers() +{ +// qDebug("setupHandler called"); + m_gstateHandler = new KarbonGStateHandler(this); + m_structureHandler = new KarbonStructureHandler(this); + m_pathHandler = new KarbonPathHandler(this); + m_documentHandler = new KarbonDocumentHandler(this); + + m_textHandler = new TextHandlerBase(); + +} + +void KarbonAIParserBase::teardownHandlers() +{ +// qDebug("teardownHandler called"); + delete m_textHandler; + + delete m_gstateHandler; + delete m_structureHandler; + delete m_pathHandler; + delete m_documentHandler; +} + + +void KarbonDocumentHandler::gotBoundingBox (int llx, int lly, int urx, int ury) +{ + delegate->gotBoundingBox(llx,lly,urx,ury); +} + +void KarbonDocumentHandler::gotCreationDate (const char */*val1*/,const char */*val2*/) +{ +// qDebug ("got creation date [%s], [%s]",val1,val2); +} + +void KarbonDocumentHandler::gotProcessColors (int /*colors*/) +{ +/* if (colors && PC_Cyan) qDebug ("contains cyan"); + if (colors && PC_Magenta) qDebug ("contains magenta"); + if (colors && PC_Yellow) qDebug ("contains yellow"); + if (colors && PC_Black) qDebug ("contains black"); */ +} + + +void KarbonGStateHandler::gotFillColor (AIColor &color) +{ + delegate->gotFillColor (color); +} + +void KarbonGStateHandler::gotStrokeColor (AIColor &color) +{ + delegate->gotStrokeColor(color); +} + +void KarbonGStateHandler::gotFlatness (double val) +{ + delegate->gotFlatness(val); +} + +void KarbonGStateHandler::gotLineWidth (double val) +{ + delegate->gotLineWidth(val); +} + +void KarbonGStateHandler::gotLineCaps (int val) +{ + delegate->gotLineCaps(val); +} + +void KarbonGStateHandler::gotLineJoin (int val) +{ + delegate->gotLineJoin(val); +} + +void KarbonGStateHandler::gotMiterLimit (double val) +{ + delegate->gotMiterLimit(val); +} + +void KarbonGStateHandler::gotWindingOrder (int val) +{ + delegate->gotWindingOrder(val); +} + +void KarbonStructureHandler::gotBeginGroup (bool clipping) +{ + delegate->gotBeginGroup(clipping); +} + +void KarbonStructureHandler::gotEndGroup (bool clipping) +{ + delegate->gotEndGroup(clipping); +} + +void KarbonStructureHandler::gotBeginCombination () +{ + delegate->gotBeginCombination(); +} + +void KarbonStructureHandler::gotEndCombination () +{ + delegate->gotEndCombination(); +} + +void KarbonPathHandler::gotPathElement (PathElement &element) +{ + delegate->gotPathElement (element); +} + +void KarbonPathHandler::gotFillPath (bool closed, bool reset) +{ + delegate->gotFillPath(closed, reset, m_fm); +} + +void KarbonPathHandler::gotFillMode (FillMode fm) +{ + m_fm = fm; +} + +void KarbonPathHandler::gotStrokePath (bool closed) +{ + delegate->gotStrokePath(closed); +} + +void KarbonPathHandler::gotIgnorePath (bool closed, bool reset) +{ + delegate->gotIgnorePath(closed, reset); +} + +void KarbonPathHandler::gotClipPath (bool closed) +{ + delegate->gotClipPath(closed); +} + +const void pottoa (PathOutputType &data) +{ + switch (data) + { + case POT_Filled : qDebug ("filled"); break; + case POT_Stroked : qDebug ("stroked"); break; + case POT_FilledStroked : qDebug ("filled/stroked"); break; + case POT_Clip : qDebug ("clip"); break; + case POT_Ignore : qDebug ("ignore"); break; + case POT_Leave : qDebug ("leave"); break; + default : qDebug ("unknown"); + } +} + diff --git a/filters/karbon/ai/karbonaiparserbase.h b/filters/karbon/ai/karbonaiparserbase.h new file mode 100644 index 000000000..4b6f05a92 --- /dev/null +++ b/filters/karbon/ai/karbonaiparserbase.h @@ -0,0 +1,202 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KARBONAIPARSERBASE_H +#define KARBONAIPARSERBASE_H + +#include +#include +#include +#include + +#include "aicolor.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + *@author + */ +typedef QPair Parameter; +typedef QPtrList Parameters; +typedef QPtrList PathElements; + +typedef enum { POT_Filled = 1, POT_Stroked = 2, POT_FilledStroked = 3, POT_Clip = 4, POT_Ignore = 8, POT_Leave = -1, POT_Other = 0 } PathOutputType; +typedef enum { PTT_Output = 1, PTT_Combine = 2 } PathTransferType; + +// typedef struct { int llx, lly, urx, ury; } BoundingBox; + +class KarbonAIParserBase; +class KarbonGStateHandler; +class KarbonStructureHandler; +class KarbonPathHandler; +class KarbonDocumentHandler; + +class KarbonDocumentHandler : public DocumentHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonDocumentHandler (KarbonAIParserBase *delegate) : DocumentHandlerBase () { this->delegate = delegate; } + + void gotBoundingBox (int llx, int lly, int urx, int ury); + void gotCreationDate (const char *val1,const char *val2); + void gotProcessColors (int colors); +}; + +class KarbonGStateHandler : public GStateHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonGStateHandler (KarbonAIParserBase *delegate) : GStateHandlerBase() { this->delegate = delegate; } + + void gotFillColor (AIColor &color); + void gotStrokeColor (AIColor &color); + + void gotFlatness (double val); + void gotLineWidth (double val); + void gotLineCaps (int val); + void gotLineJoin (int val); + void gotMiterLimit (double val); + void gotWindingOrder (int val); + +}; + +class KarbonStructureHandler : public StructureHandlerBase +{ + private: + KarbonAIParserBase *delegate; + public: + KarbonStructureHandler (KarbonAIParserBase *delegate) : StructureHandlerBase() { this->delegate = delegate; } + + void gotBeginGroup (bool clipping); + void gotEndGroup (bool clipping); + void gotBeginCombination (); + void gotEndCombination (); + +}; + +class KarbonPathHandler : public PathHandlerBase +{ + private: + KarbonAIParserBase *delegate; + FillMode m_fm; + public: + KarbonPathHandler (KarbonAIParserBase *delegate) : PathHandlerBase () + { + m_fm = FM_EvenOdd; + this->delegate = delegate; + } + + void gotPathElement (PathElement &element); + void gotFillPath (bool closed, bool reset); + void gotStrokePath (bool closed); + void gotIgnorePath (bool closed, bool reset); + void gotClipPath (bool closed); + void gotFillMode (FillMode fm); + +}; + +class KarbonAIParserBase : public AIParserBase { + friend class KarbonDocumentHandler; + friend class KarbonGStateHandler; + friend class KarbonStructureHandler; + friend class KarbonPathHandler; + +public: + KarbonAIParserBase(); + ~KarbonAIParserBase(); + + bool parse (QIODevice& fin, QDomDocument &doc); +private: + VPath *m_curKarbonPath; + VDocument *m_document; + VLayer *m_layer; + VPath *m_combination; + QPtrStack m_groupStack; + + FillMode m_fm; + PathOutputType m_pot; + PathTransferType m_ptt; + +// BoundingBox m_bbox; + KoRect m_bbox; + VFill m_fill; + VStroke m_stroke; +/** AIColor m_strokeColor; + AIColor m_fillColor; + double m_lineWidth; + double m_flatness; + int m_lineCaps; + int m_lineJoin; + double m_miterLimit; */ + int m_windingOrder; + + void doOutputCurrentPath2(PathOutputType type); + const VColor toKarbonColor (const AIColor &color); + void ensureLayer (); + + VFill m_emptyFill; + VStroke m_emptyStroke; + +protected: + void setupHandlers(); + void teardownHandlers(); + + void parsingStarted(); + void parsingFinished(); + + QString getParamList(Parameters& params); + + void gotPathElement (PathElement &element); + void gotFillPath (bool closed, bool reset, FillMode fm = FM_NonZero); + void gotStrokePath (bool closed); + void gotIgnorePath (bool closed, bool reset); + void gotClipPath (bool closed); + + void gotFillColor (AIColor &color); + void gotStrokeColor (AIColor &color); + void gotBoundingBox (int llx, int lly, int urx, int ury); + + void gotFlatness (double val); + void gotLineWidth (double val); + void gotLineCaps (int val); + void gotLineJoin (int val); + void gotMiterLimit (double val); + void gotWindingOrder (int val); + void gotBeginGroup (bool clipping); + void gotEndGroup (bool clipping); + void gotBeginCombination (); + void gotEndCombination (); + + virtual void gotStartTag (const char *tagName, Parameters& params); + virtual void gotEndTag (const char *tagName); + virtual void gotSimpleTag (const char *tagName, Parameters& params); +}; + +#endif diff --git a/filters/karbon/applixgraphics/Makefile.am b/filters/karbon/applixgraphics/Makefile.am new file mode 100644 index 000000000..b3c03f384 --- /dev/null +++ b/filters/karbon/applixgraphics/Makefile.am @@ -0,0 +1,20 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) +libapplixgraphicimport_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) + +####### Files + +kde_module_LTLIBRARIES = libapplixgraphicimport.la + +libapplixgraphicimport_la_SOURCES = applixgraphicimport.cc +libapplixgraphicimport_la_LIBADD = $(KOFFICE_LIBS) +noinst_HEADERS = applixgraphicimport.h + +METASOURCES = AUTO + +service_DATA = kontour_applixgraphic_import.desktop +servicedir = $(kde_servicesdir) + +messages: rc.cpp + $(XGETTEXT) *.cc *.cpp -o $(podir)/kontourapplixgraphicsfilter.pot diff --git a/filters/karbon/applixgraphics/applixgraphicimport.cc b/filters/karbon/applixgraphics/applixgraphicimport.cc new file mode 100644 index 000000000..2ee526858 --- /dev/null +++ b/filters/karbon/applixgraphics/applixgraphicimport.cc @@ -0,0 +1,832 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Enno Bartels + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +#define FAKTOR 39.4 // 1000 dots/inch / 2.54 cm/inch = 394 dots/cm = 39.4 dots/mm + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +typedef KGenericFactory APPLIXGRAPHICImportFactory; +K_EXPORT_COMPONENT_FACTORY( libapplixgraphicimport, APPLIXGRAPHICImportFactory( "kofficefilters" ) ) + +int s_area = 30517; + +/****************************************************************************** + * class: applixGraphicsLine function: constructor * + ****************************************************************************** + * * + * Short description : - Initialize all variables * + * * + * * + ******************************************************************************/ +applixGraphicsLine::applixGraphicsLine() +{ + offX = 0; + offY = 0; + reColor = 0; + thickNess = 1; // ?? + + for (int i=0; i<5; i++) + { + ptX[0] = 0; + ptY[0] = 0; + } +} + + + + + +/****************************************************************************** + * class: applixGraphicsRect function: constructor * + ****************************************************************************** + * * + * Short description : - Initialize all variables * + * * + * * + ******************************************************************************/ +applixGraphicsRect::applixGraphicsRect() : applixGraphicsLine() +{ + for (int i=0; i<7;i++) + { + bf[i] = 0; + lf[i] = 0; + } + + for (int i=0; i<5;i++) + { + sh[i] = 0; + } + + for (int i=0; i<8;i++) + { + pa[i] = 0; + } + + for (int i=0; i<3;i++) + { + vs[i] = 0; + } + + for (int i=0; i<2;i++) + { + xr[i] = 0; + } + +} + + + + + +/****************************************************************************** + * class: APPLIXGRAPHICImport function: constructor * + ****************************************************************************** + * * + * Short description : constructor * + * * + * * + ******************************************************************************/ +APPLIXGRAPHICImport::APPLIXGRAPHICImport (KoFilter *, const char *, const QStringList&) : + KoFilter () +{ + +} + + + +/****************************************************************************** + * class: APPLIXGRAPHICImport function: filter * + ****************************************************************************** + * * + * Short description : - Read inputfile, * + * - convert it to kontour fileformat and * + * - save it * + * * + * * + ******************************************************************************/ +KoFilter::ConversionStatus APPLIXGRAPHICImport::convert( const QCString& from, const QCString& to ) +{ + + // Check MIME Types + if (to!="application/x-karbon" || from!="application/x-applixgraphic") + return KoFilter::NotImplemented; + + // Open Inputfile + QFile in (m_chain->inputFile()); + if (!in.open (IO_ReadOnly) ) + { + kdError(30502) << "Unable to open input file!" << endl; + in.close (); + return KoFilter::FileNotFound; + } + + QString str; + + // Create karbon header + str += "\n"; + str += "\n"; + str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; +// str += " \n"; + str += " \n"; + + QTextStream stream(&in); + int step = in.size()/50; + int value = 0; + int i = 0; + int picture_rememberer = 0; + int pos = 0; + int vers[3] = { 0, 0, 0 }; + int rueck; // Check scanf inputs + QString mystr; + + // Read Headline + mystr = stream.readLine (); + rueck = sscanf ((const char *) mystr.latin1() , + "*BEGIN GRAPHICS VERSION=%d/%d ENCODING=%dBIT", + &vers[0], &vers[1], &vers[2]); + kdDebug (s_area) << "Versions info: " << vers[0] << vers[1] << vers[2] << endl; + + // Check the headline + if (rueck <= 0) + { + kdDebug (s_area) << "Header not correkt - May be it is not an applixgraphics file" << endl; + kdDebug (s_area) << "Headerline: " << mystr << endl; + + QMessageBox::critical (0L, "Applixgraphics header problem", + QString ("The Applixgraphics header is not correct. " + "May be it is not an applixgraphics file!
    " + "This is the header line I did read:
    %1").arg(mystr.latin1()), + "Comma"); + + // i18n( "What is the separator used in this file ? First line is \n%1" ).arg(firstLine), + return KoFilter::StupidError; + } + + while (!stream.atEnd ()) + { + ++i; + + // Read one line + mystr = stream.readLine (); + kdDebug (s_area) << "<<" << mystr << ">>" << endl; + + if (mystr == "PICTURE") picture_rememberer = 1; + else if (mystr == "END PICTURE") picture_rememberer = 0; + + + // Detect a point at the first place of the ascii_linie + else if ((mystr[0] == '.') && (picture_rememberer == 1)) + { + // Delete point at the first place of the ascii_linie + mystr.remove (0, 1); + kdDebug (s_area) << "StartPoint recognized <" << mystr << ">" << endl; + + + /******************************************************************** + * Element "LINE" * + ********************************************************************/ + if (mystr.startsWith ("LINE AT") ) + { + // Define + applixGraphicsLine agLine; + + //str += agLine.read (int, mystr); + + kdDebug (s_area) << " Linie recognized: " << endl; + mystr.remove (0, 8); + //mystr.remove (0, 7); + + + //remove_pos = mystr.find ('('); + //mystr.remove (0, remove_pos); + //agLine.offX= mystr.toInt(); + + //remove_pos = mystr.find (','); + //mystr.remove (0, remove_pos); + //agLine.offY= mystr.toInt(); + rueck = sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agLine.offX, &agLine.offY); + kdDebug (s_area) << " Offset -> x:" << agLine.offX << " y:" << agLine.offY << endl; + if (rueck <= 0) + { + kdDebug (s_area) << "LINE tag not correkt" << endl; + kdDebug (s_area) << "LINE: <" << mystr << ">" << endl; + return KoFilter::StupidError; + } + + do + { + // Get acutal position + pos = in.at (); + // Read one line + mystr = stream.readLine (); + + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agLine.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agLine.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Unknown RECOLOR item <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agLine.thickNess); + // + kdDebug (s_area) << agLine.thickNess << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)", + &agLine.ptX[0], &agLine.ptY[0], &agLine.ptX[1], &agLine.ptY[1]); + kdDebug (s_area) << agLine.ptX[0] << " " << agLine.ptY[0] << " " << agLine.ptX[1] << " " << agLine.ptY[1] << endl; + } + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; +// str += " "; + str += " \n"; + +// str += " "; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + + + str += " \n"; + + + } + /******************************************************************** + * Element RPOL Vieleck * + ********************************************************************/ + if (mystr.startsWith ("RPOL AT") ) + { + // Define + applixGraphicsLine agLine; + int nsides; + + //str += agLine.read (int, mystr); + + kdDebug (s_area) << " RPOL recognized: " << endl; + mystr.remove (0, 8); + + rueck = sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agLine.offX, &agLine.offY); + kdDebug (s_area) << " Offset -> x:" << agLine.offX << " y:" << agLine.offY << endl; + if (rueck <= 0) + { + kdDebug (s_area) << "RPOL tag not correkt " << endl; + kdDebug (s_area) << "RPOL: <" << mystr << ">" << endl; + return KoFilter::StupidError; + } + + do + { + // Akutelle Position bestimmen + pos = in.at (); + // Zeile einlesen + mystr = stream.readLine (); +//checkSubElement (mystr, subelements) + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor " ; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agLine.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agLine.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" NSIDES") ) + { + kdDebug (s_area) << " NSIDES: " ; + mystr.remove (0, 8); + pos = sscanf ((const char *) mystr.latin1(), "%d", &nsides); + kdDebug (s_area) << nsides << "(" << pos << ")" << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agLine.ptX[0], &agLine.ptY[0], &agLine.ptX[1], &agLine.ptY[1], + &agLine.ptX[2], &agLine.ptY[2], &agLine.ptX[3], &agLine.ptY[3], + &agLine.ptX[4], &agLine.ptY[4]); + kdDebug (s_area) << agLine.ptX[0] << " " << agLine.ptY[0] << " " << + agLine.ptX[1] << " " << agLine.ptY[1] << " " << + agLine.ptX[2] << " " << agLine.ptY[2] << " " << + agLine.ptX[3] << " " << agLine.ptY[3] << " " << + agLine.ptX[4] << " " << agLine.ptY[4] << endl; + } +//checkSubElement() ende + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + + + // An die Position zurueckspringen + in.at (pos); + + int a, b; + float wink=0.0; + int *x = new int[nsides]; + int *y = new int[nsides]; + a = agLine.ptX[2] / 2; + b = agLine.ptY[2] / 2; + for (int i=0; i\n"; + for (int i=0; i\n"; + } + + str += " \n"; + str += " \n"; + str += " \n"; + + + + str += " \n"; + + + } + /******************************************************************** + * Element TXT - Text * + ********************************************************************/ + else if (mystr.startsWith ("TXT AT") ) + { + // Define + //applixGraphicsText agText; + applixGraphicsLine agText; + + kdDebug (s_area) << " Habe Text erkannt (keine Werte uebernommen)" << endl; + mystr.remove (0, 7); + sscanf ((const char *) mystr.latin1(), "(%d,%d)", + &agText.offX, &agText.offY); + kdDebug (s_area) << " Offset -> x:" << agText.offX << " y:" << agText.offY << endl; + + + do + { + // Aktuelle Position bestimmen + pos = in.at (); + // Zeile einlesen + mystr = stream.readLine (); +//checkSubElement() + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor : "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agText.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agText.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" .STR") ) + { + kdDebug (s_area) << " Textstring: "; + + // Zeile einlesen + agText.str = stream.readLine (); + agText.str.remove (0, 3); // delete ront part + kdDebug (s_area) << agText.str; + } + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agText.thickNess); + kdDebug (s_area) << agText.thickNess << endl; + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *) mystr.latin1(), "(%d,%d)(%d,%d)", + &agText.ptX[0], &agText.ptY[0], &agText.ptX[1], &agText.ptY[1]); + kdDebug (s_area) << agText.ptX[0] << " " << agText.ptY[0] << " " << agText.ptX[1] << " " << agText.ptY[1]; + } +//checkSubElement() ende + + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + } + + /******************************************************************** + * Element rectangle * + ********************************************************************/ + else if (mystr.startsWith ("RECT AT")) + { + applixGraphicsRect agRect; + + kdDebug (s_area) << " Habe Rectangle erkannt " << endl; + mystr.remove (0, 8); + rueck = sscanf ((const char *)mystr.latin1(), "(%d,%d)", &agRect.offX, &agRect.offY); + if (rueck < 1) kdDebug (s_area) <<"Fehler im String <" << mystr.latin1() << ">" << endl; + kdDebug (s_area) << " Offset -> x:" << agRect.offX << " y:" << agRect.offY << endl; + + + do + { + // Akutelle Position bestimmen + pos = in.at (); + // read one line + mystr = stream.readLine (); + +//checkSubElement() + // option RECOLOR + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) <<(" Recolor : "); + mystr.remove (0, 9); + if (mystr == "ON") + { kdDebug (s_area) << "On" << endl; agRect.reColor = true;} + else if (mystr == "OFF") + { kdDebug (s_area) << "Off" << endl; agRect.reColor = false;} + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + // option BACKFILL + else if (mystr.startsWith (" BACKFILL ") ) + { + kdDebug (s_area) <<(" Backfill: "); + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d>", + &agRect.bf[0], &agRect.bf[1], &agRect.bf[2], + &agRect.bf[3], &agRect.bf[4], &agRect.bf[5], + &agRect.bf[6]); + kdDebug (s_area) << agRect.bf[0] << " " << agRect.bf[1] << " " << + agRect.bf[2] << " " << agRect.bf[3] << " " << + agRect.bf[4] << " " << agRect.bf[5] << " " << + agRect.bf[6]; + + } + // option LINEFILL + else if (mystr.startsWith (" LINEFILL ") ) + { + kdDebug (s_area) << " Linefill: "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d>", + &agRect.lf[0], &agRect.lf[1], &agRect.lf[2], + &agRect.lf[3], &agRect.lf[4], &agRect.lf[5], + &agRect.lf[6]); + kdDebug (s_area) << agRect.lf[0] << " " << agRect.lf[1] << " " << + agRect.lf[2] << " " << agRect.lf[3] << " " << + agRect.lf[4] << " " << agRect.lf[5] << " " << + agRect.lf[6]; + + } + // option SHADOW + else if (mystr.startsWith (" SHADOW ") ) + { + kdDebug (s_area) << " Shadow : "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d>", + &agRect.sh[0], &agRect.sh[1], &agRect.sh[2], + &agRect.sh[3], &agRect.sh[4]); + kdDebug (s_area) << agRect.sh[0] << " " << agRect.sh[1] << " " << + agRect.sh[2] << " " << agRect.sh[3] << " " << + agRect.sh[4]; + } + // option PARA + else if (mystr.startsWith (" PARA ") ) + { + kdDebug (s_area) << " Para : "; + mystr.remove (0, 12); + sscanf ((const char *)mystr.latin1(), "<%d %d %d %d %d %d %d %d>", + &agRect.pa[0], &agRect.pa[1], &agRect.pa[2], + &agRect.pa[3], &agRect.pa[4], &agRect.pa[5], + &agRect.pa[6], &agRect.pa[7]); + kdDebug (s_area) << agRect.pa[0] << " " << agRect.pa[1] << " " << + agRect.pa[2] << " " << agRect.pa[3] << " " << + agRect.pa[4] << " " << agRect.pa[5] << " " << + agRect.pa[6] << " " << agRect.pa[7] ; + + } + // option THICKNESS + else if (mystr.startsWith (" THICKNESS ") ) + { + kdDebug (s_area) << " Thickness: "; + mystr.remove (0, 11); + sscanf ((const char *) mystr.latin1(), "%d", &agRect.thickNess); + kdDebug (s_area) << agRect.thickNess << endl; + } + // option V_SPACE + else if (mystr.startsWith (" V_SPACE ") ) + { + kdDebug (s_area) << " V_Space : "; + mystr.remove (0, 9); + sscanf ((const char *)mystr.latin1(), "(%d %d %d)", + &agRect.vs[0], &agRect.vs[1], &agRect.vs[2]); + kdDebug (s_area) << agRect.vs[0] << " " << agRect.vs[1] << " " << agRect.vs[2]; + } + // option XYRAD + else if (mystr.startsWith (" XYRAD ") ) + { + kdDebug (s_area) << " XYRad : "; + mystr.remove (0, 7); + sscanf ((const char *)mystr.latin1(), "<%d %d>", + &agRect.xr[0], &agRect.xr[1]); + kdDebug (s_area) << agRect.xr[0] << " " << agRect.xr[1]; + } + // option PNTS + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) << " Pnts : "; + mystr.remove (0, 6); + sscanf ((const char *)mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agRect.ptX[0], &agRect.ptY[0], &agRect.ptX[1], &agRect.ptY[1], + &agRect.ptX[2], &agRect.ptY[2], &agRect.ptX[3], &agRect.ptY[3], + &agRect.ptX[4], &agRect.ptY[4]); + kdDebug (s_area) << agRect.ptX[0] << " " << agRect.ptY[0] << " " << + agRect.ptX[1] << " " << agRect.ptY[1] << " " << + agRect.ptX[2] << " " << agRect.ptY[2] << " " << + agRect.ptX[3] << " " << agRect.ptY[3] << " " << + agRect.ptX[4] << " " << agRect.ptY[4] << endl; + } + +//checkSubElement() ende + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + str += " \n"; + str += " \n"; + + str += " \n"; + + str += " \n"; + + str += " \n"; + + str += " \n"; + + + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + str += " \n"; + + + + + + + } + /******************************************************************** + * Element ELL - Ellipse * + ********************************************************************/ + else if (mystr.startsWith ("ELL AT")) + { + applixGraphicsRect agEll; + + kdDebug (s_area) << " Habe ELL erkannt (keine Werte uebernommen " << endl; + mystr.remove (0, 7); + sscanf ((const char *)mystr.latin1(), "(%d,%d)", + &agEll.offX, &agEll.offY); + kdDebug (s_area) << " Offset -> x:" << agEll.offX << " y:" << agEll.offY << endl; + + do + { + // Aktuelle Position bestimmen + pos = in.at (); + // read one line + mystr = stream.readLine (); + +//checkSubElement() + // option RECOLOR + if (mystr.startsWith (" RECOLOR ") ) + { + kdDebug (s_area) << " Recolor: "; + mystr.remove (0, 9); + if (mystr == "ON") + { + kdDebug (s_area) << "On" << endl; + agEll.reColor = true; + } + else if (mystr == "OFF") + { + kdDebug (s_area) << "Off" << endl; + agEll.reColor = false; + } + else + { + kdDebug (s_area) << "!!!!! Whats that <" << mystr << ">" << endl; + } + } + else if (mystr.startsWith (" PNTS ") ) + { + kdDebug (s_area) <<(" Pnts : "); + mystr.remove (0, 6); + // + sscanf ((const char *)mystr.latin1(), "(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)", + &agEll.ptX[0], &agEll.ptY[0], &agEll.ptX[1], &agEll.ptY[1], + &agEll.ptX[2], &agEll.ptY[2], &agEll.ptX[3], &agEll.ptY[3], + &agEll.ptX[4], &agEll.ptY[4]); + kdDebug (s_area) << agEll.ptX[0] << " " << agEll.ptY[0] << " " << + agEll.ptX[1] << " " << agEll.ptY[1] << " " << + agEll.ptX[2] << " " << agEll.ptY[2] << " " << + agEll.ptX[3] << " " << agEll.ptY[3] << " " << + agEll.ptX[4] << " " << agEll.ptY[4] << endl; + + } +//checkSubElement() ende + } + while ((mystr[0] != '.') && (mystr[0] != 'E')); + + // An die Position zurueckspringen + in.at (pos); + + // Werte in die Struktur einlagern + // ??? + + } + else + { + kdDebug (s_area) << "Unbekannt : " << mystr << endl; + } + + } + + + if (i>step) + { + i=0; + value+=2; + emit sigProgress (value); + } + } + emit sigProgress(100); + + str += "
    \n"; + str += "
    \n"; +// str += "\n"; + + kdDebug (s_area) << "Text " << str.utf8() << endl; + + KoStoreDevice* out= m_chain->storageFile( "root", KoStore::Write ); + if (!out) + { + kdError(s_area) << "Unable to open output file!" << endl; + in.close (); + return KoFilter::StorageCreationError; + } + + QCString cstring = str.utf8(); + out->writeBlock ( (const char*)cstring, cstring.size() - 1 ); + + in.close (); + return KoFilter::OK; +} + +#include + + + + diff --git a/filters/karbon/applixgraphics/applixgraphicimport.h b/filters/karbon/applixgraphics/applixgraphicimport.h new file mode 100644 index 000000000..a65e26db7 --- /dev/null +++ b/filters/karbon/applixgraphics/applixgraphicimport.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2001 Enno Bartels + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef APPLIXGRAPHICIMPORT_H +#define APPLIXGRAPHICIMPORT_H + +#include + + +class APPLIXGRAPHICImport : public KoFilter { + + Q_OBJECT + +public: + APPLIXGRAPHICImport (KoFilter *parent, const char *name, const QStringList&); + virtual ~APPLIXGRAPHICImport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + + + + +// Kleinstes Objekt +class applixGraphicsLine +{ + public: + int offX; + int offY; + int reColor; + int thickNess; + int ptX[5]; + int ptY[5]; + QString str; + + applixGraphicsLine (); // Constructor +}; + +class applixGraphicsRect : public applixGraphicsLine +{ + public: + int bf[7]; + int lf[7]; + + int sh[6]; + + int pa[8]; + int vs[3]; + + int xr[2]; //XYRAD + + applixGraphicsRect (); // Constructor +}; + +#endif // APPLIXGRAPHICIMPORT_H diff --git a/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop b/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop new file mode 100644 index 000000000..e7d512946 --- /dev/null +++ b/filters/karbon/applixgraphics/kontour_applixgraphic_import.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +Type=Service +Name=Kontour Applixgraphics Import Filter +Name[af]=Kontoer Applixgrafika In voer Filter +Name[ar]=مِرْشَح استيراد Applixgraphics لدى Kontour +Name[az]=Kontour Applixgraphics Alma Süzgəci +Name[bg]=Филтър за импортиране от Applixgraphics в Kontour +Name[br]=Sil enporzh Applixgraphics evit Kontour +Name[ca]=Filtre d'importació Applixgraphics per a Kontour +Name[cs]=Importní filtr Applixgraphics pro Kontour +Name[cy]=Hidlen Fewnforio Applixgraphics Kontour +Name[da]=Kontour Applixgraphics-importfilter +Name[de]=Kontour Applixgraphics-Importfilter +Name[el]=Φίλτρο εισαγωγής Applixgraphics του Kontour +Name[eo]=Apliks-grafiko-importfiltrilo por Kontour +Name[es]=Filtro de importación Applixgraphics de Kontour +Name[et]=Kontouri Applixgraphics'i impordifilter +Name[eu]=Kontour Applixgraphics-en inportaziorako iragazkia +Name[fa]=پالایۀ واردات Kontour Applixgraphics +Name[fi]=Kontour Applixgraphics -tuontisuodin +Name[fr]=Filtre d'importation Applix Graphics vers Kontour +Name[fy]=Kontour Applixgrafysk-Ymportfilter +Name[ga]=Scagaire Iompórtála Kontour +Name[gl]=Filtro de Importación de Applixgraphics para Kontour +Name[he]=מסנן ייבוא מ־Applixgraphics ל־Kontour +Name[hi]=कन्टूर एप्लिक्सग्राफ़िक्स आयात फ़िल्टर +Name[hr]=Kontour Aplixgraphics filtar uvoza +Name[hu]=Kontour Applix Graphics importszűrő +Name[is]=Kontour Applixgraphics innflutningssía +Name[it]=Filtro di importazione Applixgraphics per Kontour +Name[ja]=Kontour Applixgraphics インポートフィルタ +Name[km]=តម្រង​នាំចូល Applixgraphics សម្រាប់ Kontour +Name[lo]=ຕົວຕອງການນຳເຂົ້າ Applixgraphics ຂອງການແຕ້ມຮູບ K +Name[lt]=Kontour Applixgraphics importo filtras +Name[lv]=Kontour Applixgraphics importa filtrs +Name[ms]=Penapis Import Kontour Applixgraphics +Name[mt]=Filtru għall-importazzjoni ta' Applixgraphics ġo Kontour +Name[nb]=Applixgraphics-importfilter for Kontour +Name[nds]=Applixgraphics-Importfilter för Kontour +Name[ne]=रूपरेखा एप्लिक्सग्राफिक्स आयात फिल्टर +Name[nl]=Kontour Applixgraphics-importfilter +Name[nn]=Applixgraphics-importfilter for Kontour +Name[pl]=Filtr importu formatu Applixgraphics do Kontour +Name[pt]=Filtro de Importação de Applixgraphics para o Kontour +Name[pt_BR]=Filtro de importação de aplicativos gráficos para o Kontour +Name[ro]=Filtru importare Kontour pentru Applixgraphics +Name[ru]=Фильтр импорта файлов Applixgraphics в Kontour +Name[se]=Kontour:a Applixgraphics-sisafievrridansilli +Name[sk]=Applixgraphics filter pre import pre Kontour +Name[sl]=Uvozni filter Applixgraphics za Kontour +Name[sr]=Kontour-ов филтер за увоз из Applixgraphics-а +Name[sr@Latn]=Kontour-ov filter za uvoz iz Applixgraphics-a +Name[sv]=Kontour Applixgrafik-importfilter +Name[ta]=Kontour Applixgraphics இறக்குமதி வடிகட்டி +Name[tg]=Филтри Воридоти Applixgraphics +Name[th]=ตัวกรองการนำเข้า Applixgraphics ของวาดภาพ K +Name[tr]=Kontour Applixgraphics Alma Süzgeci +Name[uk]=Фільтр імпорту Applixgraphics для Kontour +Name[uz]=Kontour Applixgraphics import filteri +Name[uz@cyrillic]=Kontour Applixgraphics импорт филтери +Name[ven]=Filithra yau dzhenisa ya Kontour Applixgraphics +Name[xh]=Isihluzi sokurhweba se Kontour Applixgraphics +Name[zh_CN]=Kontour Applixgraphics 图形导入过滤器 +Name[zh_TW]=Kontour Applix 圖形匯入過濾程式 +X-KDE-Export=application/x-kontour +X-KDE-Import=application/x-applixgraphics +X-KDE-Weight=1 +X-KDE-Library=libapplixgraphicimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/applixgraphics/status.html b/filters/karbon/applixgraphics/status.html new file mode 100644 index 000000000..1c4bde9c2 --- /dev/null +++ b/filters/karbon/applixgraphics/status.html @@ -0,0 +1,175 @@ + + + + + KOffice filters status: ApplixGraphics FILTER + + +  + +
    +
    +

    + KOffice filters status:   ApplixGraphics FILTER +

    +
    + +
    + + + Import | + Export + + +


    +
    + +Up +
    +
    +
    +

    $projectname

    + + diff --git a/doc/karbon/Makefile.am b/doc/karbon/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/karbon/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/karbon/index.docbook b/doc/karbon/index.docbook new file mode 100644 index 000000000..670d3acce --- /dev/null +++ b/doc/karbon/index.docbook @@ -0,0 +1,67 @@ + + + + + +]> + + + + +The &karbon14; Handbook + + + + + + + +
    +
    +
    + +
    + +&FDLNotice; + + + +2005-09-04 +0.1.0 + + + + + +&karbon14; is a Scalable Graphics editer for &kde;. + + + + + +KDE +Karbon14 + + +
    + + Introduction +The documentation for &kappname; was not finished when &kde; was installed on +this computer. If you need help, please check The &kde; Website for updates, or by +submitting your question to The +&kde; User Mailing list. The &kde; +Team + +&underFDL; + + + +&documentation.index; +
    + diff --git a/doc/kchart/Makefile.am b/doc/kchart/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kchart/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kchart/cr22-action-chart_line.png b/doc/kchart/cr22-action-chart_line.png new file mode 100644 index 000000000..ea1199dbb Binary files /dev/null and b/doc/kchart/cr22-action-chart_line.png differ diff --git a/doc/kchart/cr22-action-data.png b/doc/kchart/cr22-action-data.png new file mode 100644 index 000000000..a72e5438f Binary files /dev/null and b/doc/kchart/cr22-action-data.png differ diff --git a/doc/kchart/cr22-action-options.png b/doc/kchart/cr22-action-options.png new file mode 100644 index 000000000..f03bb6735 Binary files /dev/null and b/doc/kchart/cr22-action-options.png differ diff --git a/doc/kchart/cr22-action-wizard.png b/doc/kchart/cr22-action-wizard.png new file mode 100644 index 000000000..cece74dee Binary files /dev/null and b/doc/kchart/cr22-action-wizard.png differ diff --git a/doc/kchart/file-toolbar.png b/doc/kchart/file-toolbar.png new file mode 100644 index 000000000..3297c7c09 Binary files /dev/null and b/doc/kchart/file-toolbar.png differ diff --git a/doc/kchart/file-toolbar2.png b/doc/kchart/file-toolbar2.png new file mode 100644 index 000000000..699c44799 Binary files /dev/null and b/doc/kchart/file-toolbar2.png differ diff --git a/doc/kchart/frame_chart.png b/doc/kchart/frame_chart.png new file mode 100644 index 000000000..a28f1437d Binary files /dev/null and b/doc/kchart/frame_chart.png differ diff --git a/doc/kchart/index.docbook b/doc/kchart/index.docbook new file mode 100644 index 000000000..8fdfac407 --- /dev/null +++ b/doc/kchart/index.docbook @@ -0,0 +1,1375 @@ + + + + + + +]> + + + + +The &kchart; Handbook + + + + + +&Jonathan.Drews; &Jonathan.Drews.mail; + + +Raphael +Langerhorst +raphael.langerhorst@kdemail.net + + + + + +&FDLNotice; + +2006-01-30 +1.5.0 + + + +&kchart; is an application for visualizing numerical data. It has many +different chart types available like bar graphs, line plots, pie charts, +ring charts and more. + + +&kchart; is a &koffice; component and is very well integrated with &kspread; +to allow visualization of spreadsheet data. But it is also possible to use +&kchart; as a standalone application or integrate it in other &koffice; +components. + + + + +KDE +kdeutils +Kchart +chart +graph +plot + + + + + + +Introduction + + +&kchart; is a tool for visualizing numerical data. It can be used +as a standalone application with a simple &dataeditor;. But as a +&koffice; component it offers very flexible integration. &kspread; +uses the &kchart; component for charts and diagrams. &kspread; +can be seen as a very powerful data provider for &kchart; input. + + +But embedding is not limited to &kspread;. A &kchart; chart can +be embedded in many of the &koffice; components like &kword;, +&kpresenter; or &kivio;. + + +To start with we will look at the user interface of &kchart; +and how it can be used as a standalone application. When we +are familiar with &kchart; we will investigate the charting +capabilities it offers together with &kspread;. + + + + +The User Interface + +Main Application Interface + +We will take a look at a simple example to get to know &kchart;. +Along the way we will also discuss the user interface at length +so you will learn about many details of the component. + + +When you start &kchart; as a standalone application you get +the usual startup dialog where you can choose between different +templates or load existing chart documents. + + +&kchart; Startup Dialog + + + + + + + +You can choose between various ways to startup &kchart;. On the left, you can +see three options: Recent Documents, +Charts templates and Open Existing +Document.... The first option lets you choose between +recently opened charts, the second is for creating a +new chart from various templates and the third is for opening an existing +chart with a file dialog. + + +For now we will start with the default template. Select +Charts in the left area and then select +Bar Chart in the main template area. Normally +this template should already be selected after choosing +Charts. + + +If you decide to always start &kchart; with a selected template as default +you can also check Always use this template. + + +Click the Use This Template +button on the right, under the template preview. + + +&kchart; User Interface + + + + + + + +As you can see, there is already some example data present. &kchart; +offers the default toolbar for creating a new chart, saving, loading +and printing the chart. The second toolbar offers icons for editing +the data, configuring the chart or using a configuration wizard. +You can also switch between different chart types with the rest +of the icons. Note that some of these chart types also have subtypes. + + +The menu offers all standard entries, including shortcut and +toolbar configuration and page layout for printing. + + +Note that data editing is not available if you use &kchart; from +within &kspread; because all data is provided by the spreadsheet. +As a standalone application the &dataeditor; is an important part +of the application. + + + +Chart Wizard + +The wizard is actually a very useful part of &kchart; for quickly +setting up some basic options like chart type and chart labelling +in a few easy steps. + + +You can run the wizard at any time, it will always preserve your data +and other configuration. Also, you can change every single configuration +you do with the wizard later as well, without losing anything. In fact +the wizard is just a way to set some basic and important options +in one go. + + +To start the wizard simply click on the + + + icon in the toolbar. + + + +Step 0 - Choosing the Data source + +Wizard Step 0 - Data source + + + + + + + +The first step in the wizard is to actually choose the data source. +If the selected data area does not match the data you want, +select the data now. + +Include cells that you want to use as row and column labels, +if you want them in the chart. + +Then go to the next step with the Next > +button. You can also choose Finish at any step +if you are already comfortable with the setup done so far. + + + + +Step 1 - Choosing the Chart Type + +Wizard Step 1 - Chart Type + + + + + + + +The next step in the wizard is to actually choose the primary +type of the chart. This selection has the most important +impact on how your data will be presented. Thus it should +be chosen well. You can change the type of the chart with the +icons in the toolbar without losing any data or configuration +later on. In fact it is even considered normal to test all the +various chart types to find the best fitting. + + +In this example we choose the Lines type. Depending on the +chosen chart type different options are available in the +following steps. + + +After chosing the type you can get to the next step with +the Next > button. + + + +Step 2 - Choosing the Subtype + +Wizard Step 2 - Chart Sub Type + + + + + + + +In case the chosen chart type has various sub types you can +choose it in the second step. If the chart type has no sub types, +this step will be skipped automatically. + + +If you decide to change the sub type later, you can do this +in the appropriate configuration dialog which will be shown +later. + + +You can simply leave the default selection and go to the next +step. Of course you can chose any desired sub type if you want. + + + +Step 3 - Labels and Legend, Fonts + +Wizard Step 3 - Labels and Legend + + + + + + + +In the third step you can set the text for the chart title, +the axes and the legend. You can also configure the desired +font in detail for each of these. + + + +Step 4 - Axes + +Wizard Step 4 - Axes + + + + + + + +The last step of the wizard lets you set various options for +the axes and other options, depending on the chart type. + + +You can either choose Finish to accept +the options for your chart, go < Back and +change various things or simply dismiss all options from the +wizard by choosing Cancel. + + +If you choose Finish all your choices in the wizard will +be integrated in the chart and you can continue to enter +some data and do some fine tuning of various options. + + +Remember that the chart configuration dialog has many more +options available, we will discuss these later. + + + + +The &dataeditor; + +The &dataeditor; can be reached by selecting +EditEdit Data... + from the menu or by clicking on the + + + icon in the toolbar. + + +&dataeditor; in standalone mode + + + + + + + +The &dataeditor; can be used to set all values. You can also define +the number of rows and columns. + + Depending on the chart type rows and columns have different +representations. Each row can generally be considered to be one data +series or data set while each column represents the values of all +data sets at a certain location. + + +The name of a data set can be changed by clicking on the row header +(left of the first column with values). The name of a column can +be changed by clicking on the column header (above the first +row). + + +The number of rows and columns can be adjusted to fit the needs. +Since version 1.4 the restriction to 16 rows and 16 columns has been +eliminated. + + + +Chart Configuration + +&kchart; offers many configuration options for the chart. These are +available in standalone mode and when embedded in &kspread; + + +Depending on the chart type you have selected, the available +options are slightly different. Let's choose the line chart +type by clicking on the + + icon in the toolbar. + + +To get to the chart configuration dialog, select +Format +Chart... + from the menu or click on the + + + icon in the toolbar. +You might need to click on the right or left arrow at the top of the +dialog to get all pages if the width of the dialog is too small. + +Row and Column Swapping + +Configuration page 1 - Row/column swapping + + + + + + + +The first configuration page can be used to swap the +interpretation of rows and columns. +By default one row is considered to be a data set +and each column holds the individual values of the data +series. Here you can choose to have a each column hold +one data set. Note that the values are not really swapped +but only their interpretation. + + + +Chart Subtype + +Configuration page 2 - Chart Subtype + + + + + + + +The second page can be used to select the desired sub type of +a chart. The available sub types depend on the chart type, in +this case the line chart. Some chart types have no sub type +at all in which case this configuration page is not shown. +You also get a preview for each subtype. + + +Remember that the chart type can be chosen from the toolbar while +the subtype can be set through this configuration dialog. + + + +Header and Footer + +Configuration page 3 - Header and Footer + + + + + + + +On the third page you can set the title, the subtitle and the footer of +the chart, each with individual font settings. + + + +Legend + +Configuration page 4 - Legend + + + + + + + +The legend configuration page lets you set all aspects of the legend. +The legend contains the names for all data sets with the respective +colors, this is important to identify the data on the chart. + + +The General box holds the title of the legend, which is displayed +at the top of the legend box. +The Position box can be used to place the legend at various locations +on the chart. Use the central button to hide the legend. + + +The Font box can be used to set +different fonts for the legend title and the individual entries. +Additionally you can set different colors in the Color box. + + + +Axes + +Configuration page 5 - Axes + + + + + + + +The Axes page holds configuration for the chart axes. This +page highly depends on the chart type chosen. For the line +chart you can set linear or logarithmic scales and turn the grid +on and off. + + + +Colors + +Configuration page 6 - Colors + + + + + + + +On the Colors page you can choose the colors for the individual +data sets. You can also set colors for some general chart parts +like axes Line color and Grid color. + + + +Font + +Configuration page 7 - Font + + + + + + + +The Font page can be used to configure various fonts like +titles, axes labels and so on. Some of these fonts can +be set on other pages as well, but on the font page you +have them all in one place. + + + +Background + +Configuration page 8 - Background + + + + + + + +On the Background page you will find various options for tweaking +the background settings of the chart. You can either choose +different background colors or even a background picture. + + + +More... + +This short overview of the configuration options gave you an +introduction to the configuration possibilities of your chart, +it is by no means complete. Different chart types like Bar, +Line and Pie, have +additional specialised configuration pages and you are welcome +to look around, try different chart types and look at the +configuration possibilities. Use the tooltips and read the +What's This? help. To use the What's This? help simply +click on the question mark on the window +decoration and then click on the area of the configuration +page you want get more information on. + + + + + + +&kchart; as a standalone Application + +The previous chapter described the user interface, +various configuration options, data editing and the wizard +in detail. + + +This chapter gives real-life examples on how to use +&kchart; in various situations as a standalone application. +The purpose is to give you some understanding of the +way &kchart; works and how various parts relate to each other. + + +Presenting Sales Figures + +Warming up + +This first example which might often be encountered in real +life is presenting sales figures, or in this particular case +profit. + + +Imagine you own a company that has three main categories of +business: sales, support and training. And you would like +to present the profit of these categories over some years. Making +a graphical statistics is certainly a good idea. &kchart; can +help you here. + + + +Getting started + +Run &kchart; and select the Blank Worksheeet. + + +Starting with a blank chart + + + + + + + +Hit the button Use This Template to get started. &kchart; will present to you +a completely empty document. That's good, we just need to enter +some data and do some basic configuration to get a nice chart. + + +A blank chart + + + + + + + + +Getting the numbers in + +The first step, and probably the most important, is to get the +actual data into the chart. This can easily be done with the +&dataeditor;. As usual you can get to the data editor by +clicking on the + + icon in the toolbar. + + +You will notice that no data is present. Also note that +the number of data rows and columns is set to a minimum, +which is 1. + + +Now, just enter the data you see in the next screenshot. +Note that you can increase the number of rows and columns +with the spin boxes in the lower left corner. The names +of the rows and columns themselves can be changed by +clicking on them. + + +The Data + + + + + + + +Simply click the OK button when you are done. This will present +to you a simple bar chart. + + +Simple chart without fine tuning + + + + + + + +Read on to do some fine tuning! + + + +Fine Tuning + +We will now do some fine tuning and put a title on the chart. +And, we will add a nice 3D effect to the bars as well. + + +Start up the configuration dialog by clicking on the + + + icon in the toolbar. + + +Title + +Options - Title + + + + + + + +Let's start with labeling. Go to the Header/Footer +page and enter the text like in the above screenshot. + + + +X-Axis Font Settings + +The next step is to make the font of the x axis a bit bigger. You +can do this on the Font page. + + +Options - Fonts + + + + + + + +Choose the X-Axis item and click on the +Font... button. Choose a somewhat +larger font like in the following screenshot. + + +Options - X-Axis Font + + + + + + + +Note that the font size is set to Relative. +This means that the font is automatically scaled according +to the overall chart size. This is quite usefull and most +of the time what the average user expects. + + + +Giving it a 3D Look + +Some types of charts like Bar and Pie +have an additional configuration page. + + +Options - 3D Parameters + + + + + + + +To get a 3D effect for this type of chart, go to the Bar +page and simply activate 3D bar. + + +That's all what we need for a reasonable looking chart. Note +that much of this configuration could also have been achieved +with the wizard. It's basically a matter of taste what you +use. Experienced users will likely use the full option dialog +we used in this example. + + +Simply accept the settings by clicking on the OK +button. + + + + +Final output + +The final chart will look like the next screenshot. + + +Final Chart + + + + + + + +You might want to enlarge the application window to see the chart +in full size. Note how the fonts get larger in relation to the +chart size. + + +There are certainly aspects to improve further for your personal +taste. For example try to make the title font even bigger. +Just experiment further, this way you will get to know a lot +of the &kchart; application. + + +Finally you can save the chart from the File +menu and quit &kchart; with +File +Quit + + + + +Exporting to Graphic Formats: SVG, PNG, JPG, &krita;, &karbon14;, Gimp and +more + +For further processing, the chart can also be exported as a graphics file. +Many formats are available. Using either PNG, SVG, JPG or &krita; will likely +produce the best result. + + +To export your current chart simply choose +File +Export... +from the menu and select the desired file format from the filter box. + + + + + + + + + + + + + + +Using &kchart; in &kspread; + + +In addition to standalone operation, &kchart; is designed to be used with +&kspread;. This chapter describes how to create and manipulate charts +from within &kspread;. + + +Remember that &kchart; embedding into &kspread; is a very commonly +used and well implemented feature, the examples in this chapter should +just get you started. + + +As soon as you have created a chart in &kspread; you can take full +advantage of all the &kchart; features by double clicking on the +chart area. This is necessary to get to all advanced configuration +options. Keep in mind that the data editor is not available when +&kchart; is embedded into &kspread;. This is obvious since &kspread; +serves, from &kchart;'s point of view, as a powerful data +provider. + + +Swapping x and y is of particular interest when working with &kspread;. +You can swap interpretation of x and y axis in &kchart; in the +Data Format settings which can be accessed through the Edit menu +or the context menu when right clicking on the chart itself. As noted +above you need to be inside the &kchart; component in order to access +these settings, which can be done by double clicking the embedded +chart in your spreadsheet. + + + +Plotting with &kchart; +To plot with &kchart;, when it is embedded in &kspread;, do the following: + + +Picture of toolbars dialog + + + + + + + + + +Highlight the second row of numbers. + + + +Next click on the Chart button + to create the chart. + + +Select the options you want from the chart wizard. The +chart Wizard will pop up after you insert the chart. + + + + +The whole data could also be created using two columns instead of +two rows. If using columns you might want to switch x and y axis +in the &kchart; configuration as described above. + + +To make a bar chart for individual items, put the numbers in a +column, as shown below. + + +Picture of toolbars dialog + + + + + + + +The orientation of the numbers determines how the plot will be +made. + + + +A row of numbers defines the ordinates for a single plot. + + + +A column of numbers defines the heights for each bar, in a bar +graph. It also determines the size of the slices in a pie chart. + + + + + + + +Command Reference + + +The Main &kchart; Window + + +The <guimenu>File</guimenu> Menu + + + + + +&Ctrl;N + +File +New + +Creates a new document + + + + + +&Ctrl;O + +File +Open... + +Opens a document + + + + +File +Open Recent + +Shows a list of recently opened documents + + + + + +&Ctrl;S + +File +Save + +Saves the chart to the current file. If the chart +has not yet been saved the file dialog is shown. + + + + +File +Save As... + +Saves the document, the file dialog is used. + + + + +File +Reload + +Reloads the document. + + + + + +File +Import... + +Opens a document with any supported format. +The original document will not be modified. + + + + + +File +Export... + +Saves a document to any supported format. +The original document will not be modified. You can also choose +among many image formats like PNG, SVG, &krita;, Gimp or JPG. + + + + + +File +Mail... + +Sends the chart as an email attachment. + + + + +File +Import Data... + +Imports values from a CSV (Comma Separated Values) file, much like +the CSV import in &kspread;. Note that you can specify various +options and different separators (not just commas). + + + + + +File +Create Template From Document... + +Create a &kchart; template +based on this document. + + + + + + +&Ctrl;P + +File +Print... + +Prints the document +Make sure the proper print system is selected in the +Print system currently used: section. This option can +be seen after clicking on the Options >> button. + + + + +File +Print Preview... + +Displays a preview of what the printed +document will look like. + + + + +File +Document Information + +Opens a dialog box where you can enter +information about your chart. +This document information will be +displayed in the &konqueror; file browser as a tooltip. The tooltips +are pop-ups that show the contents of a file when you move your mouse over +the file icon. + + + + + +&Ctrl;W + +File +Close + +Closes the current chart. + + + + + +&Ctrl;Q + +File +Quit + +Quits &kchart; + + + + + + +The <guimenu>Edit</guimenu> Menu + + + + +Edit +Edit Data... + +Opens the &dataeditor;. + + + + + +The <guimenu>Format</guimenu> Menu + + + + +Format +Chart... + +Opens the &kchart; Configuration +dialog. + + + + + +The Configure Tabs + + + +Data Format... + +Swap row and colums (x/y flipping). + + + + + +Chart Sub-type... + +Changes the arrangement of bar graphs. + + + + + +Header & Footer... + +Enter the titles you want for your graph here. + + + + + +Colors... + +Select graph colors, line colors, grid colors and +axis title and axis label colors here. + + + + + +Font... + +Select font style and size here. The +series colors can be selected here also. The series refer to the +individual graphs. Each graphed set of data is a series. + + + + + +Background... + +Select a color or a wallpaper as background for your +graph. + + + + + +Legend... + +Change title, font and location of the legend box. The +color of the legend box can be changed also. + + + + + +Page Layout... + +Set the Margins of the page here. + + + + + + + + +The <guimenu>Settings</guimenu> Menu + + + + + +Settings +Toolbars + +Show/Hide various toolbars (File, +Actions and Types). + + + + +Settings +Configure Shortcuts... + +Configure key shortcuts for &kchart;. + + + + +Settings +Configure Toolbars... + +Configure the &kchart; toolbars. + + + + + + + + +The <guimenu>Help</guimenu> Menu + +&help.menu.documentation; + + + + +Configuring Shortcuts + +The +SettingsConfigure Shortcuts... +allows you to specify shortcuts. + + +Below is an example of how to configure a shortcut for opening +the chart wizard. + + +Picture of shortcut dialog + + + + + + + + + +Click on Custom. + + + +Next click on Primary shortcut:. + + + +Do &Alt;&Ctrl;W +and the dialog should disappear. The shortcut is now entered. + + + +Pressing the keys &Alt;&Ctrl;W +now opens the wizard. + + + + +Configuring Toolbars +The +SettingsConfigure Toolbars... +is used to add additional buttons to the toolbars. + + +Picture of toolbars dialog + + + + + + + + + + +To add a button to the File toolbar, + + + +Picture of toolbars dialog + + + + + + + + make sure File + <&koffice;> is displayed in the top combo box. + + + +Click on one of the items in the left hand pane. This item will now be +highlighted showing that it has been selected. + + + +Next click on the Right arrow button to place it in +the right pane. + + + +Click on Apply and then +click on OK + + + + +The new Item should be in the toolbar. + + + + + + + + + + +Credits and License + + +&kchart; + + +Program copyright 1998-2005 the &kchart; Team + + +Original Authors: + + +&Matthias.Kalle.Dalheimer; &Matthias.Kalle.Dalheimer.mail; + +Torben Weis weis@kde.org + + + +Contributors: + + +Laurent Montel lmontel@mandrakesoft.com + +Karl-Heinz Zimmer khz@kde.org + +Inge Wallin inge@lysator.liu.se + + + + +Documentation copyright 2002 &Jonathan.Drews; &Jonathan.Drews.mail; + + +Documentation copyright 2005 Raphael Langerhorst +raphael.langerhorst@kdemail.net + + + +&underFDL; +&underGPL; + + + +&documentation.index; + + + + diff --git a/doc/kchart/kchart-config1.png b/doc/kchart/kchart-config1.png new file mode 100644 index 000000000..5aeb06ad6 Binary files /dev/null and b/doc/kchart/kchart-config1.png differ diff --git a/doc/kchart/kchart-config2.png b/doc/kchart/kchart-config2.png new file mode 100644 index 000000000..9fec6cfd2 Binary files /dev/null and b/doc/kchart/kchart-config2.png differ diff --git a/doc/kchart/kchart-config3.png b/doc/kchart/kchart-config3.png new file mode 100644 index 000000000..cd52c606b Binary files /dev/null and b/doc/kchart/kchart-config3.png differ diff --git a/doc/kchart/kchart-config4.png b/doc/kchart/kchart-config4.png new file mode 100644 index 000000000..b3b12a4d3 Binary files /dev/null and b/doc/kchart/kchart-config4.png differ diff --git a/doc/kchart/kchart-config5.png b/doc/kchart/kchart-config5.png new file mode 100644 index 000000000..1fe1cf1f3 Binary files /dev/null and b/doc/kchart/kchart-config5.png differ diff --git a/doc/kchart/kchart-config6.png b/doc/kchart/kchart-config6.png new file mode 100644 index 000000000..206f1a443 Binary files /dev/null and b/doc/kchart/kchart-config6.png differ diff --git a/doc/kchart/kchart-config7.png b/doc/kchart/kchart-config7.png new file mode 100644 index 000000000..9c9729458 Binary files /dev/null and b/doc/kchart/kchart-config7.png differ diff --git a/doc/kchart/kchart-config8.png b/doc/kchart/kchart-config8.png new file mode 100644 index 000000000..51d43a8a3 Binary files /dev/null and b/doc/kchart/kchart-config8.png differ diff --git a/doc/kchart/kchart-dataeditor.png b/doc/kchart/kchart-dataeditor.png new file mode 100644 index 000000000..ac06d9d30 Binary files /dev/null and b/doc/kchart/kchart-dataeditor.png differ diff --git a/doc/kchart/kchart-default.png b/doc/kchart/kchart-default.png new file mode 100644 index 000000000..b8c751b8b Binary files /dev/null and b/doc/kchart/kchart-default.png differ diff --git a/doc/kchart/kchart-example1-1.png b/doc/kchart/kchart-example1-1.png new file mode 100644 index 000000000..9efa5708f Binary files /dev/null and b/doc/kchart/kchart-example1-1.png differ diff --git a/doc/kchart/kchart-example1-2.png b/doc/kchart/kchart-example1-2.png new file mode 100644 index 000000000..2a5373c3a Binary files /dev/null and b/doc/kchart/kchart-example1-2.png differ diff --git a/doc/kchart/kchart-example1-3.png b/doc/kchart/kchart-example1-3.png new file mode 100644 index 000000000..5cbaab82e Binary files /dev/null and b/doc/kchart/kchart-example1-3.png differ diff --git a/doc/kchart/kchart-example1-4.png b/doc/kchart/kchart-example1-4.png new file mode 100644 index 000000000..6e144ee09 Binary files /dev/null and b/doc/kchart/kchart-example1-4.png differ diff --git a/doc/kchart/kchart-example1-5.png b/doc/kchart/kchart-example1-5.png new file mode 100644 index 000000000..c15585b49 Binary files /dev/null and b/doc/kchart/kchart-example1-5.png differ diff --git a/doc/kchart/kchart-example1-6.png b/doc/kchart/kchart-example1-6.png new file mode 100644 index 000000000..da621f0ae Binary files /dev/null and b/doc/kchart/kchart-example1-6.png differ diff --git a/doc/kchart/kchart-example1-7.png b/doc/kchart/kchart-example1-7.png new file mode 100644 index 000000000..3cbbba7f3 Binary files /dev/null and b/doc/kchart/kchart-example1-7.png differ diff --git a/doc/kchart/kchart-example1-8.png b/doc/kchart/kchart-example1-8.png new file mode 100644 index 000000000..c2f88cfe3 Binary files /dev/null and b/doc/kchart/kchart-example1-8.png differ diff --git a/doc/kchart/kchart-example1-9.png b/doc/kchart/kchart-example1-9.png new file mode 100644 index 000000000..80c6493b0 Binary files /dev/null and b/doc/kchart/kchart-example1-9.png differ diff --git a/doc/kchart/kchart-kspread-bar.png b/doc/kchart/kchart-kspread-bar.png new file mode 100644 index 000000000..e363f2d66 Binary files /dev/null and b/doc/kchart/kchart-kspread-bar.png differ diff --git a/doc/kchart/kchart-kspread.png b/doc/kchart/kchart-kspread.png new file mode 100644 index 000000000..fec93cc68 Binary files /dev/null and b/doc/kchart/kchart-kspread.png differ diff --git a/doc/kchart/kchart-startupdialog.png b/doc/kchart/kchart-startupdialog.png new file mode 100644 index 000000000..0e64ca9e8 Binary files /dev/null and b/doc/kchart/kchart-startupdialog.png differ diff --git a/doc/kchart/kchart-wizard0.png b/doc/kchart/kchart-wizard0.png new file mode 100644 index 000000000..e53f73c76 Binary files /dev/null and b/doc/kchart/kchart-wizard0.png differ diff --git a/doc/kchart/kchart-wizard1.png b/doc/kchart/kchart-wizard1.png new file mode 100644 index 000000000..9b07001af Binary files /dev/null and b/doc/kchart/kchart-wizard1.png differ diff --git a/doc/kchart/kchart-wizard2.png b/doc/kchart/kchart-wizard2.png new file mode 100644 index 000000000..4c5c711ba Binary files /dev/null and b/doc/kchart/kchart-wizard2.png differ diff --git a/doc/kchart/kchart-wizard3.png b/doc/kchart/kchart-wizard3.png new file mode 100644 index 000000000..73c85a492 Binary files /dev/null and b/doc/kchart/kchart-wizard3.png differ diff --git a/doc/kchart/kchart-wizard4.png b/doc/kchart/kchart-wizard4.png new file mode 100644 index 000000000..6069b8901 Binary files /dev/null and b/doc/kchart/kchart-wizard4.png differ diff --git a/doc/kchart/shortcut.png b/doc/kchart/shortcut.png new file mode 100644 index 000000000..faa522435 Binary files /dev/null and b/doc/kchart/shortcut.png differ diff --git a/doc/kchart/toolbars.png b/doc/kchart/toolbars.png new file mode 100644 index 000000000..6c94d35c9 Binary files /dev/null and b/doc/kchart/toolbars.png differ diff --git a/doc/kexi/Makefile.am b/doc/kexi/Makefile.am new file mode 100644 index 000000000..085981d9b --- /dev/null +++ b/doc/kexi/Makefile.am @@ -0,0 +1,4 @@ + +KDE_LANG = en +KDE_DOCS = AUTO + diff --git a/doc/kexi/basics.docbook b/doc/kexi/basics.docbook new file mode 100644 index 000000000..7bb34b9f9 --- /dev/null +++ b/doc/kexi/basics.docbook @@ -0,0 +1,504 @@ + + + + + &kexi; Basics + + + + + &kexi; Databases + + + Many applications such as OpenOffice.org or Microsoft Excel create + files which are called documents. &kexi; + creates files too, but we refer to them as &kexi; + database files, or simple database + files here. &kexi; database files usually have the + extension .kexi. + + + + + + In addition to storing your databases in database files, &kexi; + can also use databases on database + servers, which is why we refer to them as + database files, and not simply as + databases. + + + + The term &kexi; project, or simply + project is also used to refer to a &kexi; + database, regardless of whether it is stored in a file or on a + database server. + + + + + + Creating a New Database File + + + + + + Run &kexi;, or if it is already running, use + + + &Ctrl;N + + FileNew + . + + + + + Click the OK to confirm the + creation of the project. + + + + + Enter a name for your project, and click Next. + + + + + Use the file browser to choose a folder where you would + like to save your database file. You may change the file + name in the Location: box if you dislike + the one that is suggested. + + + + + Click Create. + + + + + + + + The &kexi; Main Window + + + The Project Navigator and + Properties Editor are shown in panes on + each side of the child window. These can be resized or hidden + as required. A pane can be hidden by clicking the small cross + at the top of the pane (just below the toolbar). + + + Database objects (tables, queries, etc.) listed in the Project + Navigator can opened by clicking (or + double-clicking, depending upon your global &kde; settings) on their names. + + + + +Main application elements + + + + +Main elements of &kexi; application's window are: + + +Menubar + +contains available commands for the application. +You will find detailed description of any of the commands in the appendix. + + + + +Toolbar + +contains most frequently used commands. + + + + + +Project Navigator's pane + +contains a list of any object (tables, queries, forms, ...) created +within the currently opened database project. The navigator also contains +small toolbar with most usable commands related to the database objects. + + + + +Opened database objects area + +a central area of the application taking most of the screen space. +For IDEAl user interface mode it contains switchable tabs with +windows that are always maximized. For Childframe user interface +mode it contains floating windows. + + + + +Properties pane + +contains a list of properties of currently activated database object. +For certain objects (⪚ form's widgets) it can have several tabs. + + + + +Taskbar + +contains a list of currently opened windows with database objects. +For IDEAl user interface mode, it is available as a number of tabs. +For Childframe user interface mode, it is available as a number of +buttons, behaving just like your operating system's taskbar. + + + + + + +<guilabel>Project Navigator</guilabel> pane + +The Project Navigator pane is one of the most frequently used elements +of the &kexi; main window. The pane contains a list of all objects +created within the currently opened &kexi; database project. The objects +are split into groups: tables, queries, forms. + + +The Project Navigator pane also contains a small toolbar for most +frequently used commands (from left to right): Open +selected object, Design selected object, +Create a new object, and Delete selected +object. + + + +For each object on the list a context menu is available using the &RMB;. +For example, this is context menu for the persons table. + + + + + + +Double clicking with the &LMB; on the object's name on the list allows to +open the object in Data View. If the object's window was alread opened, +the action just activates the window without switching it's view mode. + + +Note that your operating system or window manager can be set up to handle +single clicks instead of double clicks. In this case it is enough to single +click on the object name to open its window. + + + + + + +Database object windows + + +Opening an object's window + + +Select the object in the Project Navigator +pane. + + + + + +Click the Open button on the Project Navigator pane's toolbar. + + + + + +Commands related to object windows +Closing an object window + +When the IDEAl user interface mode (the default) is used, each window has +its own tab. Place the mouse pointer on the icon on the tab. A + Close button will become +visible. Click it to close the tab. + + +In the Childframe on the right hand of each opened window there are +buttons you can use to control the window. Click the first one on the +right hand to close the window. + + +Alternatively, regardless of the user interface mode you are using, +you can select Window +Close from the Menubar. + + +Window buttons for Childframe user interface +mode + + +The other buttons (from right to left) can be used to: maximize, minimize +and undock the window. + + +There's a small icon on the left side of the title bar which can be clicked +to show a context menu with commands related to the window. + + + + + + + + +<guilabel>Property Editor</guilabel> pane + +In the Property Editor pane you can change properties of the object +displayed in the active window. Depending on the context, the pane is +consisted of one or more tabs. The first, always visible tab, Properties, +contains the list of available properties. + + + +Rules for using the Property Editor: + +Each row contains a single property. + + +You can use the mouse or the keyboard to change values of particular +properties. + + + +Most frequently used types of property values are: + +a number; you can enter the value directly +or increase or decrease its value by clicking with the &LMB; on the arrows. + + + +text +drop down list of values +Yes/No; +you can toggle the value by clicking on the button; +Yes (true) means that the button is +toggled on, >No (false) means that +the button is toggled off. + + + + + + +There is no need to confirm a changed value: changes are visible immediately +after moving to a different row of the Property Editor's list or by pressing +the Enter key. + + + +Names of the recently changed properties that not yet were stored in the +database are marked with bold text. + + + + +After changing the value of a property, a special Undo changes +button appears on the right side of the Property Editor's list. + +By clicking it you can revert the value of the property to the original value +that was loaded from the database upon opening the database object. The button +is only visible when the property is actually highlighted. + + + + + +The Property Editor pane is empty if: +no single database object's window is opened, or + + +the active database object's window does not offer properties; it is usually +the case when it is opened in Data View instead of Design View + + + + + + + + + + + + + + + Opening an existing &kexi; database file + + + + To open an existing &kexi; database file: + + + select it in the Open Existing Project + dialog; or + + + open it by clicking on the .kexi file icon. + + + + + + Opening a database file in the <guilabel>Open Existing + Project</guilabel> dialog + + + + Run &kexi;. + You should see Choose Project startup dialog. + Choose Open Existing Project tab. + You will see the following dialog: + + + + From Current location drop down box, pick a folder + containing a file you are looking for. + + + You can either pick a file or enter its name in the + Location: box. + + + Click OK. + + + + + + Notes + + + + By default the Filter: drop down list has + Kexi Database File-Based Project selected. + In case the file you are looking for has an other extension, + you can change the selection of the Filter: + drop down list to All Files to display + all available files (regardless of an extension). + + + If you have selected a file of an external type, like a MS Access .mdb + file, &kexi; will provide you with the option to import the file. + + + + If you have selected a connection data file + (with .kexic extension) or a shortcut to a project on + database server file (with .kexis extension), &kexi; + will display appropriate dialogs. + + + + + + + + Opening an existing &kexi; database file by clicking on .kexi file's icon + + + Click file's icon using your file manager or desktop. + &kexi; will open this database project automatically. + + + + + Notes + + + Note about database files accessed remotely. + You may want to open a database file that is located on a remote + source (⪚ a web or FTP server or a MS Windows network share). + K Desktop Environment allows you to open files from remote sources + directly in applications and to save changes back to the source, but + this is not the case with database files. By clicking on a database + file located on a remote source, a copy of the file will be + downloaded to a temporary directory on your computer and all your + changes will be made to this local file. The remote original of + the file will remain unchanged, so it's recommended to copy + (download) the file to your computer first, then open the file and + copy it back to the remote source if you want to make it up to date. + + + + + + + + Using built-in help + + + + The following ways to get built-in help in &kexi; are available: + + + The Handbook in form of electronic document. + + The Handbook is available by pressing F1 + key or selecting Help&kexi; + Handbook from the menubar. + + + + What's This? hints. + + Select HelpWhat's + This?from the menu bar and click on + an area of the application to get hints about it. + + + + + + diff --git a/doc/kexi/building.docbook b/doc/kexi/building.docbook new file mode 100644 index 000000000..9b900c778 --- /dev/null +++ b/doc/kexi/building.docbook @@ -0,0 +1,248 @@ + + + +Building Simple Databases + +Introduction + +To learn the basics of &kexi;, you could build a simple database +utilizing most elementary &kexi;'s features. To make things simpler, +advanced database design topics will not be covered here. + + +Start by creating a new empty Phone Book. + + + +Having a new empty database project, perform the following steps: + +Design database tables. Read . +Enter data into tables. Read . +Design database queries. Read . +Design forms. Read . +Use forms to enter data. Read . + + + + +Designing Database Tables + +First, there will be two tables added to your database: +persons and phone_numbers. +These are exactly the same tables as described in chapter Database and spreadsheet. +A layout for Persons can be found in section +Data integrity and validity +in that chapter. + + + + + +Select InsertTable + from the Menubar. You can also use the button Create +object: table on the Project +Navigator's toolbar. + + + + +The Table Designer's window will appear. Looking at the top of designer's window +you will notice that &kexi; proposed you a generic name like +template for the new table. The table design is not saved +yet so you will be able to assign more proper name later. Moreover, because of +the same reason, the table name is not yet visible in the +Project Navigator. + + + + + + +The Table Designer window + +Table Designer window consists of following columns: + +PK - Primary Key. + + +Field Caption - caption of the field +which will be displayed during data entering. + + +Data Type - a combo box containing a list of data types, +allowing to set a main rule for entered data for a given field. For example, +when an integer number data type is set for a field, a database user will not +able to enter letter characters into this field. + + +Comments - you can enter here any information useful for +understanding what the given field is provided for. This additional text will +be saved within the table design and only visible in design mode. + + + +In the Table designer window, every row corresponds to +a single table field. You can recognize you are in design +mode because the +Switch to Design View mode button is toggled on within +the main &kexi; toolbar. + + + + +Designing the <emphasis>Persons</emphasis> table + +In the first row click on the cell in the Field Caption +column and enter Name as field caption. + + +Notes about field names and captions + +Every table field must have a name and a caption, these cannot be empty. + + +Field name is a word used by the database, usually not visible for users of the database application. The name may not contain special (national) characters (like ±, ¶, Ü) +or space characters. The name must only contain roman letters, + +numbers and underscore sign "_". Use the latter instead of +spaces or dashes. + + +Field names must be started with a letter or underscore sign +"_", never with a number. + + +It does not matter whether you are using small or capital letters. +For &kexi; the database name "Persons" is the same as +"persons". + + +Field caption, on the other hand, allows you to enter any letters and special characters. It will be displayed for users of the database application. + + + + + + +In a similar way, enter the following fields into the table design: +surname +street +house_number +city + + + + +All the above fields, except house_number, are of type +text. +Change house_number field's type to integer +number. To do this, click on a cell in the Data +Type column, house_number row and then +click on drop down list's button +(you can also press F4 or +&Alt;Down. The list +of data types will appear. Select the Integer number type. + + +From now on, the house_number field only accepts numbers. + + + + +Persons table design is ready. Click +Switch to Data View button on the toolbar to finish +designing and switch to Data View for the table. This allows you entering +data into the table. + + + +As the design is not yet saved in the database, the Save Object As +dialog window appears. You need to specify the name for the new table. + + + +&kexi; offers a generic name like Table1. +To change the name, enter Persons into the +Caption field and press the +Enter key or click the OK +button. The Caption field will be used to display the +table to database end-users, ⪚ as a form. Unlike the name, the caption can +contain any characters including spaces and special characters. + + +Note that filling the Caption field automatically fills +the Name field. For your convenience the rule for using +only letters, numbers and the "_" character is kept. You +can alter the contents of the Name field if you want to. + + + + +You are asked about an agreement for automatic adding of primary key to the table. + + Click Add primary key +button to continue. + + + + +The Persons table has been created and opened in Data View. +Its name appears in the Project Navigator pane. + + + + +Create the phone_numbers table, in a similar +way as persons table. + + + +Create a person field of type Integer +number and phone of type Text. +Do not use a number type here because phone numbers can have many different +forms and prefixes. + + + +Click Switch to +Data View button on the toolbar and enter Phones +caption for the table. As for your previous table, allow &kexi; to automatically +create a primary key. + + + + + + + +&enteringdataintotables; + +&querydesigning; + +&designingforms; + +&enteringdatausingforms; + + + diff --git a/doc/kexi/comparing.docbook b/doc/kexi/comparing.docbook new file mode 100644 index 000000000..f213ac042 --- /dev/null +++ b/doc/kexi/comparing.docbook @@ -0,0 +1,98 @@ + + + + + Comparing &kexi; to other database applications + + + Although different database applications tend to provide similar + functionality, they often use different terminology. For your + convenience, this appendix shows how the terminology used in + &kexi; corresponds to that used by other database applications. + Thus, this chapter may be useful when migrating databases from + one application to another. + + + + Data types + + + The table below shows how the data types in &kexi; correspond + to data types in other database applications. + + + Some of the data types listed here are + sub-types of other types. For example, + the Long text type is a sub-type of the + Text type. To use a sub-type in + &kexi;, you should select the corresponding basic type (in + this case, Text) in the table designer, and then select the + sub-type using the Subtype setting in the + Properties Editor. + + + + Comparison of data types used in &kexi; and other database + applications + + + + + &kexi; + MS Access + dBase/FoxPro + Paradox + + + + + Text (Text) + Text + Character + Alphanumeric + + + Long text (Long text) + Memo + Memo + Memo + + + Date/Time (Date/Time) + Date, Time + Date + DateTime + + + + Integer Number (Integer Number) + Number (Integer) + Numeric + Integer + + + Big Integer Number (Big Integer Number) + Long Integer + Numeric + Long Integer + + + Floating Point Number (Floating Point Number) + Single/Double precision number + Float + Number + + + +
    +
    +
    diff --git a/doc/kexi/configuration.docbook b/doc/kexi/configuration.docbook new file mode 100644 index 000000000..f3d134f7f --- /dev/null +++ b/doc/kexi/configuration.docbook @@ -0,0 +1,230 @@ + + + + + Configuring &kexi; + + + + This chapter describes how you can configure &kexi; to suit your + own needs and preferences. + + + + + Window Layout + + + &kexi; provides a Mutiple Document + Interface (MDI). This means that you can have + several database objects (such as tables, queries, forms and + scripts) open at the same time and in the same &kexi; main + window. Each database object is shown in a child + window within the main window. + + + There is a choice of two MDI modes available, allowing a choice + of how child windows are managed and displayed. The two modes + are: + + IDEAl Mode; and + Childframe Mode. + + These modes are described in the following two sections. You + can change the MDI mode from the MDI + Mode sub-menu under the Window + menu. Note that changing the MDI mode requires &kexi; to be + restarted before the new mode takes effect. + + + + IDEAl mode + + + + IDEAl mode is the default MDI mode, and may be familiar from + other &kde; applications. In this mode, a single child window + is shown maximized within the &kexi; main window at once. + A tab bar, containing one tab for each child window, allows + other child windows to be viewed by simply clicking on the + relevant tab. + + + + + Childframe mode + + + + In Childframe mode, child windows are displayed in the + main &kexi; window, but need not be maximized within it. + In order to use Childframe mode, you need to select + + Window, + MDI Mode, + Childframe Mode + from the menu. + + + Each child window has a titlebar with buttons for maximizing, + minimizing and closing it. They can also be moved and resized + within the main window in the normal way (for example, they + can be moved by clicking and dragging the title bar). + + + The buttons behave as follows: the right-most button closes + the child window. The button on its left maximizes the child + window - note this causes the buttons to move to the top right + of the main window, above the Properties + editor if it is open. The next button to the left + toggles the child window between minimized and restored. + + + The left-most button detaches, or + undocks, the child window, allowing it + to be moved out of the main window. For more information on + docking and undocking windows, see the next section. + + + + + + + Docking and Undocking Windows + + + By default, the Project Navigator and + Properties Editor panels are displayed as + part of the main &kexi; window. It is possible to + undock each panel, so that it is + displayed in a separate window. Once undocked, it is possible + to dock the panel so it appears back in + the main window again. + + + In Childframe + mode, it is also possible to undock child windows. For + example, a child window showing a database table could be + undocked, allowing the child window showing the table to be + maximized on the screen. + + + It can be useful to undock a window when using: + + + + a small screen; + + + + + large tables, queries or forms; and/or + + + + + more than one montitor. + + + + + + + Docking and undocking side panels + + + The Project Navigator and + Properties Editor side panels may be + undocked by either: + + + + double-clicking on the 'grip' bar at the top of the + panel; or + + + + + clicking once on the arrow at the top of the panel, next + to the cross. + + + + + + + Once undocked, panel windows may be docked into the main + window again similarly to undocking: + + + + double-clicking on the 'grip' bar at the top of the window; or + + + + + clicking once on the arrow at the top of the panel, next + to the cross. + + + + + + + + + Docking and undocking child windows + + + Child windows may be docked and undocked in Childframe mode + only. + + + In Childframe mode, child windows may be undocked by: + + + + right-clicking in the tab bar, on the tab corresponding + to the window to be undocked, and selecting + Undock; or + + + + + + right-clicking on the title bar of the child window, and + selecting Undock; or + + + + + + if the child window is not + maximized, clicking the arrow in the top right corner of + the child window (next to the minimize, maximize and + close buttons for that child window); + + + + + + if the child window is maximized, clicking the arrow to + the right of the menu bar (next to the minimize, restore + and close buttons for that child window). + + + + + + + To dock a child window, right-clicking in the tab bar, on the + tab corresponding to the window to be docked, and select + Dock. + + + + + diff --git a/doc/kexi/contact-example.png b/doc/kexi/contact-example.png new file mode 100644 index 000000000..9b2e5dbf4 Binary files /dev/null and b/doc/kexi/contact-example.png differ diff --git a/doc/kexi/credits.docbook b/doc/kexi/credits.docbook new file mode 100644 index 000000000..6b910547f --- /dev/null +++ b/doc/kexi/credits.docbook @@ -0,0 +1,63 @@ + + + +Credits and License + + + &kexi; Copyright 2002-2006 The &kexi; Team + + &kexi; Developers: + + Jaroslaw Staniek / OpenOffice Polska js@iidea.pl + + + Lucijan Busch lucijan@kde.org + + + Cedric Pasteur cedric.pasteur@free.fr + + + Adam Pigg adam@piggz.fsnet.co.uk + + + Martin Ellis martin.ellis@kdemail.net + + + Sebastian Sauer mail@dipe.org + + + Christian Nitschkowski segfault_ii@web.de + + + Peter Simonsson psn@linux.se + + + &Joseph.Wenninger; jowenn@kde.org + + + Seth Kurzenberg seth@cql.com + + + Laurent Montel montel@kde.org + + + Till Busch till@bux.at + + + + + + Documentation by Martin A. Ellis martin.ellis@kdemail.net, + Jaroslaw Staniek js@iidea.pl + with contributions from Anne-Marie Mahfouf, Raphael Langerhorst, Michal Kubicki and Aron Stansvik. + + + + +&underFDL; +&underLGPL; + + diff --git a/doc/kexi/database.docbook b/doc/kexi/database.docbook new file mode 100644 index 000000000..e89afa55b --- /dev/null +++ b/doc/kexi/database.docbook @@ -0,0 +1,649 @@ + + + +Introduction to Databases + + +What Is a Database? + +You can define a database as a collection of data on one topic. +It is organised in a way allowing to easily browse the information, +make changes or add new items. + + +Look at this diagram for one of the above examples: a simple phone book. + + + A diagram of a phone number database + + + + + + A diagram of a phone number database + + + + +The above picture shows a set of two contacts each of which is +presented on a separate card. It appears that such a card can +constitute a single row in a table: + + +Contacts table + + +
    + +&koshell;'s Side Pane + + + + &koshell;'s Main View + + + +&koshell; Insert Object dialog + + The Color Range dialogThe Convert Image Type dialogThe Image Properties dialogThe Image Size dialogThe Rotate Image dialogThe Separate Image dialogThe Shear Image dialogThe Substrate dialogThe Convert Layer Type dialogThe Drop Shadow dialogThe Histogram dialogThe Layer Properties dialogThe Layer Size dialogThe New Adjustment Layer dialogThe New Layer dialogThe Rotate Layer dialogThe Shear Layer dialogThe Blur dialogThe Brightness / Contrast dialogThe Bumpmap dialogThe Color Adjustment dialogThe Color to Alpha dialogThe Color Transfer dialogThe Custom Convolution dialogThe Emboss dialogThe Filters Gallery dialogThe Gaussian Noise Reduction dialogThe Lens Correction dialogThe Image Restoration dialogThe Oilpaint dialogThe Pixelize dialogThe Raindrops dialogThe Random Noise dialogThe Random Pick dialogThe Round Corners dialogThe Small Tiles dialogThe Sobel dialogThe Unsharp Mask dialogThe Wave dialogThe Wavelet Noise Reduction dialogThe Add Palette dialogThe Document Information dialogThe Overview tabThe Histogram tabThe Tool tab for BrushThe Tool tab for LineThe Tool tab for RectangleThe Tool tab for StarThe Tool tab for DuplicateThe Tool tab for Paint with Filters The Tool tab for TransformThe Tool tab for CropThe Tool tab for Contiguous FillThe Tool tab for GradientThe Tool tab for TextThe Tool tab for Color PickerThe Tool tab for Select toolsThe Tool tab for Select ContiguousThe Tool tab for Select MagneticThe HSV tabThe RGB tabThe Gray tabThe Palettes tabThe Watercolors tabThe Layers tabThe Script Manager tabThe File toolbarThe Edit toolbarThe Navigation toolbarThe Krita toolbarDrawing a Bezier curveModifying a Bezier curveA finished Bezier curvePainting with filtersThe Brushes and Stuff toolbarThe Brush Shapes paletteThe Brush Shapes palette with the Autobrush +tabThe Brush Shapes palette with the Custom Brush +tabThe Gradients paletteThe Patterns paletteThe Patterns palette with the Custom Pattern tab selectedThe Oilpaint dialogThe available Preferences sectionsThe General sectionThe Display sectionThe Color Management sectionThe Performance sectionThe Tablet sectionThe Grid sectionThe starting imageThe starting imageThe Select Outline toolThe picture after selecting the headThe Subtract modeFeather selectionThe Image Size dialogThe Select Contiguous toolThe Sample merged optionThe Contiguous Fill toolThe Select Rectangular toolMoving the shadow layerThe Crop toolThe resulting imageThe Create Document dialogThe New Image dialog&krita;'s main screenA flowerThe outline of the flowerThe colored flowerThe original imageThe image with the Auto Contrast filter applied to itThe image with the Blur filter applied to itThe image with the Brightness / Contrast filter applied to itThe image with the Bumpmap filter applied to itThe image with the Color Adjustment filter applied to itThe image with the Color to Alpha filter applied to itThe image with the Color Transfer filter applied to itThe image with the Custom Convolution filter applied to itThe image with the Desaturate filter applied to itThe image with the Bottom Edge Detection filter applied to +itThe image with the Emboss in All Directions filter applied to +itThe image with the Emboss with Variable depth filter applied to +itThe image with the Gaussian Blur filter applied to +itThe image with the Gaussian Noise Reduction filter applied to itThe image with the Invert filter applied to itThe image with the Lens Correction filter applied to itThe image with the Maximize Channel filter applied to itThe image with the Mean Removal filter applied to +itThe image with the Minimize Channel filter applied to itThe image with the Oilpaint filter applied to +itThe image with the Pixelize filter applied to +itThe image with the Raindrops filter applied to +itThe image with the Random Noise filter applied to itThe image with the Random Pick filter applied to itThe image with the Round Corners filter applied to +itThe image with the Sharpen filter applied to itThe image with the Small Tiles filter applied to +itThe image with the Sobel filter applied to itThe image with the Unsharp Mask filter applied to itThe image with the Wave filter applied to itThe image with the Wavelet Noise Reduction filter applied to +itThe original imageThe gradient applied with the Normal compositing +modeThe gradient applied with the Multiply compositing +modeThe gradient applied with the Burn compositing +modeThe gradient applied with the Dodge compositing +modeThe gradient applied with the Divide compositing +modeThe gradient applied with the Screen compositing +modeThe gradient applied with the Overlay compositing +modeThe gradient applied with the Darken compositing +modeThe gradient applied with the Lighten compositing +modeThe gradient applied with the Hue compositing +modeThe gradient applied with the Saturation compositing +modeThe gradient applied with the Value compositing +modeThe gradient applied with the Color compositing +modePainting a selectionPainting a selectionUnselectingBefore the magic wandA magic wand selectionSelecting similar colors
    + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Import ApplixGraphics for karbon
    +
    +
    +
    Last update11 feb 2001
    Features- Can import simple ApplixGraphics documents
    Todo- Get format and style information and add this into kontour
    History + + + + + + + + + + + + + + + + +
    27jan2003 :  Changed the intern settings of this filter from kontour to karbon
    + Moved print function to kdDebug (area=30517) functions
    +
    11feb2001 :  Written a filter that only can filter simple applixgraphics files +
    + +
    Authors Enno Bartels
    LinksFileformat discription
    Progress report -
    +
    + +Up + +


    + +
    +


    + + +
    + +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Export kontour to ApplixGraphics

    +
    +
    Last update-
    FeaturesNone
    TodoEverything
    History-
    Authors-
    Links-
    Progress report ---
    +
    +
    +Up + + + diff --git a/filters/karbon/eps/Makefile.am b/filters/karbon/eps/Makefile.am new file mode 100644 index 000000000..3749dfdc8 --- /dev/null +++ b/filters/karbon/eps/Makefile.am @@ -0,0 +1,37 @@ +kde_module_LTLIBRARIES = \ + libkarbonepsexport.la \ + libkarbonepsimport.la + +libkarbonepsexport_la_SOURCES = \ + epsexport.cc \ + epsexportdlg.cc + +libkarbonepsexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonepsexport_la_LIBADD = $(LIB_KOFFICEUI) ../../../karbon/libkarboncommon.la + +libkarbonepsimport_la_SOURCES = epsimport.cc pscommentlexer.cc +libkarbonepsimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonepsimport_la_LIBADD = $(LIB_KOFFICEUI) + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = \ + karbon_eps_export.desktop \ + karbon_eps_import.desktop \ + karbon_ps_import.desktop + +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + epsexport.h \ + epsexportdlg.h \ + epsimport.h \ + pscommentlexer.h + +METASOURCES = AUTO diff --git a/filters/karbon/eps/epsexport.cc b/filters/karbon/eps/epsexport.cc new file mode 100644 index 000000000..8ded17728 --- /dev/null +++ b/filters/karbon/eps/epsexport.cc @@ -0,0 +1,481 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include // For creation date/time. +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "epsexport.h" +#include "epsexportdlg.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgroup.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +#include "vtext.h" +#include "vcomputeboundingbox.h" + +// Define PostScript level1 operators. +static char l1_newpath = 'N'; +static char l1_closepath = 'C'; +static char l1_moveto = 'm'; +static char l1_curveto = 'c'; +static char l1_lineto = 'l'; +static char l1_stroke = 's'; +static char l1_fill = 'f'; +//static char l1_eofill = 'e'; +static char l1_setlinewidth = 'w'; +static char l1_setdash = 'd'; +static char l1_setrgbcolor = 'r'; +static char l1_gsave = 'S'; +static char l1_grestore = 'R'; + + +class EpsExportFactory : KGenericFactory +{ +public: + EpsExportFactory( void ) + : KGenericFactory( "karbonepsexport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsexport, EpsExportFactory() ) + + +EpsExport::EpsExport( KoFilter*, const char*, const QStringList& ) + : KoFilter(), m_exportHidden( true ) +{ +} + +KoFilter::ConversionStatus +EpsExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/x-eps" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) + return KoFilter::StupidError; + + + KoFilter::ConversionStatus status = KoFilter::OK; + + // Ask questions about PS level etc. + EpsExportDlg* dialog = new EpsExportDlg(); + + QApplication::setOverrideCursor( Qt::arrowCursor ); + + if( dialog->exec() ) + { + // Which PostScript level to support? + m_psLevel = dialog->psLevel() + 1; + m_exportHidden = dialog->exportHidden(); + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + QApplication::restoreOverrideCursor(); + delete( dialog ); + + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + + // Load the document. + VDocument doc; + doc.load( docNode ); + + // Process the document. + doc.accept( *this ); + + delete m_stream; + fileOut.close(); + } + else + { + // Dialog cancelled. + status = KoFilter::UserCancelled; + } + + QApplication::restoreOverrideCursor(); + delete( dialog ); + + return status; +} + +void +EpsExport::visitVDocument( VDocument& document ) +{ + // calculate the documents bounding box + VComputeBoundingBox bbox( ! m_exportHidden ); + document.accept( bbox ); + const KoRect &rect = bbox.boundingRect(); + + // Print a header. + *m_stream << + "%!PS-Adobe-3.0 EPSF-3.0\n" + "%%BoundingBox: " << + // Round down. + qRound( rect.left() - 0.5 ) << " " << + qRound( rect.top() - 0.5 ) << " " << + // Round up. + qRound( rect.right() + 0.5 ) << " " << + qRound( rect.bottom() + 0.5 ) << "\n" << + "%%HiResBoundingBox: " << + rect.left() << " " << + rect.top() << " " << + rect.right() << " " << + rect.bottom() << "\n" + "%%Creator: Karbon14 EPS Exportfilter 0.5" + << endl; + + // Process document info. + KoStoreDevice* storeIn; + storeIn = m_chain->storageFile( "documentinfo.xml", KoStore::Read ); + + if( storeIn ) + { + QDomDocument domIn; + domIn.setContent( storeIn ); + + KoDocumentInfo docInfo; + docInfo.load( domIn ); + + KoDocumentInfoAuthor* authorPage = + static_cast( docInfo.page( "author" ) ); + + // Get creation date/time = "now". + QDateTime now( QDateTime::currentDateTime() ); + + *m_stream << + "%%CreationDate: (" << now.toString( Qt::LocalDate ) << ")\n" + "%%For: (" << authorPage->fullName() << ") (" << authorPage->company() << ")\n" + "%%Title: (" << docInfo.title() << ")" + << endl; + } + + + // Print operator definitions. + *m_stream << + "\n" + "/" << l1_newpath << " {newpath} def\n" + "/" << l1_closepath << " {closepath} def\n" + "/" << l1_moveto << " {moveto} def\n" + "/" << l1_curveto << " {curveto} def\n" + "/" << l1_lineto << " {lineto} def\n" + "/" << l1_stroke << " {stroke} def\n" + "/" << l1_fill << " {fill} def\n" + "/" << l1_setlinewidth << " {setlinewidth} def\n" + "/" << l1_setdash << " {setdash} def\n" + "/" << l1_setrgbcolor << " {setrgbcolor} def\n" + "/" << l1_gsave << " {gsave} def\n" + "/" << l1_grestore << " {grestore} def\n" + << endl; + + // Export layers. + VVisitor::visitVDocument( document ); + + // Finished. + *m_stream << + "%%EOF" + << endl; +} + +void +EpsExport::visitVGroup( VGroup& group ) +{ + VObjectListIterator itr( group.objects() ); + + for( ; itr.current(); ++itr ) + { + // do not export hidden child objects + if( ! m_exportHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +EpsExport::visitVLayer( VLayer& layer ) +{ + // do not export hidden layers + if( ! m_exportHidden && ! isVisible( &layer ) ) + return; + + VObjectListIterator itr( layer.objects() ); + + for( ; itr.current(); ++itr ) + { + // do not export hidden objects + if( ! m_exportHidden && ! isVisible( itr.current() ) ) + continue; + itr.current()->accept( *this ); + } +} + +void +EpsExport::visitVPath( VPath& composite ) +{ + *m_stream << l1_newpath << "\n"; + + VVisitor::visitVPath( composite ); + + getFill( *composite.fill() ); + getStroke( *composite.stroke() ); + + *m_stream << endl; +} + +void +EpsExport::visitVSubpath( VSubpath& path ) +{ + // Export segments. + VSubpathIterator itr( path ); + + for( ; itr.current(); ++itr ) + { + VSegment *segment = itr.current(); + if ( segment->isCurve() ) { + *m_stream << + itr.current()->point( 0 ).x() << " " << + itr.current()->point( 0 ).y() << " " << + itr.current()->point( 1 ).x() << " " << + itr.current()->point( 1 ).y() << " " << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_curveto << "\n"; + } else if ( segment->isLine() ) { + *m_stream << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_lineto << "\n"; + } else if ( segment->isBegin() ) { + *m_stream << + itr.current()->knot().x() << " " << + itr.current()->knot().y() << " " << + l1_moveto << "\n"; + } + } + + if( path.isClosed() ) + *m_stream << l1_closepath << "\n"; +} + +void +EpsExport::visitVText( VText& text ) +{ + // TODO: currently we only export the glyphs if available. + + // Export the glyphs (= VPaths). + VPathListIterator itr( text.glyphs() ); + + for( ; itr.current(); ++itr ) + { + visit( *itr.current() ); + } +} + +void +EpsExport::getStroke( const VStroke& stroke ) +{ + // Solid stroke. + if( stroke.type() == VStroke::solid ) + { + // Dash pattern. + *m_stream << "["; + + const QValueList& + array( stroke.dashPattern().array() ); + + QValueListConstIterator itr = array.begin(); + for( ; itr != array.end(); ++itr ) + *m_stream << *itr << " "; + + *m_stream << + "] " << stroke.dashPattern().offset() << + " " << l1_setdash << " "; + + getColor( stroke.color() ); + + // "setlinewidth", "stroke". + *m_stream << + " " << stroke.lineWidth() << + " " << l1_setlinewidth << + " " << l1_stroke << "\n"; + } + else if( stroke.type() == VStroke::grad ) + { + if( m_psLevel == 3 ) + { + + } + } +} + +void +EpsExport::getFill( const VFill& fill ) +{ + // Solid fill. + if( fill.type() == VFill::solid ) + { + // "gsave". + *m_stream << l1_gsave << " "; + + // "setrgbcolor". + getColor( fill.color() ); + + // "fill", "grestore". + *m_stream << " " << l1_fill << " " << l1_grestore << "\n"; + } + // Gradient. + else if( fill.type() == VFill::grad ) + { + if( m_psLevel == 3 ) + { + // "gsave". + *m_stream << l1_gsave << " "; + + VGradient grad = fill.gradient(); + QPtrVector ramp = grad.colorStops(); + if( ramp.size() < 2 ) + { + if( ramp.size() == 1 ) + getColor( ramp[0]->color ); + } + if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 ) + { + // Gradient with more than two colors or asymmetrical midpoint. + for( uint i = 1;i < ramp.size();i++ ) + { + char name[15]; + sprintf( name, "Function%d", 2 * i - 1 ); + + VColorStop stop1 = *ramp[i - 1]; + VColorStop stop2 = *ramp[i]; + VColor mid; + mid.set( 0.5 * ( stop1.color[0] + stop2.color[0] ), 0.5 * ( stop1.color[1] + stop2.color[1] ), 0.5 * ( stop1.color[2] + stop2.color[2] ) ); + *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" + << "\t/Domain [ 0 1 ] def\n" << "\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " + << stop1.color[2] << " ] def\n" << "\t/C1 [ " << mid[0] << " " << mid[1] << " " + << mid[2] << " ] def\n" << "\t/N 1 def\n" << "end\n"; + + sprintf( name, "Function%d", 2 * i ); + + *m_stream << "/" << name << " 7 dict def " << name << " begin\n" << "\t/FunctionType 2 def\n" << "\t/Domain [ 0 1 ] def\n" + << "\t/C0 [ " << mid[0] << " " << mid[1] << " " << mid[2] << " ] def\n" << "\t/C1 [ " << stop2.color[0] << " " + << stop2.color[1] << " " << stop2.color[2] << " ] def\n" << "\t/N 1 def\n" << "end\n"; + } + } + if( grad.type() == VGradient::linear ) + *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 2\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ " + << grad.origin().x() << " " << grad.origin().y() << " " << grad.vector().x() << " " << grad.vector().y() << " ]\n\t/Extend[ true true ]\n" << "\t/Function <<\n"; + else if( grad.type() == VGradient::radial ) + { + double r = sqrt( pow( grad.vector().x() - grad.origin().x(), 2 ) + pow( grad.vector().y() - grad.origin().y(), 2 ) ); + *m_stream << "clip newpath\n" << "/DeviceRGB setcolorspace\n" << "<<\n" << "\t/ShadingType 3\n" << "\t/ColorSpace /DeviceRGB\n" << "\t/Coords [ " + << grad.origin().x() << " " << grad.origin().y() << " 0.0 " << grad.origin().x() << " " << grad.origin().y() + << " " << r << "]\n\t\t/Extend [ false true ]\n" << "\t/Function <<\n"; + } + if( ramp.size() == 2 && ramp[0]->midPoint == 0.5 ) + { + // Gradient with only two colors and symmetrical midpoint. + VColorStop stop1 = *ramp[0]; + VColorStop stop2 = *ramp[1]; + *m_stream << "\t\t/FunctionType 2\n" << "\t\t/C0 [ " << stop1.color[0] << " " << stop1.color[1] << " " << stop1.color[2] + << " ]\n" << "\t\t/C1 [ " << stop2.color[0] << " " << stop2.color[1] << " " << stop2.color[2] << " ]\n" << "\t\t/N 1\n"; + } + else if( ramp.size() > 2 || ramp.size() == 2 && ramp[0]->midPoint != 0.5 ) + { + // Gradient with more than two colors or asymmetrical midpoint. + *m_stream << "\t\t/FunctionType 3\n" << "\t\t/Functions [ "; + for( uint i = 1; i < ( 2 * ramp.size() - 1 );i++ ) + *m_stream << "Function" << i << " "; + *m_stream << "]\n" << "\t\t/Bounds ["; + for( uint i = 0;i < ramp.size() - 1;i++ ) + { + VColorStop stop = *ramp[i]; + if( i > 0 ) + *m_stream << " " << stop.rampPoint; + *m_stream << " " << ( stop.rampPoint + ( ramp[i + 1]->rampPoint - stop.rampPoint ) * stop.midPoint ); + } + *m_stream << " ]\n" << "\t\t/Encode [ "; + for( uint i = 0;i < 2 * ramp.size() - 2;i++ ) + *m_stream << "0 1 "; + *m_stream << "]\n"; + } + *m_stream << "\t\t/Domain [ " << ramp[0]->rampPoint << " " + << ramp[ramp.size() - 1]->rampPoint << " ]\n" << "\t>>\n" << ">>\n"; + // "shfill", "grestore". + *m_stream << " shfill " << l1_grestore << "\n"; + } + } +} + +void +EpsExport::getColor( const VColor& color ) +{ + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + *m_stream << + copy[0] << " " << + copy[1] << " " << + copy[2] << " " << l1_setrgbcolor; +} + +bool +EpsExport::isVisible( const VObject* object ) const +{ + return object->state() != VObject::hidden && object->state() != VObject::hidden_locked; +} + +#include "epsexport.moc" diff --git a/filters/karbon/eps/epsexport.h b/filters/karbon/eps/epsexport.h new file mode 100644 index 000000000..b2dd49191 --- /dev/null +++ b/filters/karbon/eps/epsexport.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __EPSEXPORT_H__ +#define __EPSEXPORT_H__ + + +#include + +#include "vvisitor.h" + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VLayer; +class VSubpath; +class VStroke; +class VText; + + +class EpsExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + EpsExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~EpsExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVText( VText& text ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVLayer( VLayer& layer ); + + void getStroke( const VStroke& stroke ); + void getFill( const VFill& fill ); + void getColor( const VColor& color ); + + bool isVisible( const VObject* object ) const; + + QTextStream* m_stream; + + uint m_psLevel; + bool m_exportHidden; +}; + +#endif + diff --git a/filters/karbon/eps/epsexportdlg.cc b/filters/karbon/eps/epsexportdlg.cc new file mode 100644 index 000000000..2fb34e14b --- /dev/null +++ b/filters/karbon/eps/epsexportdlg.cc @@ -0,0 +1,65 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include + +#include "epsexportdlg.h" + + +EpsExportDlg::EpsExportDlg( QWidget* parent, const char* name ) + : KDialogBase( parent, name, true, i18n( "EPS Export" ), Ok | Cancel ) +{ + QVBox* page = makeVBoxMainWidget(); + + m_psLevelButtons = new QButtonGroup( 1, QGroupBox::Horizontal, + i18n( "Options" ), page ); + + QRadioButton* radio; + radio = new QRadioButton( i18n( "PostScript level 1" ), m_psLevelButtons ); + radio = new QRadioButton( i18n( "PostScript level 2" ), m_psLevelButtons ); + radio = new QRadioButton( i18n( "PostScript level 3" ), m_psLevelButtons ); + + m_hiddenExport = new QCheckBox( i18n( "Export hidden layers" ), page ); + m_hiddenExport->setChecked( true ); + + m_psLevelButtons->setRadioButtonExclusive( true ); + m_psLevelButtons->setButton( 2 ); +} + +uint +EpsExportDlg::psLevel() const +{ + return static_cast( + m_psLevelButtons->id( m_psLevelButtons->selected() ) ); +} + +bool +EpsExportDlg::exportHidden() const +{ + return m_hiddenExport->isChecked(); +} +#include "epsexportdlg.moc" + diff --git a/filters/karbon/eps/epsexportdlg.h b/filters/karbon/eps/epsexportdlg.h new file mode 100644 index 000000000..332ca882d --- /dev/null +++ b/filters/karbon/eps/epsexportdlg.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __VEPSEXPORTDLG_H__ +#define __VEPSEXPORTDLG_H__ + +#include + + +class QButtonGroup; +class QCheckBox; + +class EpsExportDlg : public KDialogBase +{ + Q_OBJECT + +public: + EpsExportDlg( QWidget* parent = 0L, const char* name = 0L ); + + uint psLevel() const; + bool exportHidden() const; +private: + QButtonGroup* m_psLevelButtons; + QCheckBox* m_hiddenExport; +}; + +#endif + diff --git a/filters/karbon/eps/epsimport.cc b/filters/karbon/eps/epsimport.cc new file mode 100644 index 000000000..2ff34a940 --- /dev/null +++ b/filters/karbon/eps/epsimport.cc @@ -0,0 +1,117 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "epsimport.h" +#include "pscommentlexer.h" + +class EpsImportFactory : KGenericFactory +{ +public: + EpsImportFactory( void ) + : KGenericFactory( "karbonepsimport" ) + {} + +protected: + virtual void setupTranslations( void ) + { + KGlobal::locale()->insertCatalogue( "kofficefilters" ); + } +}; + +K_EXPORT_COMPONENT_FACTORY( libkarbonepsimport, EpsImportFactory() ) + +EpsImport::EpsImport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +EpsImport::~EpsImport() +{ +} + +KoFilter::ConversionStatus +EpsImport::convert( const QCString& from, const QCString& to ) +{ + if( + to != "application/illustrator" || + ( + from != "image/x-eps" && + from != "application/postscript" ) ) + { + return KoFilter::NotImplemented; + } + + // Copy input filename: + QString input = m_chain->inputFile(); + + + // EPS original bounding box + int llx = -1, lly = -1, urx = -1, ury = -1; + BoundingBoxExtractor extractor; + + QFile file (input); + + if ( file.open(IO_ReadOnly) ) + { + extractor.parse (file); + llx = extractor.llx(); + lly = extractor.lly(); + urx = extractor.urx(); + ury = extractor.ury(); + file.close(); + } + else + qDebug ("file could not be opened"); + + // sed filter + QString sedFilter = QString ("sed -e \"s/%%BoundingBox: 0 0 612 792/%%BoundingBox: %1 %2 %3 %4/g\""). + arg(llx).arg(lly).arg(urx).arg(ury); + + // Build ghostscript call to convert ps/eps -> ai: + QString command( + "gs -q -P- -dBATCH -dNOPAUSE -dSAFER -dPARANOIDSAFER -dNODISPLAY ps2ai.ps "); + command += KProcess::quote(input); + command += " | "; + command += sedFilter; + command += " > "; + command += KProcess::quote(m_chain->outputFile()); + + qDebug ("command to execute is (%s)", QFile::encodeName(command).data()); + + // Execute it: + if( !system( QFile::encodeName(command)) ) + return KoFilter::OK; + else + return KoFilter::StupidError; +} + +#include "epsimport.moc" + diff --git a/filters/karbon/eps/epsimport.h b/filters/karbon/eps/epsimport.h new file mode 100644 index 000000000..156732973 --- /dev/null +++ b/filters/karbon/eps/epsimport.h @@ -0,0 +1,42 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __EPSIMPORT_H__ +#define __EPSIMPORT_H__ + +#include + +#include + +class QDomElement; +class QTextStream; + +class EpsImport : public KoFilter +{ + Q_OBJECT + +public: + EpsImport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~EpsImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif + diff --git a/filters/karbon/eps/karbon_eps_export.desktop b/filters/karbon/eps/karbon_eps_export.desktop new file mode 100644 index 000000000..4ee7d6f3e --- /dev/null +++ b/filters/karbon/eps/karbon_eps_export.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Export Filter +Name[af]=Karbon14 Eps Voer uit Filter +Name[ar]=مِرْشَح تصدير EPS لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в EPS +Name[br]=Sil ezporzh EPS evit Karbon14 +Name[ca]=Filtre d'exportació EPS per a Karbon14 +Name[cs]=Exportní filtr do formátu EPS pro Karbon14 +Name[cy]=Hidlen Allforio EPS Karbon14 +Name[da]=Karbon14 EPS-eksportfilter +Name[de]=Karbon14 EPS-Exportfilter +Name[el]=Φίλτρο εξαγωγής EPS του Karbon14 +Name[eo]=Karbon-EPS-eksportfiltrilo +Name[es]=Filtro de exportación EPS de Karbon14 +Name[et]=Karbon14 EPS-i ekspordifilter +Name[eu]=Karbon14-en EPS esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Karbon14 EPS +Name[fi]=Karbon14 EPS -vientisuodin +Name[fr]=Filtre d'exportation EPS de Karbon 14 +Name[fy]=EPS-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála EPS Karbon14 +Name[gl]=Filtro de Exportación de EPS para Karbon14 +Name[he]=מסנן ייצוא מ־Karbon14 ל־EPS +Name[hr]=Karbon14 EPS filtar izvoza +Name[hu]=Karbon14 EPS exportszűrő +Name[is]=Karbon14 EPS útflutningssía +Name[it]=Filtro di esportazione EPS per Karbon14 +Name[ja]=Karbon14 EPS エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ EPS សម្រាប់ Karbon14 +Name[lo]= ຕົວຕອງການສົ່ງອອກ EPS ຂອງຄາຮ໌ບອນ14 +Name[lt]=Karbon14 EPS eksportavimo filtras +Name[lv]=Karbon14 EPS eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 EPS +Name[mt]=Filtru għall-esportazzjoni ta' EPS minn ġo Karbon14 +Name[nb]=EPS-eksportfiler for Karbon14 +Name[nds]=EPS-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ इपिएस निर्यात फिल्टर +Name[nl]=EPS-exportfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu EPS z Karbon14 +Name[pt]=Filtro de Exportação de EPS para o Karbon14 +Name[pt_BR]=Filtro de Exportação EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=Фильтр экспорта рисунков Karbon14 в EPS +Name[se]=Karbon14:a EPS-olggosfievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Izvozni filter EPS za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у EPS +Name[sr@Latn]=Karbon14-ov filter za izvoz u EPS +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon EPS வடிகட்டி ஏற்றுமதி +Name[tg]=Karbon14 EPS Филтри Содирот +Name[th]=ตัวกรองการส่งออก EPS ของคาร์บอน14 +Name[tr]=Karbon14 EPS Aktarma Filtresi +Name[uk]=Фільтр експорту EPS для Karbon14 +Name[uz]=Karbon14 EPS eksport filteri +Name[uz@cyrillic]=Karbon14 EPS экспорт филтери +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 导出过滤器 +Name[zh_TW]=Karbon14 EPS 匯出過濾程式 +X-KDE-Export=image/x-eps +X-KDE-Import=application/x-karbon +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsexport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/karbon_eps_import.desktop b/filters/karbon/eps/karbon_eps_import.desktop new file mode 100644 index 000000000..83cae5293 --- /dev/null +++ b/filters/karbon/eps/karbon_eps_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Import Filter +Name[af]=Karbon14 Eps In voer Filter +Name[ar]=مِرْشَح استيراد EPS لدى Karbon14 +Name[bg]=Филтър за импортиране от EPS в Karbon14 +Name[br]=Sil enporzh EPS evit Karbon14 +Name[ca]=Filtre d'importació EPS per a Karbon14 +Name[cs]=Exportní filtr do formátu EPS pro Karbon14 +Name[cy]=Hidlen Fewnforio EPS Karbon14 +Name[da]=Karbon14 EPS-importfilter +Name[de]=Karbon14 EPS-Importfilter +Name[el]=Φίλτρο εισαγωγής EPS του Karbon14 +Name[eo]=Karbon-EPS-importfiltrilo +Name[es]=Filtro de importación de Karbon14 EPS +Name[et]=Karbon14 EPS-i impordifilter +Name[eu]=Karbon14-en EPS inportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon14 EPS +Name[fi]=Karbon14 EPS -tuontisuodin +Name[fr]=Filtre d'importation EPS de Karbon 14 +Name[fy]=EPS-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iompórtála EPS Karbon14 +Name[gl]=Filtro de Importación de EPS para Karbon14 +Name[he]=מסנן ייבוא מ־EPS ל־Karbon14 +Name[hr]=Karbon14 EPS filtar uvoza +Name[hu]=Karbon14 EPS importszűrő +Name[is]=Karbon14 EPS innflutningssía +Name[it]=Filtro di importazione EPS per Karbon14 +Name[ja]=Karbon14 EPS インポートフィルタ +Name[km]=តម្រង​នាំចូល EPS សម្រាប់ Karbon14 +Name[lo]=ຕົວຕອງການນຳເຂົ້າ EPS ຂອງຄາຮ໌ບອນ14 +Name[lt]=Karbon14 EPS importavimo filtras +Name[lv]=Karbon14 EPS importa filtrs +Name[ms]=Penapis Import Karbon14 EPS +Name[mt]=Filtru għall-importazzjoni ta' EPS għal Karbon14 +Name[nb]=EPS-importfilter for Karbon14 +Name[nds]=EPS-Importfilter för Karbon14 +Name[ne]=कार्बन१४ इपिएस आयात फिल्टर +Name[nl]=EPS-importfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr importu formatu EPS do Karbon14 +Name[pt]=Filtro de Importação de EPS para o Karbon14 +Name[pt_BR]=Filtro de Importação EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=Фильтр импорта EPS в Karbon14 +Name[se]=Karbon14:a EPS-sisafievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Uvozni filter EPS za Karbon14 +Name[sr]=Karbon14-ов филтер за увоз из EPS-а +Name[sr@Latn]=Karbon14-ov filter za uvoz iz EPS-a +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon 14 EPS இறக்குமதி வடிகட்டி +Name[tg]=Karbon14 EPS Филтри Воридот +Name[th]=ตัวกรองการนำเข้า EPS ของคาร์บอน14 +Name[tr]=Karbon14 EPS Alma Filtresi +Name[uk]=Фільтр експорту EPS для Karbon14 +Name[uz]=Karbon14 EPS import filteri +Name[uz@cyrillic]=Karbon14 EPS импорт филтери +Name[xh]=Isihluzi Sokurhweba se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 导入过滤器 +Name[zh_TW]=Karbon14 EPS 匯出過濾程式 +X-KDE-Export=application/illustrator +X-KDE-Import=image/x-eps +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/karbon_ps_import.desktop b/filters/karbon/eps/karbon_ps_import.desktop new file mode 100644 index 000000000..1599fcca6 --- /dev/null +++ b/filters/karbon/eps/karbon_ps_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon14 EPS Import Filter +Name[af]=Karbon14 Eps In voer Filter +Name[ar]=مِرْشَح استيراد EPS لدى Karbon14 +Name[bg]=Филтър за импортиране от EPS в Karbon14 +Name[br]=Sil enporzh EPS evit Karbon14 +Name[ca]=Filtre d'importació EPS per a Karbon14 +Name[cs]=Exportní filtr do formátu EPS pro Karbon14 +Name[cy]=Hidlen Fewnforio EPS Karbon14 +Name[da]=Karbon14 EPS-importfilter +Name[de]=Karbon14 EPS-Importfilter +Name[el]=Φίλτρο εισαγωγής EPS του Karbon14 +Name[eo]=Karbon-EPS-importfiltrilo +Name[es]=Filtro de importación de Karbon14 EPS +Name[et]=Karbon14 EPS-i impordifilter +Name[eu]=Karbon14-en EPS inportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon14 EPS +Name[fi]=Karbon14 EPS -tuontisuodin +Name[fr]=Filtre d'importation EPS de Karbon 14 +Name[fy]=EPS-Ymportfilter foar Karbon14 +Name[ga]=Scagaire Iompórtála EPS Karbon14 +Name[gl]=Filtro de Importación de EPS para Karbon14 +Name[he]=מסנן ייבוא מ־EPS ל־Karbon14 +Name[hr]=Karbon14 EPS filtar uvoza +Name[hu]=Karbon14 EPS importszűrő +Name[is]=Karbon14 EPS innflutningssía +Name[it]=Filtro di importazione EPS per Karbon14 +Name[ja]=Karbon14 EPS インポートフィルタ +Name[km]=តម្រង​នាំចូល EPS សម្រាប់ Karbon14 +Name[lo]=ຕົວຕອງການນຳເຂົ້າ EPS ຂອງຄາຮ໌ບອນ14 +Name[lt]=Karbon14 EPS importavimo filtras +Name[lv]=Karbon14 EPS importa filtrs +Name[ms]=Penapis Import Karbon14 EPS +Name[mt]=Filtru għall-importazzjoni ta' EPS għal Karbon14 +Name[nb]=EPS-importfilter for Karbon14 +Name[nds]=EPS-Importfilter för Karbon14 +Name[ne]=कार्बन१४ इपिएस आयात फिल्टर +Name[nl]=EPS-importfilter voor Karbon14 +Name[nn]=EPS-eksportfilter for Karbon14 +Name[pl]=Filtr importu formatu EPS do Karbon14 +Name[pt]=Filtro de Importação de EPS para o Karbon14 +Name[pt_BR]=Filtro de Importação EPS do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru EPS +Name[ru]=Фильтр импорта EPS в Karbon14 +Name[se]=Karbon14:a EPS-sisafievrridansilli +Name[sk]=EPS filter pre export z Karbon14 +Name[sl]=Uvozni filter EPS za Karbon14 +Name[sr]=Karbon14-ов филтер за увоз из EPS-а +Name[sr@Latn]=Karbon14-ov filter za uvoz iz EPS-a +Name[sv]=Karbon14 EPS-exportfilter +Name[ta]=Karbon 14 EPS இறக்குமதி வடிகட்டி +Name[tg]=Karbon14 EPS Филтри Воридот +Name[th]=ตัวกรองการนำเข้า EPS ของคาร์บอน14 +Name[tr]=Karbon14 EPS Alma Filtresi +Name[uk]=Фільтр експорту EPS для Karbon14 +Name[uz]=Karbon14 EPS import filteri +Name[uz@cyrillic]=Karbon14 EPS импорт филтери +Name[xh]=Isihluzi Sokurhweba se Karbon14 EPS +Name[zh_CN]=Karbon14 EPS 导入过滤器 +Name[zh_TW]=Karbon14 EPS 匯出過濾程式 +X-KDE-Export=application/illustrator +X-KDE-Import=application/postscript +X-KDE-Weight=1 +X-KDE-Library=libkarbonepsimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/eps/pscommentlexer.cc b/filters/karbon/eps/pscommentlexer.cc new file mode 100644 index 000000000..46d993dce --- /dev/null +++ b/filters/karbon/eps/pscommentlexer.cc @@ -0,0 +1,324 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include "pscommentlexer.h" + +#define CATEGORY_WHITESPACE -1 +#define CATEGORY_ALPHA -2 +#define CATEGORY_DIGIT -3 +#define CATEGORY_SPECIAL -4 +#define CATEGORY_LETTERHEX -5 +#define CATEGORY_INTTOOLONG -6 + +#define CATEGORY_ANY -127 + +#define MAX_INTLEN 9 +#define MIN_HEXCHARS 6 + +#define STOP 0 + +int iswhitespace(char c){ + return (c==' ')||(c=='\n')||(c=='\t')||(c=='\r'); +} + +int isSpecial(char c){ + return (c=='*')||(c=='_')||(c=='?')||(c=='~')||(c=='-')||(c=='^')||(c=='`')||(c=='!')||(c=='.')||(c=='@')||(c=='&')||(c=='$')||(c=='='); +} + +int isletterhex(char c){ + return (c=='A')||(c=='B')||(c=='C')||(c=='D')||(c=='E')||(c=='F'); +} + +const char*statetoa (State state){ + switch (state) + { + case State_Comment : return "comment"; + case State_CommentEncodedChar : return "encoded char (comment)"; + default : return "unknown"; + } +} + +typedef struct { + State oldState; + char c; + State newState; + Action action; +} Transition; + +static Transition transitions[] = { + { State_Comment, '\n', State_Start, Action_Output}, + { State_Comment, '\r', State_Start, Action_Output}, + { State_Comment, '\\', State_CommentEncodedChar, Action_InitTemp}, + { State_Comment, CATEGORY_ANY, State_Comment, Action_Copy}, + { State_CommentEncodedChar, '\\', State_Comment, Action_Copy}, + { State_CommentEncodedChar, CATEGORY_DIGIT, State_CommentEncodedChar, Action_CopyTemp}, + { State_CommentEncodedChar, CATEGORY_ANY, State_Comment, Action_DecodeUnget}, + { State_Start, '%', State_Comment, Action_Ignore}, + { State_Start, CATEGORY_ANY, State_Start, Action_Ignore}, + { State_Start, STOP, State_Start, Action_Abort} +}; + +PSCommentLexer::PSCommentLexer(){ +} +PSCommentLexer::~PSCommentLexer(){ +} + +bool PSCommentLexer::parse (QIODevice& fin){ + char c; + + m_buffer.clear(); + m_curState = State_Start; + + parsingStarted(); + + while (!fin.atEnd()) + { + c = fin.getch (); + +// qDebug ("got %c", c); + + State newState; + Action action; + + nextStep (c, &newState, &action); + + switch (action) + { + case Action_Copy : + m_buffer.append (c); + break; + case Action_CopyOutput : + m_buffer.append (c); + doOutput(); + break; + case Action_Output : + doOutput(); + break; + case Action_OutputUnget : + doOutput(); + fin.ungetch(c); + break; + case Action_Ignore : + /* ignore */ + break; + case Action_Abort : + qWarning ( "state %s / %s char %c (%d)" , statetoa(m_curState), statetoa(newState), c, c ); + parsingAborted(); + return false; + break; + case Action_InitTemp : + m_temp.clear(); + break; + case Action_CopyTemp : + m_temp.append (c); + break; + case Action_DecodeUnget : + m_buffer.append (decode()); + fin.ungetch(c); + break; + default : + qWarning ( "unknown action: %d ", action); + } + + m_curState = newState; + } + + parsingFinished(); + return true; +} + +void PSCommentLexer::doOutput () +{ + if (m_buffer.length() == 0) return; + switch (m_curState) + { + case State_Comment : + gotComment (m_buffer.latin1()); + break; + default: + qWarning ( "unknown state: %d", m_curState ); + } + + m_buffer.clear(); +} + +void PSCommentLexer::gotComment (const char *value) { + qDebug ( "gotComment: %s ", value ); +} + +void PSCommentLexer::parsingStarted() { + qDebug ( "parsing started" ); +} + +void PSCommentLexer::parsingFinished() { + qDebug ( "parsing finished" ); +} + +void PSCommentLexer::parsingAborted() { + qDebug ( "parsing aborted" ); +} + +void PSCommentLexer::nextStep (char c, State *newState, Action *newAction) { + int i=0; + + while (true) { + Transition trans = transitions[i]; + + if (trans.c == STOP) { + *newState = trans.newState; + *newAction = trans.action; + return; + } + + bool found = false; + + if (trans.oldState == m_curState) { + switch (trans.c) { + case CATEGORY_WHITESPACE : found = isspace(c); break; + case CATEGORY_ALPHA : found = isalpha(c); break; + case CATEGORY_DIGIT : found = isdigit(c); break; + case CATEGORY_SPECIAL : found = isSpecial(c); break; + case CATEGORY_LETTERHEX : found = isletterhex(c); break; + case CATEGORY_INTTOOLONG : found = m_buffer.length() > MAX_INTLEN; break; + case CATEGORY_ANY : found = true; break; + default : found = (trans.c == c); + } + + if (found) { + *newState = trans.newState; + *newAction = trans.action; + + return; + } + } + + + i++; + } +} + +uchar PSCommentLexer::decode() +{ + uchar value = m_temp.toString().toShort(NULL, 8); +// qDebug ("got encoded char %c",value); + return value; +} + +/* StringBuffer implementation */ + +int initialSize = 20; +int addSize = 10; + +StringBuffer::StringBuffer () { + m_buffer = (char*)calloc (initialSize, sizeof(char)); + m_length = 0; + m_capacity = initialSize; +} + +StringBuffer::~StringBuffer (){ + free(m_buffer); +} + +void StringBuffer::append (char c){ + ensureCapacity(m_length + 1); + m_buffer[m_length] = c; + m_length++; +} + +void StringBuffer::clear(){ + for (uint i=0; i= p_capacity) return; + + int newSize = m_capacity + addSize; + if (p_capacity > newSize) newSize = p_capacity; + + char* oldBuffer = m_buffer; + char *newBuffer = (char*)calloc (newSize, sizeof(char)); + strcpy (newBuffer, m_buffer); + free(oldBuffer); + m_buffer = newBuffer; + m_capacity = newSize; +} + +uint StringBuffer::length() { + return m_length; +} + +double StringBuffer::toFloat() { + QString data = toString(); + return data.toFloat(); +} + +int StringBuffer::toInt() { + QString data = toString(); + return data.toInt(); +} + +const char *StringBuffer::latin1() { + return m_buffer; +} + +QString StringBuffer::mid( uint index, uint len) const { + QString data = toString(); + return data.mid(index,len); +} + +/* BoundingBoxExtractor */ +BoundingBoxExtractor:: BoundingBoxExtractor() : m_llx(0), m_lly(0), m_urx(0), m_ury(0) {} +BoundingBoxExtractor::~BoundingBoxExtractor() {} + +void BoundingBoxExtractor::gotComment (const char *value) +{ + QString data (value); + if (data.find("%BoundingBox:")==-1) return; + + getRectangle (value, m_llx, m_lly, m_urx, m_ury); +} + +bool BoundingBoxExtractor::getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury) +{ + if (input == NULL) return false; + + QString s(input); + if (s.contains ("(atend)")) return false; + + QString s2 = s.remove("%BoundingBox:"); + QStringList values = QStringList::split (" ", s2.latin1()); + qDebug("size is %d",values.size()); +// if (values.size() < 5) return false; + llx = values[0].toInt(); + lly = values[1].toInt(); + urx = values[2].toInt(); + ury = values[3].toInt(); + + return true; +} + diff --git a/filters/karbon/eps/pscommentlexer.h b/filters/karbon/eps/pscommentlexer.h new file mode 100644 index 000000000..bf155211e --- /dev/null +++ b/filters/karbon/eps/pscommentlexer.h @@ -0,0 +1,112 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Dirk Schnberger + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef PSCOMMENTLEXER_H +#define PSCOMMENTLEXER_H + +#include +#include + +/** + *@author Dirk Schnberger + */ +typedef enum { + State_Comment=0, + State_CommentEncodedChar, + State_Start +} State; + +typedef enum { + Action_Copy=1, + Action_CopyOutput, + Action_Output, + Action_Ignore, + Action_Abort, + Action_OutputUnget, + Action_InitTemp, + Action_CopyTemp, + Action_DecodeUnget, + Action_ByteArraySpecial +} Action; + +class StringBuffer { +public: + StringBuffer (); + virtual ~StringBuffer (); + + void append (char c); + void clear(); + QString toString() const; + uint length(); + double toFloat(); + int toInt(); + const char *latin1(); + QString mid( uint index, uint len=0xffffffff) const; +private: + char *m_buffer; + uint m_length; + int m_capacity; + + void ensureCapacity (int p_capacity); +}; + +class PSCommentLexer { +public: + PSCommentLexer(); + virtual ~PSCommentLexer(); + + virtual bool parse (QIODevice& fin); +private: + State m_curState; + StringBuffer m_buffer; + StringBuffer m_temp; + + void nextStep (char c, State* newState, Action* newAction); + + void doOutput (); + uchar decode(); + +protected: + virtual void parsingStarted(); + virtual void parsingFinished(); + virtual void parsingAborted(); + + virtual void gotComment (const char *value); +}; + +class BoundingBoxExtractor : public PSCommentLexer +{ +public: + BoundingBoxExtractor(); + virtual ~BoundingBoxExtractor(); + + int llx() { return m_llx; } + int lly() { return m_lly; } + int urx() { return m_urx; } + int ury() { return m_ury; } +private: + int m_llx, m_lly, m_urx, m_ury; + bool getRectangle (const char* input, int &llx, int &lly, int &urx, int &ury); + +protected: + void gotComment (const char *value); +}; + +#endif + diff --git a/filters/karbon/kontour/Makefile.am b/filters/karbon/kontour/Makefile.am new file mode 100644 index 000000000..52d6220ac --- /dev/null +++ b/filters/karbon/kontour/Makefile.am @@ -0,0 +1,27 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) -I$(top_srcdir)/karbon -I$(top_srcdir)/karbon/core $(all_includes) + +####### Files +# Obviously you have to change "foo" (and maybe "import") to +# reflect the name of your filter. If you have more files +# than just fooimport.cc please add them to the _SOURCES line. + +kde_module_LTLIBRARIES = libkarbonkontourimport.la + +libkarbonkontourimport_la_SOURCES = kontourimport.cpp +libkarbonkontourimport_la_LDFLAGS = -module $(KDE_PLUGIN) +libkarbonkontourimport_la_LIBADD = $(KOFFICE_LIBS) ../../../karbon/libkarboncommon.la + +METASOURCES = AUTO + +service_DATA = karbon_kontour_import.desktop +servicedir = $(kde_servicesdir) + +# Note: If your filter imports or exports some special file +# which KDE doesn't have a mimetype for, yet, you'll have to +# create a mimetype and install it using those two lines. +# In case of doubt please ask koffice@kde.org or +# koffice-devel@kde.org. Thanks. +# mydata_DATA = x-foo.desktop +# mydatadir = $(kde_mimedir)/text diff --git a/filters/karbon/kontour/karbon_kontour_import.desktop b/filters/karbon/kontour/karbon_kontour_import.desktop new file mode 100644 index 000000000..e18b68b85 --- /dev/null +++ b/filters/karbon/kontour/karbon_kontour_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon Kontour Import Filter +Name[af]=Karbon Kontoer In voer Filter +Name[ar]=مِرْشَح استيراد Kontour لدى Karbon +Name[bg]=Филтър за импортиране от Kontour в Karbon +Name[br]=Sil enporzh Kontour evit Karbon +Name[ca]=Filtre d'importació Kontour per a Karbon +Name[cs]=Importní filtr Kontour pro Karbon14 +Name[cy]=Hidlen Fewnforio Kontour Karbon +Name[da]=Karbon Kontour-importfilter +Name[de]=Karbon14 Kontour-Importfilter +Name[el]=Φίλτρο εισαγωγής Kontour του Karbon +Name[eo]=Karbon-Kontour-importfiltrilo +Name[es]=Filtro de importación a Kontour de Karbon +Name[et]=Karboni Kontouri impordifilter +Name[eu]=Karbon-en Konoutr inportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon Kontour +Name[fi]=Karbon Kontour -tuontisuodin +Name[fr]=Filtre d'importation Kontour de Karbon 14 +Name[fy]=Kontour-Ymportfilter foar Karbon +Name[ga]=Scagaire Iompórtála Karbon Kontour +Name[gl]=Filtro de Importación de Kontour para Karbon +Name[he]=מסנן ייבוא מ־Kontour ל־Karbon +Name[hr]=Karbon Kontour filtar uvoza +Name[hu]=Karbon Kontour importszűrő +Name[is]=Karbon Kontour innflutningssía +Name[it]=Filtro di importazione Kontour per Karbon +Name[ja]=Karbon Kontour インポートフィルタ +Name[km]=តម្រង​នាំចូល Kontour សម្រាប់ Karbon +Name[lo]=ຕົວຕອງການນຳເຂົ້າຮູບແຕ້ມ K ຂອງຄາຮ໌ບອນ14 +Name[lt]=Karbon Kontour importavimo filtras +Name[lv]=Karbon Kontour importa filtrs +Name[ms]=Penapis Import Karbon Kontour +Name[mt]=Filtru għall-importazzjoni ta' Kontour ġo Karbon14 +Name[nb]=Kontour-importfilter for Karbon +Name[nds]=Kontour-Importfilter för Karbon +Name[ne]=कार्बन रूपरेखा आयात फिल्टर +Name[nl]= Kontour-importfilter voor Karbon +Name[nn]=Kontour-importfilter for Karbon +Name[pl]=Filtr importu formatu Kontour do Karbon +Name[pt]=Filtro de Importação de Kontour para o Karbon +Name[pt_BR]=Filtro de Importação Kontour do Karbon +Name[ro]=Filtru importare Karbon14 pentru Kontour +Name[ru]=Фильтр импорта рисунков Kontour в Karbon +Name[se]=Karbon:a Kontour sisafievrridansilli +Name[sk]=Karbon filter pre import pre Kontour +Name[sl]=Uvozni filter Kontour za Karbon +Name[sr]=Karbon-ов филтер за увоз из Kontour-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz Kontour-a +Name[sv]=Karbon Kontour-importfilter +Name[ta]= karbon Kontour இறக்குமதி வடிகட்டி +Name[tg]=Филтри Воридоти Karbon Kontour +Name[th]=ตัวกรองการนำเข้าภาพวาด K ของคาร์บอน14 +Name[tr]=Karbon Kontour Alma Filtresi +Name[uk]=Фільтр імпорту файлів Kontour для Karbon +Name[uz]=Karbon Kontour import filteri +Name[uz@cyrillic]=Karbon Kontour импорт филтери +Name[xh]=Isihluzi Sokurhweba se Karbon Kontour +Name[zh_CN]=Karbon Kontour 导入过滤器 +Name[zh_TW]=Kontour Kontour 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/x-kontour +X-KDE-Weight=1 +X-KDE-Library=libkarbonkontourimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/kontour/kontourimport.cpp b/filters/karbon/kontour/kontourimport.cpp new file mode 100644 index 000000000..88d2fc4b0 --- /dev/null +++ b/filters/karbon/kontour/kontourimport.cpp @@ -0,0 +1,323 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Sven Lppken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DPI 90 + +typedef KGenericFactory KontourImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonkontourimport, KontourImportFactory( "kofficefilters" ) ) + +KontourImport::KontourImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ +} + +KontourImport::~KontourImport() +{ + +} + +KoFilter::ConversionStatus KontourImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if ( to != "application/x-karbon" || ( from != "application/x-kontour" && from != "application/x-killustrator") ) + return KoFilter::NotImplemented; + + + KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read ); + if ( !inpdev ) + { + kdError(30502) << "Unable to open input stream" << endl; + return KoFilter::StorageCreationError; + } + + inpdoc.setContent( inpdev ); + + // Do the conversion! + convert(); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if(!out) + { + kdError(30502) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void +KontourImport::parseGObject( VObject *object, const QDomElement &e ) +{ + if( !e.attribute( "fillstyle" ).isEmpty() ) + { + VFill fill; + int fillstyle = e.attribute( "fillstyle" ).toInt(); + switch( fillstyle ) + { + case 1: + { + fill.setType( VFill::solid ); + QColor c; + c.setNamedColor( e.attribute( "fillcolor" ) ); + VColor color( c ); + fill.setColor( color ); + } + break; + case 4: + { + VGradient grad; + // set color stops + grad.clearStops(); + QColor c; + c.setNamedColor( e.attribute( "gradcolor1" ) ); + VColor color( c ); + grad.addStop( color, 0.0, 0.5 ); + c.setNamedColor( e.attribute( "gradcolor2" ) ); + VColor color2( c ); + grad.addStop( color2, 1.0, 0.5 ); + // set coords + KoRect bbox = object->boundingBox(); + grad.setOrigin( KoPoint( bbox.left(), bbox.y() ) ); + grad.setVector( KoPoint( bbox.right(), bbox.y() ) ); + grad.setType( (VGradient::VGradientType)e.attribute( "gradstyle" ).toInt() ); + fill.setType( VFill::grad ); + fill.gradient() = grad; + } + break; + } + object->setFill( fill ); + } + if( !e.attribute( "strokecolor" ).isEmpty() ) + { + VStroke stroke; + int strokestyle = e.attribute( "strokestyle" ).toInt(); + switch( strokestyle ) + { + case 0: stroke.setType( VStroke::none ); + break; + case 1: + { + QColor c; + c.setNamedColor( e.attribute( "strokecolor" ) ); + VColor color( c ); + stroke.setColor( color ); + } + break; + case 2: case 3: case 4: case 5: + { + QColor c; + c.setNamedColor( e.attribute( "strokecolor" ) ); + VColor color( c ); + stroke.setColor( color ); + VDashPattern dash; + QValueList list; + switch ( strokestyle ) + { + case 2: // dashed line + list << 10 << 5; + break; + case 3: // dotted line + list << 1 << 5; + break; + case 4: // dash-dot + list << 10 << 5 << 1 << 5; + break; + case 5: // dash-dot-dot + list << 10 << 5 << 1 << 5 << 1 << 5; + break; + } + + dash.setArray( list ); + stroke.dashPattern() = dash; + } + break; + } + float lineWidth = e.attribute( "linewidth" ).toFloat(); + stroke.setLineWidth( lineWidth ); + object->setStroke( stroke ); + } + // handle matrix + QDomElement matrix = e.namedItem( "matrix" ).toElement(); + QWMatrix mat( matrix.attribute( "m11" ).toDouble(), + matrix.attribute( "m12" ).toDouble(), + matrix.attribute( "m21" ).toDouble(), + matrix.attribute( "m22" ).toDouble(), + matrix.attribute( "dx" ).toDouble(), + matrix.attribute( "dy" ).toDouble() ); + + // undo y-mirroring + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( *object ); + +} + +void +KontourImport::convert() +{ + QDomElement docElem = inpdoc.documentElement(); + QDomElement lay; + double height; + double width; + if( docElem.attribute( "version" ).toInt() == 2 ) + { + lay = docElem; + height = lay.firstChild().namedItem( "layout" ).toElement().attribute( "height" ).toDouble(); + width = lay.firstChild().namedItem( "layout" ).toElement().attribute( "width" ).toDouble(); + } + else + { + lay = docElem.namedItem( "page" ).toElement(); + height = lay.firstChild().toElement().attribute( "height" ).toDouble(); + width = lay.firstChild().toElement().attribute( "width" ).toDouble(); + } + + m_document.setHeight( ( ( height / 72.0 ) * DPI ) ); + m_document.setWidth( ( ( width / 72.0 ) * DPI ) ); + + parseGroup( lay.firstChild().toElement() ); + + outdoc = m_document.saveXML(); +} + +void +KontourImport::parseGroup( const QDomElement &e ) +{ + QDomElement b = e; + for( ; !b.isNull(); b = b.nextSibling().toElement() ) + { + if ( b.tagName() == "rectangle" ) + { + int x = b.attribute( "x" ).toInt(); + int y = b.attribute( "y" ).toInt(); + int width = b.attribute( "width" ).toInt(); + int height = b.attribute( "height" ).toInt(); + VObject *rect = new VRectangle( 0L, KoPoint( x, height + y ) , width, height ); + QDomElement object = b.namedItem( "polyline" ).namedItem( "gobject" ).toElement(); + parseGObject( rect, object ); + m_document.append( rect ); + } + else + if ( b.tagName() == "ellipse" ) + { + QDomElement object = b.namedItem( "gobject" ).toElement(); + QDomElement matrix = object.namedItem( "matrix" ).toElement(); + /** + * Kontour uses a quite different way to display ellipses, so we + * need to calculate the values for the Karbon ellipse here + */ + double left = ( b.attribute( "x" ).toDouble() + matrix.attribute( "dx" ).toInt() ) - ( b.attribute( "rx" ).toDouble() / 2 ); + double right = left + b.attribute( "rx" ).toDouble(); + double top = ( b.attribute( "y" ).toDouble() + matrix.attribute( "dy" ).toInt() ) - ( b.attribute( "ry" ).toDouble() / 2 ); + double bottom = top + b.attribute( "ry" ).toDouble(); + double height = top - bottom; + double width = right - left; + // Append the ellipse to the document + VObject *ellipse = new VEllipse( 0L, KoPoint( left, top ), width, height ); + parseGObject( ellipse, object ); + m_document.append( ellipse ); + } + else if( b.tagName() == "polyline" ) + { + /** + * Kontour is much simpler because it doesn't support curves, so + * we're done with connecting points with lines. + */ + QDomElement point = b.firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "polygon" ) + { + QDomElement point = b.namedItem( "polyline" ).firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + path->close(); + // back to first point + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "bezier" ) + { + QDomElement point = b.namedItem( "polyline" ).firstChild().toElement(); + VPath *path = new VPath( &m_document ); + double x, y; + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->moveTo( KoPoint( x, y ) ); + point = point.nextSibling().toElement(); + for( ; point.tagName() != "gobject"; point = point.nextSibling().toElement() ) + { + x = point.attribute( "x" ).toDouble(); + y = point.attribute( "y" ).toDouble(); + path->lineTo( KoPoint( x, y ) ); + } + parseGObject( path, point ); + m_document.append( path ); + } + else if( b.tagName() == "group" || b.tagName() == "layer" ) + { + parseGroup( b.toElement().firstChild().toElement() ); + } + } +} + +#include diff --git a/filters/karbon/kontour/kontourimport.h b/filters/karbon/kontour/kontourimport.h new file mode 100644 index 000000000..f227f9083 --- /dev/null +++ b/filters/karbon/kontour/kontourimport.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2002, Sven Lppken + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __KONTOURIMPORT_H__ +#define __KONTOURIMPORT_H__ + +#include +#include +#include + +class KontourImport : public KoFilter +{ + Q_OBJECT + +public: + KontourImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KontourImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + +private: + void parseGObject( VObject *, const QDomElement & ); + void parseGroup( const QDomElement & ); + VDocument m_document; +}; + +#endif // __KONTOURIMPORT_H__ diff --git a/filters/karbon/msod/Makefile.am b/filters/karbon/msod/Makefile.am new file mode 100644 index 000000000..f7191cd11 --- /dev/null +++ b/filters/karbon/msod/Makefile.am @@ -0,0 +1,18 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) +libkarbonmsodimport_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries) +libkarbonmsodimport_la_LIBADD = $(KOFFICE_LIBS) $(LIBZ) + +####### Files + +kde_module_LTLIBRARIES = libkarbonmsodimport.la + +libkarbonmsodimport_la_SOURCES = msodimport.cc msod.cc + +noinst_HEADERS = msodimport.h msod.h + +METASOURCES = AUTO + +service_DATA = karbon_msod_import.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/msod/karbon_msod_import.desktop b/filters/karbon/msod/karbon_msod_import.desktop new file mode 100644 index 000000000..f75aac71d --- /dev/null +++ b/filters/karbon/msod/karbon_msod_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Karbon's MS Office Drawing Import Filter +Name[ar]=مِرْشَح استيراد رسم MS Office الخاص بـ Karbon +Name[bg]=Филтър за импортиране на MS Office Drawing в Karbon +Name[br]=Sil enporzh MS Office Drawing evit Karbon's +Name[ca]=Filtre d'importació MS Office Drawing per a Karbon +Name[cs]=Importní filtr Kreslení MS Office pro Karbon +Name[cy]=Hidlen Fewnforio Lluniad MS Office Karbon +Name[da]=Karbons MS Office-tegning-importfilter +Name[de]=Karbon14 Importfilter für Microsoft Office-Zeichnungen +Name[el]=Φίλτρο εισαγωγής MS Office Drawning του Karbon +Name[eo]=Filtrilo por importado de MS-Oficeja desegno al Karbon +Name[es]=Filtro de importación dibujo de MS Office de Karbon +Name[et]=Karboni MS Office'i joonistuste impordifilter +Name[eu]=Karbon-en MSG Office-en marrazkien inportaziorako iragazkia +Name[fa]=پالایۀ واردات ترسیم MS Office Karbon +Name[fi]=Karbonin MS Office -piirros tuontisuodin +Name[fr]=Filtre d'importation MS-Office Drawing de Karbon 14 +Name[fy]=MS Office Drawing-importfilter foar Karbon +Name[gl]=Filtro de Importación de Debuxos de MS Office para Karbon +Name[he]=מסנן לייבוא ציורים מ־MS Office ל־Karbon +Name[hi]=कार्बन का एमएस ऑफ़िस ड्राइंग इम्पोर्ट फ़िल्टर +Name[hr]=Karbon filtar uvoza za MS Office crteže +Name[hu]=Karbon MS Office rajz importszűrő +Name[is]=Karbon MS Office teikning innflutningssía +Name[it]=Filtro di importazione MS Office Drawing per Karbon +Name[ja]=Karbon MS Office Drawing インポートフィルタ +Name[km]=តម្រង​នាំចូល​គំនូរ MS Office សម្រាប់ Karbon +Name[lt]=Karbon's MS Office Drawing importavimo filtras +Name[lv]=Karbon MS Office zīmējumu importa filtrs +Name[ms]=Penapis Import MS Office Drawing Karbon +Name[nb]=Importfilter fra MS Office-tegning til Karbon +Name[nds]=Tekenimportfilter för Karbon +Name[ne]=कार्बनको एमएस कार्यालय रेखाचित्र आयात फिल्टर +Name[nl]=MS Office Drawing-importfilter voor Karbon +Name[nn]=Importfilter frå MS Office-teikning til Karbon +Name[pl]=Filtr importu z formatu MS Office Draw do Karbon +Name[pt]=Filtro de Importação de Desenhos do MS Office para o Karbon +Name[pt_BR]=Filtro de importação Desenho MS-Office para o Karbon +Name[ro]=Filtru importare Karbon14 pentru desene MS Office +Name[ru]=Фильтр импорта рисунков MS Office в Karbon +Name[se]=Karbon:a MS Office-sárgun sisafievrridansilli +Name[sk]=MS Office Drawing filter pre import pre Karbon +Name[sl]=Uvozni filter risbe iz MS Office za Karbon +Name[sr]=Karbon-ов филтер за увоз из MS Office Drawing-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz MS Office Drawing-a +Name[sv]=Karbon-filter för import av MS Office-teckning +Name[ta]=karbon 's MS Office வரைதல் இறக்குமதி வடிகட்டி +Name[tg]=Филтри Воридоти Karbon-и MS Office Расмкашӣ +Name[tr]=Karbon MS Office Çizim Alma Filtresi +Name[uk]=Фільтр для імпорту малюнків MS Office у Karbon +Name[uz]=MS Office chizmalarini Karbon'ga import qilish filteri +Name[uz@cyrillic]=MS Office чизмаларини Karbon'га импорт қилиш филтери +Name[zh_CN]=Karbon 的 MS Office Drawing 导入过滤器 +Name[zh_TW]=Karbon 的 MS Office 繪圖匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-msod +X-KDE-Weight=1 +X-KDE-Library=libkarbonmsodimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/msod/msod.cc b/filters/karbon/msod/msod.cc new file mode 100644 index 000000000..dd848c83c --- /dev/null +++ b/filters/karbon/msod/msod.cc @@ -0,0 +1,1340 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const int Msod::s_area = 30505; + +Msod::Msod( + unsigned dpi) : + KWmf(dpi) +{ + m_dpi = dpi; + m_images.setAutoDelete(true); + m_opt = new Options(*this); + m_shape.data = 0L; + m_shape.length = 0; +} + +Msod::~Msod() +{ + delete [] m_shape.data; + delete m_opt; +} + +void Msod::drawShape( + unsigned shapeType, + Q_UINT32 bytes, + QDataStream &operands) +{ + static const char *funcTab[] = + { + "UNKNOWN", // Unknown + "RECTANGLE", // Rectangle + "ROUNDRECTANGLE", // Roundrectangle + "ELLIPSE", // Ellipse + "DIAMOND", // Diamond + "ISOCELESTRIANGLE", // Isocelestriangle + "RIGHTTRIANGLE", // Righttriangle + "PARALLELOGRAM", // Parallelogram + "TRAPEZOID", // Trapezoid + "HEXAGON", // Hexagon + "OCTAGON", // Octagon + "PLUS", // Plus + "STAR", // Star + "ARROW", // Arrow + "THICKARROW", // Thickarrow + "HOMEPLATE", // Homeplate + "CUBE", // Cube + "BALLOON", // Balloon + "SEAL", // Seal + "ARC", // Arc + "LINE", // Line + "PLAQUE", // Plaque + "CAN", // Can + "DONUT", // Donut + "TEXTSIMPLE", // Textsimple + "TEXTOCTAGON", // Textoctagon + "TEXTHEXAGON", // Texthexagon + "TEXTCURVE", // Textcurve + "TEXTWAVE", // Textwave + "TEXTRING", // Textring + "TEXTONCURVE", // Textoncurve + "TEXTONRING", // Textonring + "STRAIGHTCONNECTOR1", // Straightconnector1 + "BENTCONNECTOR2", // Bentconnector2 + "BENTCONNECTOR3", // Bentconnector3 + "BENTCONNECTOR4", // Bentconnector4 + "BENTCONNECTOR5", // Bentconnector5 + "CURVEDCONNECTOR2", // Curvedconnector2 + "CURVEDCONNECTOR3", // Curvedconnector3 + "CURVEDCONNECTOR4", // Curvedconnector4 + "CURVEDCONNECTOR5", // Curvedconnector5 + "CALLOUT1", // Callout1 + "CALLOUT2", // Callout2 + "CALLOUT3", // Callout3 + "ACCENTCALLOUT1", // Accentcallout1 + "ACCENTCALLOUT2", // Accentcallout2 + "ACCENTCALLOUT3", // Accentcallout3 + "BORDERCALLOUT1", // bordercallout1 + "BORDERCALLOUT2", // Bordercallout2 + "BORDERCALLOUT3", // Bordercallout3 + "ACCENTBORDERCALLOUT1", // Accentbordercallout1 + "ACCENTBORDERCALLOUT2", // Accentbordercallout2 + "ACCENTBORDERCALLOUT3", // Accentbordercallout3 + "RIBBON", // Ribbon + "RIBBON2", // Ribbon2 + "CHEVRON", // Chevron + "PENTAGON", // Pentagon + "NOSMOKING", // Nosmoking + "SEAL8", // Seal8 + "SEAL16", // Seal16 + "SEAL32", // Seal32 + "WEDGERECTCALLOUT", // Wedgerectcallout + "WEDGERRECTCALLOUT", // Wedgerrectcallout + "WEDGEELLIPSECALLOUT", // Wedgeellipsecallout + "WAVE", // Wave + "FOLDEDCORNER", // Foldedcorner + "LEFTARROW", // Leftarrow + "DOWNARROW", // Downarrow + "UPARROW", // Uparrow + "LEFTRIGHTARROW", // Leftrightarrow + "UPDOWNARROW", // Updownarrow + "IRREGULARSEAL1", // Irregularseal1 + "IRREGULARSEAL2", // Irregularseal2 + "LIGHTNINGBOLT", // Lightningbolt + "HEART", // Heart + "PICTUREFRAME", // PictureFrame + "QUADARROW", // Quadarrow + "LEFTARROWCALLOUT", // Leftarrowcallout + "RIGHTARROWCALLOUT", // Rightarrowcallout + "UPARROWCALLOUT", // Uparrowcallout + "DOWNARROWCALLOUT", // Downarrowcallout + "LEFTRIGHTARROWCALLOUT", // Leftrightarrowcallout + "UPDOWNARROWCALLOUT", // Updownarrowcallout + "QUADARROWCALLOUT", // Quadarrowcallout + "BEVEL", // Bevel + "LEFTBRACKET", // Leftbracket + "RIGHTBRACKET", // Rightbracket + "LEFTBRACE", // Leftbrace + "RIGHTBRACE", // Rightbrace + "LEFTUPARROW", // Leftuparrow + "BENTUPARROW", // Bentuparrow + "BENTARROW", // Bentarrow + "SEAL24", // Seal24 + "STRIPEDRIGHTARROW", // Stripedrightarrow + "NOTCHEDRIGHTARROW", // Notchedrightarrow + "BLOCKARC", // Blockarc + "SMILEYFACE", // Smileyface + "VERTICALSCROLL", // Verticalscroll + "HORIZONTALSCROLL", // Horizontalscroll + "CIRCULARARROW", // Circulararrow + "NOTCHEDCIRCULARARROW", // Notchedcirculararrow + "UTURNARROW", // Uturnarrow + "CURVEDRIGHTARROW", // Curvedrightarrow + "CURVEDLEFTARROW", // Curvedleftarrow + "CURVEDUPARROW", // Curveduparrow + "CURVEDDOWNARROW", // Curveddownarrow + "CLOUDCALLOUT", // Cloudcallout + "ELLIPSERIBBON", // Ellipseribbon + "ELLIPSERIBBON2", // Ellipseribbon2 + "FLOWCHARTPROCESS", // Flowchartprocess + "FLOWCHARTDECISION", // Flowchartdecision + "FLOWCHARTINPUTOUTPUT", // Flowchartinputoutput + "FLOWCHARTPREDEFINEDPROCESS", // Flowchartpredefinedprocess + "FLOWCHARTINTERNALSTORAGE", // Flowchartinternalstorage + "FLOWCHARTDOCUMENT", // Flowchartdocument + "FLOWCHARTMULTIDOCUMENT", // Flowchartmultidocument + "FLOWCHARTTERMINATOR", // Flowchartterminator + "FLOWCHARTPREPARATION", // Flowchartpreparation + "FLOWCHARTMANUALINPUT", // Flowchartmanualinput + "FLOWCHARTMANUALOPERATION", // Flowchartmanualoperation + "FLOWCHARTCONNECTOR", // Flowchartconnector + "FLOWCHARTPUNCHEDCARD", // Flowchartpunchedcard + "FLOWCHARTPUNCHEDTAPE", // Flowchartpunchedtape + "FLOWCHARTSUMMINGJUNCTION", // Flowchartsummingjunction + "FLOWCHARTOR", // Flowchartor + "FLOWCHARTCOLLATE", // Flowchartcollate + "FLOWCHARTSORT", // Flowchartsort + "FLOWCHARTEXTRACT", // Flowchartextract + "FLOWCHARTMERGE", // Flowchartmerge + "FLOWCHARTOFFLINESTORAGE", // Flowchartofflinestorage + "FLOWCHARTONLINESTORAGE", // Flowchartonlinestorage + "FLOWCHARTMAGNETICTAPE", // Flowchartmagnetictape + "FLOWCHARTMAGNETICDISK", // Flowchartmagneticdisk + "FLOWCHARTMAGNETICDRUM", // Flowchartmagneticdrum + "FLOWCHARTDISPLAY", // Flowchartdisplay + "FLOWCHARTDELAY", // Flowchartdelay + "TEXTPLAINTEXT", // Textplaintext + "TEXTSTOP", // Textstop + "TEXTTRIANGLE", // Texttriangle + "TEXTTRIANGLEINVERTED", // Texttriangleinverted + "TEXTCHEVRON", // Textchevron + "TEXTCHEVRONINVERTED", // Textchevroninverted + "TEXTRINGINSIDE", // Textringinside + "TEXTRINGOUTSIDE", // Textringoutside + "TEXTARCHUPCURVE", // Textarchupcurve + "TEXTARCHDOWNCURVE", // Textarchdowncurve + "TEXTCIRCLECURVE", // Textcirclecurve + "TEXTBUTTONCURVE", // Textbuttoncurve + "TEXTARCHUPPOUR", // Textarchuppour + "TEXTARCHDOWNPOUR", // Textarchdownpour + "TEXTCIRCLEPOUR", // Textcirclepour + "TEXTBUTTONPOUR", // Textbuttonpour + "TEXTCURVEUP", // Textcurveup + "TEXTCURVEDOWN", // Textcurvedown + "TEXTCASCADEUP", // Textcascadeup + "TEXTCASCADEDOWN", // Textcascadedown + "TEXTWAVE1", // Textwave1 + "TEXTWAVE2", // Textwave2 + "TEXTWAVE3", // Textwave3 + "TEXTWAVE4", // Textwave4 + "TEXTINFLATE", // Textinflate + "TEXTDEFLATE", // Textdeflate + "TEXTINFLATEBOTTOM", // Textinflatebottom + "TEXTDEFLATEBOTTOM", // Textdeflatebottom + "TEXTINFLATETOP", // Textinflatetop + "TEXTDEFLATETOP", // Textdeflatetop + "TEXTDEFLATEINFLATE", // Textdeflateinflate + "TEXTDEFLATEINFLATEDEFLATE", // Textdeflateinflatedeflate + "TEXTFADERIGHT", // Textfaderight + "TEXTFADELEFT", // Textfadeleft + "TEXTFADEUP", // Textfadeup + "TEXTFADEDOWN", // Textfadedown + "TEXTSLANTUP", // Textslantup + "TEXTSLANTDOWN", // Textslantdown + "TEXTCANUP", // Textcanup + "TEXTCANDOWN", // Textcandown + "FLOWCHARTALTERNATEPROCESS", // Flowchartalternateprocess + "FLOWCHARTOFFPAGECONNECTOR", // Flowchartoffpageconnector + "CALLOUT90", // Callout90 + "ACCENTCALLOUT90", // Accentcallout90 + "BORDERCALLOUT90", // Bordercallout90 + "ACCENTBORDERCALLOUT90", // Accentbordercallout90 + "LEFTRIGHTUPARROW", // Leftrightuparrow + "SUN", // Sun + "MOON", // Moon + "BRACKETPAIR", // Bracketpair + "BRACEPAIR", // Bracepair + "SEAL4", // Seal4 + "DOUBLEWAVE", // Doublewave + "ACTIONBUTTONBLANK", // Actionbuttonblank + "ACTIONBUTTONHOME", // Actionbuttonhome + "ACTIONBUTTONHELP", // Actionbuttonhelp + "ACTIONBUTTONINFORMATION", // Actionbuttoninformation + "ACTIONBUTTONFORWARDNEXT", // Actionbuttonforwardnext + "ACTIONBUTTONBACKPREVIOUS", // Actionbuttonbackprevious + "ACTIONBUTTONEND", // Actionbuttonend + "ACTIONBUTTONBEGINNING", // Actionbuttonbeginning + "ACTIONBUTTONRETURN", // Actionbuttonreturn + "ACTIONBUTTONDOCUMENT", // Actionbuttondocument + "ACTIONBUTTONSOUND", // Actionbuttonsound + "ACTIONBUTTONMOVIE", // Actionbuttonmovie + "HOSTCONTROL", // Hostcontrol + "TEXTBOX", // Textbox + }; + struct + { + Q_UINT32 spid; // The shape id + union + { + Q_UINT32 info; + struct + { + Q_UINT32 fGroup : 1; // This shape is a group shape + Q_UINT32 fChild : 1; // Not a top-level shape + Q_UINT32 fPatriarch : 1; // This is the topmost group shape. + // Exactly one of these per drawing. + Q_UINT32 fDeleted : 1; // The shape has been deleted + Q_UINT32 fOleShape : 1; // The shape is an OLE object + Q_UINT32 fHaveMaster : 1; // Shape has a hspMaster property + Q_UINT32 fFlipH : 1; // Shape is flipped horizontally + Q_UINT32 fFlipV : 1; // Shape is flipped vertically + Q_UINT32 fConnector : 1; // Connector type of shape + Q_UINT32 fHaveAnchor : 1; // Shape has an anchor of some kind + Q_UINT32 fBackground : 1; // Background shape + Q_UINT32 fHaveSpt : 1; // Shape has a shape type property + Q_UINT32 reserved : 20; // Not yet used + } fields; + } grfPersistent; + } data; + + // Scan lookup table for operation. + + operands >> data.spid; + operands >> data.grfPersistent.info; + bytes -= 8; + kdDebug(s_area) << "shape-id: " << data.spid << " type: " << funcTab[shapeType] << " (" << shapeType << ")" << + (data.grfPersistent.fields.fGroup ? " group" : "") << + (data.grfPersistent.fields.fChild ? " child" : "") << + (data.grfPersistent.fields.fPatriarch ? " patriarch" : "") << + (data.grfPersistent.fields.fDeleted ? " deleted" : "") << + (data.grfPersistent.fields.fOleShape ? " oleshape" : "") << + (data.grfPersistent.fields.fHaveMaster ? " master" : "") << + (data.grfPersistent.fields.fFlipH ? " flipv" : "") << + (data.grfPersistent.fields.fConnector ? " connector" : "") << + (data.grfPersistent.fields.fHaveAnchor ? " anchor" : "") << + (data.grfPersistent.fields.fBackground ? " background" : "") << + (data.grfPersistent.fields.fHaveSpt ? " spt" : "") << + " operands: " << bytes << endl; + if (data.grfPersistent.fields.fDeleted) + return; + if ((!m_isRequiredDrawing) && (m_requestedShapeId != data.spid)) + return; + + // An active shape! Let's draw it... + + switch (shapeType) + { + case 0: + if (m_opt->m_pVertices) + { + gotPolyline(m_dc, *m_opt->m_pVertices); + } + break; + case 1: + if (bytes > 7) + { + QPoint topLeft; + QSize size; + + topLeft = normalisePoint(operands); + size = normaliseSize(operands); + + QRect rect(topLeft, size); + QPointArray points(4); + + points.setPoint(0, topLeft); + points.setPoint(1, rect.topRight()); + points.setPoint(2, rect.bottomRight()); + points.setPoint(3, rect.bottomLeft()); + gotRectangle(m_dc, points); + } + case 20: + if (bytes > 7) + { + QPoint lineFrom; + QPoint lineTo; + + lineTo = normalisePoint(operands); + + QPointArray points(2); + + points.setPoint(0, lineFrom); + points.setPoint(1, lineTo); + gotPolyline(m_dc, points); + } + break; + default: + break; + } +} + +void Msod::invokeHandler( + Header &op, + Q_UINT32 bytes, + QDataStream &operands) +{ + typedef void (Msod::*method)(Header &op, Q_UINT32 bytes, QDataStream &operands); + + typedef struct + { + const char *name; + Q_UINT16 opcode; + method handler; + } opcodeEntry; + + static const opcodeEntry funcTab[] = + { + { "ALIGNRULE", 0xF013, &Msod::opAlignrule }, + { "ANCHOR", 0xF00E, &Msod::opAnchor }, + { "ARCRULE", 0xF014, &Msod::opArcrule }, + { "BSE", 0xF007, &Msod::opBse }, + { "BSTORECONTAINER", 0xF001, &Msod::opBstorecontainer }, + { "CALLOUTRULE", 0xF017, &Msod::opCalloutrule }, + { "CHILDANCHOR", 0xF00F, &Msod::opChildanchor }, + { "CLIENTANCHOR", 0xF010, &Msod::opClientanchor }, + { "CLIENTDATA", 0xF011, &Msod::opClientdata }, + { "CLIENTRULE", 0xF015, &Msod::opClientrule }, + { "CLIENTTEXTBOX", 0xF00D, &Msod::opClienttextbox }, + { "CLSID", 0xF016, &Msod::opClsid }, + { "COLORMRU", 0xF11A, &Msod::opColormru }, + { "CONNECTORRULE", 0xF012, &Msod::opConnectorrule }, + { "DELETEDPSPL", 0xF11D, &Msod::opDeletedpspl }, + { "DG", 0xF008, &Msod::opDg }, + { "DGCONTAINER", 0xF002, &Msod::opDgcontainer }, + { "DGG", 0xF006, &Msod::opDgg }, + { "DGGCONTAINER", 0xF000, &Msod::opDggcontainer }, + { "OLEOBJECT", 0xF11F, &Msod::opOleobject }, + { "OPT", 0xF00B, &Msod::opOpt }, + { "REGROUPITEMS", 0xF118, &Msod::opRegroupitems }, + { "SELECTION", 0xF119, &Msod::opSelection }, + { "SOLVERCONTAINER", 0xF005, &Msod::opSolvercontainer }, + { "SP", 0xF00A, &Msod::opSp }, + { "SPCONTAINER", 0xF004, &Msod::opSpcontainer }, + { "SPGR", 0xF009, &Msod::opSpgr }, + { "SPGRCONTAINER", 0xF003, &Msod::opSpgrcontainer }, + { "SPLITMENUCOLORS", 0xF11E, &Msod::opSplitmenucolors }, + { "TEXTBOX", 0xF00C, &Msod::opTextbox }, + { NULL, 0, 0 }, + { "BLIP", 0, &Msod::opBlip } + }; + unsigned i; + method result; + + // Scan lookup table for operation. + + for (i = 0; funcTab[i].name; i++) + { + if (funcTab[i].opcode == op.opcode.fields.fbt) + { + break; + } + } + + // Invoke handler. + + result = funcTab[i].handler; + if (!result && (op.opcode.fields.fbt >= 0xF018) && (0xF117 >= op.opcode.fields.fbt)) + result = funcTab[++i].handler; + if (!result) + { + if (funcTab[i].name) + kdWarning(s_area) << "invokeHandler: unsupported opcode: " << + funcTab[i].name << + " operands: " << bytes << endl; + else + kdWarning(s_area) << "invokeHandler: unsupported opcode: 0x" << + QString::number(op.opcode.fields.fbt, 16) << + " operands: " << bytes << endl; + + // Skip data we cannot use. + + skip(bytes, operands); + } + else + { + kdDebug(s_area) << "invokeHandler: opcode: " << funcTab[i].name << + " operands: " << bytes << endl; + + // We don't invoke the handler directly on the incoming operands, but + // via a temporary datastream. This adds overhead, but eliminates the + // need for the individual handlers to read *exactly* the right amount + // of data (thus speeding development, and possibly adding some + // future-proofing). + + if (bytes) + { + QByteArray *record = new QByteArray(bytes); + QDataStream *body; + + operands.readRawBytes(record->data(), bytes); + body = new QDataStream(*record, IO_ReadOnly); + body->setByteOrder(QDataStream::LittleEndian); + (this->*result)(op, bytes, *body); + delete body; + delete record; + } + else + { + QDataStream *body = new QDataStream(); + + (this->*result)(op, bytes, *body); + delete body; + } + } +} + +QPoint Msod::normalisePoint( + QDataStream &operands) +{ + Q_UINT16 x; + Q_UINT16 y; + + operands >> x >> y; + return QPoint(x / m_dpi, y / m_dpi); +} + +QSize Msod::normaliseSize( + QDataStream &operands) +{ + Q_UINT16 width; + Q_UINT16 height; + + operands >> width >> height; + return QSize(width / m_dpi, height / m_dpi); +} + +bool Msod::parse( + unsigned shapeId, + const QString &file, + const char *delayStream) +{ + QFile in(file); + if (!in.open(IO_ReadOnly)) + { + kdError(s_area) << "Unable to open input file!" << endl; + in.close(); + return false; + } + QDataStream stream(&in); + bool result = parse(shapeId, stream, in.size(), delayStream); + in.close(); + return result; +} + +bool Msod::parse( + unsigned shapeId, + QDataStream &stream, + unsigned size, + const char *delayStream) +{ + stream.setByteOrder(QDataStream::LittleEndian); // Great, I love Qt ! + m_requestedShapeId = shapeId; + m_isRequiredDrawing = false; + m_delayStream = delayStream; + + // Read bits. + + walk(size, stream); + return true; +} + +void Msod::opAlignrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opAnchor( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opArcrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opBlip(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + typedef enum + { + msobiWMF = 0x216, // Metafile header then compressed WMF. + msobiEMF = 0x3D4, // Metafile header then compressed EMF. + msobiPICT = 0x542, // Metafile header then compressed PICT. + msobiPNG = 0x6E0, // One byte tag then PNG data. + msobiJPEG = 0x46A, // One byte tag then JFIF data. + msobiDIB = 0x7A8, // One byte tag then DIB data. + msobiClient = 0x800 // Clients should set this bit. + } MSOBI; + typedef enum + { + msocompressionDeflate, + msocompressionNone = 254, + msocompressionTest + } MSOBLIPCOMPRESSION; + + bool hasPrimaryId; + Q_UINT32 length = 0; + struct + { + Q_UINT32 cb; + struct + { + Q_UINT32 x; + Q_UINT32 y; + Q_UINT32 w; + Q_UINT32 h; + } bounds; + struct + { + Q_UINT32 w; + Q_UINT32 h; + } ptSize; + Q_UINT32 cbSave; + Q_UINT8 compression; + Q_UINT8 filter; + } data; + + // Skip any explicit primary header (m_rgbUidprimary). + + switch (m_blipType) + { + case msoblipEMF: + hasPrimaryId = (m_blipType ^ msobiEMF) != 0; + break; + case msoblipWMF: + hasPrimaryId = (m_blipType ^ msobiWMF) != 0; + break; + case msoblipPICT: + hasPrimaryId = (m_blipType ^ msobiPICT) != 0; + break; + case msoblipJPEG: + hasPrimaryId = (m_blipType ^ msobiJPEG) != 0; + break; + case msoblipPNG: + hasPrimaryId = (m_blipType ^ msobiPNG) != 0; + break; + case msoblipDIB: + hasPrimaryId = (m_blipType ^ msobiDIB) != 0; + break; + default: + hasPrimaryId = (m_blipType ^ msobiClient) != 0; + break; + } + if (hasPrimaryId) + { + length += 16; + skip(16, operands); + } + + // Process the rest of the header. + + data.compression = msocompressionNone; + switch (m_blipType) + { + case msoblipEMF: + case msoblipWMF: + case msoblipPICT: + length += 34; + operands >> data.cb; + operands >> data.bounds.x >> data.bounds.y >> data.bounds.w >> data.bounds.h; + operands >> data.ptSize.w >> data.ptSize.h; + operands >> data.cbSave; + operands >> data.compression >> data.filter; + break; + case msoblipJPEG: + case msoblipPNG: + case msoblipDIB: + // Skip the "tag". + length += 1; + skip(1, operands); + break; + default: + break; + } + + // Work out the file type. + + Image *image = new Image(); + switch (m_blipType) + { + case msoblipEMF: + image->extension = "emf"; + break; + case msoblipWMF: + image->extension = "wmf"; + break; + case msoblipPICT: + image->extension = "pic"; + break; + case msoblipJPEG: + image->extension = "jpg"; + break; + case msoblipPNG: + image->extension = "png"; + break; + case msoblipDIB: + image->extension = "dib"; + break; + default: + image->extension = "img"; + break; + } + image->length = bytes - length; + image->data = new char[image->length]; + operands.readRawBytes((char *)image->data, image->length); + if (data.compression == msocompressionDeflate) + { + const char *tmp; + uLongf destLen = data.cb; + int result; + + tmp = new char[data.cb]; + result = uncompress((Q_UINT8 *)tmp, &destLen, (Q_UINT8 *)image->data, image->length); + if (result != Z_OK) + { + kdError(s_area) << "opBlip: uncompress failed: " << result << endl; + } + if (destLen != data.cb) + { + kdError(s_area) << "opBlip: uncompressed " << destLen << " instead of " << data.cb << endl; + } + delete [] image->data; + image->data = tmp; + image->length = destLen; + } + m_images.resize(m_images.size() + 1); + m_images.insert(m_images.size() - 1, image); +} + +// FBSE - File Blip Store Entry + +void Msod::opBse(Header &op, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT8 btWin32; // Required type on Win32. + Q_UINT8 btMacOS; // Required type on Mac. + Q_UINT8 rgbUid[16]; // Identifier of blip. + Q_UINT16 tag; // currently unused. + Q_UINT32 size; // Blip size in stream. + Q_UINT32 cRef; // Reference count on the blip. + Q_UINT32 foDelay; // File offset in the delay stream. + Q_UINT8 usage; // How this blip is used (MSOBLIPUSAGE). + Q_UINT8 cbName; // length of the blip name. + Q_UINT8 unused2; // for the future. + Q_UINT8 unused3; // for the future. + } data; + unsigned i; + + // Work out the type of the BLIP. + + m_blipType = static_cast(op.opcode.fields.inst); + operands >> data.btWin32; + operands >> data.btMacOS; + for (i = 0; i < 16; i++) + operands >> data.rgbUid[i]; + operands >> data.tag >> data.size; + operands >> data.cRef >> data.foDelay; + operands >> data.usage >> data.cbName; + operands >> data.unused2 >> data.unused2; + + // If the Blip is not in this drawing file, process it "manually". + + if (m_delayStream) + { + // The m_pib refers to images by number, which includes images + // that are no longer here. Thus, we fake these out so that any + // references to non-deleted images are still valid (!!!). + + if (data.size && data.cRef) + { + QByteArray bytes; + bytes.setRawData(m_delayStream + data.foDelay, data.size); + QDataStream stream(bytes, IO_ReadOnly); + stream.setByteOrder(QDataStream::LittleEndian); + walk(data.size, stream); + bytes.resetRawData(m_delayStream + data.foDelay, data.size); + } + else + { + m_images.resize(m_images.size() + 1); + m_images.insert(m_images.size() - 1, 0L); + } + } +} + +void Msod::opBstorecontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opCalloutrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opChildanchor( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opClientanchor(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client anchor: " << data.unknown << endl; +} + +void Msod::opClientdata(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client data: " << data.unknown << endl; +} + +void Msod::opClientrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opClienttextbox( + Header &, + Q_UINT32, + QDataStream &operands) +{ + struct + { + Q_UINT32 unknown; + } data; + + operands >> data.unknown; + kdDebug(s_area) << "client textbox: 0x" << QString::number(data.unknown,16) << endl; +} + +void Msod::opClsid( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opColormru( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opConnectorrule( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opDeletedpspl( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +// FDG - File DG + +void Msod::opDg(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 csp; // The number of shapes in this drawing. + Q_UINT32 spidCur; // The last shape ID given to an SP in this DG. + } data; + + operands >> data.csp >> data.spidCur; + kdDebug(s_area) << "drawing id: " << data.spidCur << endl; + m_isRequiredDrawing = (m_requestedShapeId == data.spidCur); + if (m_isRequiredDrawing) + { + kdDebug(s_area) << "found requested drawing" << endl; + } +} + +void Msod::opDgcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +// FDGG - File DGG + +void Msod::opDgg(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 spidMax; // The current maximum shape ID. + Q_UINT32 cidcl; // The number of ID clusters (FIDCLs). + Q_UINT32 cspSaved; // The total number of shapes saved. + // (including deleted shapes, if undo + // information was saved). + Q_UINT32 cdgSaved; // The total number of drawings saved. + } data; + + // File ID Cluster - used to save IDCLs + + struct + { + Q_UINT32 dgid; // DG owning the SPIDs in this cluster + Q_UINT32 cspidCur; // number of SPIDs used so far + } data1; + unsigned i; + + operands >> data.spidMax >> data.cidcl >> data.cspSaved >> data.cdgSaved; + kdDebug(s_area) << data.cspSaved << " shapes in " << + data.cidcl - 1 << " clusters in " << + data.cdgSaved << " drawings" << endl; + for (i = 0; i < data.cidcl - 1; i++) + { + operands >> data1.dgid >> data1.cspidCur; + } +} + +void Msod::opDggcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opOleobject( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opOpt(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + m_opt->walk(bytes, operands); +} + +void Msod::opRegroupitems( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opSelection( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::opSolvercontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSp(Header &op, Q_UINT32 bytes, QDataStream &operands) +{ + // We want to defer the act of drawing a shape until we have seen any options + // that may affect it. Thus, we merely store the data away, and let opSpContainer + // do all the ahrd work. + + m_shape.type = op.opcode.fields.inst; + m_shape.length = bytes; + m_shape.data = new char [bytes]; + operands.readRawBytes(m_shape.data, bytes); +} + +void Msod::opSpcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); + + // Having gathered all the information for this shape, we can now draw it. + + QByteArray a; + + a.setRawData(m_shape.data, m_shape.length); + QDataStream s(a, IO_ReadOnly); + s.setByteOrder(QDataStream::LittleEndian); // Great, I love Qt ! + drawShape(m_shape.type, m_shape.length, s); + a.resetRawData(m_shape.data, m_shape.length); + delete [] m_shape.data; + m_shape.data = 0L; +} + +void Msod::opSpgr(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 x; + Q_UINT32 y; + Q_UINT32 w; + Q_UINT32 h; + } data; + + operands >> data.x >> data.y >> data.w >> data.h; +} + +void Msod::opSpgrcontainer(Header &, Q_UINT32 bytes, QDataStream &operands) +{ + walk(bytes, operands); +} + +void Msod::opSplitmenucolors(Header &, Q_UINT32, QDataStream &operands) +{ + struct + { + Q_UINT32 fill; + Q_UINT32 line; + Q_UINT32 shadow; + Q_UINT32 threeDee; + } data; + + operands >> data.fill >> data.line >> data.shadow >> data.threeDee; +} + +void Msod::opTextbox( + Header &, + Q_UINT32, + QDataStream &) +{ +} + +void Msod::skip(Q_UINT32 bytes, QDataStream &operands) +{ + if ((int)bytes < 0) + { + kdError(s_area) << "skip: " << (int)bytes << endl; + return; + } + if (bytes) + { + Q_UINT32 i; + Q_UINT8 discard; + + kdDebug(s_area) << "skip: " << bytes << endl; + for (i = 0; i < bytes; i++) + { + operands >> discard; + } + } +} + +void Msod::walk(Q_UINT32 bytes, QDataStream &operands) +{ + Header op; + Q_UINT32 length = 0; + + // Stop parsing when there are no more records. Note that we stop as soon + // as we cannot get a complete header. + while (length + 8 <= bytes) + { + operands >> op.opcode.info >> op.cbLength; + + // If we get some duff data, protect ourselves. + if (length + op.cbLength + 8 > bytes) + { + op.cbLength = bytes - length - 8; + } + length += op.cbLength + 8; + if (op.opcode.fields.fbt == 0x200) + { + // This appears to be an EOF marker. + break; + } + + // Package the arguments... + + invokeHandler(op, op.cbLength, operands); + } + + // Eat unexpected data that the caller may expect us to consume. + skip(bytes - length, operands); +} + +Msod::Options::Options( + Msod &parent) : + m_parent(parent) +{ + m_pVertices = 0L; + initialise(); +} + +Msod::Options::~Options() +{ + delete m_pVertices; +} + +double Msod::Options::from1616ToDouble(Q_UINT32 value) +{ + return (value >> 16) + 65535.0 / (double)(value & 0xffff); +} + +void Msod::Options::initialise() +{ + m_rotation = 0.0; + + m_lTxid = 0; + + m_pib = 0; + m_pibName = QString::null; + m_pibFlags = 0; + m_pictureId = 0; + m_fNoHitTestPicture = false; + m_pictureGray = false; + m_pictureBiLevel = false; + m_pictureActive = false; + + m_geoLeft = 0; + m_geoTop = 0; + m_geoRight = 21600; + m_geoBottom = 21600; + m_shapePath = 1; + delete m_pVertices; + m_pVertices = 0L; + m_fShadowOK = true; + m_f3DOK = true; + m_fLineOK = true; + m_fGTextOK = false; + m_fFillShadeShapeOK = false; + m_fFillOK = true; + + m_fFilled = true; + m_fHitTestFill = true; + m_fillShape = true; + m_fillUseRect = false; + m_fNoFillHitTest = false; + + m_lineColor = 0; + m_lineBackColor = 0xffffff; + m_lineType = 0; + m_lineWidth = 9525; + + m_fArrowheadsOK = false; + m_fLine = true; + m_fHitTestLine = true; + m_lineFillShape = true; + m_fNoLineDrawDash = false; + + m_bWMode = 1; + + m_fOleIcon = false; + m_fPreferRelativeResize = false; + m_fLockShapeType = false; + m_fDeleteAttachedObject = false; + m_fBackground = false; +} + +void Msod::Options::walk(Q_UINT32 bytes, QDataStream &operands) +{ + Header op; + Q_UINT16 length = 0; + Q_UINT16 complexLength = 0; + + // Reset all options to default values. + + initialise(); + + // First process all simple options, and add all complex options to a list. + + QPtrList
    complexOpts; + complexOpts.setAutoDelete(true); + bool unsupported; + while (length + complexLength < (int)bytes) + { + operands >> op.opcode.info >> op.value; + length += 6; + + // Defer processing of complex options. + + if (op.opcode.fields.fComplex) + { + complexLength += op.value; + complexOpts.append(new Header(op)); + continue; + } + + // Now squirrel away the option value. + + unsupported = false; + switch (op.opcode.fields.pid) + { + case 4: + m_rotation = from1616ToDouble(op.value); + break; + case 128: + m_lTxid = op.value; + kdDebug(s_area) << "textbox: 0x" << QString::number(op.value,16) << endl; + break; + case 260: + if (op.opcode.fields.fBid) + { + m_pib = op.value; + if (m_parent.m_isRequiredDrawing) + { + Image *image = m_parent.m_images[m_pib - 1]; + + // If it is an embedded WMF we don't bother with the + // part; we just extract it as more vector graphics. + + if (image->extension == "wmf") + { + QByteArray a; + a.setRawData(image->data, image->length); + QDataStream s(a, IO_ReadOnly); + m_parent.KWmf::parse(s, image->length); + a.resetRawData(image->data, image->length); + } + else + { + m_parent.gotPicture( + m_pib, + image->extension, + image->length, + image->data); + } + } + } + else + { + kdError(s_area) << "Cannot handle IMsoBlip" << endl; + } + break; + case 262: + m_pibFlags = op.value; + break; + case 267: + m_pictureId = op.value; + break; + case 319: + m_fNoHitTestPicture = (op.value & 0x0008) != 0; + m_pictureGray = (op.value & 0x0004) != 0; + m_pictureBiLevel = (op.value & 0x0002) != 0; + m_pictureActive = (op.value & 0x0001) != 0; + break; + case 320: + m_geoLeft = op.value; + break; + case 321: + m_geoTop = op.value; + break; + case 322: + m_geoRight = op.value; + break; + case 323: + m_geoBottom = op.value; + break; + case 324: + m_shapePath = op.value; + break; + case 383: + m_fShadowOK = (op.value & 0x0020) != 0; + m_f3DOK = (op.value & 0x0010) != 0; + m_fLineOK = (op.value & 0x0008) != 0; + m_fGTextOK = (op.value & 0x0004) != 0; + m_fFillShadeShapeOK = (op.value & 0x0002) != 0; + m_fFillOK = (op.value & 0x0001) != 0; + break; + case 447: + m_fFilled = (op.value & 0x0010) != 0; + m_fHitTestFill = (op.value & 0x0008) != 0; + m_fillShape = (op.value & 0x0004) != 0; + m_fillUseRect = (op.value & 0x0002) != 0; + m_fNoFillHitTest = (op.value & 0x0001) != 0; + break; + case 448: + m_lineColor = op.value; + break; + case 450: + m_lineBackColor = op.value; + break; + case 452: + m_lineType = op.value; + break; + case 459: + m_lineWidth = op.value; + break; + case 511: + m_fArrowheadsOK = (op.value & 0x0010) != 0; + m_fLine = (op.value & 0x0008) != 0; + m_fHitTestLine = (op.value & 0x0004) != 0; + m_lineFillShape = (op.value & 0x0002) != 0; + m_fNoLineDrawDash = (op.value & 0x0001) != 0; + break; + case 772: + m_bWMode = op.value; + break; + case 831: + m_fOleIcon = (op.value & 0x0010) != 0; + m_fPreferRelativeResize = (op.value & 0x0008) != 0; + m_fLockShapeType = (op.value & 0x0004) != 0; + m_fDeleteAttachedObject = (op.value & 0x0002) != 0; + m_fBackground = (op.value & 0x0001) != 0; + break; + default: + unsupported = true; + kdWarning(s_area) << "unsupported simple option: " << + op.opcode.fields.pid << endl; + break; + } + if (!unsupported) + kdDebug(s_area) << "simple option: " << + op.opcode.fields.pid << endl; + } + + // Now empty the list of complex options. + + while (complexOpts.count()) + { + Q_INT16 t16; + unsigned i; + + op = *complexOpts.getFirst(); + complexOpts.removeFirst(); + unsupported = false; + switch (op.opcode.fields.pid) + { + case 261: + while (true) + { + operands >> t16; + if (!t16) + break; + m_pibName += QChar(t16); + }; + break; + case 325: + m_pVertices = new QPointArray(op.value / 4); + for (i = 0; i < m_pVertices->count(); i++) + { + m_pVertices->setPoint(i, m_parent.normalisePoint(operands)); + }; + break; + case 326: + operands >> t16; + i = t16; + operands >> t16; + operands >> t16; + m_parent.skip(i * t16, operands); + break; + default: + unsupported = true; + kdWarning(s_area) << "unsupported complex option: " << + op.opcode.fields.pid << " operands: " << op.value << endl; + m_parent.skip(op.value, operands); + break; + } + if (!unsupported) + kdDebug(s_area) << "complex option: " << + op.opcode.fields.pid << " operands: " << op.value << endl; + complexLength -= op.value; + } +} diff --git a/filters/karbon/msod/msod.h b/filters/karbon/msod/msod.h new file mode 100644 index 000000000..a3dd9efe2 --- /dev/null +++ b/filters/karbon/msod/msod.h @@ -0,0 +1,307 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION + + This is a generic parser for Microsoft Office Drawings (MSODs). The + specification for this is the Microsoft Office 97 Drawing File Format + published in MSDN. The output is a series of callbacks (a.k.a. virtual + functions) which the caller can override as required. +*/ + +#ifndef MSOD_H +#define MSOD_H + +class QString; +class QPointArray; +#include +#include + +class Msod : + private KWmf +{ +public: + + // Construction. + + Msod( + unsigned dpi); + virtual ~Msod(); + + // Called to parse the given file. We extract a drawing by shapeId. + // If the drawing is not found, the return value will be false. + + bool parse( + unsigned shapeId, + const QString &file, + const char *delayStream = 0L); + bool parse( + unsigned shapeId, + QDataStream &stream, + unsigned size, + const char *delayStream = 0L); + + typedef KWmf::DrawContext DrawContext; + + // Should be protected... + + void brushSet( + unsigned colour, + unsigned style); + void penSet( + unsigned colour, + unsigned style, + unsigned width); + +protected: + // Override to get results of parsing. + + virtual void gotEllipse( + const DrawContext &dc, + QString type, + QPoint topLeft, + QSize halfAxes, + unsigned startAngle, + unsigned stopAngle) = 0; + virtual void gotPicture( + unsigned id, + QString extension, + unsigned length, + const char *data) = 0; + virtual void gotPolygon( + const DrawContext &dc, + const QPointArray &points) = 0; + virtual void gotPolyline( + const DrawContext &dc, + const QPointArray &points) = 0; + virtual void gotRectangle( + const DrawContext &dc, + const QPointArray &points) = 0; + +private: + Msod(const Msod &); + const Msod &operator=(const Msod &); + + // Debug support. + + static const int s_area; + +private: + int m_dpi; + DrawContext m_dc; + unsigned m_dggError; + unsigned m_requestedShapeId; + bool m_isRequiredDrawing; + const char *m_delayStream; + struct + { + unsigned type; + char *data; + unsigned length; + } m_shape; + + QPoint normalisePoint( + QDataStream &operands); + QSize normaliseSize( + QDataStream &operands); + void drawShape( + unsigned shapeType, + Q_UINT32 bytes, + QDataStream &operands); + +public: + + // Common Header (MSOBFH) + typedef struct + { + union + { + Q_UINT32 info; + struct + { + Q_UINT32 ver: 4; + Q_UINT32 inst: 12; + Q_UINT32 fbt: 16; + } fields; + } opcode; + Q_UINT32 cbLength; + } Header; + +private: + typedef enum + { + msoblipERROR, // An error occurred during loading. + msoblipUNKNOWN, // An unknown blip type. + msoblipEMF, // Windows Enhanced Metafile. + msoblipWMF, // Windows Metafile. + msoblipPICT, // Macintosh PICT. + msoblipJPEG, // JFIF. + msoblipPNG, // PNG. + msoblipDIB, // Windows DIB. + msoblipFirstClient = 32, // First client defined blip type. + msoblipLastClient = 255 // Last client defined blip type. + } MSOBLIPTYPE; + + MSOBLIPTYPE m_blipType; + unsigned m_imageId; + class Image + { + public: + QString extension; + unsigned length; + const char *data; + Image() { data = 0L; } + ~Image() { delete [] data; } + }; + QPtrVector m_images; + + // Opcode handling and painter methods. + + void walk( + Q_UINT32 bytes, + QDataStream &operands); + void skip( + Q_UINT32 bytes, + QDataStream &operands); + void invokeHandler( + Header &op, + Q_UINT32 bytes, + QDataStream &operands); + + void opAlignrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opAnchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opArcrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBlip(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBse(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opBstorecontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opCalloutrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opChildanchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientanchor(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientdata(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClientrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClienttextbox(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opClsid(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opColormru(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opConnectorrule(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDeletedpspl(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDg(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDgcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDgg(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opDggcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opOleobject(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opOpt(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opRegroupitems(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSelection(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSolvercontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSp(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpgr(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSpgrcontainer(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opSplitmenucolors(Header &op, Q_UINT32 bytes, QDataStream &operands); + void opTextbox(Header &op, Q_UINT32 bytes, QDataStream &operands); + + // Option handling. + + class Options + { + public: + Options(Msod &parent); + ~Options(); + void walk( + Q_UINT32 bytes, + QDataStream &operands); + + double m_rotation; + + Q_UINT32 m_lTxid; + + Q_UINT32 m_pib; + QString m_pibName; + Q_UINT32 m_pibFlags; + Q_UINT32 m_pictureId; + bool m_fNoHitTestPicture; + bool m_pictureGray; + bool m_pictureBiLevel; + bool m_pictureActive; + + Q_UINT32 m_geoLeft; + Q_UINT32 m_geoTop; + Q_UINT32 m_geoRight; + Q_UINT32 m_geoBottom; + Q_UINT32 m_shapePath; + QPointArray *m_pVertices; + bool m_fShadowOK; + bool m_f3DOK; + bool m_fLineOK; + bool m_fGTextOK; + bool m_fFillShadeShapeOK; + bool m_fFillOK; + + bool m_fFilled; + bool m_fHitTestFill; + bool m_fillShape; + bool m_fillUseRect; + bool m_fNoFillHitTest; + + Q_UINT32 m_lineColor; + Q_UINT32 m_lineBackColor; + Q_UINT32 m_lineType; + Q_UINT32 m_lineWidth; + + bool m_fArrowheadsOK; + bool m_fLine; + bool m_fHitTestLine; + bool m_lineFillShape; + bool m_fNoLineDrawDash; + + Q_UINT32 m_bWMode; + + bool m_fOleIcon; + bool m_fPreferRelativeResize; + bool m_fLockShapeType; + bool m_fDeleteAttachedObject; + bool m_fBackground; + + private: + Msod &m_parent; + + typedef struct + { + union + { + Q_UINT16 info; + struct + { + Q_UINT16 pid: 14; + Q_UINT16 fBid: 1; + Q_UINT16 fComplex: 1; + } fields; + } opcode; + Q_UINT32 value; + } Header; + + void initialise(); + double from1616ToDouble(Q_UINT32 value); + }; + friend class Msod::Options; + + Options *m_opt; +}; + +#endif diff --git a/filters/karbon/msod/msodimport.cc b/filters/karbon/msod/msodimport.cc new file mode 100644 index 000000000..9af11181c --- /dev/null +++ b/filters/karbon/msod/msodimport.cc @@ -0,0 +1,313 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MSODImportFactory; +K_EXPORT_COMPONENT_FACTORY( libmsodimport, MSODImportFactory( "kofficefilters" ) ) + +const int MSODImport::s_area = 30505; + +MSODImport::MSODImport( + KoFilter *, + const char *, + const QStringList&) : + KoEmbeddingFilter(), Msod(100) +{ +} + +MSODImport::~MSODImport() +{ +} + +KoFilter::ConversionStatus MSODImport::convert( const QCString& from, const QCString& to ) +{ + if (to != "application/x-karbon" || from != "image/x-msod") + return KoFilter::NotImplemented; + + // Get configuration data: the shape id, and any delay stream that we were given. + unsigned shapeId; + emit commSignalShapeID( shapeId ); + const char *delayStream = 0L; + emit commSignalDelayStream( delayStream ); + kdDebug( s_area ) << "##################################################################" << endl; + kdDebug( s_area ) << "shape id: " << shapeId << endl; + kdDebug( s_area ) << "delay stream: " << delayStream << endl; + kdDebug( s_area ) << "##################################################################" << endl; +/* + QString config = ""; // ###### FIXME: We aren't able to pass config data right now + QStringList args = QStringList::split(";", config); + unsigned i; + + kdDebug(s_area) << "MSODImport::filter: config: " << config << endl; + for (i = 0; i < args.count(); i++) + { + if (args[i].startsWith("shape-id=")) + { + shapeId = args[i].mid(9).toUInt(); + } + else + if (args[i].startsWith("delay-stream=")) + { + delayStream = (const char *)args[i].mid(13).toULong(); + } + else + { + kdError(s_area) << "Invalid argument: " << args[i] << endl; + return KoFilter::StupidError; + } + } +*/ + // doc header + m_text = ""; + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + m_text += " \n"; + + if (!parse(shapeId, m_chain->inputFile(), delayStream)) + return KoFilter::WrongFormat; + + // close doc + m_text += " \n"; + m_text += "\n"; + + emit sigProgress(100); + + KoStoreDevice* dev = m_chain->storageFile( "root", KoStore::Write ); + if (!dev) + { + kdError(s_area) << "Cannot open output file" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring ( m_text.utf8() ); + dev->writeBlock(cstring.data(), cstring.size()-1); + + return KoFilter::OK; +} + +void MSODImport::gotEllipse( + const DrawContext &/*dc*/, + QString /*type*/, + QPoint /*topLeft*/, + QSize /*halfAxes*/, + unsigned /*startAngle*/, + unsigned /*stopAngle*/) +{ +// ### TODO +#if 0 + m_text += "\n"; + m_text += " \n"; + m_text += " \n"; + m_text += " \n"; + m_text += "\n"; +#endif +} + +static void toRGB(int c, double &r, double &g, double &b) +{ + r = (c >> 16) / 255.0; + g = ((c >> 8) & 0xFF) / 255.0; + b = (c & 0xFF) / 255.0; +} + +void MSODImport::gotPicture( + unsigned key, + QString extension, + unsigned length, + const char *data) +{ +// ### TODO +#if 0 + kdDebug() << "##########################################MSODImport::gotPicture" << endl; + kdDebug() << "MSODImport::gotPicture -- " << extension << endl; + if ((extension == "wmf") || + (extension == "emf") || + (extension == "pict")) + { + int partRef = internalPartReference( QString::number( key ) ); + + if (partRef == -1) + { + m_embeddeeData = data; + m_embeddeeLength = length; + + QString srcMime( KoEmbeddingFilter::mimeTypeByExtension( extension ) ); + if ( srcMime == KMimeType::defaultMimeType() ) + kdWarning( s_area ) << "Couldn't determine the mimetype from the extension" << endl; + + QCString destMime; // intentionally empty, the filter manager will do the rest + KoFilter::ConversionStatus status; + partRef = embedPart( srcMime.latin1(), destMime, status, QString::number( key ) ); + + m_embeddeeData = 0; + m_embeddeeLength = 0; + + if ( status != KoFilter::OK ) { + kdWarning(s_area) << "Couldn't convert the image!" << endl; + return; + } + } + m_text += "\n"; + } + else + { + // We could not import it as a part. Try as an image. + KTempFile tempFile( QString::null, '.' + extension ); + tempFile.file()->writeBlock( data, length ); + tempFile.close(); + + m_text += "\n" + " \n" + " \n" + " \n" + "\n"; + + // Note that we cannot delete the file... + } +#endif +} + +void MSODImport::gotPolygon( + const DrawContext &dc, + const QPointArray &points) +{ + kdDebug(s_area) << "MSODImport::gotPolygon" << endl; + kdDebug(s_area) << QString::number(dc.m_penWidth, 16) << endl; + kdDebug(s_area) << dc.m_penStyle << endl; + m_text += "\n"; + if( dc.m_penWidth > 0 ) + { + m_text += "\n";// + QString::number(dc.m_penWidth, 16) + "\">\n"; + double r, g, b; + toRGB(dc.m_penColour, r, g, b); + m_text += "\n"; + m_text += "\n"; + } + else + m_text += "\n"; + m_text += "\n"; + double r, g, b; + toRGB(dc.m_brushColour, r, g, b); + m_text += "\n"; + m_text += "\n"; + + m_text += "\n"; + pointArray(points); + m_text += "\n"; + m_text += "\n"; +} + + +void MSODImport::gotPolyline( + const DrawContext &dc, + const QPointArray &points) +{ + kdDebug(s_area) << "MSODImport::gotPolyline" << endl; + return; // ### TODO + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + m_text += "\n"; + pointArray(points); + m_text += "\n"; + m_text += "\n"; +} + +void MSODImport::gotRectangle( + const DrawContext &dc, + const QPointArray &points) +{ +// ### TODO +#if 0 + QRect bounds = points.boundingRect(); + + m_text += "\n"; + m_text += "\n"; + pointArray(points); + m_text += " \n"; + m_text += " \n"; + m_text += " \n"; + m_text += "\n"; + m_text += "\n"; +#endif +} + +void MSODImport::savePartContents( QIODevice* file ) +{ + if ( m_embeddeeData != 0 && m_embeddeeLength != 0 ) + file->writeBlock( m_embeddeeData, m_embeddeeLength ); +} + +void MSODImport::pointArray( + const QPointArray &points) +{ + + m_text += "\n"; + kdDebug(s_area) << "\n" << endl; + for (unsigned int i = 1; i < points.count(); i++) + { + m_text += "\n"; + kdDebug(s_area) << "" << endl; + } + +} + +#include diff --git a/filters/karbon/msod/msodimport.h b/filters/karbon/msod/msodimport.h new file mode 100644 index 000000000..cb6aec16c --- /dev/null +++ b/filters/karbon/msod/msodimport.h @@ -0,0 +1,87 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#ifndef MSODIMPORT_H +#define MSODIMPORT_H + +#include +#include + +class MSODImport : + public KoEmbeddingFilter, protected Msod +{ + Q_OBJECT + +public: + MSODImport( + KoFilter *parent, + const char *name, + const QStringList&); + virtual ~MSODImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +protected: + + virtual void gotEllipse( + const DrawContext &dc, + QString type, + QPoint topLeft, + QSize halfAxes, + unsigned startAngle, + unsigned stopAngle); + virtual void gotPicture( + unsigned id, + QString extension, + unsigned length, + const char *data); + virtual void gotPolygon( + const DrawContext &dc, + const QPointArray &points); + virtual void gotPolyline( + const DrawContext &dc, + const QPointArray &points); + virtual void gotRectangle( + const DrawContext &dc, + const QPointArray &points); + +signals: + // Communication signals to the parent filters + void commSignalDelayStream( const char* delay ); + void commSignalShapeID( unsigned int& shapeID ); + +private: + virtual void savePartContents( QIODevice* file ); + + // Debug support. + static const int s_area; + + void pointArray( + const QPointArray &points); + QString m_text; + + // Embedded objects. + const char* m_embeddeeData; + int m_embeddeeLength; +}; + +#endif diff --git a/filters/karbon/msod/status.html b/filters/karbon/msod/status.html new file mode 100644 index 000000000..b9b2ce5d5 --- /dev/null +++ b/filters/karbon/msod/status.html @@ -0,0 +1,153 @@ + + + + + Karbon filters status: MSOD FILTER + + +  + +
    +
    +

    + Karbon filters status:   MSOD - MS Office Drawing +

    +
    + +
    + + + Import | + Export + + +


    +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Import MSOD for Karbon
    +
    +
    +
    Last update24 jan 2003
    Featuresvery basic
    Todomany things
    History24 jan 2003: port to Karbon
    Authors + Shaheed Haque +
    Links-
    Progress report -
    +
    +
    +Up + +


    + +
    +


    + + +
    + +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Export Karbon to MSOD

    +
    +
    Last update-
    Features-
    Todo-
    History-
    Authors-
    Links-
    Progress report -
    +
    +
    +Up + + + diff --git a/filters/karbon/oodraw/Makefile.am b/filters/karbon/oodraw/Makefile.am new file mode 100644 index 000000000..4cca1e325 --- /dev/null +++ b/filters/karbon/oodraw/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir)/../../liboofilter \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + $(all_includes) + +####### Files +kde_module_LTLIBRARIES = liboodrawimport.la + + +liboodrawimport_la_SOURCES = oodrawimport.cc +liboodrawimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +liboodrawimport_la_LIBADD = ../../liboofilter/liboofilter.la \ + ../../../karbon/libkarboncommon.la \ + $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = karbon_oodraw_import.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/oodraw/karbon_oodraw_import.desktop b/filters/karbon/oodraw/karbon_oodraw_import.desktop new file mode 100644 index 000000000..b634ba6ab --- /dev/null +++ b/filters/karbon/oodraw/karbon_oodraw_import.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Draw Import Filter for Karbon14 +Name[ar]=مِرْشَح استيراد رسم OpenOffice.org لـ Karbon14 +Name[bg]=Филтър за импортиране от OpenOffice.org Draw в Karbon14 +Name[br]=Sil enporzh OpenOffice.org Draw evit Karbon14 +Name[ca]=Filtre d'importació OpenOffice.org Draw per a Karbon14 +Name[cs]=OpenOffice.org Draw importní filtr pro Karbon14 +Name[cy]=Hidlen Fewnforio OpenOffice.org Draw ar gyfer Karbon14 +Name[da]=OpenOffice.org Draw importfilter for Karbon14 +Name[de]=Karbon14 OpenOffice.org-Draw-Importfilter +Name[el]=Φίλτρο εισαγωγής OpenOffice.org Draw για το Karbon14 +Name[eo]=OpenOffice.org desegno-importfiltrilo por Karbon14 +Name[es]=Filtro de importación de OpenOffice.org Draw para Karbon14 +Name[et]=Karbon14 OpenOffice.org Draw' impordifilter +Name[eu]=Karbon14-en OpenOffice.org Draw-en inportaziorako iragazkia +Name[fa]=پالایۀ واردات ترسیم OpenOffice.org برای Karbon14 +Name[fi]=OpenOffice.org-piirrostuontisuodin Karbon14:lle +Name[fr]=Filtre d'importation OpenOffice.org Draw de Karbon14 +Name[fy]=OpenOffice.org Draw-Ymportfilter foar Karbon14 +Name[gl]=Filtro de Importación de OpenOffice.org Draw para Karbon14 +Name[he]=מסנן לייבוא מ־OpenOffice.org Draw ל־Karbon14 +Name[hi]=कार्बन 14 के लिए ओपन-ऑफ़िस.ऑर्ग आयात छननी +Name[hr]=OpenOffice.org Draw filtar uvoza za Karbon14 +Name[hu]=OpenOffice.org Draw importszűrő a Karbon14-hez +Name[is]=OpenOffice.org Draw innflutningssía fyrir Karbon14 +Name[it]=Filtro di importazione OpenOffice.org Draw per Karbon14 +Name[ja]=Karbon14 OpenOffice.org Draw インポートフィルタ +Name[km]=តម្រង​នាំចូល OpenOffice.org Draw សម្រាប់ Karbon14 +Name[lt]=OpenOffice.org Draw importavimo filtras skirtas Karbon14 +Name[lv]=OpenOffice.org Draw importa filtrs priekš Karbon14 +Name[ms]=Penapis Import OpenOffice.org Draw bagi Karbon14 +Name[nb]=OpenOffice.org Draw-importfilter for Karbon14 +Name[nds]="OpenOffice.org Draw"-Importfilter för Karbon14 +Name[ne]=कार्बन१४का लागि OpenOffice.org रेखाचित्र आयात फिल्टर +Name[nl]=OpenOffice.org Draw-importfilter voor Karbon14 +Name[nn]=OpenOffice.org Draw-importfilter for Karbon14 +Name[pl]=Filtr importu z OpenOffice.org Draw do Karbon14 +Name[pt]=Filtro de Importação de OpenOffice.org Draw para o Karbon14 +Name[pt_BR]=Filtro de Importação OpenOffice.org Draw para o Karbon14 +Name[ru]=Фильтр импорта рисунков OpenOffice.org в Karbon14 +Name[se]=Karbon14:a OpenOffice.org Draw-sisafievrridansilli +Name[sk]=Filter pre import OpenOffice.org Draw pre Karbon14 +Name[sl]=Uvozni filter OpenOffice.org Draw za Karbon14 +Name[sr]=Karbon14-ов филтер за увоз из OpenOffice.org Draw-а +Name[sr@Latn]=Karbon14-ov filter za uvoz iz OpenOffice.org Draw-a +Name[sv]=OpenOffice.org Draw-importfilter för Karbon-14 +Name[ta]=open office.org வரைதல் இறக்குமதி வடிகட்டி karbon 14 +Name[tg]=Филтри Воридоти OpenOffice.org Расмкашӣ барои Karbon14 +Name[tr]=Karbon14 için OpenOffice.org Impress Alma Filtresi +Name[uk]=Фільтр імпорту малюнків OpenOffice.org у Karbon14 +Name[uz]=Karbon14 uchun OpenOffice.org Draw import filteri +Name[uz@cyrillic]=Karbon14 учун OpenOffice.org Draw импорт филтери +Name[zh_CN]=Karbon14 的 OpenOffice.org Draw 导入过滤器 +Name[zh_TW]=Karbon14 的 OpenOffice.org Draw 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=application/vnd.sun.xml.draw +X-KDE-Weight=1 +X-KDE-Library=liboodrawimport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/oodraw/oodrawimport.cc b/filters/karbon/oodraw/oodrawimport.cc new file mode 100644 index 000000000..f52ed5b8b --- /dev/null +++ b/filters/karbon/oodraw/oodrawimport.cc @@ -0,0 +1,757 @@ +/* This file is part of the KDE project + Copyright (c) 2003 Rob Buis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "oodrawimport.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +typedef KGenericFactory OoDrawImportFactory; +K_EXPORT_COMPONENT_FACTORY( liboodrawimport, OoDrawImportFactory( "kofficefilters" ) ) + + +OoDrawImport::OoDrawImport( KoFilter *, const char *, const QStringList & ) + : KoFilter(), + m_styles( 23, true ), + m_styleStack( ooNS::style, ooNS::fo ) +{ + m_styles.setAutoDelete( true ); +} + +OoDrawImport::~OoDrawImport() +{ +} + +KoFilter::ConversionStatus OoDrawImport::convert( QCString const & from, QCString const & to ) +{ + kdDebug() << "Entering Oodraw Import filter: " << from << " - " << to << endl; + + if( from != "application/vnd.sun.xml.draw" || to != "application/x-karbon" ) + { + kdWarning() << "Invalid mimetypes " << from << " " << to << endl; + return KoFilter::NotImplemented; + } + + m_zip = new KZip( m_chain->inputFile() ); + + if ( !m_zip->open( IO_ReadOnly ) ) + { + kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl; + delete m_zip; + return KoFilter::FileNotFound; + } + + KoFilter::ConversionStatus preStatus = openFile(); + + if( preStatus != KoFilter::OK ) + { + m_zip->close(); + delete m_zip; + return preStatus; + } +/*QDomDocument docinfo; + createDocumentInfo( docinfo ); + +// store document info +KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); +if( out ) +{ +QCString info = docinfo.toCString(); +//kdDebug() << " info :" << info << endl; +// WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. +out->writeBlock( info , info.length() ); +}*/ + QDomDocument docinfo; + createDocumentInfo( docinfo ); + // store document info + KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); + if( out ) + { + QCString info = docinfo.toCString(); + //kdDebug(30518) << " info :" << info << endl; + // WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. + out->writeBlock( info , info.length() ); + } + + convert(); + QDomDocument outdoc = m_document.saveXML(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = outdoc.createElement( "PAPER" ); + outdoc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document.width() ); + paper.setAttribute( "height", m_document.height() ); + + // store document content + out = m_chain->storageFile( "maindoc.xml", KoStore::Write ); + if( out ) + { + QCString content = outdoc.toCString(); + kdDebug() << " content :" << content << endl; + out->writeBlock( content , content.length() ); + } + m_zip->close(); + delete m_zip; + + kdDebug() << "######################## OoDrawImport::convert done ####################" << endl; + + return KoFilter::OK; +} + +// Very related to OoWriterImport::createDocumentInfo +void OoDrawImport::createDocumentInfo( QDomDocument &docinfo ) +{ + docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" ); + + OoUtils::createDocumentInfo(m_meta, docinfo); + //kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl; +} + + +// Very related to OoWriterImport::openFile() +KoFilter::ConversionStatus OoDrawImport::openFile() +{ + KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content ); + if ( status != KoFilter::OK ) + { + kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl; + return status; + } + + // We do not stop if the following calls fail. + QDomDocument styles; + loadAndParse( "styles.xml", styles ); + loadAndParse( "meta.xml", m_meta ); + loadAndParse( "settings.xml", m_settings ); + + emit sigProgress( 10 ); + createStyleMap( styles ); + + return KoFilter::OK; +} + +void OoDrawImport::convert() +{ + m_document.saveAsPath( false ); + + QDomElement content = m_content.documentElement(); + + // content.xml contains some automatic-styles that we need to store + QDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); + if( body.isNull() ) + return; + + // we take the settings of the first slide for the whole document. + QDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); + if( drawPage.isNull() ) // no pages? give up. + return; + + QDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", QString::null )]; + QDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", QString::null )]; + QDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" ).toElement(); + + if( properties.isNull() ) + { + m_document.setWidth( 550.0 ); + m_document.setHeight( 841.0 ); + } + else + { + m_document.setWidth( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", QString::null ) ) ); + m_document.setHeight( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", QString::null ) ) ); + } + + // parse all pages + for( QDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() ) + { + QDomElement dp = drawPage.toElement(); + m_styleStack.clear(); // remove all styles + fillStyleStack( dp ); + //m_styleStack.setPageMark(); + + // set the pagetitle + //QDomElement titleElement = doc.createElement( "Title" ); + //titleElement.setAttribute( "title", dp.attributeNS( "name" ) ); + //pageTitleElement.appendChild( titleElement ); + + parseGroup( 0L, dp ); + } +} + + +KoFilter::ConversionStatus OoDrawImport::loadAndParse(const QString& filename, QDomDocument& doc) +{ + return OoUtils::loadAndParse( filename, doc, m_zip); +} + +void +OoDrawImport::parseGroup( VGroup *parent, const QDomElement& parentobject ) +{ + // parse all objects + for( QDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() ) + { + QDomElement o = object.toElement(); + if( o.namespaceURI() != ooNS::draw ) continue; + QString name = o.localName(); + QString drawID = o.attributeNS( ooNS::draw, "id", QString::null ); + VObject *obj = 0L; + + if( name == "g" ) // polyline + { + storeObjectStyles( o ); + VGroup *group = new VGroup( parent ); + appendPen( *group ); + appendBrush( *group ); + obj = group; + parseGroup( group, o ); + } + else if( name == "rect" ) // rectangle + { + storeObjectStyles( o ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + int corner = static_cast( KoUnit::parseValue( o.attributeNS( ooNS::draw, "corner-radius", QString::null ) ) ); + VRectangle *rect = new VRectangle( parent, KoPoint( x, y ), w, h, corner ); + appendPen( *rect ); + appendBrush( *rect ); + obj = rect; + } + else if( name == "circle" || name == "ellipse" ) + { + storeObjectStyles( o ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ) - h; + double start = o.attributeNS( ooNS::draw, "start-angle", QString::null ).toDouble(); + double end = o.attributeNS( ooNS::draw, "end-angle", QString::null ).toDouble(); + QString kind = o.attributeNS( ooNS::draw, "kind", QString::null ); + VEllipse::VEllipseType type = VEllipse::full; + if( !kind.isEmpty() ) + { + if( kind == "section" ) + type = VEllipse::cut; + else if( kind == "cut" ) + type = VEllipse::section; + else if( kind == "arc" ) + type = VEllipse::arc; + } + VEllipse *ellipse = new VEllipse( parent, KoPoint( x, y ), w, h, type, start, end ); + appendPen( *ellipse ); + // arc has no brush + if( kind != "arc" ) + appendBrush( *ellipse ); + obj = ellipse; + } + else if( name == "line" ) // line + { + storeObjectStyles( o ); + VPath *line = new VPath( parent ); + double x1 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x1", QString::null ) ); + double y1 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y1", QString::null ) ) ); + double x2 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x2", QString::null ) ); + double y2 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y2", QString::null ) ) ); + line->moveTo( KoPoint( x1, y1 ) ); + line->lineTo( KoPoint( x2, y2 ) ); + appendPen( *line ); + appendBrush( *line ); + obj = line; + } + else if( name == "polyline" ) // polyline + { + storeObjectStyles( o ); + VPath *polyline = new VPath( parent ); + appendPoints( *polyline, o); + appendPen( *polyline ); + appendBrush( *polyline ); + obj = polyline; + } + else if( name == "polygon" ) // polygon + { + storeObjectStyles( o ); + //VPolygon *polygon = new VPolygon( parent ); + //polygon->load( o ); + VPath *polygon = new VPath( parent ); + appendPoints( *polygon, o ); + appendPen( *polygon ); + appendBrush( *polygon ); + obj = polygon; + } + else if( name == "path" ) // path + { + storeObjectStyles( o ); + VPath *path = new VPath( parent ); + path->loadSvgPath( o.attributeNS( ooNS::svg, "d", QString::null ) ); + KoRect rect = parseViewBox( o ); + double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", QString::null ) ) ); + double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", QString::null ) ); + QWMatrix mat; + mat.translate( x, y ); + mat.scale( w / rect.width(), -h / rect.height() ); + path->transform( mat ); + appendPen( *path ); + appendBrush( *path ); + obj = path; + } +/*else if( name == "draw:image" ) // image +{ +storeObjectStyles( o ); +e = doc.createElement( "OBJECT" ); +e.setAttribute( "type", 0 ); +appendImage( doc, e, pictureElement, o ); +}*/ + else + { + kdDebug() << "Unsupported object '" << name << "'" << endl; + continue; + } + if( parent && obj ) + parent->append( obj ); + else if( obj ) + m_document.append( obj ); + } +} + +void +OoDrawImport::appendPen( VObject &obj ) +{ + if( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" ) ) + { + VStroke stroke; + + if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" ) + stroke.setType( VStroke::none ); + else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" ) + stroke.setType( VStroke::solid ); + else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" ) + { + QValueList dashes; + stroke.setType( VStroke::solid ); + QString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" ); + if( style == "Ultrafine Dashed" || + style == "Fine Dashed (var)" || style == "Dashed (var)" ) + stroke.dashPattern().setArray( dashes << 2 << 2 ); + else if( style == "Fine Dashed" ) + stroke.dashPattern().setArray( dashes << 10 << 10 ); + else if( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" || + style == "Line with Fine Dots" ) + stroke.dashPattern().setArray( dashes << 2 << 10 ); + else if( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" ) + stroke.dashPattern().setArray( dashes << 3 << 3 ); + else if( style == "2 Dots 1 Dash" ) + stroke.dashPattern().setArray( dashes << 2 << 1 ); + } + if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) ) + { + double lwidth = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ); + if( lwidth == 0 ) + lwidth = 1.0; + stroke.setLineWidth( lwidth ); + } + if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) ) + { + VColor c; + parseColor( c, m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) ); + stroke.setColor( c ); + } + + obj.setStroke( stroke ); + } +} + +void +OoDrawImport::appendBrush( VObject &obj ) +{ + if( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) ) + { + const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" ); + VFill f; + + if( fill == "solid" ) + { + f.setType( VFill::solid ); + if( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) ) + { + VColor c; + parseColor( c, m_styleStack.attributeNS( ooNS::draw, "fill-color" ) ); + f.setColor( c ); + } + } + else if( fill == "gradient" ) + { + VGradient gradient; + gradient.clearStops(); + gradient.setRepeatMethod( VGradient::none ); + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" ); + + QDomElement* draw = m_draws[style]; + if( draw ) + { + double border = 0.0; + if( draw->hasAttributeNS( ooNS::draw, "border" ) ) + border += draw->attributeNS( ooNS::draw, "border", QString::null ).remove( '%' ).toDouble() / 100.0; + VColor c; + parseColor( c, draw->attributeNS( ooNS::draw, "start-color", QString::null ) ); + gradient.addStop( c, border, 0.5 ); + parseColor( c, draw->attributeNS( ooNS::draw, "end-color", QString::null ) ); + gradient.addStop( c, 1.0, 0.5 ); + + QString type = draw->attributeNS( ooNS::draw, "style", QString::null ); + if( type == "linear" || type == "axial" ) + { + gradient.setType( VGradient::linear ); + int angle = draw->attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + KoRect rect = obj.boundingBox(); + KoPoint origin, vector; + // nearAngle should now be one of: 0, 45, 90, 135, 180... + kdDebug() << "nearAngle: " << nearAngle << endl; + if( nearAngle == 0 || nearAngle == 180 ) + { + origin.setX( rect.x() + rect.width() ); + origin.setY( rect.y() + rect.height()); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() ); + } + else if( nearAngle == 90 || nearAngle == 270 ) + { + origin.setX( rect.x() ); + origin.setY( rect.y() + rect.height() ); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() + rect.height() ); + } + else if( nearAngle == 45 || nearAngle == 225 ) + { + origin.setX( rect.x() ); + origin.setY( rect.y() ); + vector.setX( rect.x() + rect.width() ); + vector.setY( rect.y() + rect.height() ); + } + else if( nearAngle == 135 || nearAngle == 315 ) + { + origin.setX( rect.x() + rect.width() ); + origin.setY( rect.y() + rect.height() ); + vector.setX( rect.x() ); + vector.setY( rect.y() ); + } + + gradient.setOrigin( origin ); + gradient.setVector( vector ); + } + else if( type == "radial" || type == "ellipsoid" ) + { + gradient.setType( VGradient::radial ); +//else if( type == "square" || type == "rectangular" ) +//gradient.setAttribute( "type", 6 ); // rectangle +//else if( type == "axial" ) +//gradient.setAttribute( "type", 7 ); // pipecross + + // Hard to map between x- and y-center settings of oodraw + // and (un-)balanced settings of kpresenter. Let's try it. + double x, y; + if( draw->hasAttributeNS( ooNS::draw, "cx" ) ) + x = draw->attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toDouble() / 100.0; + else + x = 0.5; + + if( draw->hasAttributeNS( ooNS::draw, "cy" ) ) + y = draw->attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toDouble() / 100.0; + else + y = 0.5; + + KoRect rect = obj.boundingBox(); + gradient.setOrigin( KoPoint( rect.x() + x * rect.width(), + rect.y() + y * rect.height() ) ); + gradient.setFocalPoint( KoPoint( rect.x() + x * rect.width(), + rect.y() + y * rect.height() ) ); + gradient.setVector( KoPoint( rect.x() + rect.width(), + rect.y() + y * rect.height() ) ); + } + f.gradient() = gradient; + f.setType( VFill::grad ); + } + } + obj.setFill( f ); + } +/*else if( fill == "hatch" ) +{ +QDomElement brush = doc.createElement( "BRUSH" ); +QString style = m_styleStack.attributeNS( "fill-hatch-name" ); +if( style == "Black 0 Degrees" ) +brush.setAttribute( "style", 9 ); +else if( style == "Black 90 Degrees" ) +brush.setAttribute( "style", 10 ); +else if( style == "Red Crossed 0 Degrees" || style == "Blue Crossed 0 Degrees" ) +brush.setAttribute( "style", 11 ); +else if( style == "Black 45 Degrees" || style == "Black 45 Degrees Wide" ) +brush.setAttribute( "style", 12 ); +else if( style == "Black -45 Degrees" ) +brush.setAttribute( "style", 13 ); +else if( style == "Red Crossed 45 Degrees" || style == "Blue Crossed 45 Degrees" ) +brush.setAttribute( "style", 14 ); + +QDomElement* draw = m_draws[style]; +if( draw && draw->hasAttributeNS( "color" ) ) +brush.setAttribute( "color", draw->attributeNS( "color" ) ); +e.appendChild( brush ); +}*/ +} + +void +OoDrawImport::createStyleMap( QDomDocument &docstyles ) +{ + QDomElement styles = docstyles.documentElement(); + if( styles.isNull() ) + return; + + QDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); + if( !fixedStyles.isNull() ) + { + insertDraws( fixedStyles.toElement() ); + insertStyles( fixedStyles.toElement() ); + } + QDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); + if( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); + if( !masterStyles.isNull() ) + insertStyles( masterStyles.toElement() ); +} + +void +OoDrawImport::insertDraws( const QDomElement& styles ) +{ + for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::draw, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::draw, "name", QString::null ); + m_draws.insert( name, new QDomElement( e ) ); + } +} + + +void +OoDrawImport::insertStyles( const QDomElement& styles ) +{ + for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + + if( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::style, "name", QString::null ); + m_styles.insert( name, new QDomElement( e ) ); + //kdDebug() << "Style: '" << name << "' loaded " << endl; + } +} + +void +OoDrawImport::fillStyleStack( const QDomElement& object ) +{ + // find all styles associated with an object and push them on the stack + if( object.hasAttributeNS( ooNS::presentation, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::draw, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::draw, "text-style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", QString::null )] ); + + if( object.hasAttributeNS( ooNS::text, "style-name" ) ) + addStyles( m_styles[object.attributeNS( ooNS::text, "style-name", QString::null )] ); +} + +void +OoDrawImport::addStyles( const QDomElement* style ) +{ + // this function is necessary as parent styles can have parents themself + if( style->hasAttributeNS( ooNS::style, "parent-style-name" ) ) + addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", QString::null )] ); + + m_styleStack.push( *style ); +} + +void +OoDrawImport::storeObjectStyles( const QDomElement& object ) +{ + //m_styleStack.clearPageMark(); // remove styles of previous object + fillStyleStack( object ); + //m_styleStack.setObjectMark(); +} + +KoRect +OoDrawImport::parseViewBox( const QDomElement& object ) +{ + KoRect rect; + if( !object.attributeNS( ooNS::svg, "viewBox", QString::null ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( object.attributeNS( ooNS::svg, "viewBox", QString::null ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + rect.setX( points[0].toFloat() ); + rect.setY( points[1].toFloat() ); + rect.setWidth( points[2].toFloat() ); + rect.setHeight( points[3].toFloat() ); + } + return rect; +} + +void +OoDrawImport::appendPoints(VPath &path, const QDomElement& object) +{ + double x = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", QString::null ) ); + double y = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", QString::null ) ); + double w = KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", QString::null ) ); + double h = KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", QString::null ) ); + + KoRect rect = parseViewBox( object ); + rect.setX( rect.x() + x ); + rect.setY( rect.y() + y ); + + QStringList ptList = QStringList::split( ' ', object.attributeNS( ooNS::draw, "points", QString::null ) ); + + QString pt_x, pt_y; + double tmp_x, tmp_y; + KoPoint point; + bool bFirst = true; + for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it ) + { + tmp_x = rect.x() + ( (*it).section( ',', 0, 0 ).toInt() * w ) / rect.width(); + tmp_y = rect.y() + ( (*it).section( ',', 1, 1 ).toInt() * h ) / rect.height(); + + point.setX( tmp_x ); + point.setY( ymirror( tmp_y ) ); + if( bFirst ) + { + path.moveTo( point ); + bFirst = false; + } + else + path.lineTo( point ); + } +} + +void +OoDrawImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + //else + // c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +double +OoDrawImport::ymirror( double y ) +{ + return m_document.height() - y; +} + +#include "oodrawimport.moc" diff --git a/filters/karbon/oodraw/oodrawimport.h b/filters/karbon/oodraw/oodrawimport.h new file mode 100644 index 000000000..06e664ac4 --- /dev/null +++ b/filters/karbon/oodraw/oodrawimport.h @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (c) 2003 Rob Buis + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef OODRAW_IMPORT_H__ +#define OODRAW_IMPORT_H__ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +class KZip; + +class VGroup; + +class OoDrawImport : public KoFilter +{ + Q_OBJECT +public: + OoDrawImport( KoFilter *parent, const char *name, const QStringList & ); + virtual ~OoDrawImport(); + + virtual KoFilter::ConversionStatus convert( QCString const & from, QCString const & to ); + +private: + void createDocumentInfo( QDomDocument &docinfo ); + + void createStyleMap( QDomDocument &docstyles ); + void insertStyles( const QDomElement& styles ); + void insertDraws( const QDomElement& styles ); + void fillStyleStack( const QDomElement& object ); + void addStyles( const QDomElement* style ); + void storeObjectStyles( const QDomElement& object ); + void appendPen( VObject &obj ); + void appendBrush( VObject &obj ); + void appendPoints(VPath &path, const QDomElement& object); + void convert(); + void parseGroup( VGroup *parent, const QDomElement& object ); + void parseColor( VColor &color, const QString &s ); + double ymirror( double y ); + KoRect parseViewBox( const QDomElement& object ); + + KoFilter::ConversionStatus openFile(); + KoFilter::ConversionStatus loadAndParse(const QString& filename, QDomDocument& doc); + + VDocument m_document; + QDomDocument m_content; + QDomDocument m_meta; + QDomDocument m_settings; + QDict m_styles, m_draws; + KoStyleStack m_styleStack; + KZip * m_zip; + +}; + +#endif diff --git a/filters/karbon/png/Makefile.am b/filters/karbon/png/Makefile.am new file mode 100644 index 000000000..5d8a4efb0 --- /dev/null +++ b/filters/karbon/png/Makefile.am @@ -0,0 +1,27 @@ +kde_module_LTLIBRARIES = libkarbonpngexport.la + +libkarbonpngexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonpngexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/render \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_png_export.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + pngexport.h + +libkarbonpngexport_la_SOURCES = \ + pngexport.cc + +libkarbonpngexport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/png/karbon_png_export.desktop b/filters/karbon/png/karbon_png_export.desktop new file mode 100644 index 000000000..e3715bc0b --- /dev/null +++ b/filters/karbon/png/karbon_png_export.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Icon= +Name=Karbon14 PNG Export Filter +Name[af]=Karbon14 Png Voer uit Filter +Name[ar]=مِرْشَح تصدير PNG لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в PNG +Name[br]=Sil ezporzh PNG evit Karbon14 +Name[ca]=Filtre d'exportació PNG per a Karbon14 +Name[cs]=Exportní filtr do formátu PNG pro Karbon14 +Name[cy]=Hidlen Allforio PNG Karbon14 +Name[da]=Karbon14 SVG-eksportfilter +Name[de]=Karbon14 PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του Karbon14 +Name[eo]=Karbon-PNG-eksportfiltrilo +Name[es]=Filtro de exportación Karbon14 PNG +Name[et]=Karbon14 PNG ekspordifilter +Name[eu]=Karbon14-en PNG esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Karbon14 PNG +Name[fi]=Karbon14 PNG -vientisuodin +Name[fr]=Filtre d'exportation PNG de Karbon 14 +Name[fy]=PNG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála PNG Karbon14 +Name[gl]=Filtro de Exportación de PNG para Karbon14 +Name[he]=מסנן ייצוא מ־Karbon14 ל־PNG +Name[hr]=Karbon14 SVG filtar izvoza +Name[hu]=Karbon14 PNG exportszűrő +Name[is]=Karbon14 PNG útflutningssía +Name[it]=Filtro di esportazione PNG per Karbon14 +Name[ja]=Karbon14 PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ Karbon14 +Name[lo]=ຕົວຕອງການສົ່ງອອກ PNG ຂອງ Karbon14 +Name[lt]=Karbon14 PNG eksportavimo filtras +Name[lv]=Karbon14 PNG eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 PNG +Name[mt]=Filtru għall-esportazzjoni ta' PNG minn ġo Karbon14 +Name[nb]=PNG-eksportfilter for Karbon14 +Name[nds]=PNG-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ पीएनजी निर्यात फिल्टर +Name[nl]=PNG-exportfilter voor Karbon14 +Name[nn]=PNG-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu PNG z Karbon14 +Name[pt]=Filtro de Exportação de PNG para o Karbon14 +Name[pt_BR]=Filtro de Exportação PNG do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru SVG +Name[ru]=Фильтр экспорта рисунков Karbon в PNG +Name[se]=Karbon14:a PNG-olggosfievrridansilli +Name[sk]=PNG filter pre export z Karbon14 +Name[sl]=Izvozni filter PNG za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у PNG +Name[sr@Latn]=Karbon14-ov filter za izvoz u PNG +Name[sv]=Karbon14 PNG-exportfilter +Name[ta]=Karbon 14 PNG S ஏற்றுமதி வடிகட்டி +Name[tg]=Karbon14 PNG Филтри Содирот +Name[th]=ตัวกรองการส่งออก PNG ของ Karbon14 +Name[tr]=Karbon14 PNG Aktarma Filtresi +Name[uk]=Фільтр експорту SVG для Karbon14 +Name[uz]=Karbon14 PNG eksport filteri +Name[uz@cyrillic]=Karbon14 PNG экспорт филтери +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 PNG +Name[zh_CN]=Karbon14 PNG 导出过滤器 +Name[zh_TW]=Karbon14 EPS 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/png +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonpngexport +X-KDE-Weight=1 diff --git a/filters/karbon/png/pngexport.cc b/filters/karbon/png/pngexport.cc new file mode 100644 index 000000000..652074e93 --- /dev/null +++ b/filters/karbon/png/pngexport.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pngexport.h" +#include "vdocument.h" +#include "vselection.h" +#include "vkopainter.h" +#include "vlayer.h" +#include "vcomputeboundingbox.h" + +#include + + +typedef KGenericFactory PngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonpngexport, PngExportFactory( "kofficefilters" ) ) + + +PngExport::PngExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ +} + +KoFilter::ConversionStatus +PngExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/png" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + + // calculate the documents bounding box + VComputeBoundingBox bbox( true ); + doc.accept( bbox ); + const KoRect &rect = bbox.boundingRect(); + + // create image with correct width and height + QImage img( int( rect.width() ), int( rect.height() ), 32 ); + //img.setAlphaBuffer( true ); + + // Create painter and set up objects to draw + VKoPainter p( img.bits(), rect.width(), rect.height() ); + p.clear( qRgba( 0xFF, 0xFF, 0xFF, 0xFF ) ); + p.setWorldMatrix( QWMatrix().translate( -rect.x(), -rect.y() ) ); + + doc.draw( &p, &rect ); + + QImage image = img.swapRGB(); + QImage mirrored = image.mirror( false, true ); + // save png + mirrored.save( m_chain->outputFile(), "PNG" ); + + return KoFilter::OK; +} + +#include "pngexport.moc" + diff --git a/filters/karbon/png/pngexport.h b/filters/karbon/png/pngexport.h new file mode 100644 index 000000000..a14e81c83 --- /dev/null +++ b/filters/karbon/png/pngexport.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __PNGEXPORT_H__ +#define __PNGEXPORT_H__ + +#include + +#include "vvisitor.h" + +class PngExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + PngExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~PngExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif + diff --git a/filters/karbon/svg/Makefile.am b/filters/karbon/svg/Makefile.am new file mode 100644 index 000000000..a1b01f9bd --- /dev/null +++ b/filters/karbon/svg/Makefile.am @@ -0,0 +1,34 @@ +kde_module_LTLIBRARIES = libkarbonsvgexport.la libkarbonsvgimport.la + +libkarbonsvgexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonsvgexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonsvgimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonsvgimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_svg_export.desktop karbon_svg_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + svgexport.h + +libkarbonsvgexport_la_SOURCES = \ + svgexport.cc + +METASOURCES = AUTO + +libkarbonsvgimport_la_SOURCES = \ + svgimport.cc + diff --git a/filters/karbon/svg/TODO b/filters/karbon/svg/TODO new file mode 100644 index 000000000..999f37a62 --- /dev/null +++ b/filters/karbon/svg/TODO @@ -0,0 +1,8 @@ +SVG export +- patterns +- text + +SVG import +- units (cm, mm) +- trafo's +- fix text diff --git a/filters/karbon/svg/color.h b/filters/karbon/svg/color.h new file mode 100644 index 000000000..bfdc93c6e --- /dev/null +++ b/filters/karbon/svg/color.h @@ -0,0 +1,306 @@ + +#define TORGB( red, green, blue ) \ +{ \ + r = red; \ + b = blue; \ + g = green; \ +} + +void keywordToRGB( QString rgbColor, int &r, int &g, int &b ) +{ + if( rgbColor == "aliceblue" ) + TORGB( 240, 248, 255) + else if( rgbColor == "antiquewhite" ) + TORGB( 250, 235, 215) + else if( rgbColor == "aqua" ) + TORGB( 0, 255, 255) + else if( rgbColor == "aquamarine" ) + TORGB( 127, 255, 212 ) + else if( rgbColor == "azure" ) + TORGB( 240, 255, 255 ) + else if( rgbColor == "beige" ) + TORGB( 245, 245, 220 ) + else if( rgbColor == "bisque" ) + TORGB( 255, 228, 196 ) + else if( rgbColor == "black" ) + TORGB( 0, 0, 0 ) + else if( rgbColor == "blanchedalmond" ) + TORGB( 255, 235, 205 ) + else if( rgbColor == "blue" ) + TORGB( 0, 0, 255 ) + else if( rgbColor == "blueviolet" ) + TORGB( 138, 43, 226 ) + else if( rgbColor == "brown" ) + TORGB( 165, 42, 42 ) + else if( rgbColor == "burlywood" ) + TORGB( 222, 184, 135 ) + else if( rgbColor == "cadetblue" ) + TORGB( 95, 158, 160 ) + else if( rgbColor == "chartreuse" ) + TORGB( 127, 255, 0 ) + else if( rgbColor == "chocolate" ) + TORGB( 210, 105, 30 ) + else if( rgbColor == "coral" ) + TORGB( 255, 127, 80 ) + else if( rgbColor == "cornflowerblue" ) + TORGB( 100, 149, 237 ) + else if( rgbColor == "cornsilk" ) + TORGB( 255, 248, 220 ) + else if( rgbColor == "crimson" ) + TORGB( 220, 20, 60 ) + else if( rgbColor == "cyan" ) + TORGB( 0, 255, 255 ) + else if( rgbColor == "darkblue" ) + TORGB( 0, 0, 139 ) + else if( rgbColor == "darkcyan" ) + TORGB( 0, 139, 139 ) + else if( rgbColor == "darkgoldenrod" ) + TORGB( 184, 134, 11 ) + else if( rgbColor == "darkgray" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgrey" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgreen" ) + TORGB( 0, 100, 0 ) + else if( rgbColor == "darkkhaki" ) + TORGB( 189, 183, 107 ) + else if( rgbColor == "darkmagenta" ) + TORGB( 139, 0, 139 ) + else if( rgbColor == "darkolivegreen" ) + TORGB( 85, 107, 47 ) + else if( rgbColor == "darkorange" ) + TORGB( 255, 140, 0 ) + else if( rgbColor == "darkorchid" ) + TORGB( 153, 50, 204 ) + else if( rgbColor == "darkred" ) + TORGB( 139, 0, 0 ) + else if( rgbColor == "darksalmon" ) + TORGB( 233, 150, 122 ) + else if( rgbColor == "darkseagreen" ) + TORGB( 143, 188, 143 ) + else if( rgbColor == "darkslateblue" ) + TORGB( 72, 61, 139 ) + else if( rgbColor == "darkslategray" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkslategrey" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkturquoise" ) + TORGB( 0, 206, 209 ) + else if( rgbColor == "darkviolet" ) + TORGB( 148, 0, 211 ) + else if( rgbColor == "deeppink" ) + TORGB( 255, 20, 147 ) + else if( rgbColor == "deepskyblue" ) + TORGB( 0, 191, 255 ) + else if( rgbColor == "dimgray" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dimgrey" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dodgerblue" ) + TORGB( 30, 144, 255 ) + else if( rgbColor == "firebrick" ) + TORGB( 178, 34, 34 ) + else if( rgbColor == "floralwhite" ) + TORGB( 255, 250, 240 ) + else if( rgbColor == "forestgreen" ) + TORGB( 34, 139, 34 ) + else if( rgbColor == "fuchsia" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "gainsboro" ) + TORGB( 220, 220, 220 ) + else if( rgbColor == "ghostwhite" ) + TORGB( 248, 248, 255 ) + else if( rgbColor == "gold" ) + TORGB( 255, 215, 0 ) + else if( rgbColor == "goldenrod" ) + TORGB( 218, 165, 32 ) + else if( rgbColor == "gray" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "grey" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "green" ) + TORGB( 0, 128, 0 ) + else if( rgbColor == "greenyellow" ) + TORGB( 173, 255, 47 ) + else if( rgbColor == "honeydew" ) + TORGB( 240, 255, 240 ) + else if( rgbColor == "hotpink" ) + TORGB( 255, 105, 180 ) + else if( rgbColor == "indianred" ) + TORGB( 205, 92, 92 ) + else if( rgbColor == "indigo" ) + TORGB( 75, 0, 130 ) + else if( rgbColor == "ivory" ) + TORGB( 255, 255, 240 ) + else if( rgbColor == "khaki" ) + TORGB( 240, 230, 140 ) + else if( rgbColor == "lavender" ) + TORGB( 230, 230, 250 ) + else if( rgbColor == "lavenderblush" ) + TORGB( 255, 240, 245 ) + else if( rgbColor == "lawngreen" ) + TORGB( 124, 252, 0 ) + else if( rgbColor == "lemonchiffon" ) + TORGB( 255, 250, 205 ) + else if( rgbColor == "lightblue" ) + TORGB( 173, 216, 230 ) + else if( rgbColor == "lightcoral" ) + TORGB( 240, 128, 128 ) + else if( rgbColor == "lightcyan" ) + TORGB( 224, 255, 255 ) + else if( rgbColor == "lightgoldenrodyellow" ) + TORGB( 250, 250, 210 ) + else if( rgbColor == "lightgray" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgrey" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgreen" ) + TORGB( 144, 238, 144 ) + else if( rgbColor == "lightpink" ) + TORGB( 255, 182, 193 ) + else if( rgbColor == "lightsalmon" ) + TORGB( 255, 160, 122 ) + else if( rgbColor == "lightseagreen" ) + TORGB( 32, 178, 170 ) + else if( rgbColor == "lightskyblue" ) + TORGB( 135, 206, 250 ) + else if( rgbColor == "lightslategray" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightslategrey" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightsteelblue" ) + TORGB( 176, 196, 222 ) + else if( rgbColor == "lightyellow" ) + TORGB( 255, 255, 224 ) + else if( rgbColor == "lime" ) + TORGB( 0, 255, 0 ) + else if( rgbColor == "limegreen" ) + TORGB( 50, 205, 50 ) + else if( rgbColor == "linen" ) + TORGB( 250, 240, 230 ) + else if( rgbColor == "magenta" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "maroon" ) + TORGB( 128, 0, 0 ) + else if( rgbColor == "mediumaquamarine" ) + TORGB( 102, 205, 170 ) + else if( rgbColor == "mediumblue" ) + TORGB( 0, 0, 205 ) + else if( rgbColor == "mediumorchid" ) + TORGB( 186, 85, 211 ) + else if( rgbColor == "mediumpurple" ) + TORGB( 147, 112, 219 ) + else if( rgbColor == "mediumseagreen" ) + TORGB( 60, 179, 113 ) + else if( rgbColor == "mediumslateblue" ) + TORGB( 123, 104, 238 ) + else if( rgbColor == "mediumspringgreen" ) + TORGB( 0, 250, 154 ) + else if( rgbColor == "mediumturquoise" ) + TORGB( 72, 209, 204 ) + else if( rgbColor == "mediumvioletred" ) + TORGB( 199, 21, 133 ) + else if( rgbColor == "midnightblue" ) + TORGB( 25, 25, 112 ) + else if( rgbColor == "mintcream" ) + TORGB( 245, 255, 250 ) + else if( rgbColor == "mistyrose" ) + TORGB( 255, 228, 225 ) + else if( rgbColor == "moccasin" ) + TORGB( 255, 228, 181 ) + else if( rgbColor == "navajowhite" ) + TORGB( 255, 222, 173 ) + else if( rgbColor == "navy" ) + TORGB( 0, 0, 128 ) + else if( rgbColor == "oldlace" ) + TORGB( 253, 245, 230 ) + else if( rgbColor == "olive" ) + TORGB( 128, 128, 0 ) + else if( rgbColor == "olivedrab" ) + TORGB( 107, 142, 35 ) + else if( rgbColor == "orange" ) + TORGB( 255, 165, 0 ) + else if( rgbColor == "orangered" ) + TORGB( 255, 69, 0 ) + else if( rgbColor == "orchid" ) + TORGB( 218, 112, 214 ) + else if( rgbColor == "palegoldenrod" ) + TORGB( 238, 232, 170 ) + else if( rgbColor == "palegreen" ) + TORGB( 152, 251, 152 ) + else if( rgbColor == "paleturquoise" ) + TORGB( 175, 238, 238 ) + else if( rgbColor == "palevioletred" ) + TORGB( 219, 112, 147 ) + else if( rgbColor == "papayawhip" ) + TORGB( 255, 239, 213 ) + else if( rgbColor == "peachpuff" ) + TORGB( 255, 218, 185 ) + else if( rgbColor == "peru" ) + TORGB( 205, 133, 63 ) + else if( rgbColor == "pink" ) + TORGB( 255, 192, 203 ) + else if( rgbColor == "plum" ) + TORGB( 221, 160, 221 ) + else if( rgbColor == "powderblue" ) + TORGB( 176, 224, 230 ) + else if( rgbColor == "purple" ) + TORGB( 128, 0, 128 ) + else if( rgbColor == "red" ) + TORGB( 255, 0, 0 ) + else if( rgbColor == "rosybrown" ) + TORGB( 188, 143, 143 ) + else if( rgbColor == "royalblue" ) + TORGB( 65, 105, 225 ) + else if( rgbColor == "saddlebrown" ) + TORGB( 139, 69, 19 ) + else if( rgbColor == "salmon" ) + TORGB( 250, 128, 114 ) + else if( rgbColor == "sandybrown" ) + TORGB( 244, 164, 96 ) + else if( rgbColor == "seagreen" ) + TORGB( 46, 139, 87 ) + else if( rgbColor == "seashell" ) + TORGB( 255, 245, 238 ) + else if( rgbColor == "sienna" ) + TORGB( 160, 82, 45 ) + else if( rgbColor == "silver" ) + TORGB( 192, 192, 192 ) + else if( rgbColor == "skyblue" ) + TORGB( 135, 206, 235 ) + else if( rgbColor == "slateblue" ) + TORGB( 106, 90, 205 ) + else if( rgbColor == "slategray" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "slategrey" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "snow" ) + TORGB( 255, 250, 250 ) + else if( rgbColor == "springgreen" ) + TORGB( 0, 255, 127 ) + else if( rgbColor == "steelblue" ) + TORGB( 70, 130, 180 ) + else if( rgbColor == "tan" ) + TORGB( 210, 180, 140 ) + else if( rgbColor == "teal" ) + TORGB( 0, 128, 128 ) + else if( rgbColor == "thistle" ) + TORGB( 216, 191, 216 ) + else if( rgbColor == "tomato" ) + TORGB( 255, 99, 71 ) + else if( rgbColor == "turquoise" ) + TORGB( 64, 224, 208 ) + else if( rgbColor == "violet" ) + TORGB( 238, 130, 238 ) + else if( rgbColor == "wheat" ) + TORGB( 245, 222, 179 ) + else if( rgbColor == "white" ) + TORGB( 255, 255, 255 ) + else if( rgbColor == "whitesmoke" ) + TORGB( 245, 245, 245 ) + else if( rgbColor == "yellow" ) + TORGB( 255, 255, 0 ) + else if( rgbColor == "yellowgreen" ) + TORGB( 154, 205, 50 ) +} + diff --git a/filters/karbon/svg/karbon_svg_export.desktop b/filters/karbon/svg/karbon_svg_export.desktop new file mode 100644 index 000000000..e09904782 --- /dev/null +++ b/filters/karbon/svg/karbon_svg_export.desktop @@ -0,0 +1,67 @@ +[Desktop Entry] +Icon= +Name=Karbon14 SVG Export Filter +Name[af]=Karbon14 Svg Voer uit Filter +Name[ar]=مِرْشَح تصدير SVG لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в SVG +Name[br]=Sil ezporzh SVG evit Karbon14 +Name[ca]=Filtre d'exportació SVG per a Karbon14 +Name[cs]=Exportní filtr do formátu SVG pro Karbon14 +Name[cy]=Hidlen Allforio SVG Karbon14 +Name[da]=Karbon14 SVG-eksportfilter +Name[de]=Karbon14 SVG-Exportfilter +Name[el]=Φίλτρο εξαγωγής SVG του Karbon14 +Name[eo]=Karbon-SVG-eksportfiltrilo +Name[es]=Filtro de exportación Karbon14 SVG +Name[et]=Karbon14 SVG ekspordifilter +Name[eu]=Karbon14-en SVG esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Karbon14 SVG +Name[fi]=Karbon14 SVG -vientisuodin +Name[fr]=Filtre d'exportation SVG de Karbon 14 +Name[fy]=SVG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála SVG Karbon14 +Name[gl]=Filtro de Exportación de SVG para Karbon14 +Name[he]=מסנן ייצוא מ־Karbon14 ל־SVG +Name[hr]=Karbon14 SVG filtar izvoza +Name[hu]=Karbon14 SVG exportszűrő +Name[is]=Karbon14 SVG útflutningssía +Name[it]=Filtro di esportazione SVG per Karbon14 +Name[ja]=Karbon14 SVG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ SVG សម្រាប់ Karbon14 +Name[lo]= ຕົວຕອງການສົ່ງອອກ SVG ຂອງ Karbon14 +Name[lt]=Karbon14 SVG eksportavimo filtras +Name[lv]=Karbon14 SVG eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 SVG +Name[mt]=Filtru għall-esportazzjoni ta' SVG minn ġo Karbon14 +Name[nb]=SVG-eksportfiler for Karbon14 +Name[nds]=SVG-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ एसभीजी निर्यात फिल्टर +Name[nl]=SVG-exportfilter voor Karbon14 +Name[nn]=SVG-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu SVG z Karbon14 +Name[pt]=Filtro de Exportação de SVG para o Karbon14 +Name[pt_BR]=Filtro de Exportação SVG do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru SVG +Name[ru]=Фильтр экспорта рисунков Karbon в SVG +Name[se]=Karbon14:a SVG-olggosfievrridansilli +Name[sk]=SVG filter pre export z Karbon14 +Name[sl]=Izvozni filter SVG za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у SVG +Name[sr@Latn]=Karbon14-ov filter za izvoz u SVG +Name[sv]=Karbon14 SVG-exportfilter +Name[ta]=Karbon 14 SVG ஏற்றுமதி வடிகட்டி +Name[tg]=Karbon14 SVG Филтри Содирот +Name[th]=ตัวกรองการส่งออก SVG ของ Karbon14 +Name[tr]=Karbon14 SVG Aktarma Filtresi +Name[uk]=Фільтр експорту SVG для Karbon14 +Name[uz]=Karbon14 SVG eksport filteri +Name[uz@cyrillic]=Karbon14 SVG экспорт филтери +Name[xh]=Isihluzi Sokurhweba Sangaphandle se Karbon14 SVG +Name[zh_CN]=Karbon14 SVG 导出过滤器 +Name[zh_TW]=Karbon14 SVG 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/svg+xml +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonsvgexport +X-KDE-Weight=1 diff --git a/filters/karbon/svg/karbon_svg_import.desktop b/filters/karbon/svg/karbon_svg_import.desktop new file mode 100644 index 000000000..a1f7eaeac --- /dev/null +++ b/filters/karbon/svg/karbon_svg_import.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +Type=Service +Name=Karbon SVG Import Filter +Name[af]=Karbon Svg In voer Filter +Name[ar]=مِرْشَح استيراد SVG لدى Karbon +Name[bg]=Филтър за импортиране от SVG в Karbon +Name[br]=Sil enporzh SVG evit Karbon +Name[ca]=Filtre d'importació SVG per a Karbon +Name[cs]=Exportní filtr do formátu SVG pro Karbon +Name[cy]=Hidlen Fewnforio SVG Karbon +Name[da]=Karbon SVG-importfilter +Name[de]=Karbon14 SVG-Importfilter +Name[el]=Φίλτρο εισαγωγής SVG του Karbon +Name[eo]=Karbon-SVG-importfiltrilo +Name[es]=Filtro de importación de SVG de Karbon +Name[et]=Karboni SVG impordifilter +Name[eu]=Karbon-en SVG inportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon SVG +Name[fi]=Karbon SVG -tuontisuodin +Name[fr]=Filtre d'exportation SVG de Karbon 14 +Name[fy]=SVG-Ymportfilter foar Karbon +Name[ga]=Scagaire Iompórtála Karbon SVG +Name[gl]=Filtro de Importación de SVG para Karbon +Name[he]=מסנן ייבוא מ־SVG ל־Karbon +Name[hr]=Karbon SVG filtar uvoza +Name[hu]=Karbon SVG importszűrő +Name[is]=Karbon SVG innflutningssía +Name[it]=Filtro di importazione SVG per Karbon14 +Name[ja]=Karbon SVG インポートフィルタ +Name[km]=តម្រង​នាំចូល SVG សម្រាប់ Karbon +Name[lo]=ຕົວຕອງການນຳເຂົ້າ EPS ຂອງຄາຮ໌ບອນ14 +Name[lt]=Karbon SVG importavimo filtras +Name[lv]=Karbon SVG importa filtrs +Name[ms]=Penapis Import Karbon SVG +Name[nb]=SVG-importfilter for Karbon +Name[nds]=SVG-Importfilter för Karbon +Name[ne]=कार्बन एसभीजी निर्यात फिल्टर +Name[nl]=SVG-importfilter voor Karbon14 +Name[nn]=SVG-importfilter for Karbon +Name[pl]=Filtr importu formatu SVG do Karbon +Name[pt]=Filtro de Importação de SVG para o Karbon +Name[pt_BR]=Filtro de Importação SVG do Karbon +Name[ro]=Filtru importare Karbon14 pentru SVG +Name[ru]=Фильтр импорта рисунков SVG в Karbon +Name[se]=Karbon:a SVG-sisafievrridansilli +Name[sk]=SVG filter pre import do Karbon +Name[sl]=Uvozni filter SVG za Karbon +Name[sr]=Karbon-ов филтер за увоз из SVG-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz SVG-a +Name[sv]=Karbon SVG-importfilter +Name[ta]=Karbon SVG ஏற்றுமதி வடிகட்டி +Name[tg]=Karbon SVG I Филтри Воридот +Name[tr]=Karbon SVG Alma Filtresi +Name[uk]=Фільтр імпорту малюнків SVG у Karbon +Name[uz]=Karbon SVG import filteri +Name[uz@cyrillic]=Karbon SVG импорт филтери +Name[xh]=Isihluzi Sokurhweba se Karbon SVG +Name[zh_CN]=Karbon SVG 导入过滤器 +Name[zh_TW]=Karbon SVG 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/svg+xml +X-KDE-Weight=1 +X-KDE-Library=libkarbonsvgimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/svg/svgexport.cc b/filters/karbon/svg/svgexport.cc new file mode 100644 index 000000000..4f434d4db --- /dev/null +++ b/filters/karbon/svg/svgexport.cc @@ -0,0 +1,512 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "svgexport.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgradient.h" +#include "vgroup.h" +#include "vimage.h" +#include "vlayer.h" +#include "vpath.h" +#include "vpattern.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +#include "vtext.h" +#include + +#include + +QString INDENT(" "); + +void +printIndentation( QTextStream *stream, unsigned int indent ) +{ + for( unsigned int i = 0; i < indent;++i) + *stream << INDENT; +} + +typedef KGenericFactory SvgExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonsvgexport, SvgExportFactory( "kofficefilters" ) ) + + +SvgExport::SvgExport( KoFilter*, const char*, const QStringList& ) + : KoFilter(), m_indent( 0 ), m_indent2( 0 ), m_trans( 0L ) +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +SvgExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/svg+xml" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + QString body; + m_body = new QTextStream( &body, IO_ReadWrite ); + QString defs; + m_defs = new QTextStream( &defs, IO_ReadWrite ); + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + doc.accept( *this ); + + *m_stream << defs; + *m_stream << body; + + fileOut.close(); + + delete m_stream; + delete m_defs; + delete m_body; + + return KoFilter::OK; +} + +void +SvgExport::visitVDocument( VDocument& document ) +{ + // select all objects: + document.selection()->append(); + + // get the bounding box of the page + KoRect rect( 0, 0, document.width(), document.height() ); + + // standard header: + *m_defs << + "\n" << + "" + << endl; + + // add some PR. one line is more than enough. + *m_defs << + "" << endl; + + *m_defs << + "" << endl; + printIndentation( m_defs, ++m_indent2 ); + *m_defs << "" << endl; + + m_indent++; + m_indent2++; + + // we dont need the selection anymore: + document.selection()->clear(); + + // set up gc + SvgGraphicsContext *gc = new SvgGraphicsContext; + m_gc.push( gc ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -document.height() ); + + m_trans = new VTransformCmd( 0L, mat, false ); + + // export layers: + VVisitor::visitVDocument( document ); + + delete m_trans; + m_trans = 0L; + + // end tag: + printIndentation( m_defs, --m_indent2 ); + *m_defs << "" << endl; + *m_body << "" << endl; +} + +QString +SvgExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return QString( " id=\"%1\"" ).arg( obj->name() ); + return QString(); +} + +void +SvgExport::visitVGroup( VGroup& group ) +{ + printIndentation( m_body, m_indent++ ); + *m_body << "" << endl; + VVisitor::visitVGroup( group ); + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +// horrible but at least something gets exported now +// will need this for patterns +void +SvgExport::visitVImage( VImage& image ) +{ + printIndentation( m_body, m_indent ); + *m_body << "" << endl; +} + +void +SvgExport::visitVLayer( VLayer& layer ) +{ + printIndentation( m_body, m_indent++ ); + *m_body << "" << endl; + //*m_body << " transform=\"scale(1, -1) translate(0, -" << layer.document()->height() << ")\">" << endl; + VVisitor::visitVLayer( layer ); + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +void +SvgExport::writePathToStream( VPath &composite, const QString &id, QTextStream *stream, unsigned int indent ) +{ + if( ! stream ) + return; + + printIndentation( stream, indent ); + *stream << "fillRule ) + { + if( composite.fillRule() == evenOdd ) + *stream << " fill-rule=\"evenodd\""; + else + *stream << " fill-rule=\"nonzero\""; + } + + *stream << " />" << endl; +} + +void +SvgExport::visitVPath( VPath& composite ) +{ + m_trans->visitVPath( composite ); + writePathToStream( composite, getID( &composite ), m_body, m_indent ); + m_trans->visitVPath( composite ); +} + +void +SvgExport::visitVSubpath( VSubpath& ) +{ +} + +QString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + QString().setNum( nr++ ); +} + +void +SvgExport::getColorStops( const QPtrVector &colorStops ) +{ + m_indent2++; + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + printIndentation( m_defs, m_indent2 ); + *m_defs << "color ); + *m_defs << "\" offset=\"" << QString().setNum( colorStops.at( i )->rampPoint ); + *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; + } + m_indent2--; +} + +void +SvgExport::getGradient( const VGradient& grad ) +{ + QString uid = createUID(); + if( grad.type() == VGradient::linear ) + { + printIndentation( m_defs, m_indent2 ); + // do linear grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + else if( grad.type() == VGradient::radial ) + { + // do radial grad + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + // gah! pointless abbreviation of conical to conic + else if( grad.type() == VGradient::conic ) + { + // fake conical grad as radial. + // fugly but better than data loss. + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } +} + +// better than nothing +void +SvgExport::getPattern( const VPattern & ) +{ + QString uid = createUID(); + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + // TODO: insert hard work here ;) + printIndentation( m_defs, m_indent2 ); + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; +} + +void +SvgExport::getFill( const VFill& fill, QTextStream *stream ) +{ + *stream << " fill=\""; + if( fill.type() == VFill::none ) + *stream << "none"; + else if( fill.type() == VFill::grad ) + getGradient( fill.gradient() ); + else if( fill.type() == VFill::patt ) + getPattern( fill.pattern() ); + else + getHexColor( stream, fill.color() ); + *stream << "\""; + + if( fill.color().opacity() != m_gc.current()->fill.color().opacity() ) + *stream << " fill-opacity=\"" << fill.color().opacity() << "\""; +} + +void +SvgExport::getStroke( const VStroke& stroke, QTextStream *stream ) +{ + if( stroke.type() != m_gc.current()->stroke.type() ) + { + *stream << " stroke=\""; + if( stroke.type() == VStroke::none ) + *stream << "none"; + else if( stroke.type() == VStroke::grad ) + getGradient( stroke.gradient() ); + else + getHexColor( stream, stroke.color() ); + *stream << "\""; + } + + if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() ) + *stream << " stroke-opacity=\"" << stroke.color().opacity() << "\""; + + if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() ) + *stream << " stroke-width=\"" << stroke.lineWidth() << "\""; + + if( stroke.lineCap() != m_gc.current()->stroke.lineCap() ) + { + if( stroke.lineCap() == VStroke::capButt ) + *stream << " stroke-linecap=\"butt\""; + else if( stroke.lineCap() == VStroke::capRound ) + *stream << " stroke-linecap=\"round\""; + else if( stroke.lineCap() == VStroke::capSquare ) + *stream << " stroke-linecap=\"square\""; + } + + if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() ) + { + if( stroke.lineJoin() == VStroke::joinMiter ) + { + *stream << " stroke-linejoin=\"miter\""; + *stream << " stroke-miterlimit=\"" << stroke.miterLimit() << "\""; + } + else if( stroke.lineJoin() == VStroke::joinRound ) + *stream << " stroke-linejoin=\"round\""; + else if( stroke.lineJoin() == VStroke::joinBevel ) + *stream << " stroke-linejoin=\"bevel\""; + } + + // dash + if( stroke.dashPattern().array().count() > 0 ) + { + *stream << " stroke-dashoffset=\"" << stroke.dashPattern().offset() << "\""; + *stream << " stroke-dasharray=\" "; + + QValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *stream << *itr << " "; + } + *stream << "\""; + } +} + +void +SvgExport::getHexColor( QTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + QString Output; + + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) ); + + *stream << Output; +} + +void +SvgExport::visitVText( VText& text ) +{ + VPath path( 0L ); + path.combinePath( text.basePath() ); + + m_trans->visitVPath( path ); + + QString id = createUID(); + writePathToStream( path, " id=\""+ id + "\"", m_defs, m_indent2 ); + + printIndentation( m_body, m_indent++ ); + *m_body << "height() << ")\""; + getFill( *( text.fill() ), m_body ); + getStroke( *( text.stroke() ), m_body ); + + *m_body << " font-family=\"" << text.font().family() << "\""; + *m_body << " font-size=\"" << text.font().pointSize() << "\""; + if( text.font().bold() ) + *m_body << " font-weight=\"bold\""; + if( text.font().italic() ) + *m_body << " font-style=\"italic\""; + if( text.alignment() == VText::Center ) + *m_body << " text-anchor=\"middle\""; + else if( text.alignment() == VText::Right ) + *m_body << " text-anchor=\"end\""; + + *m_body << ">" << endl; + + printIndentation( m_body, m_indent ); + *m_body << " 0.0 ) + *m_body << " startOffset=\"" << text.offset() * 100.0 << "%\""; + *m_body << ">"; + *m_body << text.text(); + *m_body << "" << endl; + printIndentation( m_body, --m_indent ); + *m_body << "" << endl; +} + +#include "svgexport.moc" + diff --git a/filters/karbon/svg/svgexport.h b/filters/karbon/svg/svgexport.h new file mode 100644 index 000000000..8a4eab637 --- /dev/null +++ b/filters/karbon/svg/svgexport.h @@ -0,0 +1,88 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __SVGEXPORT_H__ +#define __SVGEXPORT_H__ + +#include + +#include "vvisitor.h" +#include "vgradient.h" + +#include "svggraphiccontext.h" + +#include + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VImage; +class VLayer; +class VSubpath; +class VStroke; +class VText; +class VTransformCmd; + + +class SvgExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + SvgExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~SvgExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVImage( VImage& image ); + virtual void visitVLayer( VLayer& layer ); + virtual void visitVSubpath( VSubpath& path ); + virtual void visitVText( VText& text ); + + void getStroke( const VStroke& stroke, QTextStream *stream ); + void getColorStops( const QPtrVector &colorStops ); + void getFill( const VFill& fill, QTextStream *stream ); + void getGradient( const VGradient& grad ); + void getPattern( const VPattern& patt ); + void getHexColor( QTextStream *, const VColor& color ); + QString getID( VObject *obj ); + + void writePathToStream( VPath &composite, const QString &id, QTextStream *stream, unsigned int indent ); + + QTextStream* m_stream; + QTextStream* m_defs; + QTextStream* m_body; + + QPtrStack m_gc; + + unsigned int m_indent; + unsigned int m_indent2; + + VTransformCmd *m_trans; +}; + +#endif + diff --git a/filters/karbon/svg/svggraphiccontext.h b/filters/karbon/svg/svggraphiccontext.h new file mode 100644 index 000000000..96737fd98 --- /dev/null +++ b/filters/karbon/svg/svggraphiccontext.h @@ -0,0 +1,48 @@ +/* This file is part of the KDE project + Copyright (C) 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __SVGGRAPHICSCONTEXT_H__ +#define __SVGGRAPHICSCONTEXT_H__ + +#include +#include +#include + +class SvgGraphicsContext +{ +public: + SvgGraphicsContext() + { + stroke.setType( VStroke::none ); // default is no stroke + stroke.setLineWidth( 1.0 ); + stroke.setLineCap( VStroke::capButt ); + stroke.setLineJoin( VStroke::joinMiter ); + fill.setColor( VColor( Qt::black ) ); + fillRule = winding; + color = Qt::black; + } + VFill fill; + VFillRule fillRule; + VStroke stroke; + QWMatrix matrix; + QFont font; + QColor color; +}; + +#endif diff --git a/filters/karbon/svg/svgimport.cc b/filters/karbon/svg/svgimport.cc new file mode 100644 index 000000000..f97546c64 --- /dev/null +++ b/filters/karbon/svg/svgimport.cc @@ -0,0 +1,1389 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include "color.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory SvgImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonsvgimport, SvgImportFactory( "kofficefilters" ) ) + +SvgImport::SvgImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +SvgImport::~SvgImport() +{ +} + +KoFilter::ConversionStatus SvgImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/svg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + QString strExt; + QString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + strExt=fileIn.mid(result).lower(); + + QString strMime; // Mime type of the compressor + if ((strExt==".gz") //in case of .svg.gz (logical extension) + ||(strExt==".svgz")) //in case of .svgz (extension used prioritary) + strMime="application/x-gzip"; // Compressed with gzip + else if (strExt==".bz2") //in case of .svg.bz2 (logical extension) + strMime="application/x-bzip2"; // Compressed with bzip2 + else + strMime="text/plain"; + + /*kdDebug(30514) << "File extension: -" << strExt << "- Compression: " << strMime << endl;*/ + + QIODevice* in = KFilterDev::deviceForFile(fileIn,strMime); + + if (!in->open(IO_ReadOnly)) + { + kdError(30514) << "Cannot open file! Aborting!" << endl; + delete in; + return KoFilter::FileNotFound; + } + + int line, col; + QString errormessage; + + const bool parsed=inpdoc.setContent( in, &errormessage, &line, &col ); + + in->close(); + delete in; + + if ( ! parsed ) + { + kdError(30514) << "Error while parsing file: " + << "at line " << line << " column: " << col + << " message: " << errormessage << endl; + // ### TODO: feedback to the user + return KoFilter::ParsingError; + } + + // Do the conversion! + convert(); + // add paper info, we always need custom for svg (Rob) + QDomElement paper = outdoc.createElement( "PAPER" ); + outdoc.documentElement().appendChild( paper ); + paper.setAttribute( "format", PG_CUSTOM ); + paper.setAttribute( "width", m_document.width() ); + paper.setAttribute( "height", m_document.height() ); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) + { + kdError(30514) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void SvgImport::convert() +{ + SvgGraphicsContext *gc = new SvgGraphicsContext; + QDomElement docElem = inpdoc.documentElement(); + KoRect bbox( 0, 0, 550.0, 841.0 ); + double width = !docElem.attribute( "width" ).isEmpty() ? parseUnit( docElem.attribute( "width" ), true, false, bbox ) : 550.0; + double height = !docElem.attribute( "height" ).isEmpty() ? parseUnit( docElem.attribute( "height" ), false, true, bbox ) : 841.0; + m_document.setWidth( width ); + m_document.setHeight( height ); + + m_outerRect = m_document.boundingBox(); + + // undo y-mirroring + //m_debug->append(QString("%1\tUndo Y-mirroring.").arg(m_time.elapsed())); + if( !docElem.attribute( "viewBox" ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( docElem.attribute( "viewBox" ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + gc->matrix.scale( width / points[2].toFloat() , height / points[3].toFloat() ); + m_outerRect.setWidth( m_outerRect.width() * ( points[2].toFloat() / width ) ); + m_outerRect.setHeight( m_outerRect.height() * ( points[3].toFloat() / height ) ); + } + + m_gc.push( gc ); + parseGroup( 0L, docElem ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( m_document ); + outdoc = m_document.saveXML(); +} + +#define DPI 90 + +// Helper functions +// --------------------------------------------------------------------------------------- + +double SvgImport::toPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double SvgImport::fromPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble() / 100.0; + else + return s.toDouble(); +} + +double SvgImport::getScalingFromMatrix( QWMatrix &matrix ) +{ + double xscale = matrix.m11() + matrix.m12(); + double yscale = matrix.m22() + matrix.m21(); + return sqrt( xscale*xscale + yscale*yscale ) / sqrt( 2.0 ); +} + +// parses the number into parameter number +const char * getNumber( const char *ptr, double &number ) +{ + int integer, exponent; + double decimal, frac; + int sign, expsign; + + exponent = 0; + integer = 0; + frac = 1.0; + decimal = 0; + sign = 1; + expsign = 1; + + // read the sign + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + sign = -1; + } + + // read the integer part + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + integer = (integer * 10) + *(ptr++) - '0'; + if(*ptr == '.') // read the decimals + { + ptr++; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + decimal += (*(ptr++) - '0') * (frac *= 0.1); + } + + if(*ptr == 'e' || *ptr == 'E') // read the exponent part + { + ptr++; + + // read the sign of the exponent + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + expsign = -1; + } + + exponent = 0; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + { + exponent *= 10; + exponent += *ptr - '0'; + ptr++; + } + } + number = integer + decimal; + number *= sign * pow( (double)10, double( expsign * exponent ) ); + + return ptr; +} + +void SvgImport::addGraphicContext() +{ + SvgGraphicsContext *gc = new SvgGraphicsContext; + // set as default + if( m_gc.current() ) + *gc = *( m_gc.current() ); + m_gc.push( gc ); +} + +void SvgImport::setupTransform( const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + + QWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +VObject* SvgImport::findObject( const QString &name, VGroup* group ) +{ + if( ! group ) + return 0L; + + VObjectListIterator itr = group->objects(); + + for( uint objcount = 1; itr.current(); ++itr, objcount++ ) + if( itr.current()->state() != VObject::deleted ) + { + if( itr.current()->name() == name ) + return itr.current(); + + if( dynamic_cast( itr.current() ) ) + { + VObject *obj = findObject( name, dynamic_cast( itr.current() ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +VObject* SvgImport::findObject( const QString &name ) +{ + QPtrVector vector; + m_document.layers().toVector( &vector ); + for( int i = vector.count() - 1; i >= 0; i-- ) + { + if ( vector[i]->state() != VObject::deleted ) + { + VObject* obj = findObject( name, dynamic_cast( vector[i] ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +SvgImport::GradientHelper* SvgImport::findGradient( const QString &id, const QString &href) +{ + // check if gradient was already parsed, and return it + if( m_gradients.contains( id ) ) + return &m_gradients[ id ]; + + // check if gradient was stored for later parsing + if( !m_defs.contains( id ) ) + return 0L; + + QDomElement e = m_defs[ id ]; + if(e.childNodes().count() == 0) + { + QString mhref = e.attribute("xlink:href").mid(1); + + if(m_defs.contains(mhref)) + return findGradient(mhref, id); + else + return 0L; + } + else + { + // ok parse gradient now + parseGradient( m_defs[ id ], m_defs[ href ] ); + } + + // return successfully parsed gradient or NULL + QString n; + if(href.isEmpty()) + n = id; + else + n = href; + + if( m_gradients.contains( n ) ) + return &m_gradients[ n ]; + else + return 0L; +} + +QDomElement SvgImport::mergeStyles( const QDomElement &referencedBy, const QDomElement &referencedElement ) +{ + // First use all the style attributes of the element being referenced. + QDomElement e = referencedElement; + + // Now go through the style attributes of the element that is referencing and substitute the original ones. + if( !referencedBy.attribute( "color" ).isEmpty() ) + e.setAttribute( "color", referencedBy.attribute( "color" ) ); + if( !referencedBy.attribute( "fill" ).isEmpty() ) + e.setAttribute( "fill", referencedBy.attribute( "fill" ) ); + if( !referencedBy.attribute( "fill-rule" ).isEmpty() ) + e.setAttribute( "fill-rule", referencedBy.attribute( "fill-rule" ) ); + if( !referencedBy.attribute( "stroke" ).isEmpty() ) + e.setAttribute( "stroke", referencedBy.attribute( "stroke" ) ); + if( !referencedBy.attribute( "stroke-width" ).isEmpty() ) + e.setAttribute( "stroke-width", referencedBy.attribute( "stroke-width" ) ); + if( !referencedBy.attribute( "stroke-linejoin" ).isEmpty() ) + e.setAttribute( "stroke-linejoin", referencedBy.attribute( "stroke-linejoin" ) ); + if( !referencedBy.attribute( "stroke-linecap" ).isEmpty() ) + e.setAttribute( "stroke-linecap", referencedBy.attribute( "stroke-linecap" ) ); + if( !referencedBy.attribute( "stroke-dasharray" ).isEmpty() ) + e.setAttribute( "stroke-dasharray", referencedBy.attribute( "stroke-dasharray" ) ); + if( !referencedBy.attribute( "stroke-dashoffset" ).isEmpty() ) + e.setAttribute( "stroke-dashoffset", referencedBy.attribute( "stroke-dashoffset" ) ); + if( !referencedBy.attribute( "stroke-opacity" ).isEmpty() ) + e.setAttribute( "stroke-opacity", referencedBy.attribute( "stroke-opacity" ) ); + if( !referencedBy.attribute( "stroke-miterlimit" ).isEmpty() ) + e.setAttribute( "stroke-miterlimit", referencedBy.attribute( "stroke-miterlimit" ) ); + if( !referencedBy.attribute( "fill-opacity" ).isEmpty() ) + e.setAttribute( "fill-opacity", referencedBy.attribute( "fill-opacity" ) ); + if( !referencedBy.attribute( "opacity" ).isEmpty() ) + e.setAttribute( "opacity", referencedBy.attribute( "opacity" ) ); + + // TODO merge style attribute too. + + return e; +} + + +// Parsing functions +// --------------------------------------------------------------------------------------- + +double SvgImport::parseUnit( const QString &unit, bool horiz, bool vert, KoRect bbox ) +{ + // TODO : percentage? + double value = 0; + const char *start = unit.latin1(); + if(!start) { + return 0; + } + const char *end = getNumber( start, value ); + + if( uint( end - start ) < unit.length() ) + { + if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "cm" ) + value = ( value / 2.54 ) * DPI; + else if( unit.right( 2 ) == "pc" ) + value = ( value / 6.0 ) * DPI; + else if( unit.right( 2 ) == "mm" ) + value = ( value / 25.4 ) * DPI; + else if( unit.right( 2 ) == "in" ) + value = value * DPI; + else if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "em" ) + value = value * m_gc.current()->font.pointSize() / ( sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + else if( unit.right( 1 ) == "%" ) + { + if( horiz && vert ) + value = ( value / 100.0 ) * (sqrt( pow( bbox.width(), 2 ) + pow( bbox.height(), 2 ) ) / sqrt( 2.0 ) ); + else if( horiz ) + value = ( value / 100.0 ) * bbox.width(); + else if( vert ) + value = ( value / 100.0 ) * bbox.height(); + } + } + /*else + { + if( m_gc.current() ) + { + if( horiz && vert ) + value *= sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ); + else if( horiz ) + value /= m_gc.current()->matrix.m11(); + else if( vert ) + value /= m_gc.current()->matrix.m22(); + } + }*/ + return value; +} + +QColor SvgImport::parseColor( const QString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return QColor( r, g, b ); +} + +void SvgImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else if( s == "currentColor" ) + { + SvgGraphicsContext *gc = m_gc.current(); + color = gc->color; + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + else + c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +void SvgImport::parseColorStops( VGradient *gradient, const QDomElement &e ) +{ + VColor c; + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + QString temp = stop.attribute( "offset" ); + if( temp.contains( '%' ) ) + { + temp = temp.left( temp.length() - 1 ); + offset = temp.toFloat() / 100.0; + } + else + offset = temp.toFloat(); + + if( !stop.attribute( "stop-color" ).isEmpty() ) + parseColor( c, stop.attribute( "stop-color" ) ); + else + { + // try style attr + QString style = stop.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "stop-color" ) + parseColor( c, params ); + if( command == "stop-opacity" ) + c.setOpacity( params.toDouble() ); + } + + } + if( !stop.attribute( "stop-opacity" ).isEmpty() ) + c.setOpacity( stop.attribute( "stop-opacity" ).toDouble() ); + gradient->addStop( c, offset, 0.5 ); + } + } +} + +void SvgImport::parseGradient( const QDomElement &e , const QDomElement &referencedBy) +{ + // IMPROVEMENTS: + // - Store the parsed colorstops in some sort of a cache so they don't need to be parsed again. + // - A gradient inherits attributes it does not have from the referencing gradient. + // - Gradients with no color stops have no fill or stroke. + // - Gradients with one color stop have a solid color. + + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + GradientHelper gradhelper; + gradhelper.gradient.clearStops(); + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + if(e.childNodes().count() == 0) + { + QString href = e.attribute("xlink:href").mid(1); + + if(href.isEmpty()) + { + //gc->fill.setType( VFill::none ); // <--- TODO Fill OR Stroke are none + return; + } + else + { + // copy the referenced gradient if found + GradientHelper *pGrad = findGradient( href ); + if( pGrad ) + gradhelper = *pGrad; + } + } + + // Use the gradient that is referencing, or if there isn't one, the original gradient. + QDomElement b; + if( !referencedBy.isNull() ) + b = referencedBy; + else + b = e; + + QString id = b.attribute("id"); + if( !id.isEmpty() ) + { + // Copy existing gradient if it exists + if( m_gradients.find( id ) != m_gradients.end() ) + gradhelper.gradient = m_gradients[ id ].gradient; + } + + gradhelper.bbox = b.attribute( "gradientUnits" ) != "userSpaceOnUse"; + + // parse color prop + VColor c = m_gc.current()->color; + + if( !b.attribute( "color" ).isEmpty() ) + { + parseColor( c, b.attribute( "color" ) ); + } + else + { + // try style attr + QString style = b.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "color" ) + parseColor( c, params ); + } + } + m_gc.current()->color = c; + + if( b.tagName() == "linearGradient" ) + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( b.attribute( "x1", "0%" ) ), toPercentage( b.attribute( "y1", "0%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( b.attribute( "x2", "100%" ) ), toPercentage( b.attribute( "y2", "0%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( b.attribute( "x1" ).toDouble(), b.attribute( "y1" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( b.attribute( "x2" ).toDouble(), b.attribute( "y2" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::linear ); + } + else + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( b.attribute( "cx", "50%" ) ), toPercentage( b.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( b.attribute( "cx", "50%" ) ) + toPercentage( b.attribute( "r", "50%" ) ), toPercentage( b.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setFocalPoint( KoPoint( toPercentage( b.attribute( "fx", "50%" ) ), toPercentage( b.attribute( "fy", "50%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( b.attribute( "cx" ).toDouble(), b.attribute( "cy" ).toDouble() ) ); + gradhelper.gradient.setFocalPoint( KoPoint( b.attribute( "fx" ).toDouble(), b.attribute( "fy" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( b.attribute( "cx" ).toDouble() + b.attribute( "r" ).toDouble(), b.attribute( "cy" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::radial ); + } + // handle spread method + QString spreadMethod = b.attribute( "spreadMethod" ); + if( !spreadMethod.isEmpty() ) + { + if( spreadMethod == "reflect" ) + gradhelper.gradient.setRepeatMethod( VGradient::reflect ); + else if( spreadMethod == "repeat" ) + gradhelper.gradient.setRepeatMethod( VGradient::repeat ); + else + gradhelper.gradient.setRepeatMethod( VGradient::none ); + } + else + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + // Parse the color stops. The referencing gradient does not have colorstops, + // so use the stops from the gradient it references to (e in this case and not b) + parseColorStops( &gradhelper.gradient, e ); + //gradient.setGradientTransform( parseTransform( e.attribute( "gradientTransform" ) ) ); + gradhelper.gradientTransform = VPath::parseTransform( b.attribute( "gradientTransform" ) ); + m_gradients.insert( b.attribute( "id" ), gradhelper ); +} + +void SvgImport::parsePA( VObject *obj, SvgGraphicsContext *gc, const QString &command, const QString ¶ms ) +{ + VColor fillcolor = gc->fill.color(); + VColor strokecolor = gc->stroke.color(); + + if( params == "inherit" ) return; + + if( command == "fill" ) + { + if( params == "none" ) + gc->fill.setType( VFill::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + GradientHelper *gradHelper = findGradient( key ); + if( gradHelper ) + { + gc->fill.gradient() = gradHelper->gradient; + + if( gradHelper->bbox ) + { + // adjust to bbox + KoRect bbox = obj->boundingBox(); + //kdDebug() << "bbox x : " << bbox.x() << endl; + //kdDebug() << "!!!!!!bbox y : " << bbox.y() << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + double offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); + gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + if(gc->fill.gradient().type() == VGradient::radial) + { + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + } + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().y() ), false, true, bbox ); + gc->fill.gradient().setVector( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + //kdDebug() << offsety << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().origin().y() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + //kdDebug() << gc->fill.gradient().vector().y() << endl; + } + gc->fill.gradient().transform( gradHelper->gradientTransform ); + + if( !gradHelper->bbox ) + gc->fill.gradient().transform( gc->matrix ); + + gc->fill.setType( VFill::grad ); + } + else + gc->fill.setType( VFill::none ); + } + else + { + parseColor( fillcolor, params ); + gc->fill.setType( VFill::solid ); + } + } + else if( command == "fill-rule" ) + { + if( params == "nonzero" ) + gc->fillRule = winding; + else if( params == "evenodd" ) + gc->fillRule = evenOdd; + } + else if( command == "stroke" ) + { + if( params == "none" ) + gc->stroke.setType( VStroke::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + + GradientHelper *gradHelper = findGradient( key ); + if( gradHelper ) + { + gc->stroke.gradient() = gradHelper->gradient; + gc->stroke.gradient().transform( gradHelper->gradientTransform ); + gc->stroke.gradient().transform( gc->matrix ); + gc->stroke.setType( VStroke::grad ); + } + else + gc->stroke.setType( VStroke::none ); + } + else + { + parseColor( strokecolor, params ); + gc->stroke.setType( VStroke::solid ); + } + } + else if( command == "stroke-width" ) + gc->stroke.setLineWidth( parseUnit( params, true, true, m_outerRect ) ); + else if( command == "stroke-linejoin" ) + { + if( params == "miter" ) + gc->stroke.setLineJoin( VStroke::joinMiter ); + else if( params == "round" ) + gc->stroke.setLineJoin( VStroke::joinRound ); + else if( params == "bevel" ) + gc->stroke.setLineJoin( VStroke::joinBevel ); + } + else if( command == "stroke-linecap" ) + { + if( params == "butt" ) + gc->stroke.setLineCap( VStroke::capButt ); + else if( params == "round" ) + gc->stroke.setLineCap( VStroke::capRound ); + else if( params == "square" ) + gc->stroke.setLineCap( VStroke::capSquare ); + } + else if( command == "stroke-miterlimit" ) + gc->stroke.setMiterLimit( params.toFloat() ); + else if( command == "stroke-dasharray" ) + { + QValueList array; + if(params != "none") + { + // with "stroke-dasharray", the separator is a white space + // inside style attribute, stroke-dasharray is separated by comma (,) + QStringList dashes = QStringList::split( QRegExp("[\\s,]"), params ); + for( QStringList::Iterator it = dashes.begin(); it != dashes.end(); ++it ) + array.append( (*it).toFloat() ); + } + gc->stroke.dashPattern().setArray( array ); + } + else if( command == "stroke-dashoffset" ) + gc->stroke.dashPattern().setOffset( params.toFloat() ); + // handle opacity + else if( command == "stroke-opacity" ) + strokecolor.setOpacity( fromPercentage( params ) ); + else if( command == "fill-opacity" ) + fillcolor.setOpacity( fromPercentage( params ) ); + else if( command == "opacity" ) + { + fillcolor.setOpacity( fromPercentage( params ) ); + strokecolor.setOpacity( fromPercentage( params ) ); + } + else if( command == "font-family" ) + { + QString family = params; + family.replace( '\'' , ' ' ); + gc->font.setFamily( family ); + } + else if( command == "font-size" ) + { + float pointSize = parseUnit( params ); + gc->font.setPointSizeFloat( pointSize * getScalingFromMatrix( gc->matrix ) ); + } + else if( command == "font-weight" ) + { + int weight = QFont::Normal; + + // map svg weight to qt weight + // svg value qt value + // 100,200,300 1, 17, 33 + // 400 50 (normal) + // 500,600 58,66 + // 700 75 (bold) + // 800,900 87,99 + + if( params == "bold" ) + weight = QFont::Bold; + else if( params == "lighter" ) + { + weight = gc->font.weight(); + if( weight <= 17 ) + weight = 1; + else if( weight <= 33 ) + weight = 17; + else if( weight <= 50 ) + weight = 33; + else if( weight <= 58 ) + weight = 50; + else if( weight <= 66 ) + weight = 58; + else if( weight <= 75 ) + weight = 66; + else if( weight <= 87 ) + weight = 75; + else if( weight <= 99 ) + weight = 87; + } + else if( params == "bolder" ) + { + weight = gc->font.weight(); + if( weight >= 87 ) + weight = 99; + else if( weight >= 75 ) + weight = 87; + else if( weight >= 66 ) + weight = 75; + else if( weight >= 58 ) + weight = 66; + else if( weight >= 50 ) + weight = 58; + else if( weight >= 33 ) + weight = 50; + else if( weight >= 17 ) + weight = 50; + else if( weight >= 1 ) + weight = 17; + } + else + { + bool ok; + // try to read numerical weight value + weight = params.toInt( &ok, 10 ); + + if( !ok ) + return; + + switch( weight ) + { + case 100: weight = 1; break; + case 200: weight = 17; break; + case 300: weight = 33; break; + case 400: weight = 50; break; + case 500: weight = 58; break; + case 600: weight = 66; break; + case 700: weight = 75; break; + case 800: weight = 87; break; + case 900: weight = 99; break; + } + } + gc->font.setWeight( weight ); + } + else if( command == "text-decoration" ) + { + if( params == "line-through" ) + gc->font.setStrikeOut( true ); + else if( params == "underline" ) + gc->font.setUnderline( true ); + } + else if( command == "color" ) + { + VColor color; + parseColor( color, params ); + gc->color = color; + } + if( gc->fill.type() != VFill::none ) + gc->fill.setColor( fillcolor, false ); + //if( gc->stroke.type() == VStroke::solid ) + gc->stroke.setColor( strokecolor ); +} + +void SvgImport::parseStyle( VObject *obj, const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + // try normal PA + if( !e.attribute( "color" ).isEmpty() ) + parsePA( obj, gc, "color", e.attribute( "color" ) ); + if( !e.attribute( "fill" ).isEmpty() ) + parsePA( obj, gc, "fill", e.attribute( "fill" ) ); + if( !e.attribute( "fill-rule" ).isEmpty() ) + parsePA( obj, gc, "fill-rule", e.attribute( "fill-rule" ) ); + if( !e.attribute( "stroke" ).isEmpty() ) + parsePA( obj, gc, "stroke", e.attribute( "stroke" ) ); + if( !e.attribute( "stroke-width" ).isEmpty() ) + parsePA( obj, gc, "stroke-width", e.attribute( "stroke-width" ) ); + if( !e.attribute( "stroke-linejoin" ).isEmpty() ) + parsePA( obj, gc, "stroke-linejoin", e.attribute( "stroke-linejoin" ) ); + if( !e.attribute( "stroke-linecap" ).isEmpty() ) + parsePA( obj, gc, "stroke-linecap", e.attribute( "stroke-linecap" ) ); + if( !e.attribute( "stroke-dasharray" ).isEmpty() ) + parsePA( obj, gc, "stroke-dasharray", e.attribute( "stroke-dasharray" ) ); + if( !e.attribute( "stroke-dashoffset" ).isEmpty() ) + parsePA( obj, gc, "stroke-dashoffset", e.attribute( "stroke-dashoffset" ) ); + if( !e.attribute( "stroke-opacity" ).isEmpty() ) + parsePA( obj, gc, "stroke-opacity", e.attribute( "stroke-opacity" ) ); + if( !e.attribute( "stroke-miterlimit" ).isEmpty() ) + parsePA( obj, gc, "stroke-miterlimit", e.attribute( "stroke-miterlimit" ) ); + if( !e.attribute( "fill-opacity" ).isEmpty() ) + parsePA( obj, gc, "fill-opacity", e.attribute( "fill-opacity" ) ); + if( !e.attribute( "opacity" ).isEmpty() ) + parsePA( obj, gc, "opacity", e.attribute( "opacity" ) ); + + // try style attr + QString style = e.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + parsePA( obj, gc, command, params ); + } + + if(!obj) + return; + + obj->setFill( gc->fill ); + if( dynamic_cast( obj ) ) + dynamic_cast( obj )->setFillRule( gc->fillRule ); + // stroke scaling + double lineWidth = gc->stroke.lineWidth(); + gc->stroke.setLineWidth( lineWidth * getScalingFromMatrix( gc->matrix ) ); + obj->setStroke( gc->stroke ); + gc->stroke.setLineWidth( lineWidth ); +} + +void SvgImport::parseFont( const QDomElement &e ) +{ + SvgGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + if( ! e.attribute( "font-family" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-family", e.attribute( "font-family" ) ); + if( ! e.attribute( "font-size" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-size", e.attribute( "font-size" ) ); + if( ! e.attribute( "font-weight" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-weight", e.attribute( "font-weight" ) ); + if( ! e.attribute( "text-decoration" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "text-decoration", e.attribute( "text-decoration" ) ); +} + +void SvgImport::parseUse( VGroup *grp, const QDomElement &e ) +{ + QString id = e.attribute( "xlink:href" ); + + if( !id.isEmpty() ) + { + addGraphicContext(); + setupTransform( e ); + + QString key = id.mid( 1 ); + + if( !e.attribute( "x" ).isEmpty() && !e.attribute( "y" ).isEmpty() ) + { + double tx = e.attribute( "x" ).toDouble(); + double ty = e.attribute( "y" ).toDouble(); + + m_gc.current()->matrix.translate(tx,ty); + } + + if(m_defs.contains(key)) + { + QDomElement a = m_defs[key]; + if(a.tagName() == "g" || a.tagName() == "a") + parseGroup( grp, a); + else + { + // Create the object with the merged styles. + // The object inherits all style attributes from the use tag, but keeps it's own attributes. + // So, not just use the style attributes of the use tag, but merge them first. + createObject( grp, a, VObject::normal, mergeStyles(e, a) ); + } + } + delete( m_gc.pop() ); + } +} + +void SvgImport::parseGroup( VGroup *grp, const QDomElement &e ) +{ + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + + // treat svg link as group so we don't miss its child elements + if( b.tagName() == "g" || b.tagName() == "a" ) + { + VGroup *group; + if ( grp ) + group = new VGroup( grp ); + else + group = new VGroup( &m_document ); + + addGraphicContext(); + setupTransform( b ); + parseStyle( group, b ); + parseFont( b ); + parseGroup( group, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + group->setName( b.attribute("id") ); + if( grp ) + grp->append( group ); + else + m_document.append( group ); + delete( m_gc.pop() ); + continue; + } + if( b.tagName() == "defs" ) + { + parseDefs( b ); + continue; + } + else if( b.tagName() == "linearGradient" || b.tagName() == "radialGradient" ) + { + parseGradient( b ); + continue; + } + if( b.tagName() == "rect" || + b.tagName() == "ellipse" || + b.tagName() == "circle" || + b.tagName() == "line" || + b.tagName() == "polyline" || + b.tagName() == "polygon" || + b.tagName() == "path" || + b.tagName() == "image" ) + { + createObject( grp, b ); + continue; + } + else if( b.tagName() == "text" ) + { + createText( grp, b ); + continue; + } + else if( b.tagName() == "use" ) + { + parseUse( grp, b ); + continue; + } + } +} + +void SvgImport::parseDefs( const QDomElement &e ) +{ + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + + QString definition = b.attribute( "id" ); + if( !definition.isEmpty() ) + { + if( !m_defs.contains( definition ) ) + m_defs.insert( definition, b ); + } + } +} + + +// Creating functions +// --------------------------------------------------------------------------------------- + +void SvgImport::createText( VGroup *grp, const QDomElement &b ) +{ + const double pathLength = 10.0; + + VText *text = 0L; + QString content; + QString anchor; + VSubpath base( 0L ); + VPath *path = 0L; + double offset = 0.0; + + addGraphicContext(); + setupTransform( b ); + + parseFont( b ); + + if( ! b.attribute( "text-anchor" ).isEmpty() ) + anchor = b.attribute( "text-anchor" ); + + if( b.hasChildNodes() ) + { + if( base.isEmpty() && ! b.attribute( "x" ).isEmpty() && ! b.attribute( "y" ).isEmpty() ) + { + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + } + + for( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString key = e.attribute( "xlink:href" ).mid( 1 ); + if( ! m_defs.contains(key) ) + { + // try to find referenced object in document + VObject* obj = findObject( key ); + // try to find referenced object in actual group, which is not yet part of document + if( ! obj ) + obj = findObject( key, grp ); + if( obj ) + path = dynamic_cast( obj ); + } + else + { + QDomElement p = m_defs[key]; + createObject( grp, p, VObject::deleted); + } + if( ! path ) + continue; + base = *path->paths().getFirst(); + content += e.text(); + + if( ! e.attribute( "startOffset" ).isEmpty() ) + { + QString start = e.attribute( "startOffset" ); + if( start.endsWith( "%" ) ) + offset = 0.01 * start.remove( '%' ).toDouble(); + else + { + float pathLength = 0; + VSubpathIterator pIt( base ); + + for( ; pIt.current(); ++pIt ) + pathLength += pIt.current()->length(); + + if( pathLength > 0.0 ) + offset = start.toDouble() / pathLength; + } + } + } + else if( e.tagName() == "tspan" ) + { + // only use text of tspan element, as we are not supporting text + // with different styles + content += e.text(); + if( base.isEmpty() && ! e.attribute( "x" ).isEmpty() && ! e.attribute( "y" ).isEmpty() ) + { + QStringList posX = QStringList::split( ", ", e.attribute( "x" ) ); + QStringList posY = QStringList::split( ", ", e.attribute( "y" ) ); + if( posX.count() && posY.count() ) + { + double x = parseUnit( posX.first() ); + double y = parseUnit( posY.first() ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + } + } + } + else if( e.tagName() == "tref" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString key = e.attribute( "xlink:href" ).mid( 1 ); + if( ! m_defs.contains(key) ) + { + // try to find referenced object in document + VObject* obj = findObject( key ); + // try to find referenced object in actual group, which is not yet part of document + if( ! obj ) + obj = findObject( key, grp ); + if( obj ) + content += dynamic_cast( obj )->text(); + } + else + { + QDomElement p = m_defs[key]; + content += p.text(); + } + } + else + continue; + + if( ! e.attribute( "text-anchor" ).isEmpty() ) + anchor = e.attribute( "text-anchor" ); + } + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, content.simplifyWhiteSpace() ); + } + else + { + VSubpath base( 0L ); + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + pathLength, y ) ); + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, b.text().simplifyWhiteSpace() ); + } + + if( text ) + { + text->setParent( &m_document ); + + parseStyle( text, b ); + + text->setFont( m_gc.current()->font ); + + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *text ); + + if( !b.attribute("id").isEmpty() ) + text->setName( b.attribute("id") ); + + if( anchor == "middle" ) + text->setAlignment( VText::Center ); + else if( anchor == "end" ) + text->setAlignment( VText::Right ); + + if( offset > 0.0 ) + text->setOffset( offset ); + + if( grp ) + grp->append( text ); + else + m_document.append( text ); + } + + delete( m_gc.pop() ); +} + +void SvgImport::createObject( VGroup *grp, const QDomElement &b, const VObject::VState state, const QDomElement &style ) +{ + VObject *obj = 0L; + + addGraphicContext(); + setupTransform( b ); + + if( b.tagName() == "rect" ) + { + double x = parseUnit( b.attribute( "x" ), true, false, m_outerRect ); + double y = parseUnit( b.attribute( "y" ), false, true, m_outerRect ); + double width = parseUnit( b.attribute( "width" ), true, false, m_outerRect ); + double height = parseUnit( b.attribute( "height" ), false, true, m_outerRect ); + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + obj = new VRectangle( 0L, KoPoint( x, height + y ) , width, height, rx, ry ); + } + else if( b.tagName() == "ellipse" ) + { + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - rx; + double top = parseUnit( b.attribute( "cy" ) ) - ry; + obj = new VEllipse( 0L, KoPoint( left, top ), rx * 2.0, ry * 2.0 ); + } + else if( b.tagName() == "circle" ) + { + double r = parseUnit( b.attribute( "r" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - r; + double top = parseUnit( b.attribute( "cy" ) ) - r; + obj = new VEllipse( 0L, KoPoint( left, top ), r * 2.0, r * 2.0 ); + } + else if( b.tagName() == "line" ) + { + VPath *path = new VPath( &m_document ); + double x1 = b.attribute( "x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x1" ) ); + double y1 = b.attribute( "y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y1" ) ); + double x2 = b.attribute( "x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x2" ) ); + double y2 = b.attribute( "y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y2" ) ); + path->moveTo( KoPoint( x1, y1 ) ); + path->lineTo( KoPoint( x2, y2 ) ); + obj = path; + } + else if( b.tagName() == "polyline" || b.tagName() == "polygon" ) + { + VPath *path = new VPath( &m_document ); + bool bFirst = true; + + QString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); ++it) + { + KoPoint point; + point.setX( (*it).toDouble() ); + ++it; + point.setY( (*it).toDouble() ); + if( bFirst ) + { + path->moveTo( point ); + bFirst = false; + } + else + path->lineTo( point ); + } + if( b.tagName() == "polygon" ) path->close(); + obj = path; + } + else if( b.tagName() == "path" ) + { + VPath *path = new VPath( &m_document ); + path->loadSvgPath( b.attribute( "d" ) ); + obj = path; + } + else if( b.tagName() == "image" ) + { + QString fname = b.attribute("xlink:href"); + obj = new VImage( 0L, fname ); + } + + if( !obj ) + return; + + if (state != VObject::normal) + obj->setState(state); + + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *obj ); + + if( !style.isNull() ) + parseStyle( obj, style ); + else + parseStyle( obj, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + obj->setName( b.attribute("id") ); + if( grp ) + grp->append( obj ); + else + m_document.append( obj ); + + delete( m_gc.pop() ); +} + +#include diff --git a/filters/karbon/svg/svgimport.h b/filters/karbon/svg/svgimport.h new file mode 100644 index 000000000..a558c1fc1 --- /dev/null +++ b/filters/karbon/svg/svgimport.h @@ -0,0 +1,102 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __SVGIMPORT_H__ +#define __SVGIMPORT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "svggraphiccontext.h" + +#include + +class VGroup; +class VPath; + +class SvgImport : public KoFilter +{ + Q_OBJECT + +public: + SvgImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~SvgImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + class GradientHelper + { + public: + GradientHelper() + { + bbox = true; + } + VGradient gradient; + bool bbox; + QWMatrix gradientTransform; + }; + + void parseGroup( VGroup *, const QDomElement & ); + void parseDefs( const QDomElement & ); + void parseUse( VGroup *, const QDomElement & ); + void parseStyle( VObject *, const QDomElement & ); + void parsePA( VObject *, SvgGraphicsContext *, const QString &, const QString & ); + void parseGradient( const QDomElement &, const QDomElement &referencedBy = QDomElement() ); + void parseColorStops( VGradient *, const QDomElement & ); + double parseUnit( const QString &, bool horiz = false, bool vert = false, KoRect bbox = KoRect() ); + void parseColor( VColor &, const QString & ); + QColor parseColor( const QString & ); + double toPercentage( QString ); + double fromPercentage( QString ); + void setupTransform( const QDomElement & ); + void addGraphicContext(); + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + void createObject( VGroup *grp, const QDomElement &, VObject::VState state = VObject::normal, const QDomElement &style = QDomElement() ); + void createText( VGroup *, const QDomElement & ); + void parseFont( const QDomElement & ); + // find object with given id in document + VObject* findObject( const QString &name ); + // find object with given id in given group + VObject* findObject( const QString &name, VGroup * ); + // find gradient with given id in gradient map + GradientHelper* findGradient( const QString &id, const QString &href = 0 ); + + // Determine scaling factor from given matrix + double getScalingFromMatrix( QWMatrix &matrix ); + + QDomElement mergeStyles( const QDomElement &, const QDomElement & ); + +private: + VDocument m_document; + QPtrStack m_gc; + QMap m_gradients; + QMap m_defs; + KoRect m_outerRect; +}; + +#endif diff --git a/filters/karbon/wmf/Makefile.am b/filters/karbon/wmf/Makefile.am new file mode 100644 index 000000000..38acbe445 --- /dev/null +++ b/filters/karbon/wmf/Makefile.am @@ -0,0 +1,27 @@ + +INCLUDES= \ + -I$(srcdir) \ + $(KWMF_INCLUDES) \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/commands \ + $(all_includes) + +kde_module_LTLIBRARIES = libwmfimport.la libwmfexport.la + +libwmfimport_la_LDFLAGS = -module $(KDE_PLUGIN) +libwmfimport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la +libwmfimport_la_SOURCES = wmfimport.cc wmfimportparser.cc + +libwmfexport_la_LDFLAGS = -module $(KDE_PLUGIN) +libwmfexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KOWMF) ../../../karbon/libkarboncommon.la +libwmfexport_la_SOURCES = wmfexport.cc + +noinst_HEADERS = wmfimport.h wmfimportparser.h wmfexport.h + +METASOURCES = AUTO + +service_DATA = karbon_wmf_import.desktop karbon_wmf_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/karbon/wmf/karbon_wmf_export.desktop b/filters/karbon/wmf/karbon_wmf_export.desktop new file mode 100644 index 000000000..d859d2742 --- /dev/null +++ b/filters/karbon/wmf/karbon_wmf_export.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Icon= +Name=Karbon14 WMF Export Filter +Name[ar]=مِرْشَح تصدير WMF لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в WMF +Name[br]=Sil ezporzh WMF evit Karbon14 +Name[ca]=Filtre d'exportació WMF per a Karbon14 +Name[cs]=Exportní filtr do formátu WMF pro Karbon14 +Name[cy]=Hidlen Allforio WMF Karbon14 +Name[da]=Karbon14 WMF-eksportfilter +Name[de]=Karbon14 WMF-Exportfilter +Name[el]=Φίλτρο εξαγωγής WMF του Karbon14 +Name[eo]=Karbon14-WMF-eksportfiltrilo +Name[es]=Filtro de exportación WMF de Karbon14 +Name[et]=Karbon14 WMF-i ekspordifilter +Name[eu]=Karbon14-en WMF esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Karbon14 WMF +Name[fi]=Karbon14 WMF -vientisuodin +Name[fr]=Filtre d'exportation WMF de Karbon 14 +Name[fy]=WMF-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála WMF Karbon14 +Name[gl]=Filtro de Exportación de WMF para Karbon14 +Name[he]=מסנן ייצוא מ־Karbon14 ל־WMF +Name[hr]=Karbon14 WMF filtar izvoza +Name[hu]=Karbon14 WMF exportszűrő +Name[is]=Karbon14 WMF útflutningssía +Name[it]=Filtro di esportazione WMF per Karbon14 +Name[ja]=Karbon14 WMF エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ WMF សម្រាប់ Karbon14 +Name[lt]=Karbon14 WMF eksportavimo filtras +Name[lv]=Karbon14 WMF eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 WMF +Name[nb]=WMF-eksportfilter for Karbon14 +Name[nds]=WMF-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ डब्लुएमएफ निर्यात फिल्टर +Name[nl]=WMF-exportfilter voor Karbon14 +Name[nn]=WMF-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu WMF z Karbon14 +Name[pt]=Filtro de Exportação de WMF para o Karbon14 +Name[pt_BR]=Filtro de Exportação WMF do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru WMF +Name[ru]=Фильтр экспорта рисунков Karbon14 в WMF +Name[se]=Karbon14:a WMF-olggosfievrridansilli +Name[sk]=WFM filter pre export z Karbon14 +Name[sl]=Izvozni filter WMF za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у WMF +Name[sr@Latn]=Karbon14-ov filter za izvoz u WMF +Name[sv]=Karbon14 WMF-exportfilter +Name[ta]=Karbon 14 WNF ஏற்றுமதி வடிகட்டி +Name[tg]=Karbon14 WMF Филтри Содирот +Name[tr]=Karbon14 WMF Aktarma Filtresi +Name[uk]=Фільтр експорту WMF для Karbon14 +Name[uz]=Karbon14 WMF eksport filteri +Name[uz@cyrillic]=Karbon14 WMF экспорт филтери +Name[zh_CN]=Karbon14 WMF 导出过滤器 +Name[zh_TW]=Karbon14 WMF 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/x-wmf +X-KDE-Import=application/x-karbon +X-KDE-Weight=1 +X-KDE-Library=libwmfexport + diff --git a/filters/karbon/wmf/karbon_wmf_import.desktop b/filters/karbon/wmf/karbon_wmf_import.desktop new file mode 100644 index 000000000..d1711ff99 --- /dev/null +++ b/filters/karbon/wmf/karbon_wmf_import.desktop @@ -0,0 +1,66 @@ +[Desktop Entry] +Type=Service +Name=Karbon WMF Import Filter +Name[af]=Karbon Wmf In voer Filter +Name[ar]=مِرْشَح استيراد WMF لدى Karbon +Name[bg]=Филтър за импортиране от WMF в Karbon +Name[br]=Sil enporzh WMF evit Karbon +Name[ca]=Filtre d'importació WMF per a Karbon +Name[cs]=Importní filtr WMF pro Karbon14 +Name[cy]=Hidlen Fewnforio WMF Karbon +Name[da]=Karbon WMF-importfilter +Name[de]=Karbon14 WMF-Importfilter +Name[el]=Φίλτρο εισαγωγής WMF του Karbon +Name[eo]=Karbon-WMF-importfiltrilo +Name[es]=Filtro de importación WMF de Karbon +Name[et]=Karboni WMF-i impordifilter +Name[eu]=Karbon-en WMF inportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon WMF +Name[fi]=Karbon WMF- tuontisuodin +Name[fr]=Filtre d'importation WMF de Karbon 14 +Name[fy]=WMF-Ymportfilter foar Karbon +Name[ga]=Scagaire Iompórtála Karbon WMF +Name[gl]=Filtro de Importación de WMF para Karbon14 +Name[he]=מסנן ייבוא מ־WMF ל־Karbon +Name[hr]=Kontour WMF filtar uvoza +Name[hu]=Karbon WMF importszűrő +Name[is]=Karbon WMF innflutningssía +Name[it]=Filtro di importazione WMF per Karbon +Name[ja]=Karbon WMF インポートフィルタ +Name[km]=តម្រង​នាំចូល WMF សម្រាប់ Karbon +Name[lo]=ຕົວຕອງການນຳເຂົ້າ WMF ຂອງ Karbon +Name[lt]=Karbon WMF importavimo filtras +Name[lv]=Karbon WMF importa filtrs +Name[ms]=Penapis Import Karbon WMF +Name[mt]=Filtru għall-importazzjoni ta' WMF ġo Karbon14 +Name[nb]=WMF-importfilter for Karbon +Name[nds]=WMF-Importfilter för Karbon +Name[ne]=कार्बन डब्लुएमएफ निर्यात फिल्टर +Name[nl]=WMF-importfilter voor Karbon +Name[nn]=WMF-importfilter for Karbon14 +Name[pl]=Filtr importu formatu WMF do Karbon +Name[pt]=Filtro de Importação de WMF para o Karbon14 +Name[pt_BR]=Filtro de Importação WMF do Karbon +Name[ro]=Filtru importare Karbon14 pentru WMF +Name[ru]=Фильтр импорта рисунков WMF в Karbon +Name[se]=Karbon:a WMF-sisafievrridansilli +Name[sk]=WMF filter pre import pre Karbon +Name[sl]=Uvozni filter WMF za Karbon +Name[sr]=Karbon-ов филтер за увоз из WMF-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz WMF-a +Name[sv]=Karbon WMF-importfilter +Name[ta]=Karbon wmf இறக்குமதி வடிகட்டி +Name[tg]=Karbon WMF IФилтри Воридот +Name[th]=ตัวกรองการนำเข้า WMF ของ Karbon +Name[tr]=Karbon WMF Alma Filtresi +Name[uk]=Фільтр імпорту WMF для Karbon +Name[uz]=Karbon WMF import filteri +Name[uz@cyrillic]=Karbon WMF импорт филтери +Name[xh]=Isihluzi Sokurhweba se Karbon WMF +Name[zh_CN]=Karbon WMF 导入过滤器 +Name[zh_TW]=Karbon WMF 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-wmf +X-KDE-Weight=1 +X-KDE-Library=libwmfimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/wmf/wmfexport.cc b/filters/karbon/wmf/wmfexport.cc new file mode 100644 index 000000000..5f1e94d73 --- /dev/null +++ b/filters/karbon/wmf/wmfexport.cc @@ -0,0 +1,263 @@ +/* This file is part of the KDE project + * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "vdocument.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vfill.h" +#include "vstroke.h" +#include "vtext.h" +#include "vflattencmd.h" + +#include "wmfexport.h" +#include "kowmfwrite.h" + +/* +TODO: bs.wmf stroke in red with MSword and in brown with Kword ?? +*/ + +typedef KGenericFactory WmfExportFactory; +K_EXPORT_COMPONENT_FACTORY( libwmfexport, WmfExportFactory( "kofficefilters" ) ) + + +WmfExport::WmfExport( KoFilter *, const char *, const QStringList&) : + KoFilter() +{ +} + +WmfExport::~WmfExport() +{ +} + +KoFilter::ConversionStatus WmfExport::convert( const QCString& from, const QCString& to ) +{ + if( to != "image/x-wmf" || from != "application/x-karbon" ) { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) { + return KoFilter::StupidError; + } + + // open Placeable Wmf file + mWmf = new KoWmfWrite( m_chain->outputFile() ); + if( !mWmf->begin() ) { + delete mWmf; + return KoFilter::WrongFormat; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // Load the document. + mDoc = new VDocument; + mDoc->load( docNode ); + + // Process the document. + mDoc->accept( *this ); + + mWmf->end(); + + delete mWmf; + delete mDoc; + + return KoFilter::OK; +} + + +void WmfExport::visitVDocument( VDocument& document ) { + int width; + int height; + + mDoc = &document; + mListPa.setAutoDelete( true ); + + // resolution + mDpi = 1000; + width = (int)(POINT_TO_INCH( document.width() ) * mDpi); + height = (int)(POINT_TO_INCH( document.height() ) * mDpi); + + mWmf->setDefaultDpi( mDpi ); + mWmf->setWindow( 0, 0, width, height ); + + if ( (document.width() != 0) && (document.height() != 0) ) { + mScaleX = (double)width / document.width(); + mScaleY = (double)height / document.height(); + } + + // Export layers. + VVisitor::visitVDocument( document ); + +} + + +void WmfExport::visitVPath( VPath& composite ) { + QPen pen; + QBrush brush; + + getPen( pen, composite.stroke() ); + getBrush( brush, composite.fill() ); + + VVisitor::visitVPath( composite ); + + if ( mListPa.count() > 0 ) { + mWmf->setPen( pen ); + if( (brush.style() == Qt::NoBrush) + && (mListPa.count() == 1) ) { + mWmf->drawPolyline( *mListPa.first() ); + } + else { + mWmf->setBrush( brush ); + + if ( mListPa.count() == 1 ) { + mWmf->drawPolygon( *mListPa.first() ); + } + else { + // combined path + mWmf->drawPolyPolygon( mListPa ); + } + } + } + mListPa.clear(); +} + + +// Export segment. +void WmfExport::visitVSubpath( VSubpath& path ) { + VSubpath *newPath; + VSubpathIterator itr( path ); + VFlattenCmd cmd( 0L, INCH_TO_POINT(0.3 / (double)mDpi) ); + QPointArray *pa = new QPointArray( path.count() ); + int nbrPoint=0; // number of points in the path + + for( ; itr.current(); ++itr ) { + VSegment *segment= itr.current(); + if (segment->isCurve()) { + newPath = new VSubpath( mDoc ); + + // newPath duplicate the list of curve + newPath->moveTo( itr.current()->prev()->knot() ); + newPath->append( itr.current()->clone() ); + while( itr.current()->next() ) { + if ( itr.current()->next()->isCurve() ) { + newPath->append( itr.current()->next()->clone() ); + } + else { + break; + } + ++itr; + } + + // flatten the curve + cmd.visit( *newPath ); + + // adjust the number of points + pa->resize( pa->size() + newPath->count() - 2 ); + + // Ommit the first segment and insert points + newPath->first(); + while( newPath->next() ) { + pa->setPoint( nbrPoint++, coordX( newPath->current()->knot().x() ), + coordY( newPath->current()->knot().y() ) ); + } + delete newPath; + } else if (segment->isLine()) { + pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ), + coordY( itr.current()->knot().y() ) ); + } else if (segment->isBegin()) { + // start a new polygon + pa->setPoint( nbrPoint++, coordX( itr.current()->knot().x() ), + coordY( itr.current()->knot().y() ) ); + } + } + + // adjust the number of points + if ( nbrPoint > 1 ) { + pa->resize( nbrPoint ); + mListPa.append( pa ); + } + else { + delete pa; + // TODO: check why we have empty path + kdDebug() << "WmfExport::visitVSubpath : Empty path ?" << endl; + } +} + + +void WmfExport::visitVText( VText& text ) { + // TODO: export text + visitVSubpath( text.basePath() ); +} + + +void WmfExport::getBrush( QBrush& brush, const VFill *fill ) { + if( (fill->type() == VFill::solid) || (fill->type() == VFill::grad) + || (fill->type() == VFill::patt) ) { + if ( fill->color().opacity() < 0.1 ) { + brush.setStyle( Qt::NoBrush ); + } + else { + brush.setStyle( Qt::SolidPattern ); + brush.setColor( fill->color() ); + } + } + else { + brush.setStyle( Qt::NoBrush ); + } +} + + +void WmfExport::getPen( QPen& pen, const VStroke *stroke ) { + if( (stroke->type() == VStroke::solid) || (stroke->type() == VStroke::grad) + || (stroke->type() == VStroke::patt) ) { + // TODO : Dash pattern. + + if ( stroke->lineCap() == VStroke::capRound ) { + pen.setCapStyle( Qt::RoundCap ); + } + else { + pen.setCapStyle( Qt::SquareCap ); + } + pen.setStyle( Qt::SolidLine ); + pen.setColor( stroke->color() ); + pen.setWidth( coordX( stroke->lineWidth() ) ); + } + else { + pen.setStyle( Qt::NoPen ); + } +} + + +#include + diff --git a/filters/karbon/wmf/wmfexport.h b/filters/karbon/wmf/wmfexport.h new file mode 100644 index 000000000..8f107ee0c --- /dev/null +++ b/filters/karbon/wmf/wmfexport.h @@ -0,0 +1,71 @@ +/* This file is part of the KDE project + * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef WMFEXPORT_H +#define WMFEXPORT_H + +#include +#include +#include +#include +#include +#include "vvisitor.h" + +class KoWmfWrite; +class VPath; +class VDocument; +class VSubpath; +class VText; + +class WmfExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + WmfExport( KoFilter *parent, const char *name, const QStringList&); + virtual ~WmfExport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + void visitVPath( VPath& composite ); + void visitVDocument( VDocument& document ); + void visitVSubpath( VSubpath& path ); + void visitVText( VText& text ); + void getBrush( QBrush& brush, const VFill *fill ); + void getPen( QPen& pen, const VStroke *stroke ); + + // coordinate transformation + // translate origin from (left,bottom) to (left,top) -> scale to wmf size + // Wmf origin is (left,top) corner + // Karbon origin is (left,bottom) corner + int coordX( double left ) + { return (int)(left * mScaleX); } + int coordY( double top ) + { return (int)((mDoc->height() - top) * mScaleY); } + +private: + KoWmfWrite *mWmf; + VDocument *mDoc; + int mDpi; + double mScaleX; + double mScaleY; + QPtrList mListPa; +}; + +#endif diff --git a/filters/karbon/wmf/wmfimport.cc b/filters/karbon/wmf/wmfimport.cc new file mode 100644 index 000000000..eadad26b4 --- /dev/null +++ b/filters/karbon/wmf/wmfimport.cc @@ -0,0 +1,78 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wmfimport.h" +#include "wmfimportparser.h" + +typedef KGenericFactory WMFImportFactory; +K_EXPORT_COMPONENT_FACTORY( libwmfimport, WMFImportFactory( "kofficefilters" ) ) + + +WMFImport::WMFImport( KoFilter *, const char *, const QStringList&) : + KoFilter() +{ +} + +WMFImport::~WMFImport() +{ +} + +KoFilter::ConversionStatus WMFImport::convert( const QCString& from, const QCString& to ) +{ + if( to != "application/x-karbon" || from != "image/x-wmf" ) + return KoFilter::NotImplemented; + + WMFImportParser wmfParser; + if( !wmfParser.load( m_chain->inputFile() ) ) { + return KoFilter::WrongFormat; + } + + // Do the conversion! + VDocument document; + if (!wmfParser.play( document )) { + return KoFilter::WrongFormat; + } + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) { + kdError(3800) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QDomDocument outdoc = document.saveXML(); + QCString content = outdoc.toCString(); + // kdDebug() << " content : " << content << endl; + out->writeBlock( content , content.length() ); + + return KoFilter::OK; +} + + +#include diff --git a/filters/karbon/wmf/wmfimport.h b/filters/karbon/wmf/wmfimport.h new file mode 100644 index 000000000..e1290422f --- /dev/null +++ b/filters/karbon/wmf/wmfimport.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2000, S.R.Haque . + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#ifndef WMFIMPORT_H +#define WMFIMPORT_H + +#include +#include + + +class WMFImport : public KoFilter +{ + Q_OBJECT + +public: + WMFImport( KoFilter *parent, const char *name, const QStringList&); + virtual ~WMFImport(); + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +}; + +#endif diff --git a/filters/karbon/wmf/wmfimportparser.cc b/filters/karbon/wmf/wmfimportparser.cc new file mode 100644 index 000000000..2eb380a47 --- /dev/null +++ b/filters/karbon/wmf/wmfimportparser.cc @@ -0,0 +1,371 @@ +/* This file is part of the KDE project + * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include + +#include "wmfimportparser.h" + +/* +bug : see motar.wmf +*/ + +WMFImportParser::WMFImportParser() : KoWmfRead() { +} + + +bool WMFImportParser::play( VDocument& doc ) +{ + mDoc = &doc; + mScaleX = mScaleY = 1; + + // Play the wmf file + return KoWmfRead::play( ); +} + + +//----------------------------------------------------------------------------- +// Virtual Painter + +bool WMFImportParser::begin() { + QRect bounding = boundingRect(); + + mBackgroundMode = Qt::TransparentMode; + mCurrentOrg.setX( bounding.left() ); + mCurrentOrg.setY( bounding.top() ); + + if ( isStandard() ) { + mDoc->setUnit( KoUnit::U_PT ); + mDoc->setWidth( bounding.width() ); + mDoc->setHeight( bounding.height() ); + } + else { + // Placeable Wmf store the boundingRect() in pixel and the default DPI + // The placeable format doesn't have informations on witch Unit to use + // so we choose millimeters by default + mDoc->setUnit( KoUnit::U_MM ); + mDoc->setWidth( INCH_TO_POINT( (double)bounding.width() / defaultDpi() ) ); + mDoc->setHeight( INCH_TO_POINT( (double)bounding.height() / defaultDpi() ) ); + } + if ( (bounding.width() != 0) && (bounding.height() != 0) ) { + mScaleX = mDoc->width() / (double)bounding.width(); + mScaleY = mDoc->height() / (double)bounding.height(); + } + return true; +} + + +bool WMFImportParser::end() { + return true; +} + + +void WMFImportParser::save() { +} + + +void WMFImportParser::restore() { +} + + +void WMFImportParser::setFont( const QFont & ) { +} + + +void WMFImportParser::setPen( const QPen &pen ) { + mPen = pen; +} + + +const QPen &WMFImportParser::pen() const { + return mPen; +} + + +void WMFImportParser::setBrush( const QBrush &brush ) { + mBrush = brush; +} + + +void WMFImportParser::setBackgroundColor( const QColor &c ) { + mBackgroundColor = c; +} + + +void WMFImportParser::setBackgroundMode( Qt::BGMode mode ) { + mBackgroundMode = mode; +} + + +void WMFImportParser::setRasterOp( Qt::RasterOp ) { +} + + +void WMFImportParser::setWindowOrg( int left, int top ) { + mCurrentOrg.setX( left ); + mCurrentOrg.setY( top ); +} + + +void WMFImportParser::setWindowExt( int width, int height ) { + // the wmf file can change width/height during the drawing + if ( (width != 0) && (height != 0) ) { + mScaleX = mDoc->width() / (double)width; + mScaleY = mDoc->height() / (double)height; + } +} + + +void WMFImportParser::setWorldMatrix( const QWMatrix &, bool ) { +} + + +void WMFImportParser::setClipRegion( const QRegion & ) { +} + + +QRegion WMFImportParser::clipRegion() { + return mClippingRegion; +} + + +void WMFImportParser::moveTo( int left, int top ) { + mCurrentPoint.setX( left ); + mCurrentPoint.setY( top ); +} + + +void WMFImportParser::lineTo( int left, int top ) { + VPath *line = new VPath( mDoc ); + line->moveTo( KoPoint( coordX(mCurrentPoint.x()), coordY(mCurrentPoint.y()) ) ); + line->lineTo( KoPoint( coordX(left), coordY(top) ) ); + appendPen( *line ); + + mDoc->append( line ); + mCurrentPoint.setX( left ); + mCurrentPoint.setY( top ); +} + + +void WMFImportParser::drawRect( int left, int top, int width, int height ) { + VRectangle *rectangle; + + rectangle = new VRectangle( mDoc, KoPoint( coordX(left), coordY(top) ), scaleW(width), scaleH(height), 0 ); + appendPen( *rectangle ); + appendBrush( *rectangle ); + + mDoc->append( rectangle ); +} + + +void WMFImportParser::drawRoundRect( int left, int top, int width, int height, int roudw, int ) { + VRectangle *rectangle; + + // TODO : round rectangle + rectangle = new VRectangle( mDoc, KoPoint( coordX(left), coordY(top) ), scaleW(width), scaleH(height), roudw ); + appendPen( *rectangle ); + appendBrush( *rectangle ); + + mDoc->append( rectangle ); +} + + +void WMFImportParser::drawEllipse( int left, int top, int width, int height ) { + VEllipse *ellipse; + + ellipse = new VEllipse( mDoc, KoPoint( coordX(left), coordY(top+height) ), scaleW(width), scaleH(height) ); + appendPen( *ellipse ); + appendBrush( *ellipse ); + + mDoc->append( ellipse ); +} + + +void WMFImportParser::drawArc( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::arc; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawPie( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::cut; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + appendBrush( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawChord( int x, int y, int w, int h, int aStart, int aLen ) { + double start = (aStart * 180) / 2880.0; + double end = (aLen * 180) / 2880.0; + end += start; + VEllipse::VEllipseType type = VEllipse::section; + + VEllipse *arc = new VEllipse( mDoc, KoPoint( coordX(x), coordY(y+h) ), scaleW(w), scaleH(h), type, start, end ); + appendPen( *arc ); + appendBrush( *arc ); + + mDoc->append( arc ); +} + + +void WMFImportParser::drawPolyline( const QPointArray &pa ) { + VPath *polyline = new VPath( mDoc ); + appendPen( *polyline ); + appendPoints( *polyline, pa ); + + mDoc->append( polyline ); +} + + +void WMFImportParser::drawPolygon( const QPointArray &pa, bool ) { + VPath *polygon = new VPath( mDoc ); + appendPen( *polygon ); + appendBrush( *polygon ); + appendPoints( *polygon, pa ); + + polygon->close(); + mDoc->append( polygon ); +} + + +void WMFImportParser::drawPolyPolygon( QPtrList& listPa, bool ) { + VPath *path = new VPath( mDoc ); + + if ( listPa.count() > 0 ) { + appendPen( *path ); + appendBrush( *path ); + appendPoints( *path, *listPa.first() ); + path->close(); + + while ( listPa.next() ) { + VPath *newPath = new VPath( mDoc ); + appendPoints( *newPath, *listPa.current() ); + newPath->close(); + path->combine( *newPath ); + } + + mDoc->append( path ); + } +} + + +void WMFImportParser::drawImage( int , int , const QImage &, int , int , int , int ) {} + + +void WMFImportParser::drawText( int , int , int , int , int , const QString& , double ) {} + + +//----------------------------------------------------------------------------- +// Utilities + +void WMFImportParser::appendPen( VObject& obj ) +{ + VStroke stroke( mDoc ); + stroke.setLineCap( VStroke::capRound ); + + if ( mPen.style() == Qt::NoPen ) { + stroke.setType( VStroke::none ); + } + else { + QValueList dashes; + stroke.setType( VStroke::solid ); + switch ( mPen.style() ) { + case Qt::DashLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(2) ); + break; + case Qt::DotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case Qt::DashDotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + case Qt::DashDotDotLine : + stroke.dashPattern().setArray( dashes << MM_TO_POINT(3) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) << MM_TO_POINT(1) ); + break; + default: + break; + } + } + stroke.setColor( mPen.color() ); + double width = mPen.width() * mScaleX; + stroke.setLineWidth( ((width < 0.99) ? 1 : width) ); + obj.setStroke( stroke ); +} + + +void WMFImportParser::appendBrush( VObject& obj ) +{ + VFill fill( mBackgroundColor ); + fill.setColor( mBrush.color() ); + + switch ( mBrush.style() ) { + case Qt::NoBrush : + fill.setType( VFill::none ); + break; + case Qt::SolidPattern : + fill.setType( VFill::solid ); + break; + case Qt::CustomPattern : + // TODO: bitmap pattern brush + fill.setType( VFill::solid ); + //fill.pattern(). + break; + default : + // TODO: pattern brush + if ( mBackgroundMode == Qt::OpaqueMode ) { + fill.setColor( mBackgroundColor ); + fill.setType( VFill::solid ); + } + else { + fill.setType( VFill::none ); + } + break; + } + obj.setFill( fill ); +} + + +void WMFImportParser::appendPoints(VPath &path, const QPointArray& pa) +{ + // list of point array + if ( pa.size() > 0 ) { + path.moveTo( KoPoint( coordX(pa.point(0).x()), coordY(pa.point(0).y()) ) ); + } + for ( uint i=1 ; i < pa.size() ; i++ ) { + path.lineTo( KoPoint( coordX(pa.point(i).x()), coordY(pa.point(i).y()) ) ); + } +} + diff --git a/filters/karbon/wmf/wmfimportparser.h b/filters/karbon/wmf/wmfimportparser.h new file mode 100644 index 000000000..fcb1fbe26 --- /dev/null +++ b/filters/karbon/wmf/wmfimportparser.h @@ -0,0 +1,141 @@ +/* This file is part of the KDE project + * Copyright (c) 2003 thierry lorthiois (lorthioist@wanadoo.fr) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License version 2 as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ +#ifndef _WMFIMPORTPARSER_H_ +#define _WMFIMPORTPARSER_H_ + +#include +#include +#include +#include +#include + + +/** + * WMFImportParser inherit KoWmfRead + * and translate WMF functions + * + */ + +class WMFImportParser : public KoWmfRead +{ +public: + WMFImportParser(); + ~WMFImportParser() { } + + /** + * play WMF file on a VDocument. Return true on success. + */ + bool play( VDocument& doc ); + + +private: + // ------------------------------------------------------------------------- + // A virtual QPainter + bool begin(); + bool end(); + void save(); + void restore(); + + // Drawing tools + void setFont( const QFont &font ); + // the pen : the width of the pen is in logical coordinate + void setPen( const QPen &pen ); + const QPen &pen() const; + void setBrush( const QBrush &brush ); + + // Drawing attributes/modes + void setBackgroundColor( const QColor &c ); + void setBackgroundMode( Qt::BGMode mode ); + void setRasterOp( Qt::RasterOp op ); + + /** + * Change logical Coordinate + * some wmf files call those functions several times in the middle of a drawing + * others wmf files doesn't call setWindow* at all + * negative width and height are possible + */ + void setWindowOrg( int left, int top ); + void setWindowExt( int width, int height ); + + // Clipping + // the 'CoordinateMode' is ommitted : always CoordPainter in wmf + // setClipRegion() is often used with save() and restore() => implement all or none + void setClipRegion( const QRegion &rec ); + QRegion clipRegion(); + + // Graphics drawing functions + void moveTo( int x, int y ); + void lineTo( int x, int y ); + void drawRect( int x, int y, int w, int h ); + void drawRoundRect( int x, int y, int w, int h, int = 25, int = 25 ); + void drawEllipse( int x, int y, int w, int h ); + void drawArc( int x, int y, int w, int h, int a, int alen ); + void drawPie( int x, int y, int w, int h, int a, int alen ); + void drawChord( int x, int y, int w, int h, int a, int alen ); + void drawPolyline( const QPointArray &pa ); + void drawPolygon( const QPointArray &pa, bool winding=FALSE ); + /** + * drawPolyPolygon draw the XOR of a list of polygons + * listPa : list of polygons + */ + void drawPolyPolygon( QPtrList& listPa, bool winding=FALSE ); + void drawImage( int x, int y, const QImage &, int sx = 0, int sy = 0, int sw = -1, int sh = -1 ); + + // Text drawing + // rotation = the degrees of rotation in counterclockwise + // not yet implemented in KWinMetaFile + void drawText( int x, int y, int w, int h, int flags, const QString &s, double rotation ); + + // matrix transformation : only used in some bitmap manipulation + void setWorldMatrix( const QWMatrix &, bool combine=FALSE ); + + //----------------------------------------------------------------------------- + // Utilities + // Add pen, brush and points to a path + void appendPen( VObject& obj ); + void appendBrush( VObject& obj ); + void appendPoints(VPath& path, const QPointArray& pa); + // coordinate transformation + // translate wmf to (0,0) -> scale to document size -> translate to karbon (0,0) + // Wmf origin is (left,top) corner + // Karbon origin is (left,bottom) corner + double coordX( int left ) + { return ((double)(left - mCurrentOrg.x()) * mScaleX); } + double coordY( int top ) + { return (mDoc->height() - ((double)(top - mCurrentOrg.y()) * mScaleY)); } + double scaleW( int width ) + { return (width * mScaleX); } + double scaleH( int height ) + { return (height * mScaleY); } + +private: + VDocument *mDoc; + QRegion mClippingRegion; + QPen mPen; + QBrush mBrush; + Qt::BGMode mBackgroundMode; + QColor mBackgroundColor; + // current origin of WMF logical coordinate + QPoint mCurrentOrg; + double mScaleX; + double mScaleY; + // current position in WMF coordinate (INT16) + QPoint mCurrentPoint; +}; + +#endif diff --git a/filters/karbon/xaml/Makefile.am b/filters/karbon/xaml/Makefile.am new file mode 100644 index 000000000..f7036adac --- /dev/null +++ b/filters/karbon/xaml/Makefile.am @@ -0,0 +1,35 @@ +kde_module_LTLIBRARIES = libkarbonxamlexport.la libkarbonxamlimport.la + +libkarbonxamlexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxamlexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +libkarbonxamlimport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxamlimport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_xaml_export.desktop karbon_xaml_import.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + xamlexport.h \ + xamlimport.h + +libkarbonxamlexport_la_SOURCES = \ + xamlexport.cc + +libkarbonxamlimport_la_SOURCES = \ + xamlimport.cc + +METASOURCES = AUTO + diff --git a/filters/karbon/xaml/color.h b/filters/karbon/xaml/color.h new file mode 100644 index 000000000..bfdc93c6e --- /dev/null +++ b/filters/karbon/xaml/color.h @@ -0,0 +1,306 @@ + +#define TORGB( red, green, blue ) \ +{ \ + r = red; \ + b = blue; \ + g = green; \ +} + +void keywordToRGB( QString rgbColor, int &r, int &g, int &b ) +{ + if( rgbColor == "aliceblue" ) + TORGB( 240, 248, 255) + else if( rgbColor == "antiquewhite" ) + TORGB( 250, 235, 215) + else if( rgbColor == "aqua" ) + TORGB( 0, 255, 255) + else if( rgbColor == "aquamarine" ) + TORGB( 127, 255, 212 ) + else if( rgbColor == "azure" ) + TORGB( 240, 255, 255 ) + else if( rgbColor == "beige" ) + TORGB( 245, 245, 220 ) + else if( rgbColor == "bisque" ) + TORGB( 255, 228, 196 ) + else if( rgbColor == "black" ) + TORGB( 0, 0, 0 ) + else if( rgbColor == "blanchedalmond" ) + TORGB( 255, 235, 205 ) + else if( rgbColor == "blue" ) + TORGB( 0, 0, 255 ) + else if( rgbColor == "blueviolet" ) + TORGB( 138, 43, 226 ) + else if( rgbColor == "brown" ) + TORGB( 165, 42, 42 ) + else if( rgbColor == "burlywood" ) + TORGB( 222, 184, 135 ) + else if( rgbColor == "cadetblue" ) + TORGB( 95, 158, 160 ) + else if( rgbColor == "chartreuse" ) + TORGB( 127, 255, 0 ) + else if( rgbColor == "chocolate" ) + TORGB( 210, 105, 30 ) + else if( rgbColor == "coral" ) + TORGB( 255, 127, 80 ) + else if( rgbColor == "cornflowerblue" ) + TORGB( 100, 149, 237 ) + else if( rgbColor == "cornsilk" ) + TORGB( 255, 248, 220 ) + else if( rgbColor == "crimson" ) + TORGB( 220, 20, 60 ) + else if( rgbColor == "cyan" ) + TORGB( 0, 255, 255 ) + else if( rgbColor == "darkblue" ) + TORGB( 0, 0, 139 ) + else if( rgbColor == "darkcyan" ) + TORGB( 0, 139, 139 ) + else if( rgbColor == "darkgoldenrod" ) + TORGB( 184, 134, 11 ) + else if( rgbColor == "darkgray" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgrey" ) + TORGB( 169, 169, 169 ) + else if( rgbColor == "darkgreen" ) + TORGB( 0, 100, 0 ) + else if( rgbColor == "darkkhaki" ) + TORGB( 189, 183, 107 ) + else if( rgbColor == "darkmagenta" ) + TORGB( 139, 0, 139 ) + else if( rgbColor == "darkolivegreen" ) + TORGB( 85, 107, 47 ) + else if( rgbColor == "darkorange" ) + TORGB( 255, 140, 0 ) + else if( rgbColor == "darkorchid" ) + TORGB( 153, 50, 204 ) + else if( rgbColor == "darkred" ) + TORGB( 139, 0, 0 ) + else if( rgbColor == "darksalmon" ) + TORGB( 233, 150, 122 ) + else if( rgbColor == "darkseagreen" ) + TORGB( 143, 188, 143 ) + else if( rgbColor == "darkslateblue" ) + TORGB( 72, 61, 139 ) + else if( rgbColor == "darkslategray" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkslategrey" ) + TORGB( 47, 79, 79 ) + else if( rgbColor == "darkturquoise" ) + TORGB( 0, 206, 209 ) + else if( rgbColor == "darkviolet" ) + TORGB( 148, 0, 211 ) + else if( rgbColor == "deeppink" ) + TORGB( 255, 20, 147 ) + else if( rgbColor == "deepskyblue" ) + TORGB( 0, 191, 255 ) + else if( rgbColor == "dimgray" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dimgrey" ) + TORGB( 105, 105, 105 ) + else if( rgbColor == "dodgerblue" ) + TORGB( 30, 144, 255 ) + else if( rgbColor == "firebrick" ) + TORGB( 178, 34, 34 ) + else if( rgbColor == "floralwhite" ) + TORGB( 255, 250, 240 ) + else if( rgbColor == "forestgreen" ) + TORGB( 34, 139, 34 ) + else if( rgbColor == "fuchsia" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "gainsboro" ) + TORGB( 220, 220, 220 ) + else if( rgbColor == "ghostwhite" ) + TORGB( 248, 248, 255 ) + else if( rgbColor == "gold" ) + TORGB( 255, 215, 0 ) + else if( rgbColor == "goldenrod" ) + TORGB( 218, 165, 32 ) + else if( rgbColor == "gray" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "grey" ) + TORGB( 128, 128, 128 ) + else if( rgbColor == "green" ) + TORGB( 0, 128, 0 ) + else if( rgbColor == "greenyellow" ) + TORGB( 173, 255, 47 ) + else if( rgbColor == "honeydew" ) + TORGB( 240, 255, 240 ) + else if( rgbColor == "hotpink" ) + TORGB( 255, 105, 180 ) + else if( rgbColor == "indianred" ) + TORGB( 205, 92, 92 ) + else if( rgbColor == "indigo" ) + TORGB( 75, 0, 130 ) + else if( rgbColor == "ivory" ) + TORGB( 255, 255, 240 ) + else if( rgbColor == "khaki" ) + TORGB( 240, 230, 140 ) + else if( rgbColor == "lavender" ) + TORGB( 230, 230, 250 ) + else if( rgbColor == "lavenderblush" ) + TORGB( 255, 240, 245 ) + else if( rgbColor == "lawngreen" ) + TORGB( 124, 252, 0 ) + else if( rgbColor == "lemonchiffon" ) + TORGB( 255, 250, 205 ) + else if( rgbColor == "lightblue" ) + TORGB( 173, 216, 230 ) + else if( rgbColor == "lightcoral" ) + TORGB( 240, 128, 128 ) + else if( rgbColor == "lightcyan" ) + TORGB( 224, 255, 255 ) + else if( rgbColor == "lightgoldenrodyellow" ) + TORGB( 250, 250, 210 ) + else if( rgbColor == "lightgray" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgrey" ) + TORGB( 211, 211, 211 ) + else if( rgbColor == "lightgreen" ) + TORGB( 144, 238, 144 ) + else if( rgbColor == "lightpink" ) + TORGB( 255, 182, 193 ) + else if( rgbColor == "lightsalmon" ) + TORGB( 255, 160, 122 ) + else if( rgbColor == "lightseagreen" ) + TORGB( 32, 178, 170 ) + else if( rgbColor == "lightskyblue" ) + TORGB( 135, 206, 250 ) + else if( rgbColor == "lightslategray" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightslategrey" ) + TORGB( 119, 136, 153 ) + else if( rgbColor == "lightsteelblue" ) + TORGB( 176, 196, 222 ) + else if( rgbColor == "lightyellow" ) + TORGB( 255, 255, 224 ) + else if( rgbColor == "lime" ) + TORGB( 0, 255, 0 ) + else if( rgbColor == "limegreen" ) + TORGB( 50, 205, 50 ) + else if( rgbColor == "linen" ) + TORGB( 250, 240, 230 ) + else if( rgbColor == "magenta" ) + TORGB( 255, 0, 255 ) + else if( rgbColor == "maroon" ) + TORGB( 128, 0, 0 ) + else if( rgbColor == "mediumaquamarine" ) + TORGB( 102, 205, 170 ) + else if( rgbColor == "mediumblue" ) + TORGB( 0, 0, 205 ) + else if( rgbColor == "mediumorchid" ) + TORGB( 186, 85, 211 ) + else if( rgbColor == "mediumpurple" ) + TORGB( 147, 112, 219 ) + else if( rgbColor == "mediumseagreen" ) + TORGB( 60, 179, 113 ) + else if( rgbColor == "mediumslateblue" ) + TORGB( 123, 104, 238 ) + else if( rgbColor == "mediumspringgreen" ) + TORGB( 0, 250, 154 ) + else if( rgbColor == "mediumturquoise" ) + TORGB( 72, 209, 204 ) + else if( rgbColor == "mediumvioletred" ) + TORGB( 199, 21, 133 ) + else if( rgbColor == "midnightblue" ) + TORGB( 25, 25, 112 ) + else if( rgbColor == "mintcream" ) + TORGB( 245, 255, 250 ) + else if( rgbColor == "mistyrose" ) + TORGB( 255, 228, 225 ) + else if( rgbColor == "moccasin" ) + TORGB( 255, 228, 181 ) + else if( rgbColor == "navajowhite" ) + TORGB( 255, 222, 173 ) + else if( rgbColor == "navy" ) + TORGB( 0, 0, 128 ) + else if( rgbColor == "oldlace" ) + TORGB( 253, 245, 230 ) + else if( rgbColor == "olive" ) + TORGB( 128, 128, 0 ) + else if( rgbColor == "olivedrab" ) + TORGB( 107, 142, 35 ) + else if( rgbColor == "orange" ) + TORGB( 255, 165, 0 ) + else if( rgbColor == "orangered" ) + TORGB( 255, 69, 0 ) + else if( rgbColor == "orchid" ) + TORGB( 218, 112, 214 ) + else if( rgbColor == "palegoldenrod" ) + TORGB( 238, 232, 170 ) + else if( rgbColor == "palegreen" ) + TORGB( 152, 251, 152 ) + else if( rgbColor == "paleturquoise" ) + TORGB( 175, 238, 238 ) + else if( rgbColor == "palevioletred" ) + TORGB( 219, 112, 147 ) + else if( rgbColor == "papayawhip" ) + TORGB( 255, 239, 213 ) + else if( rgbColor == "peachpuff" ) + TORGB( 255, 218, 185 ) + else if( rgbColor == "peru" ) + TORGB( 205, 133, 63 ) + else if( rgbColor == "pink" ) + TORGB( 255, 192, 203 ) + else if( rgbColor == "plum" ) + TORGB( 221, 160, 221 ) + else if( rgbColor == "powderblue" ) + TORGB( 176, 224, 230 ) + else if( rgbColor == "purple" ) + TORGB( 128, 0, 128 ) + else if( rgbColor == "red" ) + TORGB( 255, 0, 0 ) + else if( rgbColor == "rosybrown" ) + TORGB( 188, 143, 143 ) + else if( rgbColor == "royalblue" ) + TORGB( 65, 105, 225 ) + else if( rgbColor == "saddlebrown" ) + TORGB( 139, 69, 19 ) + else if( rgbColor == "salmon" ) + TORGB( 250, 128, 114 ) + else if( rgbColor == "sandybrown" ) + TORGB( 244, 164, 96 ) + else if( rgbColor == "seagreen" ) + TORGB( 46, 139, 87 ) + else if( rgbColor == "seashell" ) + TORGB( 255, 245, 238 ) + else if( rgbColor == "sienna" ) + TORGB( 160, 82, 45 ) + else if( rgbColor == "silver" ) + TORGB( 192, 192, 192 ) + else if( rgbColor == "skyblue" ) + TORGB( 135, 206, 235 ) + else if( rgbColor == "slateblue" ) + TORGB( 106, 90, 205 ) + else if( rgbColor == "slategray" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "slategrey" ) + TORGB( 112, 128, 144 ) + else if( rgbColor == "snow" ) + TORGB( 255, 250, 250 ) + else if( rgbColor == "springgreen" ) + TORGB( 0, 255, 127 ) + else if( rgbColor == "steelblue" ) + TORGB( 70, 130, 180 ) + else if( rgbColor == "tan" ) + TORGB( 210, 180, 140 ) + else if( rgbColor == "teal" ) + TORGB( 0, 128, 128 ) + else if( rgbColor == "thistle" ) + TORGB( 216, 191, 216 ) + else if( rgbColor == "tomato" ) + TORGB( 255, 99, 71 ) + else if( rgbColor == "turquoise" ) + TORGB( 64, 224, 208 ) + else if( rgbColor == "violet" ) + TORGB( 238, 130, 238 ) + else if( rgbColor == "wheat" ) + TORGB( 245, 222, 179 ) + else if( rgbColor == "white" ) + TORGB( 255, 255, 255 ) + else if( rgbColor == "whitesmoke" ) + TORGB( 245, 245, 245 ) + else if( rgbColor == "yellow" ) + TORGB( 255, 255, 0 ) + else if( rgbColor == "yellowgreen" ) + TORGB( 154, 205, 50 ) +} + diff --git a/filters/karbon/xaml/karbon_xaml_export.desktop b/filters/karbon/xaml/karbon_xaml_export.desktop new file mode 100644 index 000000000..082c29e83 --- /dev/null +++ b/filters/karbon/xaml/karbon_xaml_export.desktop @@ -0,0 +1,54 @@ +[Desktop Entry] +Icon= +Name=Karbon14 WVG Export Filter +Name[ar]=مِرْشَح تصدير WVG لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в WVG +Name[br]=Sil ezporzh WVG evit Karbon14 +Name[ca]=Filtre d'exportació WVG per a Karbon14 +Name[cy]=Hidlen Allforio WVG Karbon14 +Name[da]=Karbon14 WVG-eksportfilter +Name[de]=Karbon14 WVG-Exportfilter +Name[el]=Φίλτρο εξαγωγής SVG του Karbon14 +Name[eo]=Karbon14-WVG-eksportfiltrilo +Name[es]=Filtro de exportación a WVG de Karbon14 +Name[et]=Karbon14 WVG ekspordifilter +Name[fa]=پالایۀ صادرات Karbon14 WVG +Name[fi]=Karbon14 WVG -vientisuodin +Name[fr]=Filtre d'exportation WVG de Karbon 14 +Name[fy]=WVG-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála WVG Karbon14 +Name[gl]=Filtro de Exportación de WVG para Karbon14 +Name[he]=Karbon14 WVG מסנן יצוא +Name[hr]=Karbon14 WVG filtar izvoza +Name[hu]=Karbon14 WVG exportszűrő +Name[is]=Karbon14 WVG útflutningssía +Name[it]=Filtro di esportazione WVG per Karbon14 +Name[ja]=Karbon14 WVG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ WVG សម្រាប់ Karbon14 +Name[lt]=Karbon14 WVG eksportavimo filtras +Name[lv]=Karbon14 WVG eksporta filtrs +Name[nb]=WVG-eksportfiler for Karbon14 +Name[nds]=WVG-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ डब्लुभीजी निर्यात फिल्टर +Name[nl]= WVG-exportfilter voor Karbon14 +Name[pl]=Filtr eksportu do formatu WVG z Karbon14 +Name[pt]=Filtro de Exportação de WVG para o Karbon14 +Name[pt_BR]=Filtro de Exportação de WVG para o Karbon14 +Name[ru]=Фильтр экспорта рисунков Karbon в WVG +Name[se]=Karbon14:a WVG-olggosfievrridansilli +Name[sk]=WVG filter pre export z Karbon14 +Name[sl]=Izvozni filter WVG za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у WVG +Name[sr@Latn]=Karbon14-ov filter za izvoz u WVG +Name[sv]=Karbon14 WVG-exportfilter +Name[uk]=Фільтр експорту WVG для Karbon14 +Name[uz]=Karbon14 WVG eksport filteri +Name[uz@cyrillic]=Karbon14 WVG экспорт филтери +Name[zh_CN]=Karbon14 WVG 导出过滤器 +Name[zh_TW]=Karbon14 WVG 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/wvg+xml +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonxamlexport +X-KDE-Weight=1 diff --git a/filters/karbon/xaml/karbon_xaml_import.desktop b/filters/karbon/xaml/karbon_xaml_import.desktop new file mode 100644 index 000000000..6acd1f1fc --- /dev/null +++ b/filters/karbon/xaml/karbon_xaml_import.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Type=Service +Name=Karbon XAML Import Filter +Name[ar]=مِرْشَح استيراد XAML لدى Karbon +Name[bg]=Филтър за импортиране от XAML в Karbon +Name[br]=Sil enporzh XAML evit Karbon +Name[ca]=Filtre d'importació XAML per a Karbon +Name[cy]=Hidlen Fewnforio XAML Karbon +Name[da]=Karbon XAML-importfilter +Name[de]=Karbon14 XAML-Importfilter +Name[el]=Φίλτρο εισαγωγής XAML του Karbon +Name[eo]=Karbon-XAML-importfiltrilo +Name[es]=Filtro de importación a XAML de Karbon +Name[et]=Karboni XAML-i impordifilter +Name[fa]=پالایۀ واردات Karbon XAML +Name[fi]=Karbon XAML -tuontisuodin +Name[fr]=Filtre d'importation XAML de Karbon 14 +Name[fy]=XAML-tmportfilter foar Karbon +Name[ga]=Scagaire Iompórtála Karbon XAML +Name[gl]=Filtro de Importación de XAML para Karbon +Name[he]=Karbon XAML מסנן יבוא +Name[hr]=Karbon XAML filtar uvoza +Name[hu]=Karbon XAML importszűrő +Name[is]=Karbon XAML innflutningssía +Name[it]=Filtro di importazione XAML per Karbon +Name[ja]=Karbon XAML インポートフィルタ +Name[km]=តម្រង​នាំចូល XAML សម្រាប់ Karbon +Name[lt]=Karbon XAML importavimo filtras +Name[lv]=Karbon XAML importa filtrs +Name[nb]=XAML-importfilter for Karbon +Name[nds]=XAML-Importfilter för Karbon +Name[ne]=कार्बन एक्सएएमएल निर्यात फिल्टर +Name[nl]=XAML-importfilter voor Karbon +Name[pl]=Filtr importu formatu XAML do Karbon +Name[pt]=Filtro de Importação de XAML para o Karbon +Name[pt_BR]=Filtro de Importação de XAML para o Karbon +Name[ru]=Фильтр импорта файлов XAML в Karbon +Name[se]=Karbon:a XAML-sisafievrridansilli +Name[sk]=XAML importný filter pre Karbon +Name[sl]=Uvozni filter XAML za Karbon +Name[sr]=Karbon-ов филтер за увоз из XAML-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz XAML-a +Name[sv]=Karbon XAML-importfilter +Name[uk]=Фільтр імпорту XAML для Karbon +Name[uz]=Karbon XAML import filteri +Name[uz@cyrillic]=Karbon XAML импорт филтери +Name[zh_CN]=Karbon XAML 导入过滤器 +Name[zh_TW]=Karbon XAML 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/wvg+xml +X-KDE-Weight=1 +X-KDE-Library=libkarbonxamlimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/xaml/xamlexport.cc b/filters/karbon/xaml/xamlexport.cc new file mode 100644 index 000000000..c4ccb467e --- /dev/null +++ b/filters/karbon/xaml/xamlexport.cc @@ -0,0 +1,371 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +// based on the SVG exporter. Not intended for public release +// Microsoft WVG renamed to XAML Graphics. Worry about that later. + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "xamlexport.h" +#include "vcolor.h" +#include "vcomposite.h" +#include "vdashpattern.h" +#include "vdocument.h" +#include "vfill.h" +#include "vgradient.h" +#include "vgroup.h" +#include "vlayer.h" +#include "vpath.h" +#include "vsegment.h" +#include "vselection.h" +#include "vstroke.h" +//#include "vtext.h" // TODO Convert Text to Paths for basic export. Not our problem. +// TODO inline Images? + +#include + + +typedef KGenericFactory XAMLExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxamlexport, XAMLExportFactory( "kofficefilters" ) ) + + +XAMLExport::XAMLExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ + m_gc.setAutoDelete( true ); +} + +KoFilter::ConversionStatus +XAMLExport::convert( const QCString& from, const QCString& to ) +{ + // TODO: ??? + if ( to != "image/wvg+xml" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if( !storeIn ) + return KoFilter::StupidError; + + QFile fileOut( m_chain->outputFile() ); + if( !fileOut.open( IO_WriteOnly ) ) + { + delete storeIn; + return KoFilter::StupidError; + } + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QTextStream( &fileOut ); + QString body; + m_body = new QTextStream( &body, IO_ReadWrite ); + QString defs; + m_defs = new QTextStream( &defs, IO_ReadWrite ); + + + // load the document and export it: + VDocument doc; + doc.load( docNode ); + doc.accept( *this ); + + *m_stream << defs; + *m_stream << body; + + fileOut.close(); + + delete m_stream; + delete m_defs; + delete m_body; + + return KoFilter::OK; +} + +void +XAMLExport::visitVDocument( VDocument& document ) +{ + // select all objects: + document.selection()->append(); + + // get the bounding box of the page + KoRect rect( 0, 0, document.width(), document.height() ); + + // standard header: + *m_defs << + "\n" << + /* "" + /*<<*/ endl; + + // Add one line comment to identify Content Creator, + // probably remove this later + // TODO: schemas + // http://schemas.microsoft.com/winfx/avalon/2005 + // http://schemas.microsoft.com/2003/xaml + // need to mention defs too Defenitions namespace xmlns:def="Definition" + *m_defs << + "" << endl; + *m_defs << + "" << endl; + *m_defs << "" << endl; + + // bleuch: this is horrible, do something about it TODO + // Microsoft Acrylic has a transform group just like this + *m_body << "" << endl; + + // we dont need the selection anymore: + document.selection()->clear(); + + // set up gc + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + m_gc.push( gc ); + + // export layers: + VVisitor::visitVDocument( document ); + + // end tag: + *m_body << "" << endl; + *m_defs << "" << endl; + *m_body << "" << endl; +} + +QString +XAMLExport::getID( VObject *obj ) +{ + if( obj && !obj->name().isEmpty() ) + return QString( " Name=\"%1\"" ).arg( obj->name() ); + return QString(); +} + +// which markup to use? Group or Canvas? +// for now assume Group will work. TODO: Test properly! +void +XAMLExport::visitVGroup( VGroup& group ) +{ + *m_body << "" << endl; + VVisitor::visitVGroup( group ); + *m_body << "" << endl; +} + +void +XAMLExport::visitVPath( VPath& composite ) +{ + *m_body << "fillRule ) + { + if( composite.fillRule() == evenOdd ) + *m_body << " FillRule=\"EvenOdd\""; + else + *m_body << " FillRule=\"NonZero\""; + } + + *m_body << " />" << endl; +} + +void +XAMLExport::visitVSubpath( VSubpath& ) +{ +} + +QString createUID() +{ + static unsigned int nr = 0; + + return "defitem" + QString().setNum( nr++ ); +} + +void +XAMLExport::getColorStops( const QPtrVector &colorStops ) +{ + for( unsigned int i = 0; i < colorStops.count() ; i++ ) + { + *m_defs << "color ); + *m_defs << "\" Offset=\"" << QString().setNum( colorStops.at( i )->rampPoint ); + // XAML uses ARGB values and other methods such as masks for Transparency/Opacity # aa rrggbb + // *m_defs << "\" stop-opacity=\"" << colorStops.at( i )->color.opacity() << "\"" << " />" << endl; + // Maybe this only applies to gradients, need to check. + } +} + +void +XAMLExport::getGradient( const VGradient& grad ) +{ + QString uid = createUID(); + if( grad.type() == VGradient::linear ) + { + // do linear grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } + else if( grad.type() == VGradient::radial ) + { + // do radial grad + *m_defs << "" << endl; + + // color stops + getColorStops( grad.colorStops() ); + + *m_defs << "" << endl; + *m_body << "url(#" << uid << ")"; + } +} + +void +XAMLExport::getFill( const VFill& fill ) +{ + *m_body << " Fill=\""; + if( fill.type() == VFill::none ) + *m_body << "none"; + else if( fill.type() == VFill::grad ) + getGradient( fill.gradient() ); + else + getHexColor( m_body, fill.color() ); + *m_body << "\""; + + if( fill.color().opacity() != m_gc.current()->fill.color().opacity() ) + *m_body << " FillOpacity=\"" << fill.color().opacity() << "\""; +} + +void +XAMLExport::getStroke( const VStroke& stroke ) +{ + if( stroke.type() != m_gc.current()->stroke.type() ) + { + *m_body << " Stroke=\""; + if( stroke.type() == VStroke::none ) + *m_body << "None"; + else if( stroke.type() == VStroke::grad ) + getGradient( stroke.gradient() ); + else + getHexColor( m_body, stroke.color() ); + *m_body << "\""; + } + + if( stroke.color().opacity() != m_gc.current()->stroke.color().opacity() ) + *m_body << " StrokeOpacity=\"" << stroke.color().opacity() << "\""; + + if( stroke.lineWidth() != m_gc.current()->stroke.lineWidth() ) + *m_body << " StrokeThickness=\"" << stroke.lineWidth() << "\""; + + if( stroke.lineCap() != m_gc.current()->stroke.lineCap() ) + { + if( stroke.lineCap() == VStroke::capButt ) + *m_body << " StrokeLineCap=\"Butt\""; + else if( stroke.lineCap() == VStroke::capRound ) + *m_body << " StrokeLineCap=\"round\""; + else if( stroke.lineCap() == VStroke::capSquare ) + *m_body << " StrokeLineCap=\"square\""; + } + + if( stroke.lineJoin() != m_gc.current()->stroke.lineJoin() ) + { + if( stroke.lineJoin() == VStroke::joinMiter ) + { + *m_body << " StrokeLineJoin=\"Miter\""; + *m_body << " StrokeMiterLimit=\"" << stroke.miterLimit() << "\""; + } + else if( stroke.lineJoin() == VStroke::joinRound ) + *m_body << " StrokeLineJoin=\"Round\""; + else if( stroke.lineJoin() == VStroke::joinBevel ) + *m_body << " StrokeLineJoin=\"Bevel\""; + } + + // dash + if( stroke.dashPattern().array().count() > 0 ) + { + *m_body << " StrokeDashOffset=\"" << stroke.dashPattern().offset() << "\""; + *m_body << " StrokeDashArray=\" "; + + QValueListConstIterator itr; + for(itr = stroke.dashPattern().array().begin(); itr != stroke.dashPattern().array().end(); ++itr ) + { + *m_body << *itr << " "; + } + *m_body << "\""; + } +} + +void +XAMLExport::getHexColor( QTextStream *stream, const VColor& color ) +{ + // Convert the various color-spaces to hex + + QString Output; + + VColor copy( color ); + copy.setColorSpace( VColor::rgb ); + + Output.sprintf( "#%02x%02x%02x", int( copy[0] * 255.0 ), int( copy[1] * 255.0 ), int( copy[2] * 255.0 ) ); + + *stream << Output; +} + +#include "xamlexport.moc" + diff --git a/filters/karbon/xaml/xamlexport.h b/filters/karbon/xaml/xamlexport.h new file mode 100644 index 000000000..3d2701c6a --- /dev/null +++ b/filters/karbon/xaml/xamlexport.h @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003 The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XAMLEXPORT_H__ +#define __XAMLEXPORT_H__ + +#include + +#include "vvisitor.h" +#include "vgradient.h" + +#include "xamlgraphiccontext.h" + +#include + +class QTextStream; +class VColor; +class VPath; +class VDocument; +class VFill; +class VGroup; +class VLayer; +class VSubpath; +class VStroke; +class VText; + + +class XAMLExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + XAMLExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~XAMLExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +private: + virtual void visitVPath( VPath& composite ); + virtual void visitVDocument( VDocument& document ); + virtual void visitVGroup( VGroup& group ); + virtual void visitVSubpath( VSubpath& path ); + //virtual void visitVText( VText& text ); + + void getStroke( const VStroke& stroke ); + void getColorStops( const QPtrVector &colorStops ); + void getFill( const VFill& fill ); + void getGradient( const VGradient& grad ); + void getHexColor( QTextStream *, const VColor& color ); + QString getID( VObject *obj ); + + QTextStream* m_stream; + QTextStream* m_defs; + QTextStream* m_body; + + QPtrStack m_gc; +}; + +#endif + diff --git a/filters/karbon/xaml/xamlgraphiccontext.h b/filters/karbon/xaml/xamlgraphiccontext.h new file mode 100644 index 000000000..db4a83635 --- /dev/null +++ b/filters/karbon/xaml/xamlgraphiccontext.h @@ -0,0 +1,46 @@ +/* This file is part of the KDE project + Copyright (C) 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XAMLGRAPHICSCONTEXT_H__ +#define __XAMLGRAPHICSCONTEXT_H__ + +#include +#include +#include + +class XAMLGraphicsContext +{ +public: + XAMLGraphicsContext() + { + stroke.setType( VStroke::none ); // default is no stroke + stroke.setLineWidth( 1.0 ); + stroke.setLineCap( VStroke::capButt ); + stroke.setLineJoin( VStroke::joinMiter ); + fill.setColor( VColor( Qt::black ) ); + fillRule = winding; + } + VFill fill; + VFillRule fillRule; + VStroke stroke; + QWMatrix matrix; + QFont font; +}; + +#endif diff --git a/filters/karbon/xaml/xamlimport.cc b/filters/karbon/xaml/xamlimport.cc new file mode 100644 index 000000000..297ff68d1 --- /dev/null +++ b/filters/karbon/xaml/xamlimport.cc @@ -0,0 +1,1042 @@ +/* This file is part of the KDE project + Copyright (C) 2002, 2003, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "xamlimport.h" +#include "color.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory XAMLImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxamlimport, XAMLImportFactory( "kofficefilters" ) ) + +XAMLImport::XAMLImport(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ + m_gc.setAutoDelete( true ); +} + +XAMLImport::~XAMLImport() +{ +} + +KoFilter::ConversionStatus XAMLImport::convert(const QCString& from, const QCString& to) +{ + // check for proper conversion + if( to != "application/x-karbon" || from != "image/wvg+xml" ) + return KoFilter::NotImplemented; + + //Find the last extension + QString strExt; + QString fileIn ( m_chain->inputFile() ); + const int result=fileIn.findRev('.'); + if (result>=0) + { + strExt=fileIn.mid(result).lower(); + } + + QString strMime; // Mime type of the compressor + if ((strExt==".gz") //in case of .svg.gz (logical extension) + ||(strExt==".wvgz")) //in case of .svgz (extension used prioritary) + strMime="application/x-gzip"; // Compressed with gzip + else if (strExt==".bz2") //in case of .svg.bz2 (logical extension) + strMime="application/x-bzip2"; // Compressed with bzip2 + else + strMime="text/plain"; + + kdDebug(30514) << "File extension: -" << strExt << "- Compression: " << strMime << endl; + + QIODevice* in = KFilterDev::deviceForFile(fileIn,strMime); + + if (!in->open(IO_ReadOnly)) + { + kdError(30514) << "Cannot open file! Aborting!" << endl; + delete in; + return KoFilter::FileNotFound; + } + + int line, col; + QString errormessage; + const bool parsed=inpdoc.setContent( in, &errormessage, &line, &col ); + in->close(); + delete in; + if ( ! parsed ) + { + kdError(30514) << "Error while parsing file: " + << "at line " << line << " column: " << col + << " message: " << errormessage << endl; + // ### TODO: feedback to the user + return KoFilter::ParsingError; + } + + // Do the conversion! + convert(); + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if( !out ) + { + kdError(30514) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + + return KoFilter::OK; // was successful +} + +void +XAMLImport::convert() +{ + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + QDomElement docElem = inpdoc.documentElement(); + KoRect bbox( 0, 0, 550.0, 841.0 ); + double width = !docElem.attribute( "width" ).isEmpty() ? parseUnit( docElem.attribute( "width" ), true, false, bbox ) : 550.0; + double height = !docElem.attribute( "height" ).isEmpty() ? parseUnit( docElem.attribute( "height" ), false, true, bbox ) : 841.0; + m_document.setWidth( width ); + m_document.setHeight( height ); + m_outerRect = m_document.boundingBox(); + + // undo y-mirroring + if( !docElem.attribute( "viewBox" ).isEmpty() ) + { + // allow for viewbox def with ',' or whitespace + QString viewbox( docElem.attribute( "viewBox" ) ); + QStringList points = QStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() ); + + gc->matrix.scale( width / points[2].toFloat() , height / points[3].toFloat() ); + m_outerRect.setWidth( m_outerRect.width() * ( points[2].toFloat() / width ) ); + m_outerRect.setHeight( m_outerRect.height() * ( points[3].toFloat() / height ) ); + } + m_gc.push( gc ); + parseGroup( 0L, docElem ); + + QWMatrix mat; + mat.scale( 1, -1 ); + mat.translate( 0, -m_document.height() ); + VTransformCmd trafo( 0L, mat ); + trafo.visit( m_document ); + outdoc = m_document.saveXML(); +} + +#define DPI 90 + +double +XAMLImport::toPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble(); + else + return s.toDouble() * 100.0; +} + +double +XAMLImport::fromPercentage( QString s ) +{ + if( s.endsWith( "%" ) ) + return s.remove( '%' ).toDouble() / 100.0; + else + return s.toDouble(); +} + +// parses the number into parameter number +const char * +getNumber( const char *ptr, double &number ) +{ + int integer, exponent; + double decimal, frac; + int sign, expsign; + + exponent = 0; + integer = 0; + frac = 1.0; + decimal = 0; + sign = 1; + expsign = 1; + + // read the sign + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + sign = -1; + } + + // read the integer part + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + integer = (integer * 10) + *(ptr++) - '0'; + if(*ptr == '.') // read the decimals + { + ptr++; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + decimal += (*(ptr++) - '0') * (frac *= 0.1); + } + + if(*ptr == 'e' || *ptr == 'E') // read the exponent part + { + ptr++; + + // read the sign of the exponent + if(*ptr == '+') + ptr++; + else if(*ptr == '-') + { + ptr++; + expsign = -1; + } + + exponent = 0; + while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9') + { + exponent *= 10; + exponent += *ptr - '0'; + ptr++; + } + } + number = integer + decimal; + number *= sign * pow( (double)10, double( expsign * exponent ) ); + + return ptr; +} + + +double +XAMLImport::parseUnit( const QString &unit, bool horiz, bool vert, KoRect bbox ) +{ + // TODO : percentage? + double value = 0; + const char *start = unit.latin1(); + if(!start) { + return 0; + } + const char *end = getNumber( start, value ); + + if( uint( end - start ) < unit.length() ) + { + if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "cm" ) + value = ( value / 2.54 ) * DPI; + else if( unit.right( 2 ) == "pc" ) + value = ( value / 6.0 ) * DPI; + else if( unit.right( 2 ) == "mm" ) + value = ( value / 25.4 ) * DPI; + else if( unit.right( 2 ) == "in" ) + value = value * DPI; + else if( unit.right( 2 ) == "pt" ) + value = ( value / 72.0 ) * DPI; + else if( unit.right( 2 ) == "em" ) + value = value * m_gc.current()->font.pointSize() / ( sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + else if( unit.right( 1 ) == "%" ) + { + if( horiz && vert ) + value = ( value / 100.0 ) * (sqrt( pow( bbox.width(), 2 ) + pow( bbox.height(), 2 ) ) / sqrt( 2.0 ) ); + else if( horiz ) + value = ( value / 100.0 ) * bbox.width(); + else if( vert ) + value = ( value / 100.0 ) * bbox.height(); + } + } + /*else + { + if( m_gc.current() ) + { + if( horiz && vert ) + value *= sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ); + else if( horiz ) + value /= m_gc.current()->matrix.m11(); + else if( vert ) + value /= m_gc.current()->matrix.m22(); + } + }*/ + return value; +} + +QColor +XAMLImport::parseColor( const QString &rgbColor ) +{ + int r, g, b; + keywordToRGB( rgbColor, r, g, b ); + return QColor( r, g, b ); +} + +void +XAMLImport::parseColor( VColor &color, const QString &s ) +{ + if( s.startsWith( "rgb(" ) ) + { + QString parse = s.stripWhiteSpace(); + QStringList colors = QStringList::split( ',', parse ); + QString r = colors[0].right( ( colors[0].length() - 4 ) ); + QString g = colors[1]; + QString b = colors[2].left( ( colors[2].length() - 1 ) ); + + if( r.contains( "%" ) ) + { + r = r.left( r.length() - 1 ); + r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) ); + } + + if( g.contains( "%" ) ) + { + g = g.left( g.length() - 1 ); + g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) ); + } + + if( b.contains( "%" ) ) + { + b = b.left( b.length() - 1 ); + b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) ); + } + + QColor c( r.toInt(), g.toInt(), b.toInt() ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } + else + { + QString rgbColor = s.stripWhiteSpace(); + QColor c; + if( rgbColor.startsWith( "#" ) ) + c.setNamedColor( rgbColor ); + else + c = parseColor( rgbColor ); + color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 ); + } +} + +void +XAMLImport::parseColorStops( VGradient *gradient, const QDomElement &e ) +{ + VColor c; + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement stop = n.toElement(); + if( stop.tagName() == "stop" ) + { + float offset; + QString temp = stop.attribute( "offset" ); + if( temp.contains( '%' ) ) + { + temp = temp.left( temp.length() - 1 ); + offset = temp.toFloat() / 100.0; + } + else + offset = temp.toFloat(); + + if( !stop.attribute( "stop-color" ).isEmpty() ) + parseColor( c, stop.attribute( "stop-color" ) ); + else + { + // try style attr + QString style = stop.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + if( command == "stop-color" ) + parseColor( c, params ); + if( command == "stop-opacity" ) + c.setOpacity( params.toDouble() ); + } + + } + if( !stop.attribute( "stop-opacity" ).isEmpty() ) + c.setOpacity( stop.attribute( "stop-opacity" ).toDouble() ); + gradient->addStop( c, offset, 0.5 ); + } + } +} + +void +XAMLImport::parseGradient( const QDomElement &e ) +{ + GradientHelper gradhelper; + gradhelper.gradient.clearStops(); + gradhelper.gradient.setRepeatMethod( VGradient::none ); + + QString href = e.attribute( "xlink:href" ).mid( 1 ); + if( !href.isEmpty() ) + { + //kdDebug() << "Indexing with href : " << href.latin1() << endl; + gradhelper.gradient = m_gradients[ href ].gradient; + } + + gradhelper.bbox = e.attribute( "gradientUnits" ) != "userSpaceOnUse"; + + if( e.tagName() == "linearGradient" ) + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "x1", "0%" ) ), toPercentage( e.attribute( "y1", "0%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "x2", "100%" ) ), toPercentage( e.attribute( "y2", "0%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( e.attribute( "x1" ).toDouble(), e.attribute( "y1" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( e.attribute( "x2" ).toDouble(), e.attribute( "y2" ).toDouble() ) ); + } + } + else + { + if( gradhelper.bbox ) + { + gradhelper.gradient.setOrigin( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ), toPercentage( e.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setVector( KoPoint( toPercentage( e.attribute( "cx", "50%" ) ) + toPercentage( e.attribute( "r", "50%" ) ), + toPercentage( e.attribute( "cy", "50%" ) ) ) ); + gradhelper.gradient.setFocalPoint( KoPoint( toPercentage( e.attribute( "fx", "50%" ) ), toPercentage( e.attribute( "fy", "50%" ) ) ) ); + } + else + { + gradhelper.gradient.setOrigin( KoPoint( e.attribute( "cx" ).toDouble(), e.attribute( "cy" ).toDouble() ) ); + gradhelper.gradient.setFocalPoint( KoPoint( e.attribute( "fx" ).toDouble(), e.attribute( "fy" ).toDouble() ) ); + gradhelper.gradient.setVector( KoPoint( e.attribute( "cx" ).toDouble() + e.attribute( "r" ).toDouble(), e.attribute( "cy" ).toDouble() ) ); + } + gradhelper.gradient.setType( VGradient::radial ); + } + // handle spread method + QString spreadMethod = e.attribute( "spreadMethod" ); + if( !spreadMethod.isEmpty() ) + { + if( spreadMethod == "reflect" ) + gradhelper.gradient.setRepeatMethod( VGradient::reflect ); + else if( spreadMethod == "repeat" ) + gradhelper.gradient.setRepeatMethod( VGradient::repeat ); + } + parseColorStops( &gradhelper.gradient, e ); + //gradient.setGradientTransform( parseTransform( e.attribute( "gradientTransform" ) ) ); + gradhelper.gradientTransform = VPath::parseTransform( e.attribute( "gradientTransform" ) ); + m_gradients.insert( e.attribute( "id" ), gradhelper ); +} + +void +XAMLImport::parsePA( VObject *obj, XAMLGraphicsContext *gc, const QString &command, const QString ¶ms ) +{ + VColor fillcolor = gc->fill.color(); + VColor strokecolor = gc->stroke.color(); + + if( command == "fill" ) + { + if( params == "none" ) + gc->fill.setType( VFill::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + gc->fill.gradient() = m_gradients[ key ].gradient; + if( m_gradients[ key ].bbox ) + { + // adjust to bbox + KoRect bbox = obj->boundingBox(); + //kdDebug() << "bbox x : " << bbox.x() << endl; + //kdDebug() << "!!!!!!bbox y : " << bbox.y() << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + double offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().x() ), true, false, bbox ); + double offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().origin().y() ), false, true, bbox ); + gc->fill.gradient().setOrigin( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().focalPoint().y() ), false, true, bbox ); + gc->fill.gradient().setFocalPoint( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + offsetx = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().x() ), true, false, bbox ); + offsety = parseUnit( QString( "%1%" ).arg( gc->fill.gradient().vector().y() ), false, true, bbox ); + gc->fill.gradient().setVector( KoPoint( bbox.x() + offsetx, bbox.y() + offsety ) ); + //kdDebug() << offsety << endl; + //kdDebug() << gc->fill.gradient().origin().x() << endl; + //kdDebug() << gc->fill.gradient().origin().y() << endl; + //kdDebug() << gc->fill.gradient().vector().x() << endl; + //kdDebug() << gc->fill.gradient().vector().y() << endl; + } + gc->fill.gradient().transform( m_gradients[ key ].gradientTransform ); + if( !m_gradients[ key ].bbox ) + gc->fill.gradient().transform( gc->matrix ); + gc->fill.setType( VFill::grad ); + } + else + { + parseColor( fillcolor, params ); + gc->fill.setType( VFill::solid ); + } + } + else if( command == "fill-rule" ) + { + if( params == "nonzero" ) + gc->fillRule = winding; + else if( params == "evenodd" ) + gc->fillRule = evenOdd; + } + else if( command == "stroke" ) + { + if( params == "none" ) + gc->stroke.setType( VStroke::none ); + else if( params.startsWith( "url(" ) ) + { + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + gc->stroke.gradient() = m_gradients[ key ].gradient; + gc->stroke.gradient().transform( m_gradients[ key ].gradientTransform ); + gc->stroke.gradient().transform( gc->matrix ); + gc->stroke.setType( VStroke::grad ); + } + else + { + parseColor( strokecolor, params ); + gc->stroke.setType( VStroke::solid ); + } + } + else if( command == "stroke-width" ) + gc->stroke.setLineWidth( parseUnit( params, true, true, m_outerRect ) ); + else if( command == "stroke-linejoin" ) + { + if( params == "miter" ) + gc->stroke.setLineJoin( VStroke::joinMiter ); + else if( params == "round" ) + gc->stroke.setLineJoin( VStroke::joinRound ); + else if( params == "bevel" ) + gc->stroke.setLineJoin( VStroke::joinBevel ); + } + else if( command == "stroke-linecap" ) + { + if( params == "butt" ) + gc->stroke.setLineCap( VStroke::capButt ); + else if( params == "round" ) + gc->stroke.setLineCap( VStroke::capRound ); + else if( params == "square" ) + gc->stroke.setLineCap( VStroke::capSquare ); + } + else if( command == "stroke-miterlimit" ) + gc->stroke.setMiterLimit( params.toFloat() ); + else if( command == "stroke-dasharray" ) + { + QValueList array; + if(params != "none") + { + QStringList dashes = QStringList::split( ' ', params ); + for( QStringList::Iterator it = dashes.begin(); it != dashes.end(); ++it ) + array.append( (*it).toFloat() ); + } + gc->stroke.dashPattern().setArray( array ); + } + else if( command == "stroke-dashoffset" ) + gc->stroke.dashPattern().setOffset( params.toFloat() ); + // handle opacity + else if( command == "stroke-opacity" ) + strokecolor.setOpacity( fromPercentage( params ) ); + else if( command == "fill-opacity" ) + fillcolor.setOpacity( fromPercentage( params ) ); + else if( command == "opacity" ) + { + fillcolor.setOpacity( fromPercentage( params ) ); + strokecolor.setOpacity( fromPercentage( params ) ); + } + else if( command == "font-family" ) + { + QString family = params; + family.replace( '\'' , ' ' ); + gc->font.setFamily( family ); + } + else if( command == "font-size" ) + { + float pointSize = parseUnit( params ); + pointSize *= gc->matrix.m22() > 0 ? gc->matrix.m22() : -1.0 * gc->matrix.m22(); + gc->font.setPointSizeFloat( pointSize ); + } + else if( command == "text-decoration" ) + { + if( params == "line-through" ) + gc->font.setStrikeOut( true ); + else if( params == "underline" ) + gc->font.setUnderline( true ); + } + if( gc->fill.type() != VFill::none ) + gc->fill.setColor( fillcolor, false ); + //if( gc->stroke.type() == VStroke::solid ) + gc->stroke.setColor( strokecolor ); +} + +void +XAMLImport::addGraphicContext() +{ + XAMLGraphicsContext *gc = new XAMLGraphicsContext; + // set as default + if( m_gc.current() ) + *gc = *( m_gc.current() ); + m_gc.push( gc ); +} + +void +XAMLImport::setupTransform( const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + + QWMatrix mat = VPath::parseTransform( e.attribute( "transform" ) ); + gc->matrix = mat * gc->matrix; +} + +void +XAMLImport::parseStyle( VObject *obj, const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + // try normal PA + if( !e.attribute( "fill" ).isEmpty() ) + parsePA( obj, gc, "fill", e.attribute( "fill" ) ); + if( !e.attribute( "fill-rule" ).isEmpty() ) + parsePA( obj, gc, "fill-rule", e.attribute( "fill-rule" ) ); + if( !e.attribute( "stroke" ).isEmpty() ) + parsePA( obj, gc, "stroke", e.attribute( "stroke" ) ); + if( !e.attribute( "stroke-width" ).isEmpty() ) + parsePA( obj, gc, "stroke-width", e.attribute( "stroke-width" ) ); + if( !e.attribute( "stroke-linejoin" ).isEmpty() ) + parsePA( obj, gc, "stroke-linejoin", e.attribute( "stroke-linejoin" ) ); + if( !e.attribute( "stroke-linecap" ).isEmpty() ) + parsePA( obj, gc, "stroke-linecap", e.attribute( "stroke-linecap" ) ); + if( !e.attribute( "stroke-dasharray" ).isEmpty() ) + parsePA( obj, gc, "stroke-dasharray", e.attribute( "stroke-dasharray" ) ); + if( !e.attribute( "stroke-dashoffset" ).isEmpty() ) + parsePA( obj, gc, "stroke-dashoffset", e.attribute( "stroke-dashoffset" ) ); + if( !e.attribute( "stroke-opacity" ).isEmpty() ) + parsePA( obj, gc, "stroke-opacity", e.attribute( "stroke-opacity" ) ); + if( !e.attribute( "stroke-miterlimit" ).isEmpty() ) + parsePA( obj, gc, "stroke-miterlimit", e.attribute( "stroke-miterlimit" ) ); + if( !e.attribute( "fill-opacity" ).isEmpty() ) + parsePA( obj, gc, "fill-opacity", e.attribute( "fill-opacity" ) ); + if( !e.attribute( "opacity" ).isEmpty() ) + parsePA( obj, gc, "opacity", e.attribute( "opacity" ) ); + + // try style attr + QString style = e.attribute( "style" ).simplifyWhiteSpace(); + QStringList substyles = QStringList::split( ';', style ); + for( QStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it ) + { + QStringList substyle = QStringList::split( ':', (*it) ); + QString command = substyle[0].stripWhiteSpace(); + QString params = substyle[1].stripWhiteSpace(); + parsePA( obj, gc, command, params ); + } + + obj->setFill( gc->fill ); + if( dynamic_cast( obj ) ) + dynamic_cast( obj )->setFillRule( gc->fillRule ); + // stroke scaling + double lineWidth = gc->stroke.lineWidth(); + gc->stroke.setLineWidth( lineWidth * sqrt( pow( m_gc.current()->matrix.m11(), 2 ) + pow( m_gc.current()->matrix.m22(), 2 ) ) / sqrt( 2.0 ) ); + obj->setStroke( gc->stroke ); + gc->stroke.setLineWidth( lineWidth ); +} + +void +XAMLImport::parseFont( const QDomElement &e ) +{ + XAMLGraphicsContext *gc = m_gc.current(); + if( !gc ) return; + + if( ! e.attribute( "font-family" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-family", e.attribute( "font-family" ) ); + if( ! e.attribute( "font-size" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "font-size", e.attribute( "font-size" ) ); + if( ! e.attribute( "text-decoration" ).isEmpty() ) + parsePA( 0L, m_gc.current(), "text-decoration", e.attribute( "text-decoration" ) ); +} + +void +XAMLImport::parseGroup( VGroup *grp, const QDomElement &e ) +{ + bool isDef = false; + if( e.tagName() == "defs" ) + isDef = true; + + for( QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement b = n.toElement(); + if( b.isNull() ) continue; + VObject *obj = 0L; + if( b.tagName() == "g" ) + { + VGroup *group; + if ( grp ) + group = new VGroup( grp ); + else + group = new VGroup( &m_document ); + + addGraphicContext(); + setupTransform( b ); + parseStyle( group, b ); + parseFont( b ); + parseGroup( group, b ); + + // handle id + if( !b.attribute("id").isEmpty() ) + group->setName( b.attribute("id") ); + if( grp ) + grp->append( group ); + else + m_document.append( group ); + delete( m_gc.pop() ); + continue; + } + if( b.tagName() == "defs" ) + { + parseGroup( 0L, b ); // try for gradients at least + continue; + } + else if( b.tagName() == "linearGradient" || b.tagName() == "radialGradient" ) + { + parseGradient( b ); + continue; + } + else if( b.tagName() == "rect" || + b.tagName() == "ellipse" || + b.tagName() == "circle" || + b.tagName() == "line" || + b.tagName() == "polyline" || + b.tagName() == "polygon" || + b.tagName() == "path" || + b.tagName() == "image" ) + { + if (!isDef) + obj = createObject( b ); + else + m_paths.insert( b.attribute( "id" ), b ); + } + else if( b.tagName() == "text" ) + { + if( isDef ) + m_paths.insert( b.attribute( "id" ), b ); + else + createText( grp, b ); + } + else if( b.tagName() == "use" ) + { + double tx = b.attribute( "x" ).toDouble(); + double ty = b.attribute( "y" ).toDouble(); + + if( !b.attribute( "xlink:href" ).isEmpty() ) + { + QString params = b.attribute( "xlink:href" ); + unsigned int start = params.find("#") + 1; + unsigned int end = params.findRev(")"); + QString key = params.mid( start, end - start ); + if(m_paths.contains(key)) + { + QDomElement a = m_paths[key]; + obj = createObject( a ); + m_gc.current()->matrix.translate(tx,ty); + parsePA( grp, m_gc.current(), "fill", b.attribute( "fill" ) ); + } + } + } + if( !obj ) continue; + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + trafo.visit( *obj ); + parseStyle( obj, b ); + // handle id + if( !b.attribute("id").isEmpty() ) + obj->setName( b.attribute("id") ); + if( grp ) + grp->append( obj ); + else + m_document.append( obj ); + delete( m_gc.pop() ); + } +} + +VObject* XAMLImport::findObject( const QString &name, VGroup* group ) +{ + if( ! group ) + return 0L; + + VObjectListIterator itr = group->objects(); + + for( uint objcount = 1; itr.current(); ++itr, objcount++ ) + if( itr.current()->state() != VObject::deleted ) + { + if( itr.current()->name() == name ) + return itr.current(); + + if( dynamic_cast( itr.current() ) ) + { + VObject *obj = findObject( name, dynamic_cast( itr.current() ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +VObject* XAMLImport::findObject( const QString &name ) +{ + QPtrVector vector; + m_document.layers().toVector( &vector ); + for( int i = vector.count() - 1; i >= 0; i-- ) + { + if ( vector[i]->state() != VObject::deleted ) + { + VObject* obj = findObject( name, dynamic_cast( vector[i] ) ); + if( obj ) + return obj; + } + } + + return 0L; +} + +void XAMLImport::createText( VGroup *grp, const QDomElement &b ) +{ + VText *text = 0L; + QString content; + VSubpath base( 0L ); + VPath *path = 0L; + + addGraphicContext(); + setupTransform( b ); + VTransformCmd trafo( 0L, m_gc.current()->matrix ); + + parseFont( b ); + + if( b.hasChildNodes() ) + { + if( base.isEmpty() && ! b.attribute( "x" ).isEmpty() && ! b.attribute( "y" ).isEmpty() ) + { + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + } + + for( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() ) + { + QDomElement e = n.toElement(); + if( e.isNull() ) + { + content += n.toCharacterData().data(); + } + else if( e.tagName() == "textPath" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + QString key = uri.mid( start, end - start ); + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + path = dynamic_cast( obj ); + } + else + { + QDomElement p = m_paths[key]; + path = dynamic_cast( createObject( p ) ); + if( path ) + path->setState( VObject::deleted ); + } + if( ! path ) + continue; + base = *path->paths().getFirst(); + content += e.text(); + } + else if( e.tagName() == "tspan" ) + { + // only use text of tspan element, as we are not supporting text + // with different styles + content += e.text(); + if( base.isEmpty() && ! e.attribute( "x" ).isEmpty() && ! e.attribute( "y" ).isEmpty() ) + { + QStringList posX = QStringList::split( ", ", e.attribute( "x" ) ); + QStringList posY = QStringList::split( ", ", e.attribute( "y" ) ); + if( posX.count() && posY.count() ) + { + double x = parseUnit( posX.first() ); + double y = parseUnit( posY.first() ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + } + } + } + else if( e.tagName() == "tref" ) + { + if( e.attribute( "xlink:href" ).isEmpty() ) + continue; + + QString uri = e.attribute( "xlink:href" ); + unsigned int start = uri.find("#") + 1; + unsigned int end = uri.findRev(")"); + QString key = uri.mid( start, end - start ); + + if( ! m_paths.contains(key) ) + { + VObject* obj = findObject( key ); + if( obj ) + content += dynamic_cast( obj )->text(); + } + else + { + QDomElement p = m_paths[key]; + content += p.text(); + } + } + else + continue; + } + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, content.simplifyWhiteSpace() ); + } + else + { + VSubpath base( 0L ); + double x = parseUnit( b.attribute( "x" ) ); + double y = parseUnit( b.attribute( "y" ) ); + base.moveTo( KoPoint( x, y ) ); + base.lineTo( KoPoint( x + 10, y ) ); + text = new VText( m_gc.current()->font, base, VText::Above, VText::Left, b.text().simplifyWhiteSpace() ); + } + + if( text ) + { + text->setParent( &m_document ); + + parseStyle( text, b ); + trafo.visit( *text ); + + if( !b.attribute("id").isEmpty() ) + text->setName( b.attribute("id") ); + + if( grp ) + grp->append( text ); + else + m_document.append( text ); + } + delete( m_gc.pop() ); +} + +VObject* XAMLImport::createObject( const QDomElement &b ) +{ + if( b.tagName() == "rect" ) + { + addGraphicContext(); + double x = parseUnit( b.attribute( "x" ), true, false, m_outerRect ); + double y = parseUnit( b.attribute( "y" ), false, true, m_outerRect ); + double width = parseUnit( b.attribute( "width" ), true, false, m_outerRect ); + double height = parseUnit( b.attribute( "height" ), false, true, m_outerRect ); + setupTransform( b ); + return new VRectangle( 0L, KoPoint( x, height + y ) , width, height ); + } + else if( b.tagName() == "ellipse" ) + { + addGraphicContext(); + setupTransform( b ); + double rx = parseUnit( b.attribute( "rx" ) ); + double ry = parseUnit( b.attribute( "ry" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - rx; + double top = parseUnit( b.attribute( "cy" ) ) - ry; + return new VEllipse( 0L, KoPoint( left, top ), rx * 2.0, ry * 2.0 ); + } + else if( b.tagName() == "circle" ) + { + addGraphicContext(); + setupTransform( b ); + double r = parseUnit( b.attribute( "r" ) ); + double left = parseUnit( b.attribute( "cx" ) ) - r; + double top = parseUnit( b.attribute( "cy" ) ) - r; + return new VEllipse( 0L, KoPoint( left, top ), r * 2.0, r * 2.0 ); + } + else if( b.tagName() == "line" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + double x1 = b.attribute( "x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x1" ) ); + double y1 = b.attribute( "y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y1" ) ); + double x2 = b.attribute( "x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "x2" ) ); + double y2 = b.attribute( "y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "y2" ) ); + path->moveTo( KoPoint( x1, y1 ) ); + path->lineTo( KoPoint( x2, y2 ) ); + return path; + } + else if( b.tagName() == "polyline" || b.tagName() == "polygon" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + bool bFirst = true; + + QString points = b.attribute( "points" ).simplifyWhiteSpace(); + points.replace( ',', ' ' ); + points.remove( '\r' ); + points.remove( '\n' ); + QStringList pointList = QStringList::split( ' ', points ); + for( QStringList::Iterator it = pointList.begin(); it != pointList.end(); ++it) + { + KoPoint point; + point.setX( (*it).toDouble() ); + point.setY( (*it).toDouble() ); + if( bFirst ) + { + path->moveTo( point ); + bFirst = false; + } + else + path->lineTo( point ); + } + if( b.tagName() == "polygon" ) path->close(); + return path; + } + else if( b.tagName() == "path" ) + { + addGraphicContext(); + setupTransform( b ); + VPath *path = new VPath( &m_document ); + path->loadSvgPath( b.attribute( "d" ) ); + return path; + } + else if( b.tagName() == "image" ) + { + addGraphicContext(); + setupTransform( b ); + QString fname = b.attribute("xlink:href"); + return new VImage( 0L, fname ); + } + + return 0L; +} + +#include diff --git a/filters/karbon/xaml/xamlimport.h b/filters/karbon/xaml/xamlimport.h new file mode 100644 index 000000000..057634192 --- /dev/null +++ b/filters/karbon/xaml/xamlimport.h @@ -0,0 +1,91 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XAMLIMPORT_H__ +#define __XAMLIMPORT_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xamlgraphiccontext.h" + +class VGroup; +class VPath; + +class XAMLImport : public KoFilter +{ + Q_OBJECT + +public: + XAMLImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XAMLImport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + +protected: + class GradientHelper + { + public: + GradientHelper() + { + bbox = true; + } + VGradient gradient; + bool bbox; + QWMatrix gradientTransform; + }; + + void parseGroup( VGroup *, const QDomElement & ); + void parseStyle( VObject *, const QDomElement & ); + void parsePA( VObject *, XAMLGraphicsContext *, const QString &, const QString & ); + void parseGradient( const QDomElement & ); + void parseColorStops( VGradient *, const QDomElement & ); + double parseUnit( const QString &, bool horiz = false, bool vert = false, KoRect bbox = KoRect() ); + void parseColor( VColor &, const QString & ); + QColor parseColor( const QString & ); + double toPercentage( QString ); + double fromPercentage( QString ); + void setupTransform( const QDomElement & ); + void addGraphicContext(); + QDomDocument inpdoc; + QDomDocument outdoc; + void convert(); + VObject* createObject( const QDomElement & ); + void createText( VGroup *, const QDomElement & ); + void parseFont( const QDomElement & ); + // find object with given id in document + VObject* findObject( const QString &name ); + // find object with given id in given group + VObject* findObject( const QString &name, VGroup * ); + +private: + VDocument m_document; + QPtrStack m_gc; + QMap m_gradients; + QMap m_paths; + KoRect m_outerRect; +}; + +#endif diff --git a/filters/karbon/xcf/Makefile.am b/filters/karbon/xcf/Makefile.am new file mode 100644 index 000000000..83ef82299 --- /dev/null +++ b/filters/karbon/xcf/Makefile.am @@ -0,0 +1,27 @@ +kde_module_LTLIBRARIES = libkarbonxcfexport.la + +libkarbonxcfexport_la_LDFLAGS = $(KDE_PLUGIN) +libkarbonxcfexport_la_LIBADD = \ + $(LIB_KOFFICEUI) \ + ../../../karbon/libkarboncommon.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) $(KOPAINTER_INCLUDES) \ + -I$(top_srcdir)/karbon \ + -I$(top_srcdir)/karbon/core \ + -I$(top_srcdir)/karbon/render \ + -I$(top_srcdir)/karbon/visitors \ + $(all_includes) + +service_DATA = karbon_xcf_export.desktop +servicedir = $(kde_servicesdir) + +noinst_HEADERS = \ + xcfexport.h + +libkarbonxcfexport_la_SOURCES = \ + xcfexport.cc + +libkarbonxcfexport_la_METASOURCES = \ + AUTO + diff --git a/filters/karbon/xcf/karbon_xcf_export.desktop b/filters/karbon/xcf/karbon_xcf_export.desktop new file mode 100644 index 000000000..78772e8ef --- /dev/null +++ b/filters/karbon/xcf/karbon_xcf_export.desktop @@ -0,0 +1,65 @@ +[Desktop Entry] +Icon= +Name=Karbon14 Gimp Export Filter +Name[af]=Karbon14 Gimp Voer uit Filter +Name[ar]=مِرْشَح تصدير Gimp لدى Karbon14 +Name[bg]=Филтър за експортиране от Karbon14 в Gimp +Name[br]=Sil ezporzh Gimp evit Karbon14 +Name[ca]=Filtre d'exportació Gimp per a Karbon14 +Name[cs]=Exportní filtr do formátu Gimp pro Karbon +Name[cy]=Hidlen Allforio Gimp Karbon14 +Name[da]=Karbon14 Gimp-eksportfilter +Name[de]=Karbon14 Gimp-Exportfilter +Name[el]=Φίλτρο εξαγωγής Gimp του Karbon14 +Name[eo]=Karbon14-Gimp-eksportfiltrilo +Name[es]=Filtro de exportación Gimp de Karbon14 +Name[et]=Karbon14 Gimp'i ekspordifilter +Name[eu]=Karbon14-en Gimp esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Karbon14 Gimp +Name[fi]=Karbon14 Gimp -vientisuodin +Name[fr]=Filtre d'exportation Gimp de Karbon 14 +Name[fy]=Gimp-Eksportfilter foar Karbon14 +Name[ga]=Scagaire Easpórtála Gimp Karbon14 +Name[gl]=Filtro de Exportación de Gimp para Karbon14 +Name[he]=מסנן ייצוא מ־Karbon14 ל־Gimp +Name[hr]=Karbon14 Gimp filtar izvoza +Name[hu]=Karbon14 Gimp exportszűrő +Name[is]=Karbon14 Gimp útflutningssía +Name[it]=Filtro di esportazione Gimp per Karbon14 +Name[ja]=Karbon14 Gimp エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ Gimp សម្រាប់ Karbon14 +Name[lo]=ຕົວຕອງການສົ່ງອອກ SVG ຂອງ Karbon14 +Name[lt]=Karbon14 Gimp eksportavimo filtras +Name[lv]=Karbon14 Gimp eksporta filtrs +Name[ms]=Penapis Eksport Karbon14 Gimp +Name[nb]=Gimp-eksportfiler for Karbon14 +Name[nds]=Gimp-Exportfilter för Karbon14 +Name[ne]=कार्बन१४ गिम्प निर्यात फिल्टर +Name[nl]=Gimp-exportfilter voor Karbon14 +Name[nn]=Gimp-eksportfilter for Karbon14 +Name[pl]=Filtr eksportu do formatu Gimpa z Karbon14 +Name[pt]=Filtro de Exportação de Gimp para o Karbon14 +Name[pt_BR]=Filtro de Exportação para o Gimp do Karbon14 +Name[ro]=Filtru exportare Karbon14 pentru Gimp +Name[ru]=Фильтр экспорта рисунков Karbon14 в формат Gimp +Name[se]=Karbon14:a Gimp-olggosfievrridansilli +Name[sk]=GIMP filter pre export z Karbon14 +Name[sl]=Izvozni filter Gimp za Karbon14 +Name[sr]=Karbon14-ов филтер за извоз у Gimp-а +Name[sr@Latn]=Karbon14-ov filter za izvoz u Gimp-a +Name[sv]=Karbon14 Gimp-exportfilter +Name[ta]=Karbon 14 gimp ஏற்றுமதி வடிகட்டி +Name[tg]=Karbon14 Gimp Филтри Содирот +Name[tr]=Karbon14 Gimp Aktarma Filtresi +Name[uk]=Фільтр експорту Gimp для Karbon +Name[uz]=Karbon14 Gimp eksport filteri +Name[uz@cyrillic]=Karbon14 Gimp экспорт филтери +Name[xh]=Isihluzi Sokurhweba ngaphandle se Karbon14 Gimp +Name[zh_CN]=Karbon14 Gimp 导出过滤器 +Name[zh_TW]=Karbon14 Gimp 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/x-xcf-gimp +X-KDE-Import=application/x-karbon +X-KDE-Library=libkarbonxcfexport +X-KDE-Weight=1 diff --git a/filters/karbon/xcf/xcfexport.cc b/filters/karbon/xcf/xcfexport.cc new file mode 100644 index 000000000..fde8bbd57 --- /dev/null +++ b/filters/karbon/xcf/xcfexport.cc @@ -0,0 +1,458 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "vdocument.h" +#include "vlayer.h" +#include "xcfexport.h" + +#include + + +// Tile size constants. +const unsigned XcfExport::m_tileWidth = 64; +const unsigned XcfExport::m_tileHeight = 64; + + +typedef KGenericFactory XcfExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkarbonxcfexport, XcfExportFactory( "kofficefilters" ) ) + + +XcfExport::XcfExport( KoFilter*, const char*, const QStringList& ) + : KoFilter() +{ + m_zoomX = 1.0; + m_zoomY = 1.0; +} + +KoFilter::ConversionStatus +XcfExport::convert( const QCString& from, const QCString& to ) +{ + if( to != "image/x-xcf-gimp" || from != "application/x-karbon" ) + { + return KoFilter::NotImplemented; + } + + + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + + if( !storeIn ) + return KoFilter::StupidError; + + + QFile fileOut( m_chain->outputFile() ); + + if( !fileOut.open( IO_WriteOnly ) ) + return KoFilter::StupidError; + + + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + m_stream = new QDataStream( &fileOut ); + + + // Load the document. + VDocument doc; + doc.load( docNode ); + + // Process the document. + doc.accept( *this ); + + + delete m_stream; + fileOut.close(); + + return KoFilter::OK; +} + +void +XcfExport::visitVDocument( VDocument& document ) +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Save width and height for layer saving. + m_width = static_cast( document.width() * m_zoomX ); + m_height = static_cast( document.height() * m_zoomY ); + + + // Header tag (size 14 bytes). + m_stream->writeRawBytes( "gimp xcf file", 14 ); + + // Image width. + *m_stream << static_cast( m_width ); + + // Image height. + *m_stream << static_cast( m_height ); + + // Image type = RGB. + *m_stream << static_cast( 0 ); + + // Do not save any properties currently. + *m_stream + // "END". + << static_cast( 0 ) + // Property size in bytes. + << static_cast( 0 ); + + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for layer and channel offsets. + m_stream->device()->at( + // current position + (number layers + number channels + 2) * 4. + current + ( document.layers().count() + 3 + 2 ) * 4 ); + + + // Iterate over layers. + VLayerListIterator itr( document.layers() ); + + for( ; itr.current(); ++itr ) + { + // Save start offset. + start = m_stream->device()->at(); + + + // Write layer. + itr.current()->accept( *this ); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save layer offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } + + + // Return to current offset. + m_stream->device()->at( current ); + + // Append a zero offset to indicate end of layer offsets. + *m_stream << static_cast( 0 ); + + + // Return to end offset. + m_stream->device()->at( end ); + + // Append a zero offset to indicate end of channel offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::visitVLayer( VLayer& layer ) +{ + // Layer width = image width. + *m_stream << static_cast( m_width ); + + // Layer height = image height. + *m_stream << static_cast( m_height ); + + // Layer type = RGBA. + *m_stream << static_cast( 1 ); + + // Layer name. + *m_stream << layer.name().latin1(); + + // Layer opacity. + *m_stream << static_cast( 6 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // Fully opaque = 255. + *m_stream << static_cast( 255 ); + + // Layer visible? + *m_stream << static_cast( 8 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // True. + *m_stream << static_cast( 1 ); + + // Layer linked? + *m_stream << static_cast( 9 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Preserve transparency? + *m_stream << static_cast( 10 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Apply mask? + *m_stream << static_cast( 11 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Edit mask? + *m_stream << static_cast( 12 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Show mask? + *m_stream << static_cast( 13 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Layer offsets. + *m_stream << static_cast( 15 ); + // Property size in bytes. + *m_stream << static_cast( 8 ); + // X-Offset. + *m_stream << static_cast( 0 ); + // Y-Offset. + *m_stream << static_cast( 0 ); + + // Layer mode. + *m_stream << static_cast( 7 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // Normal mode. + *m_stream << static_cast( 0 ); + + // TODO: Tattoo. + *m_stream << static_cast( 20 ); + // Property size in bytes. + *m_stream << static_cast( 4 ); + // False. + *m_stream << static_cast( 0 ); + + // Layer properties end. + *m_stream << static_cast( 0 ); + // Property size in bytes. + *m_stream << static_cast( 0 ); + + + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for hierarchy offsets. + m_stream->device()->at( current + 8 ); + + // Save start offset. + start = m_stream->device()->at(); + + + // Write hierarchy. + writeHierarchy(); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save hierarchy offset. + *m_stream << start; + + + // Append a zero offset to indicate end of layer mask offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::writeHierarchy() +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + // Width (again?). + *m_stream << m_width; + + // Height (again?). + *m_stream << m_height; + + // Color depth. + *m_stream << static_cast( 3 ); + + + // Calculate level number. + int levX = levels( m_width, m_tileWidth ); + int levY = levels( m_height, m_tileHeight ); + int levels = QMAX( levX, levY ); + + int width = m_width; + int height = m_height; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for level offsets. + m_stream->device()->at( current + ( levels + 1 ) * 4 ); + + for( int i = 0; i < levels; ++i ) + { + // Save start offset. + start = m_stream->device()->at(); + + if( i == 0 ) + { + // Write level. + writeLevel(); + } + else + { + // Fake an empty level. + width /= 2; + height /= 2; + + *m_stream << static_cast( width ); + *m_stream << static_cast( height ); + *m_stream << static_cast( 0 ); + } + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save level offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } + + // Return to current offset. + m_stream->device()->at( current ); + + // Append a zero offset to indicate end of level offsets. + *m_stream << static_cast( 0 ); +} + +void +XcfExport::writeLevel() +{ + // Offsets. + QIODevice::Offset current = 0; + QIODevice::Offset start = 0; + QIODevice::Offset end = 0; + + *m_stream << static_cast( m_width ); + *m_stream << static_cast( m_height ); + + int rows = ( m_height + m_tileHeight - 1 ) / m_tileHeight; + int cols = ( m_width + m_tileWidth - 1 ) / m_tileWidth; + int tiles = rows * cols; + + // Save current offset. + current = m_stream->device()->at(); + + // Leave space for tile offsets. + m_stream->device()->at( current + ( tiles + 1 ) * 4 ); + + for( int i = 0; i < tiles; ++i ) + { + // Save start offset. + start = m_stream->device()->at(); + + + // TODO: Save tile. + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + *m_stream << static_cast( 1 ); + + + // Save end offset. + end = m_stream->device()->at(); + + // Return to current offset. + m_stream->device()->at( current ); + + // Save tile offset. + *m_stream << start; + + // Increment offset. + current = m_stream->device()->at(); + + // Return to end offset. + m_stream->device()->at( end ); + } +} + +int +XcfExport::levels( int layerSize, int tileSize ) +{ + int l = 1; + + while( layerSize > tileSize ) + { + layerSize /= 2; + l += 1; + } + + return l; +} + +#include "xcfexport.moc" diff --git a/filters/karbon/xcf/xcfexport.h b/filters/karbon/xcf/xcfexport.h new file mode 100644 index 000000000..92913cb44 --- /dev/null +++ b/filters/karbon/xcf/xcfexport.h @@ -0,0 +1,97 @@ +/* This file is part of the KDE project + Copyright (C) 2002, The Karbon Developers + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XCFEXPORT_H__ +#define __XCFEXPORT_H__ + + +#include + +#include "vvisitor.h" + + +class QDataStream; +class VDocument; +class VLayer; + + +class XcfExport : public KoFilter, private VVisitor +{ + Q_OBJECT + +public: + XcfExport( KoFilter* parent, const char* name, const QStringList& ); + virtual ~XcfExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + + virtual void visitVDocument( VDocument& document ); + virtual void visitVLayer( VLayer& layer ); + +private: + /** + * Writes a hierarchy. + */ + void writeHierarchy(); + + /** + * Writes a level. + */ + void writeLevel(); + + /** + * Calculates levels from layer and tile size. + */ + static int levels( int layerSize, int tileSize ); + + + /** + * Tile size constants. + */ + static const unsigned m_tileWidth; + static const unsigned m_tileHeight; + + /** + * Output stream. + */ + QDataStream* m_stream; + + /** + * Image width. + */ + unsigned m_width; + + /** + * Image height. + */ + unsigned m_height; + + /** + * X-zoom factor. + */ + double m_zoomX; + + /** + * Y-zoom factor. + */ + double m_zoomY; +}; + +#endif + diff --git a/filters/karbon/xfig/karbon_xfig_import.desktop b/filters/karbon/xfig/karbon_xfig_import.desktop new file mode 100644 index 000000000..227854c12 --- /dev/null +++ b/filters/karbon/xfig/karbon_xfig_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Karbon XFig Import Filter +Name[ar]=مِرْشَح استيراد XFig لدى Karbon +Name[bg]=Филтър за импортиране от XFig в Karbon +Name[br]=Sil enporzh XFig evit Karbon +Name[ca]=Filtre d'importació XFig per a Karbon +Name[cs]=Importní filtr Xfig pro Karbon +Name[cy]=Hidlen Fewnforio XFig Karbon +Name[da]=Karbon XFig-importfilter +Name[de]=Karbon14 XFig-Importfilter +Name[el]=Φίλτρο εισαγωγής XFig του Karbon +Name[eo]=Karbon-XFig-importfiltrilo +Name[es]=Filtro de importación XFig de Karbon +Name[et]=Karboni XFig'i impordifilter +Name[eu]=Karbon14-en XFig esportaziorako iragazkia +Name[fa]=پالایۀ واردات Karbon XFig +Name[fi]=Karbon XFig -tuontisuodin +Name[fr]=Filtre d'importation XFig de Karbon 14 +Name[fy]=Xfig-Ymportfilter foar Karbon +Name[ga]=Scagaire Iompórtála Karbon XFig +Name[gl]=Filtro de Importación de XFig para Karbon +Name[he]=מסנן ייבוא מ־XFig ל־Karbon +Name[hr]=Karbon XFig filtar uvoza +Name[hu]=Karbon XFig importszűrő +Name[is]=Karbon XFig innflutningssía +Name[it]=Filtro di importazione XFig per Karbon +Name[ja]=Karbon XFig インポートフィルタ +Name[km]=តម្រង​នាំចូល XFig សម្រាប់ Karbon +Name[lt]=Karbon XFig importavimo filtras +Name[lv]=Karbon XFig importa filtrs +Name[ms]=Penapis Import Karbon XFig +Name[nb]=XFig-importfilter for Karbon +Name[nds]=XFig-Importfilter för Karbon14 +Name[ne]=कार्बन एक्सआकृति निर्यात फिल्टर +Name[nl]=Xfig-importfilter voor Karbon +Name[nn]=XFig-importfilter for Karbon +Name[pl]=Filtr importu formatu XFig do Karbon +Name[pt]=Filtro de Importação de XFig para o Karbon +Name[pt_BR]=Filtro de Importação XFig do Karbon +Name[ro]=Filtru importare Karbon14 pentru XFig +Name[ru]=Фильтр импорта рисунков XFig в Karbon +Name[se]=Karbon:a XFig-sisafievrridansilli +Name[sk]=XFig filter pre import pre Karbon +Name[sl]=Uvozni filter XFig za Karbon +Name[sr]=Karbon-ов филтер за увоз из XFig-а +Name[sr@Latn]=Karbon-ov filter za uvoz iz XFig-a +Name[sv]=Karbon Xfig-importfilter +Name[ta]=karbon xfig இறக்குமதி வடிகட்டி +Name[tg]=Karbon XFig Филтри Воридот +Name[tr]=Karbon XFig Alma Filtresi +Name[uk]=Фільтр імпорту XFig для Karbon +Name[uz]=Karbon XFig import filteri +Name[uz@cyrillic]=Karbon XFig импорт филтери +Name[zh_CN]=Karbon XFig 导入过滤器 +Name[zh_TW]=Karbon XFig 匯入過濾程式 +X-KDE-Export=application/x-karbon +X-KDE-Import=image/x-xfig +X-KDE-Weight=1 +X-KDE-Library=libxfigimport +ServiceTypes=KOfficeFilter diff --git a/filters/karbon/xfig/status.html b/filters/karbon/xfig/status.html new file mode 100644 index 000000000..e86ff8d9f --- /dev/null +++ b/filters/karbon/xfig/status.html @@ -0,0 +1,157 @@ + + + + + KOffice filters status: XFig FILTER + + +  + +
    +
    +

    + KOffice filters status:   XFig FILTER +

    +
    + +
    + + + Import | + Export + + +


    +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Import XFig for karbon
    +
    +
    +
    Last update-
    Features- Can import XFig documents.
    TodoNeeds to be ported from kontour to karbon libs.
    History-
    Authors -
    Links-
    Progress report ---
    +
    +
    +Up + +


    + +
    +


    + + +
    + +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Export karbon file to XFig

    +
    +
    Last update-
    Features-
    TodoEverything
    History-
    Authors-
    Links
    Progress report -
    +
    +
    +Up + +
    +






    + + + diff --git a/filters/karbon/xfig/xfigimport.cc b/filters/karbon/xfig/xfigimport.cc new file mode 100644 index 000000000..06301e01d --- /dev/null +++ b/filters/karbon/xfig/xfigimport.cc @@ -0,0 +1,760 @@ +/* + Copyright (C) 1998 Kai-Uwe Sattler + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +namespace std { }; +using namespace std; + +#define RAD_FACTOR 180.0 / M_PI + +unsigned int colors[] = { + 0x000090, + 0x0000b0, + 0x0000d0, + 0x87ceff, + 0x009000, + 0x00b000, + 0x00d000, + 0x009090, + 0x00b0b0, + 0x00d0d0, + 0x900000, + 0xb00000, + 0xd00000, + 0x900090, + 0xb000b0, + 0xd000d0, + 0x803000, + 0xa04000, + 0xc06000, + 0xff8080, + 0xffa0a0, + 0xffc0c0, + 0xffe0e0, + 0xffd700 +}; + +int arrow_ids[] = { + 6, 1, 2, 7 +}; + +struct PSFont { + const char* family; + QFont::Weight weight; + bool italic; +} psFontTable[] = { + { "times", QFont::Normal, false }, // Times Roman + { "times", QFont::Normal, true }, // Times Italic + { "times", QFont::Bold, false }, // Times Bold + { "times", QFont::Bold, true }, // Times Bold Italic + { "avantgarde", QFont::Normal, false }, // AvantGarde Book + { "avantgarde", QFont::Normal, true }, // AvantGarde Book Oblique + { "avantgarde", QFont::DemiBold, false }, // AvantGarde Demi + { "avantgarde", QFont::DemiBold, true }, // AvantGarde Demi Oblique + { "bookman", QFont::Light, false }, // Bookman Light + { "bookman", QFont::Light, true }, // Bookman Light Italic + { "bookman", QFont::DemiBold, false }, // Bookman Demi + { "bookman", QFont::DemiBold, true }, // Bookman Demi Italic + { "courier", QFont::Normal, false }, // Courier + { "courier", QFont::Normal, true }, // Courier Oblique + { "courier", QFont::Bold, false }, // Courier Bold + { "courier", QFont::Bold, true }, // Courier Bold Oblique + { "helvetica", QFont::Normal, false }, // Helvetica + { "helvetica", QFont::Normal, true }, // Helvetica Oblique + { "helvetica", QFont::Bold, false }, // Helvetica Bold + { "helvetica", QFont::Bold, true }, // Helvetica Bold Oblique + { "helvetica", QFont::Normal, false }, // Helvetica Narrow + { "helvetica", QFont::Normal, true }, // Helvetica Narrow Oblique + { "helvetica", QFont::Bold, false }, // Helvetica Narrow Bold + { "helvetica", QFont::Bold, true }, // Helvetica Narrow Bold Oblique + { "newcenturyschoolbook", QFont::Normal, false },// New Century Schoolbook + { "newcenturyschoolbook", QFont::Normal, true }, // New Century Italic + { "newcenturyschoolbook", QFont::Bold, false }, // New Century Bold + { "newcenturyschoolbook", QFont::Bold, true }, // New Century Bold Italic + { "palatino", QFont::Normal, false }, // Palatino Roman + { "palatino", QFont::Normal, true }, // Palatino Italic + { "palatino", QFont::Bold, false }, // Palatino Bold + { "palatino", QFont::Bold, true }, // Palatino Bold Italic + { "symbol", QFont::Normal, false }, // Symbol + { "zapfchancery", QFont::Normal, false }, // Zapf Chancery Medium Italic + { "zapfdingbats", QFont::Normal, false }, // Zapf Dingbats +}; + +int hexstrToInt (const char *str) { + const int fak[] = { 16, 1 }; + int value = 0, v; + + for (int i = 0; i < 2; i++) { + if (str[i] >= '0' && str[i] <= '9') + v = str[i] - '0'; + else + v = str[i] - 'a' + 10; + value += v * fak[i]; + } + + return value; +} + +XFIGImport::XFIGImport( KoFilter *parent, const char *name ) : KoFilter(parent, name) +{ + fig_resolution = 1200.0 / 72.0; + coordinate_system = 2; + + colorTable.insert (0, new QColor (Qt::black)); + colorTable.insert (1, new QColor (Qt::blue)); + colorTable.insert (2, new QColor (Qt::green)); + colorTable.insert (3, new QColor (Qt::cyan)); + colorTable.insert (4, new QColor (Qt::red)); + colorTable.insert (5, new QColor (Qt::magenta)); + colorTable.insert (6, new QColor (Qt::yellow)); + colorTable.insert (7, new QColor (Qt::white)); + + for (int i = 0; i <= 23; i++) + colorTable.insert (i + 8, new QColor (colors[i])); + + objList.clear (); +} + +XFIGImport::~XFIGImport() +{ +} + +bool XFIGImport::filterImport( const QString &file, KoDocument *doc, + const QString &from, const QString &to, + const QString & ) { + + if( to != "application/x-karbon" || from != "image/x-xfig" ) + return false; + + char buf[255]; + int value; + KoPageLayout layout; + + ifstream fin( file.local8Bit() ); + if (! fin) + return false; + + KIllustratorDocument *kidoc = (KIllustratorDocument *) doc; + GDocument *gdoc = kidoc->gdoc(); + //GPage *activePage = gdoc->activePage(); + + layout = gdoc->activePage()->pageLayout (); + + fin.getline (buf, 255); + if (::strncmp (buf, "#FIG 3", 6)) { + kdDebug() << "ERROR: no xfig file or wrong header" << endl; + return false; + } + + if (buf[7] == '2') { + version = 320; + } + else if (buf[7] == '1') { + version = 310; + } + else { + kdDebug() << "ERROR: unsupported xfig version" << endl; + return false; + } + + /* + * read the header + */ + + // orientation + fin.getline (buf, 255); + if (::strcmp (buf, "Landscape") == 0) + layout.orientation = PG_LANDSCAPE; + else if (::strcmp (buf, "Portrait") == 0) + layout.orientation = PG_PORTRAIT; + else + kdDebug() << "ERROR: invalid orientation" << endl; + + // justification (don't know how to handle this) + fin.getline (buf, 255); + + // units + fin.getline (buf, 255); + if (::strcmp (buf, "Metric") == 0) + layout.unit = PG_MM; + else if (::strcmp (buf, "Inches") == 0) + layout.unit = PG_INCH; + else + kdDebug() << "ERROR: invalid units" << endl; + + if (version >= 320) { + // paper size (don't know how to handle this) + fin.getline (buf, 255); + + // magnification + float magnification; + fin >> magnification; + fin.ignore (INT_MAX, '\n'); + + //multiple page (not supported yet) + fin.getline (buf, 255); + + // transparent color (not supported yet) + int transColor; + fin >> transColor; + fin.ignore (INT_MAX, '\n'); + } + + // resolution and coordinate system + fin >> value >> coordinate_system; + fig_resolution = value / 72.0; + fin.ignore (INT_MAX, '\n'); + + // now read in the objects + while (! fin.eof ()) { + int tag = -1; + fin >> tag; + if (tag == -1) { + // EOF + buildDocument (gdoc); + return true; + } + + switch (tag) { + case 0: + // a color pseudo object + parseColorObject (fin); + break; + case 1: + // a ellipse + parseEllipse (fin, gdoc); + break; + case 2: + // a polyline + parsePolyline (fin, gdoc); + break; + case 3: + // a spline + parseSpline (fin, gdoc); + break; + case 4: + // a text + parseText (fin, gdoc); + break; + case 5: + // an arc + parseArc (fin, gdoc); + break; + case 6: + // a compound object + parseCompoundObject (fin, gdoc); + break; + case -6: + // end of compound object --> ignore it + break; + default: + // should not occur + kdDebug() << "unknown object type: " << tag << endl; + break; + } + } + buildDocument (gdoc); + return true; +} + + +void XFIGImport::parseColorObject (istream& fin) { + int number, red, green, blue; + char buf[20], red_str[3], green_str[3], blue_str[3]; + + fin >> number >> buf; + strncpy (red_str, &buf[1], 2); red_str[2] = '\0'; + strncpy (green_str, &buf[3], 2); green_str[2] = '\0'; + strncpy (blue_str, &buf[5], 2); blue_str[2] = '\0'; + + red = hexstrToInt (red_str); + green = hexstrToInt (green_str); + blue = hexstrToInt (blue_str); + + colorTable.insert (number, new QColor (red, green, blue)); +} + +void XFIGImport::parseArc (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, cap_style, direction, + forward_arrow, backward_arrow, x1, y1, x2, y2, x3, y3; + float center_x, center_y; + float style_val; + GOval *obj = new GOval (doc); + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> cap_style + >> direction >> forward_arrow >> backward_arrow + >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; + + if (forward_arrow > 0) { + // forward arow line + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin.ignore (INT_MAX, '\n'); + } + + // compute radius + float dx = x1 - center_x; + float dy = y1 - center_y; + float radius = sqrt (dx * dx + dy * dy); + + if (radius==0) { + delete obj; + return; + } + + Coord p1 ((center_x - radius) / fig_resolution, + (center_y - radius) / fig_resolution); + Coord p2 ((center_x + radius) / fig_resolution, + (center_y + radius) / fig_resolution); + + obj->setStartPoint (p1); + obj->setEndPoint (p2); + + if (sub_type == 0) + obj->setOutlineShape (GObject::OutlineInfo::PieShape); + else if (sub_type == 1) + obj->setOutlineShape (GObject::OutlineInfo::ArcShape); + + p1 = Coord (center_x / fig_resolution, center_y /fig_resolution); + float m; + + float angle1; + p2 = Coord (x1 / fig_resolution, y1 /fig_resolution); + if (p2.x () == p1.x ()) { + if (p2.y () > p1.y ()) + angle1 = 90; + else + angle1 = -90; + } + else { + m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ())); + if ( p2.x () > p1.x ()) + angle1 = atan (m) * RAD_FACTOR; + else + angle1 = 180 + atan (m) * RAD_FACTOR; + } + + float angle2; + p2 = Coord (x3 / fig_resolution, y3 /fig_resolution); + if (p2.x () == p1.x ()) { + if (p2.y () > p1.y ()) + angle2 = 90; + else + angle2 = -90; + } + else { + m = ((p2.y () - p1.y ()) / (p2.x () - p1.x ())); + if ( p2.x () > p1.x ()) + angle2 = atan (m) * RAD_FACTOR; + else + angle2 = 180 + atan (m) * RAD_FACTOR; + } + + if (direction==0) // clockwise + obj->setAngles (angle2, angle1); + else if (direction==1) // counterclockwise + obj->setAngles (angle1, angle2); + + // now set the properties + setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color); + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseEllipse (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, direction, center_x, center_y, + radius_x, radius_y, start_x, start_y, end_x, end_y; + float style_val, angle; + GOval *obj = new GOval (doc); + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> direction + >> angle >> center_x >> center_y >> radius_x >> radius_y + >> start_x >> start_y >> end_x >> end_y; + Coord p1, p2; + + p1 = Coord ((center_x - radius_x) /fig_resolution, + (center_y - radius_y) /fig_resolution); + p2 = Coord ((center_x + radius_x) /fig_resolution, + (center_y + radius_y) /fig_resolution); + + obj->setStartPoint (p1); + obj->setEndPoint (p2); + + // now set the properties + setProperties (obj, pen_color, pen_style, thickness, area_fill, fill_color); + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parsePolyline (istream& fin, GDocument* doc) { + int sub_type, line_style, thickness, pen_color, fill_color, + depth, pen_style, area_fill, join_style, cap_style, radius, + forward_arrow, backward_arrow, npoints; + float style_val; + GPolyline *obj = NULL; + + // first line + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> join_style + >> cap_style >> radius >> forward_arrow >> backward_arrow + >> npoints; + fin.ignore (INT_MAX, '\n'); + + switch (sub_type) { + case 1: // polyline + obj = new GPolyline (doc); + break; + case 2: // box + obj = new GPolygon (doc); + break; + case 3: // polygon + obj = new GPolygon (doc); + break; + case 4: // arc-box + obj = new GPolygon (doc); + break; + case 5: // imported picture + return; + break; + default: + // doesn't occur + kdDebug() << "unknown subtype: " << sub_type << endl; + break; + } + + assert (obj != NULL); + + int arrow_type, arrow_style; + float arrow_thickness, arrow_width, arrow_height; + GObject::OutlineInfo oinfo; + oinfo.mask = GObject::OutlineInfo::Custom; + oinfo.startArrowId = oinfo.endArrowId = 0; + + if (forward_arrow > 0) { + + // forward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.endArrowId = arrow_ids[arrow_type]; + if (oinfo.endArrowId == 1 && arrow_style == 0) + oinfo.endArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.startArrowId = arrow_ids[arrow_type]; + if (oinfo.startArrowId == 1 && arrow_style == 0) + oinfo.startArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + // points line + for (int i = 0; i < npoints; i++) { + int x, y; + fin >> x >> y; + if ((sub_type == 2 || sub_type == 3) && i == npoints -1) + // first point == last point + break; + + Coord p (x / fig_resolution, y / fig_resolution); + obj->_addPoint (i, p); + } + + if (oinfo.startArrowId || oinfo.endArrowId) + obj->setOutlineInfo (oinfo); + + // now set the properties + setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color); + + // and insert the object + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseSpline (istream& fin, GDocument* doc) +{ + int sub_type, line_style, thickness, pen_color, fill_color, depth, + pen_style, area_fill, cap_style, forward_arrow, backward_arrow, npoints; + float style_val; + + // this should be a spline + GPolyline *obj = 0L; + fin >> sub_type >> line_style >> thickness >> pen_color >> fill_color + >> depth >> pen_style >> area_fill >> style_val >> cap_style + >> forward_arrow >> backward_arrow >> npoints; + if (sub_type == 1 || sub_type == 3 || sub_type == 5) + obj = new GPolygon (doc); + else + obj = new GPolyline (doc); + + int arrow_type, arrow_style; + float arrow_thickness, arrow_width, arrow_height; + GObject::OutlineInfo oinfo; + oinfo.mask = GObject::OutlineInfo::Custom; + oinfo.startArrowId = oinfo.endArrowId = 0; + + if (forward_arrow > 0) { + + // forward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.endArrowId = arrow_ids[arrow_type]; + if (oinfo.endArrowId == 1 && arrow_style == 0) + oinfo.endArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + if (backward_arrow > 0) { + // backward arrow line + fin >> arrow_type >> arrow_style >> arrow_thickness + >> arrow_width >> arrow_height; + oinfo.startArrowId = arrow_ids[arrow_type]; + if (oinfo.startArrowId == 1 && arrow_style == 0) + oinfo.startArrowId = 4; + fin.ignore (INT_MAX, '\n'); + } + + // points line + for (int i = 0; i < npoints; i++) { + int x, y; + fin >> x >> y; + if ((sub_type == 1 || sub_type == 3 || sub_type == 5) && i == npoints -1) + // first point == last point + break; + + Coord p (x / fig_resolution, y / fig_resolution); + obj->_addPoint (i, p); + } + + // control points line + for (int i = 0; i < npoints; i++) { + float fac; + fin >> fac; + // ignore it now + // fin.ignore (INT_MAX, '\n'); + } + + if (oinfo.startArrowId || oinfo.endArrowId) + obj->setOutlineInfo (oinfo); + + // now set the properties + setProperties (obj, pen_color, line_style, thickness, area_fill, fill_color); + + // and insert the object + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseText (istream& fin, GDocument* doc) +{ + int sub_type, color, depth, pen_style, font, font_flags, x, y; + float font_size, angle, height, length; + GText *obj = new GText (doc); + char c; + char ocode[4]; + bool finished = false; + QString text; + QFont qfont; + + fin >> sub_type >> color >> depth >> pen_style >> font >> font_size + >> angle >> font_flags >> height >> length >> x >> y; + + if (font_flags & 4) { + // PostScript font + if (font == -1) + font = 0; + qfont = QFont (psFontTable[font].family, qRound (font_size), + psFontTable[font].weight, psFontTable[font].italic); + } + else { + // LaTeX font + switch (font) { + case 1: // Roman + qfont.setFamily ("times"); + break; + case 2: // Bold + qfont.setBold (true); + break; + case 3: // Italic + qfont.setItalic (true); + break; + case 4: // Sans Serif + qfont.setFamily ("helvetica"); + break; + case 5: // Typewriter + qfont.setFamily ("Courier"); + break; + default: + break; + } + } + qfont.setPointSize (qRound (font_size)); + obj->setFont (qfont); + + while (! finished) { + fin.get (c); + if (c == '\\') { + fin.get (ocode, 4); + int code = (ocode[0] - '0') * 64 + + (ocode[1] - '0') * 8 + + (ocode[2] - '0'); + if (code == 1) + finished = true; + else + text += (char) code; + } + else + text += c; + } + obj->setText (text); + + if (sub_type == 1) { + GText::TextInfo ti = obj->getTextInfo (); + ti.align = GText::TextInfo::AlignCenter; + obj->setTextInfo (ti); + } + else if (sub_type == 2) { + GText::TextInfo ti = obj->getTextInfo (); + ti.align = GText::TextInfo::AlignRight; + obj->setTextInfo (ti); + } + Coord origin (x / fig_resolution, y / fig_resolution - qfont.pointSize ()); + obj->setOrigin (origin); + + if (angle != 0) { + // rotate the text + float nangle = angle * RAD_FACTOR; + QWMatrix m1, m2, m3; + Coord rotCenter; + + if (sub_type == 0) { + rotCenter = Coord (obj->boundingBox ().left (), + obj->boundingBox ().bottom ()); + } + else if (sub_type == 1) { + rotCenter = Coord (obj->boundingBox ().width () / 2, + obj->boundingBox ().bottom ()); + } + else if (sub_type == 2) { + rotCenter = Coord (obj->boundingBox ().right (), + obj->boundingBox ().bottom ()); + } + m1.translate (-rotCenter.x (), -rotCenter.y ()); + m2.rotate (-nangle); + m3.translate (rotCenter.x (), rotCenter.y ()); + obj->transform (m1); + obj->transform (m2); + obj->transform (m3, true); + } + + objList.append( GObjectListItem( depth, obj ) ); +} + +void XFIGImport::parseCompoundObject (istream& fin, GDocument* /*doc*/) { + int upperright_x, upperright_y, lowerleft_x, lowerleft_y; + + fin >> upperright_x >> upperright_y >> lowerleft_x >> lowerleft_y; + fin.ignore (INT_MAX, '\n'); +} + + +/** + * Copy all parsed objects from the sorted list to the document. + */ +void XFIGImport::buildDocument (GDocument *doc) { + doc->setAutoUpdate (false); + // This will sort all object, by decreasing depth + qBubbleSort(objList); + + // Now all we need to do is insert them in the document, in that order + QValueList::Iterator it=objList.begin(); + for ( ; it != objList.end() ; ++it ) + { + //kdDebug() << "Inserting object with depth=" << (*it).depth << endl; + GObject* obj = (*it).object; + obj->ref (); + doc->activePage()->insertObject (obj); + } + doc->setAutoUpdate (true); + objList.clear(); // save memory +} + +void XFIGImport::setProperties (GObject* obj, int pen_color, int style, + int thickness, int area_fill, int fill_color) { + if (pen_color >= 0) + obj->setOutlineColor (*colorTable[pen_color]); + + if (style < 1) + obj->setOutlineStyle (Qt::SolidLine); + else if (style == 1) + obj->setOutlineStyle (Qt::DashLine); + else if (style == 2) + obj->setOutlineStyle (Qt::DotLine); + + obj->setOutlineWidth (thickness * 72.0 / 80.0); + + if (area_fill == -1) + obj->setFillStyle (GObject::FillInfo::NoFill); + else { + obj->setFillStyle (GObject::FillInfo::SolidFill); + if (fill_color < 1) { + // for BLACK or DEFAULT color + int val = qRound ((20 - area_fill) * 255.0 / 20.0); + obj->setFillColor (QColor (val, val, val)); + } + else if (fill_color == 7) { + // for WHITE color + int val = qRound ( area_fill * 255.0 / 20.0); + obj->setFillColor (QColor (val, val, val)); + } + else + obj->setFillColor (*colorTable[fill_color]); + } +} + diff --git a/filters/karbon/xfig/xfigimport.h b/filters/karbon/xfig/xfigimport.h new file mode 100644 index 000000000..bf9593150 --- /dev/null +++ b/filters/karbon/xfig/xfigimport.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 1998 Kai-Uwe Sattler + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#ifndef XFIGIMPORT_H +#define XFIGIMPORT_H + +#include +#include +#include + +class GDocument; +class GObject; +class QColor; + +#include +#include +#include + +class XFIGImport : public KoFilter +{ + Q_OBJECT + +public: + XFIGImport( KoFilter *parent, const char *name ); + virtual ~XFIGImport(); + + virtual bool filterImport( const QString &file, KoDocument *, + const QString &from, const QString &to, + const QString &config=QString::null ); + +private: + void parseColorObject (istream& fin); + void parseArc (istream& fin, GDocument* doc); + void parseEllipse (istream& fin, GDocument* doc); + void parsePolyline (istream& fin, GDocument* doc); + void parseSpline (istream& fin, GDocument* doc); + void parseText (istream& fin, GDocument* doc); + void parseCompoundObject (istream& fin, GDocument* doc); + void buildDocument (GDocument *doc); + + void setProperties (GObject* obj, int pen_color, int style, int thickness, + int area_fill, int fill_color); + + float fig_resolution; + int coordinate_system; + int version; + QIntDict colorTable; + + // An object and the depth. Used for sorting objects + // in the object list + struct GObjectListItem + { + GObjectListItem() : object(0L) {} // for QValueList + + GObjectListItem( int d, GObject * obj ) : + object(obj), depth(d) {} + + GObject * object; + int depth; + bool operator < (const GObjectListItem & item ) const + { + // We want to sort by decreasing depths + return depth > item.depth; + } + bool operator == (const GObjectListItem & item ) const + { + return depth == item.depth; + } + }; + QValueList objList; +}; + +#endif diff --git a/filters/karbon/xfig/xfigimport_factory.cc b/filters/karbon/xfig/xfigimport_factory.cc new file mode 100644 index 000000000..7783072dd --- /dev/null +++ b/filters/karbon/xfig/xfigimport_factory.cc @@ -0,0 +1,67 @@ +/* + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#include "xfigimport_factory.h" +#include "xfigimport_factory.moc" +#include "xfigimport.h" + +#include +#include + +K_EXPORT_COMPONENT_FACTORY( libxfigimport, XFIGImportFactory ) + +KInstance *XFIGImportFactory::s_global = 0; + +XFIGImportFactory::XFIGImportFactory( + QObject *parent, + const char *name) : + KLibFactory(parent, name) +{ + s_global = new KInstance("xfigimport"); +} + +XFIGImportFactory::~XFIGImportFactory() +{ + delete s_global; + s_global = 0L; +} + +QObject *XFIGImportFactory::createObject( + QObject *parent, + const char *name, + const char*, + const QStringList &) +{ + if (parent && !parent->inherits("KoFilter")) + { + kdDebug(30502) << "XFIGImportFactory: parent does not inherit KoFilter" << endl; + return 0L; + } + XFIGImport *f = new XFIGImport((KoFilter*)parent, name); + return f; +} + +KInstance *XFIGImportFactory::global() +{ + return s_global; +} diff --git a/filters/karbon/xfig/xfigimport_factory.h b/filters/karbon/xfig/xfigimport_factory.h new file mode 100644 index 000000000..8da700402 --- /dev/null +++ b/filters/karbon/xfig/xfigimport_factory.h @@ -0,0 +1,46 @@ +/* + Copyright (C) 2001, Rob Buis + Copyright (C) 2003, Rob Buis + This file is part of the KDE project + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + +DESCRIPTION +*/ + +#ifndef XFIGIMPORT_FACTORY_H +#define XFIGIMPORT_FACTORY_H + +#include + +class KInstance; + +class XFIGImportFactory : + public KLibFactory +{ + Q_OBJECT +public: + XFIGImportFactory(QObject* parent = 0, const char* name = 0); + virtual ~XFIGImportFactory(); + + virtual QObject* createObject(QObject* parent = 0, const char* name = 0, const char* classname = "QObject", const QStringList &args = QStringList()); + + static KInstance* global(); + +private: + static KInstance* s_global; +}; +#endif diff --git a/filters/kchart/Makefile.am b/filters/kchart/Makefile.am new file mode 100644 index 000000000..913e248da --- /dev/null +++ b/filters/kchart/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = libimageexport bmp jpeg mng png svg xbm xpm diff --git a/filters/kchart/bmp/Makefile.am b/filters/kchart/bmp/Makefile.am new file mode 100644 index 000000000..de6eedf5a --- /dev/null +++ b/filters/kchart/bmp/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) +####### Files + +kde_module_LTLIBRARIES = libkchartbmpexport.la + +libkchartbmpexport_la_SOURCES = bmpexport.cpp +libkchartbmpexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartbmpexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + bmpexport.h + +METASOURCES = AUTO + +service_DATA = kchart_bmp_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kchart/bmp/bmpexport.cpp b/filters/kchart/bmp/bmpexport.cpp new file mode 100644 index 000000000..26ff2fe1a --- /dev/null +++ b/filters/kchart/bmp/bmpexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "bmpexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory bmpExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartbmpexport, bmpExportFactory( "bmpexport" ) ) + +BmpExport::BmpExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +BmpExport::~BmpExport() +{ +} + +void BmpExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "PNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + + +bool BmpExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "BMP" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "BMP Export Error" ) ); + } + return ret; +} + +const char * BmpExport::exportFormat() +{ + return "image/x-bmp"; +} + +#include "bmpexport.moc" + diff --git a/filters/kchart/bmp/bmpexport.h b/filters/kchart/bmp/bmpexport.h new file mode 100644 index 000000000..89afa941b --- /dev/null +++ b/filters/kchart/bmp/bmpexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __BMPEXPORT_H__ +#define __BMPEXPORT_H__ + +#include "imageexport.h" + +class BmpExport : public ImageExport +{ + Q_OBJECT + +public: + BmpExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~BmpExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __PNGEXPORT_H__ + diff --git a/filters/kchart/bmp/kchart_bmp_export.desktop b/filters/kchart/bmp/kchart_bmp_export.desktop new file mode 100644 index 000000000..008fd0005 --- /dev/null +++ b/filters/kchart/bmp/kchart_bmp_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KChart BMP Export Filter +Name[ar]=مِرْشَح تصدير BMP لدى Karbon14 +Name[bg]=Филтър за експортиране от KChart в BMP +Name[br]=Sil ezporzh BMP evit KChart +Name[ca]=Filtre d'exportació BMP per a KChart +Name[da]=KChart BMP-eksportfilter +Name[de]=KChart BMP-Exportfilter +Name[el]=Φίλτρο εξαγωγής BMP του KChart +Name[eo]=KChart-BMP-eksportfiltrilo +Name[es]=Filtro de exportación a BMP para KChart +Name[et]=KCharti BMP ekspordifilter +Name[fa]=پالایۀ صادرات KChart BMP +Name[fi]=KChart BMP -vientisuodin +Name[fr]=Filtre d'exportation BMP de KChart +Name[fy]=BMP-Eksportfilter foar Kchart +Name[ga]=Scagaire Easpórtála BMP KChart +Name[gl]=Filtro de Exportación de BMP para KChart +Name[he]=KChart BMP מסנן יצוא +Name[hr]=KChart BMP filtar izvoza +Name[hu]=KChart BMP exportszűrő +Name[is]=KChart BMP útflutningssía +Name[it]=Filtro di esportazione BMP per KChart +Name[ja]=KChar BMP エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ BMP សម្រាប់ KChart +Name[lt]=KChart BMP eksportavimo filtras +Name[lv]=KChart BMP eksporta filtrs +Name[nb]=BMP-eksportfilter for KChart +Name[nds]=BMP-Exportfilter för KChart +Name[ne]=केडीई चित्रपट बीएमपी निर्यात फिल्टर +Name[nl]=BMP-exportfilter voor KChart +Name[pl]=Filtr eksportu do formatu BMP z KChart +Name[pt]=Filtro de Exportação de BMP para o KChart +Name[pt_BR]=Filtro de Exportação de BMP para o KChart +Name[ru]=Фильтр экспорта диаграмм KChart в BMP +Name[se]=KChart:a BMP-olggosfievrridansilli +Name[sk]=Exportný filter KChart BMP +Name[sl]=Izvozni filter BMP za KChart +Name[sr]=KChart-ов филтер за извоз у BMP +Name[sr@Latn]=KChart-ov filter za izvoz u BMP +Name[sv]=Kchart BMP-exportfilter +Name[uk]=Фільтр експорту BMP для KChart +Name[uz]=KChart BMP eksport filteri +Name[uz@cyrillic]=KChart BMP экспорт филтери +Name[zh_CN]=KChart BMP 导出过滤器 +Name[zh_TW]=KChart BMP 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/x-bmp +X-KDE-Weight=1 +X-KDE-Library=libkchartbmpexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/jpeg/Makefile.am b/filters/kchart/jpeg/Makefile.am new file mode 100644 index 000000000..88f87b407 --- /dev/null +++ b/filters/kchart/jpeg/Makefile.am @@ -0,0 +1,26 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkchartjpegexport.la + +libkchartjpegexport_la_SOURCES = jpegexport.cpp +libkchartjpegexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartjpegexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) + +noinst_HEADERS = \ + jpegexport.h + +METASOURCES = AUTO + +service_DATA = kchart_jpeg_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kchart/jpeg/jpegexport.cpp b/filters/kchart/jpeg/jpegexport.cpp new file mode 100644 index 000000000..709e2d0f1 --- /dev/null +++ b/filters/kchart/jpeg/jpegexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "jpegexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory jpegExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartjpegexport, jpegExportFactory( "jpegexport" ) ) + +JpegExport::JpegExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +JpegExport::~JpegExport() +{ +} + +void JpegExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "MNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + + +bool JpegExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "JPEG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "JPEG Export Error" ) ); + } + return ret; +} + +const char * JpegExport::exportFormat() +{ + return "image/jpeg"; +} + +#include "jpegexport.moc" + diff --git a/filters/kchart/jpeg/jpegexport.h b/filters/kchart/jpeg/jpegexport.h new file mode 100644 index 000000000..f167b0a28 --- /dev/null +++ b/filters/kchart/jpeg/jpegexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class JpegExport : public ImageExport +{ + Q_OBJECT + +public: + JpegExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~JpegExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/kchart/jpeg/kchart_jpeg_export.desktop b/filters/kchart/jpeg/kchart_jpeg_export.desktop new file mode 100644 index 000000000..a9561a5d4 --- /dev/null +++ b/filters/kchart/jpeg/kchart_jpeg_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KChart JPEG Export Filter +Name[ar]=مرشح تصدير KChart JPEG +Name[bg]=Филтър за експортиране от KChart в JPEG +Name[br]=Sil ezporzh JPEG evit KChart +Name[ca]=Filtre d'exportació JPEG per a KChart +Name[da]=KChart JPEG-eksportfilter +Name[de]=KChart JPEG-Exportfilter +Name[el]=Φίλτρο εξαγωγής JPEG του KChart +Name[eo]=KChart-JPEG-eksportfiltrilo +Name[es]=Filtro de exportación a JPEG para KChart +Name[et]=KCharti JPEG ekspordifilter +Name[fa]=پالایۀ صادرات KChart JPEG +Name[fi]=KChart JPEG -vientisuodin +Name[fr]=Filtre d'exportation JPEG de KChart +Name[fy]=JPEG-Eksportfilter foar KChart +Name[ga]=Scagaire Easpórtála JPEG KChart +Name[gl]=Filtro de Exportación de JPEG para KChart +Name[he]=KChart JPEG מסנן יצוא +Name[hr]=KChart JPEG filtar izvoza +Name[hu]=KChart JPEG exportszűrő +Name[is]=KChart JPEG útflutningssía +Name[it]=Filtro di esportazione JPEG per KChart +Name[ja]=KChart JPEG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ JPEG សម្រាប់ KChart +Name[lt]=KChart JPEG eksportavimo filtras +Name[lv]=KChart JPEG eksporta filtrs +Name[nb]=JPEG-eksportfilter for KChart +Name[nds]=JPEG-Exportfilter för KChart +Name[ne]=केडीई चित्रपट जेपीईजी निर्यात फिल्टर +Name[nl]=JPEG-exportfilter voor KChart +Name[pl]=Filtr eksportu do formatu JPEG z KChart +Name[pt]=Filtro de Exportação de JPEG para o KChart +Name[pt_BR]=Filtro de Exportação de JPEG para o KChart +Name[ru]=Фильтр экспорта диаграмм KChart в JPEG +Name[se]=KChart:a JPEG-olggosfievrridansilli +Name[sk]=Exportný filter KChart JPEG +Name[sl]=Izvozni filter JPEG za KChart +Name[sr]=KChart-ов филтер за извоз у JPEG +Name[sr@Latn]=KChart-ov filter za izvoz u JPEG +Name[sv]=Kchart JPEG-exportfilter +Name[uk]=Фільтр експорту JPEG для KChart +Name[uz]=KChart JPEG eksport filteri +Name[uz@cyrillic]=KChart JPEG экспорт филтери +Name[zh_CN]=KChart JPEG 导出过滤器 +Name[zh_TW]=KChart JPEG 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/jpeg +X-KDE-Weight=1 +X-KDE-Library=libkchartjpegexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/libimageexport/Makefile.am b/filters/kchart/libimageexport/Makefile.am new file mode 100644 index 000000000..e31b87302 --- /dev/null +++ b/filters/kchart/libimageexport/Makefile.am @@ -0,0 +1,23 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + $(all_includes) + +####### Files + +lib_LTLIBRARIES = libkchartimageexport.la + +libkchartimageexport_la_SOURCES = imageexport.cpp +libkchartimageexport_la_LDFLAGS = $(all_libraries) -version-info 4:0 -no-undefined +libkchartimageexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) + +noinst_HEADERS = \ + imageexport.h + +METASOURCES = AUTO + + diff --git a/filters/kchart/libimageexport/imageexport.cpp b/filters/kchart/libimageexport/imageexport.cpp new file mode 100644 index 000000000..7b9a61c4a --- /dev/null +++ b/filters/kchart/libimageexport/imageexport.cpp @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "imageexport.h" +#include "kchart_part.h" + +ImageExport::ImageExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +ImageExport::~ImageExport() +{ +} + + +KoFilter::ConversionStatus +ImageExport::convert(const QCString& from, const QCString& to) +{ + // Check for proper conversion. + if ( from != "application/x-kchart" || to != exportFormat() ) + return KoFilter::NotImplemented; + + // Read the contents of the KChart file + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if ( !storeIn ) { + KMessageBox::error( 0, i18n("Failed to read data." ), + i18n( "Export Error" ) ); + return KoFilter::FileNotFound; + } + + // Get the XML tree. + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // Read the document from the XML tree. + KChart::KChartPart kchartDoc; + if ( !kchartDoc.loadXML(0, domIn) ) { + KMessageBox::error( 0, i18n( "Malformed XML data." ), + i18n( "Export Error" ) ); + return KoFilter::WrongFormat; + } + width = 500; + height = 400; + extraImageAttribute(); + pixmap = QPixmap(width, height); + QPainter painter(&pixmap); + kchartDoc.paintContent(painter, pixmap.rect(), false); + if(!saveImage( m_chain->outputFile())) + return KoFilter::CreationError; + return KoFilter::OK; +} + + +#include "imageexport.moc" + diff --git a/filters/kchart/libimageexport/imageexport.h b/filters/kchart/libimageexport/imageexport.h new file mode 100644 index 000000000..a8314a08c --- /dev/null +++ b/filters/kchart/libimageexport/imageexport.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __IMAGEEXPORT_H__ +#define __IMAGEEXPORT_H__ + +#include + +class QPixmap; +class ImageExport : public KoFilter +{ + Q_OBJECT + +public: + ImageExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~ImageExport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + virtual void extraImageAttribute() {}; + virtual bool saveImage( QString fileName) = 0; + virtual const char* exportFormat() = 0; +protected: + int width; + int height; + QPixmap pixmap; +}; + +#endif // __IMAGEEXPORT_H__ + diff --git a/filters/kchart/mng/Makefile.am b/filters/kchart/mng/Makefile.am new file mode 100644 index 000000000..aaf62f2f3 --- /dev/null +++ b/filters/kchart/mng/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) +####### Files + +kde_module_LTLIBRARIES = libkchartmngexport.la + +libkchartmngexport_la_SOURCES = mngexport.cpp +libkchartmngexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartmngexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + mngexport.h + +METASOURCES = AUTO + +service_DATA = kchart_mng_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kchart/mng/kchart_mng_export.desktop b/filters/kchart/mng/kchart_mng_export.desktop new file mode 100644 index 000000000..c21755741 --- /dev/null +++ b/filters/kchart/mng/kchart_mng_export.desktop @@ -0,0 +1,47 @@ +[Desktop Entry] +Name=KChart MNG Export Filter +Name[bg]=Филтър за експортиране от KChart в MNG +Name[ca]=Filtre d'exportació MNG per a KChart +Name[da]=KChart MNG-eksportfilter +Name[de]=KChart MNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής MNG του KChart +Name[eo]=KChart-MNG-eksportfiltrilo +Name[es]=Filtro de exportación MNG para KChart +Name[et]=KCharti MNG ekspordifilter +Name[fa]=پالایۀ صادرات KChart MNG +Name[fi]=KChart MNG -vientisuodin +Name[fr]=Filtre d'exportation MNG de KChart +Name[fy]=MNG-Eksportfilter foar KChart +Name[he]=KChart MNG מסנן יצוא +Name[hr]=KChart MNG filtar izvoza +Name[hu]=KChart MNG exportszűrő +Name[it]=Filtro di esportazione MNG per KChart +Name[ja]=KChart MNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ MNG សម្រាប់ KChart +Name[lt]=KChart MNG eksportavimo filtras +Name[lv]=KChart MNG eksporta filtrs +Name[nb]=MNG-eksportfilter for KChart +Name[nds]=KMNG-Exportfilter för KChart +Name[ne]=केडीई चित्रपट एमएनजी निर्यात फिल्टर +Name[nl]=MNG-exportfilter voor KChart +Name[pl]=Filtr eksportu do formatu MNG z KChart +Name[pt]=Filtro de Exportação de MNG para o KChart +Name[pt_BR]=Filtro de Exportação MNG do KChart +Name[ru]=Фильтр экспорта диаграмм KChart в MNG +Name[se]=KChart:a MNG-olggosfievrridansilli +Name[sk]=Exportný filter KChart MNG +Name[sl]=Izvozni filter MNG za KChart +Name[sr]=KChart-ов филтер за извоз у MNG +Name[sr@Latn]=KChart-ov filter za izvoz u MNG +Name[sv]=Kchart MNG-exportfilter +Name[uk]=Фільтр експорту MNG для KChart +Name[uz]=KChart MNG eksport filteri +Name[uz@cyrillic]=KChart MNG экспорт филтери +Name[zh_CN]=KChart MNG 导出过滤器 +Name[zh_TW]=KChart MNG 匯出過濾程式 +Type=Service +X-KDE-Import=application/x-kchart +X-KDE-Export=video/x-mng +X-KDE-Weight=1 +X-KDE-Library=libkchartmngexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/mng/mngexport.cpp b/filters/kchart/mng/mngexport.cpp new file mode 100644 index 000000000..b029beeaa --- /dev/null +++ b/filters/kchart/mng/mngexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "mngexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory mngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartmngexport, mngExportFactory( "mngexport" ) ) + +MngExport::MngExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +MngExport::~MngExport() +{ +} + +void MngExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "MNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + + +bool MngExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "MNG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "MNG Export Error" ) ); + } + return ret; +} + +const char * MngExport::exportFormat() +{ + return "video/x-mng"; +} + +#include "mngexport.moc" + diff --git a/filters/kchart/mng/mngexport.h b/filters/kchart/mng/mngexport.h new file mode 100644 index 000000000..38f7830e8 --- /dev/null +++ b/filters/kchart/mng/mngexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class MngExport : public ImageExport +{ + Q_OBJECT + +public: + MngExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MngExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/kchart/png/Makefile.am b/filters/kchart/png/Makefile.am new file mode 100644 index 000000000..7231ef130 --- /dev/null +++ b/filters/kchart/png/Makefile.am @@ -0,0 +1,32 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkchartpngexport.la + +libkchartpngexport_la_SOURCES = pngexport.cpp +libkchartpngexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartpngexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + pngexport.h + +METASOURCES = AUTO + +service_DATA = kchart_png_export.desktop +servicedir = $(kde_servicesdir) + +# Note: If your filter exports or exports some special file +# which KDE doesn't have a mimetype for, yet, you'll have to +# create a mimetype and install it using those two lines. +# In case of doubt please ask koffice@kde.org or +# koffice-devel@kde.org. Thanks. +# data_DATA = x-png.desktop +# datadir = $(kde_mimedir)/text diff --git a/filters/kchart/png/kchart_png_export.desktop b/filters/kchart/png/kchart_png_export.desktop new file mode 100644 index 000000000..8f33bdf36 --- /dev/null +++ b/filters/kchart/png/kchart_png_export.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Type=Service +Name=KChart PNG Export Filter +Name[ar]=مِرْشَح تصدير PNG لدى KChart +Name[bg]=Филтър за експортиране от KChart в PNG +Name[br]=Sil ezporzh PNG evit KChart +Name[ca]=Filtre d'exportació PNG per a KChart +Name[cs]=Exportní filtr do formátu PNG pro KChart +Name[cy]=Hidlen Allforio PNG KChart +Name[da]=KChart PNG-eksportfilter +Name[de]=KChart PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του KChart +Name[eo]=KChart-PNG-eksportfiltrilo +Name[es]=Filtro de exportación a PNG para KChart +Name[et]=KCharti PNG ekspordifilter +Name[eu]=KChart-en PNG esportaziorako iragazkia +Name[fa]=پالایۀ صادرات KChart PNG +Name[fi]=KChart PNG -vientisuodin +Name[fr]=Filtre d'exportation PNG de KChart +Name[fy]=PNG-Eksportfilter foar KChart +Name[ga]=Scagaire Easpórtála PNG KChart +Name[gl]=Filtro de Exportación de PNG para KChart +Name[he]=מסנן ייצוא מ־KChart ל־PNG +Name[hr]=KChart PNG filtar izvoza +Name[hu]=KChart PNG exportszűrő +Name[is]=KChart PNG útflutningssía +Name[it]=Filtro di esportazione PNG per KChart +Name[ja]=KChart PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ KChart +Name[lt]=KChart PNG eksportavimo filtras +Name[lv]=KChart PNG eksporta filtrs +Name[ms]=Penapis Eksport KChart PNG +Name[nb]=PNG-eksportfilter for KChart +Name[nds]=PNG-Exportfilter för KChart +Name[ne]=केडीई चित्रपट पीएनजी निर्यात फिल्टर +Name[nl]=PNG-exportfilter voor KChart +Name[nn]=PNG-eksportfilter for KChart +Name[pl]=Filtr eksportu do formatu PNG z KChart +Name[pt]=Filtro de Exportação de PNG para o KChart +Name[pt_BR]=Filtro de Exportação PNG do KChart +Name[ru]=Фильтр экспорта диаграмм KChart в PNG +Name[se]=KChart:a PNG-olggosfievrridansilli +Name[sk]=Exportný filter KChart PNG +Name[sl]=Izvozni filter PNG za KChart +Name[sr]=KChart-ов филтер за извоз у PNG +Name[sr@Latn]=KChart-ov filter za izvoz u PNG +Name[sv]=Kchart PNG-exportfilter +Name[uk]=Фільтр експорту PNG для KChart +Name[uz]=KChart PNG eksport filteri +Name[uz@cyrillic]=KChart PNG экспорт филтери +Name[zh_CN]=KChart PNG 导出过滤器 +Name[zh_TW]=KChart PNG 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/png +X-KDE-Weight=1 +X-KDE-Library=libkchartpngexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/png/pngexport.cpp b/filters/kchart/png/pngexport.cpp new file mode 100644 index 000000000..d0a871545 --- /dev/null +++ b/filters/kchart/png/pngexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "pngexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory PngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartpngexport, PngExportFactory( "pngexport" ) ) + +PngExport::PngExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +PngExport::~PngExport() +{ +} + +void PngExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "PNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + +const char * PngExport::exportFormat() +{ + return "image/png"; +} + +bool PngExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "PNG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "PNG Export Error" ) ); + } + return ret; +} + + +#include "pngexport.moc" + diff --git a/filters/kchart/png/pngexport.h b/filters/kchart/png/pngexport.h new file mode 100644 index 000000000..342144770 --- /dev/null +++ b/filters/kchart/png/pngexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __PNGEXPORT_H__ +#define __PNGEXPORT_H__ + +#include "imageexport.h" + +class PngExport : public ImageExport +{ + Q_OBJECT + +public: + PngExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~PngExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __PNGEXPORT_H__ + diff --git a/filters/kchart/png/status.html b/filters/kchart/png/status.html new file mode 100644 index 000000000..99754a03e --- /dev/null +++ b/filters/kchart/png/status.html @@ -0,0 +1,103 @@ + + + + + KOffice filters status: KChart PNG export Filter + + +  + +
    +
    +

    + KOffice filters status: KChart PNG export Filter +

    +
    + +
    + + + Import + + +


    +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Export PNG for kchart
    +
    +
    +
    Last update8 April 2005
    Features + Can export to a fixed size PNG image. +
    Todo +
      +
    • Make a dialog to let the user choose the size of the output + image.
    • +
    • Make it also export to SVG.
    • +
    +
    History + 2005-04-08: Created the first working version with fixed-size output.
    + 2005-03-24: Start of the PNG export filter +
    Author + Inge Wallin <inge@lysator.liu.se> +
    Links + -- +
    Progress report See History above.
    +
    +
    +Up + +


    + + + diff --git a/filters/kchart/svg/Makefile.am b/filters/kchart/svg/Makefile.am new file mode 100644 index 000000000..4322ff2ab --- /dev/null +++ b/filters/kchart/svg/Makefile.am @@ -0,0 +1,29 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libkchartsvgexport.la + +libkchartsvgexport_la_SOURCES = svgexport.cc +libkchartsvgexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartsvgexport_la_LIBADD = ../../../kchart/libkchartcommon.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + svgexport.h + +METASOURCES = AUTO + +service_DATA = kchart_svg_export.desktop +servicedir = $(kde_servicesdir) + +# Note: If your filter exports or exports some special file +# which KDE doesn't have a mimetype for, yet, you'll have to +# create a mimetype and install it using those two lines. +# In case of doubt please ask koffice@kde.org or +# koffice-devel@kde.org. Thanks. +# data_DATA = x-png.desktop +# datadir = $(kde_mimedir)/text diff --git a/filters/kchart/svg/kchart_svg_export.desktop b/filters/kchart/svg/kchart_svg_export.desktop new file mode 100644 index 000000000..1ad5a1289 --- /dev/null +++ b/filters/kchart/svg/kchart_svg_export.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Type=Service +Name=KChart SVG Export Filter +Name[ar]=مِرْشَح تصدير SVG لدى KChart +Name[bg]=Филтър за експортиране от KChart в SVG +Name[br]=Sil ezporzh SVG evit KChart +Name[ca]=Filtre d'exportació SVG per a KChart +Name[cs]=Exportní filtr do formátu SVG pro KChart +Name[cy]=Hidlen Allforio SVG KChart +Name[da]=KChart SVG-eksportfilter +Name[de]=KChart SVG-Exportfilter +Name[el]=Φίλτρο εξαγωγής SVG του KChart +Name[eo]=KChart-SVG-eksportfiltrilo +Name[es]=Filtro de exportación a SVG para KChart +Name[et]=KCharti SVG ekspordifilter +Name[eu]=KChart-en SVG esportaziorako iragazkia +Name[fa]=پالایۀ صادرات KChart SVG +Name[fi]=KChart SVG -vientisuodin +Name[fr]=Filtre d'exportation SVG de KChart +Name[fy]=SVG-Eksportfilter foar KChart +Name[ga]=Scagaire Easpórtála SVG KChart +Name[gl]=Filtro de Exportación de SVG para KChart +Name[he]=KChart SVG מסנן יצוא +Name[hr]=KChart SVG filtar izvoza +Name[hu]=KChart SVG exportszűrő +Name[is]=KChart SVG útflutningssía +Name[it]=Filtro di esportazione SVG per KChart +Name[ja]=KChart SVG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ SVG សម្រាប់ KChart +Name[lt]=KChart SVG eksportavimo filtras +Name[lv]=KChart SVG eksporta filtrs +Name[ms]=Penapis Eksport KChart SVG +Name[nb]=SVG-eksportfilter for KChart +Name[nds]=SVG-Exportfilter för KChart +Name[ne]=केडीई चित्रपट एसभीजी निर्यात फिल्टर +Name[nl]=SVG-exportfilter voor KChart +Name[nn]=SVG-eksportfilter for KChart +Name[pl]=Filtr eksportu do formatu SVG z KChart +Name[pt]=Filtro de Exportação de SVG para o KChart +Name[pt_BR]=Filtro de Exportação SVG do KChart +Name[ru]=Фильтр экспорта диаграмм KChart в SVG +Name[se]=KChart:a SVG-olggosfievrridansilli +Name[sk]=Exportný filter KChart SVG +Name[sl]=Izvozni filter SVG za KChart +Name[sr]=KChart-ов филтер за извоз у SVG +Name[sr@Latn]=KChart-ov filter za izvoz u SVG +Name[sv]=Kchart SVG-exportfilter +Name[uk]=Фільтр експорту SVG для KChart +Name[uz]=KChart SVG eksport filteri +Name[uz@cyrillic]=KChart SVG экспорт филтери +Name[zh_CN]=KChart SVG 导出过滤器 +Name[zh_TW]=KChart SVG 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/svg+xml +X-KDE-Weight=1 +X-KDE-Library=libkchartsvgexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/svg/status.html b/filters/kchart/svg/status.html new file mode 100644 index 000000000..75610d071 --- /dev/null +++ b/filters/kchart/svg/status.html @@ -0,0 +1,100 @@ + + + + + KOffice filters status: KChart SVG export Filter + + +  + +
    +
    +

    + KOffice filters status: KChart SVG export Filter +

    +
    + +
    + + + Import + + +


    +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Export SVG for kchart
    +
    +
    +
    Last update8 April 2005
    Features + Can export to a SVG (Scalable Vector Graphics) file. +
    Todo +
      +
    • --
    • +
    +
    History + 2005-04-09: First version: Copied from the PNG filter +
    Author + Inge Wallin <inge@lysator.liu.se> +
    Links + -- +
    Progress report See History above.
    +
    +
    +Up + +


    + + + diff --git a/filters/kchart/svg/svgexport.cc b/filters/kchart/svg/svgexport.cc new file mode 100644 index 000000000..204c59dbb --- /dev/null +++ b/filters/kchart/svg/svgexport.cc @@ -0,0 +1,93 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#include +#include + +#include + +#include +#include +//#include +#include + +#include "kchart_part.h" + +#include "svgexport.h" + + +typedef KGenericFactory SvgExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartsvgexport, SvgExportFactory( "svgexport" ) ) + +SvgExport::SvgExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +SvgExport::~SvgExport() +{ +} + + +KoFilter::ConversionStatus +SvgExport::convert(const QCString& from, const QCString& to) +{ + // Check for proper conversion. + if ( from != "application/x-kchart" || to != "image/svg+xml" ) + return KoFilter::NotImplemented; + + // Read the contents of the KChart file + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if ( !storeIn ) { + KMessageBox::error( 0, i18n("Failed to read data." ), + i18n( "SVG Export Error" ) ); + return KoFilter::FileNotFound; + } + + // Get the XML tree. + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // Read the document from the XML tree. + KChart::KChartPart kchartDoc; + if ( !kchartDoc.loadXML(0, domIn) ) { + KMessageBox::error( 0, i18n( "Malformed XML data." ), + i18n( "SVG Export Error" ) ); + return KoFilter::WrongFormat; + } + + // Draw the actual bitmap. + QPicture picture; + QPainter painter(&picture); + QRect rect(QPoint(0, 0), QPoint(500, 400)); + kchartDoc.paintContent(painter, rect, false); + painter.end(); + + // Save the image. + if ( !picture.save( m_chain->outputFile(), "SVG" ) ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "SVG Export Error" ) ); + } + + return KoFilter::OK; +} + + +#include diff --git a/filters/kchart/svg/svgexport.h b/filters/kchart/svg/svgexport.h new file mode 100644 index 000000000..d2a9823c0 --- /dev/null +++ b/filters/kchart/svg/svgexport.h @@ -0,0 +1,36 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#ifndef __SVGEXPORT_H__ +#define __SVGEXPORT_H__ + +#include + +class SvgExport : public KoFilter +{ + Q_OBJECT + +public: + SvgExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~SvgExport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // __SVGEXPORT_H__ diff --git a/filters/kchart/xbm/Makefile.am b/filters/kchart/xbm/Makefile.am new file mode 100644 index 000000000..a544e2d51 --- /dev/null +++ b/filters/kchart/xbm/Makefile.am @@ -0,0 +1,25 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkchartxbmexport.la + +libkchartxbmexport_la_SOURCES = xbmexport.cpp +libkchartxbmexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartxbmexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + xbmexport.h + +METASOURCES = AUTO + +service_DATA = kchart_xbm_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kchart/xbm/kchart_xbm_export.desktop b/filters/kchart/xbm/kchart_xbm_export.desktop new file mode 100644 index 000000000..01347476f --- /dev/null +++ b/filters/kchart/xbm/kchart_xbm_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KChart XBM Export Filter +Name[ar]=مرشح تصدير XBM لدى KChart +Name[bg]=Филтър за експортиране от KChart в XBM +Name[br]=Sil ezporzh XBM evit KChart +Name[ca]=Filtre d'exportació XBM per a KChart +Name[da]=KChart XBM-eksportfilter +Name[de]=KChart XBM-Exportfilter +Name[el]=Φίλτρο εξαγωγής XBM του KChart +Name[eo]=KChart-XBM-eksportfiltrilo +Name[es]=Filtro de exportación a XBM para KChart +Name[et]=KCharti XBM-i ekspordifilter +Name[fa]=پالایۀ صادرات KChart XBM +Name[fi]=KChart XBM -vientisuodin +Name[fr]=Filtre d'exportation XBM de KChart +Name[fy]=XBM-Eksportfilter foar KChart +Name[ga]=Scagaire Easpórtála XBM KChart +Name[gl]=Filtro de Exportación de XBM para KChart +Name[he]=KChart XBM מסנן יצוא +Name[hr]=KChart XBM filtar izvoza +Name[hu]=KChart XBM exportszűrő +Name[is]=KChart XBM útflutningssía +Name[it]=Filtro di esportazione XBM per KChart +Name[ja]=KChart XBM エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ XBM សម្រាប់ KChart +Name[lt]=KChart XBM eksportavimo filtras +Name[lv]=KChart XBM eksporta filtrs +Name[nb]=XMB-eksportfilter for KChart +Name[nds]=XBM-Exportfilter för KChart +Name[ne]=केडीई चित्रपट एक्सबीएम निर्यात फिल्टर +Name[nl]=PNG-exportfilter voor KChart +Name[pl]=Filtr eksportu do formatu XBM z KChart +Name[pt]=Filtro de Exportação de XBM para o KChart +Name[pt_BR]=Filtro de Exportação de XBM para o KChart +Name[ru]=Фильтр экспорта диаграмм KChart в XBM +Name[se]=KChart:a XMB-olggosfievrridansilli +Name[sk]=Exportný filter KChart XBM +Name[sl]=Izvozni filter XBM za KChart +Name[sr]=KChart-ов филтер за извоз у XBM +Name[sr@Latn]=KChart-ov filter za izvoz u XBM +Name[sv]=Kchart XBM-exportfilter +Name[uk]=Фільтр експорту XBM для KChart +Name[uz]=KChart XBM eksport filteri +Name[uz@cyrillic]=KChart XBM экспорт филтери +Name[zh_CN]=KChart XBM 导出过滤器 +Name[zh_TW]=KChart XBM 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/x-xbm +X-KDE-Weight=1 +X-KDE-Library=libkchartxbmexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/xbm/xbmexport.cpp b/filters/kchart/xbm/xbmexport.cpp new file mode 100644 index 000000000..f6b6fab0d --- /dev/null +++ b/filters/kchart/xbm/xbmexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "xbmexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory xbmExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartxbmexport, xbmExportFactory( "xbmexport" ) ) + +XbmExport::XbmExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +XbmExport::~XbmExport() +{ +} + +void XbmExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "Xbm Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + + +bool XbmExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "XBM" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "Xbm Export Error" ) ); + } + return ret; +} + +const char * XbmExport::exportFormat() +{ + return "image/x-xbm"; +} + +#include "xbmexport.moc" + diff --git a/filters/kchart/xbm/xbmexport.h b/filters/kchart/xbm/xbmexport.h new file mode 100644 index 000000000..1ab779e3f --- /dev/null +++ b/filters/kchart/xbm/xbmexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XBMEXPORT_H__ +#define __XBMEXPORT_H__ + +#include "imageexport.h" + +class XbmExport : public ImageExport +{ + Q_OBJECT + +public: + XbmExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XbmExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XBMEXPORT_H__ + diff --git a/filters/kchart/xpm/Makefile.am b/filters/kchart/xpm/Makefile.am new file mode 100644 index 000000000..cf92e4235 --- /dev/null +++ b/filters/kchart/xpm/Makefile.am @@ -0,0 +1,25 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kchart \ + -I$(top_srcdir)/kchart/kdchart \ + -I$(top_srcdir)/interfaces \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kchart/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkchartxpmexport.la + +libkchartxpmexport_la_SOURCES = xpmexport.cpp +libkchartxpmexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkchartxpmexport_la_LIBADD = ../../../kchart/libkchartcommon.la ../libimageexport/libkchartimageexport.la ../../../filters/libdialogfilter/libdialogfilter.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + xpmexport.h + +METASOURCES = AUTO + +service_DATA = kchart_xpm_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kchart/xpm/kchart_xpm_export.desktop b/filters/kchart/xpm/kchart_xpm_export.desktop new file mode 100644 index 000000000..58ea9a6f6 --- /dev/null +++ b/filters/kchart/xpm/kchart_xpm_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KChart XPM Export Filter +Name[ar]=مرشح تصدير XPM لدى KChart +Name[bg]=Филтър за експортиране от KChart в XPM +Name[br]=Sil ezporzh XPM evit KChart +Name[ca]=Filtre d'exportació XPM per a KChart +Name[da]=KChart XPM-eksportfilter +Name[de]=KChart XPM-Exportfilter +Name[el]=Φίλτρο εξαγωγής XPM του KChart +Name[eo]=KChart-XPM-eksportfiltrilo +Name[es]=Filtro de exportación a XPM para KChart +Name[et]=KCharti XPM-i ekspordifilter +Name[fa]=پالایۀ صادرات KChart XPM +Name[fi]=KChart XPM -vientisuodin +Name[fr]=Filtre d'exportation XPM de KChart +Name[fy]=XPM-Eksportfilter foar KChart +Name[ga]=Scagaire Easpórtála XPM KChart +Name[gl]=Filtro de Exportación de XPM para KChart +Name[he]=KChart XPM מסנן יצוא +Name[hr]=KChart XPM filtar izvoza +Name[hu]=KChart XPM exportszűrő +Name[is]=KChart XPM útflutningssía +Name[it]=Filtro di esportazione XPM per KChart +Name[ja]=KChart XPM エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ XPM សម្រាប់ KChart +Name[lt]=KChart XPM eksportavimo filtras +Name[lv]=KChart XPM eksporta filtrs +Name[nb]=XPM-eksportfilter for KChart +Name[nds]=XPM-Exportfilter för KChart +Name[ne]=केडीई चित्रपट एक्सपीएम निर्यात फिल्टर +Name[nl]=XPM-exportfilter voor KChart +Name[pl]=Filtr eksportu do formatu XPM z KChart +Name[pt]=Filtro de Exportação de XPM para o KChart +Name[pt_BR]=Filtro de Exportação de XPM para o KChart +Name[ru]=Фильтр экспорта диаграмм KChart в XPM +Name[se]=KChart:a XPM-olggosfievrridansilli +Name[sk]=Exportný filter KChart XPM +Name[sl]=Izvozni filter XPM za KChart +Name[sr]=KChart-ов филтер за извоз у XPM +Name[sr@Latn]=KChart-ov filter za izvoz u XPM +Name[sv]=Kchart XPM-exportfilter +Name[uk]=Фільтр експорту XPM для KChart +Name[uz]=KChart XPM eksport filteri +Name[uz@cyrillic]=KChart XPM экспорт филтери +Name[zh_CN]=KChart XPM 导出过滤器 +Name[zh_TW]=KChart XPM 匯出過濾程式 +X-KDE-Import=application/x-kchart +X-KDE-Export=image/x-xpm +X-KDE-Weight=1 +X-KDE-Library=libkchartxpmexport +ServiceTypes=KOfficeFilter diff --git a/filters/kchart/xpm/xpmexport.cpp b/filters/kchart/xpm/xpmexport.cpp new file mode 100644 index 000000000..116fef467 --- /dev/null +++ b/filters/kchart/xpm/xpmexport.cpp @@ -0,0 +1,76 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "xpmexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory xpmExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkchartxpmexport, xpmExportFactory( "xpmexport" ) ) + +XpmExport::XpmExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +XpmExport::~XpmExport() +{ +} + +void XpmExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "Xpm Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; +} + + +bool XpmExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "XPM" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "Xpm Export Error" ) ); + } + return ret; +} + +const char * XpmExport::exportFormat() +{ + return "image/x-xpm"; +} + +#include "xpmexport.moc" + diff --git a/filters/kchart/xpm/xpmexport.h b/filters/kchart/xpm/xpmexport.h new file mode 100644 index 000000000..8fc7e0083 --- /dev/null +++ b/filters/kchart/xpm/xpmexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class XpmExport : public ImageExport +{ + Q_OBJECT + +public: + XpmExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XpmExport(); + virtual bool saveImage( QString fileName); + virtual void extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/kformula/Makefile.am b/filters/kformula/Makefile.am new file mode 100644 index 000000000..9e0d28290 --- /dev/null +++ b/filters/kformula/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = png latex mathml svg diff --git a/filters/kformula/latex/Makefile.am b/filters/kformula/latex/Makefile.am new file mode 100644 index 000000000..5e022eec7 --- /dev/null +++ b/filters/kformula/latex/Makefile.am @@ -0,0 +1,25 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KFORMULA_INCLUDES) $(all_includes) +libkfolatexexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkfolatexexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KFORMULA) + +####### Files + +kde_module_LTLIBRARIES = libkfolatexexport.la + +libkfolatexexport_la_SOURCES = latexexport.cc + +noinst_HEADERS = latexexport.h + +######## Debug +#check_PROGRAMS = texlauncher +#texlauncher_SOURCES = texlauncher.cc +#texlauncher_LDADD = liblatexexport.la +#texlauncher_LDFLAGS = $(KDE_RPATH) $(all_libraries) + + +METASOURCES = AUTO + +service_DATA = kformula_latex_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kformula/latex/kformula_latex_export.desktop b/filters/kformula/latex/kformula_latex_export.desktop new file mode 100644 index 000000000..d14b62a29 --- /dev/null +++ b/filters/kformula/latex/kformula_latex_export.desktop @@ -0,0 +1,69 @@ +[Desktop Entry] +X-KDE-Export=text/x-tex +ExportDescription=LATEX +Icon= +X-KDE-Import=application/x-kformula +X-KDE-Weight=1 +ImportDescription=KFormula +Name=KFormula LaTeX Export Filter +Name[af]=Kformula Latex Voer uit Filter +Name[ar]=مِرْشَح تصدير LaTeX لدى KFormula +Name[bg]=Филтър за експортиране от KFormula в LaTeX +Name[br]=Sil ezporzh LaTeX evit KFormula +Name[ca]=Filtre d'exportació LaTeX per a KFormula +Name[cs]=Exportní filtr formátu LaTeX pro KFormula +Name[cy]=Hidlen Allforio LaTeX KFormula +Name[da]=KFormula LaTex-eksportfilter +Name[de]=KFormula LaTeX-Exportfilter +Name[el]=Φίλτρο εξαγωγής LaTeX του KFormula +Name[eo]=LaTeX-eksportfiltrilo por KFormula +Name[es]=Filtro de exportación LaTeX de KFormula +Name[et]=KFormula LaTeX'i ekspordifilter +Name[eu]=KFormula-ren LaTeX esportaziorako iragazkia +Name[fa]=پالایۀ صادرات KFormula LaTeX +Name[fi]=KFormula LaTeX -vientisuodin +Name[fr]=Filtre d'exportation LaTeX de KFormula +Name[fy]=LaTeX-Eksportfilter foar KFormula +Name[ga]=Scagaire Easpórtála LaTeX KFormula +Name[gl]=Filtro de Exportación de LaTeX para KFormula +Name[he]=מסנן ייצוא מ־KFormula ל־LaTeX +Name[hr]=KFormula LaTeX filtar izvoza +Name[hu]=KFormula LaTeX exportszűrő +Name[is]=KFormula LaTeX útflutningssía +Name[it]=Filtro di esportazione LaTeX per KFormula +Name[ja]=KFormula LaTeX エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ LaTeX សម្រាប់ KFormula +Name[lo]= ຕົວຕອງການສົ່ງອອກລາເທັກຊ໌ຂອງສູດຄະນິດສາດ์ K +Name[lt]=KFormula LATEX eksporto filtras +Name[lv]=KFormula LaTeX eksporta filtrs +Name[ms]=Penapis Eksport KFormula LaTeX +Name[mt]=Filtru għall-esportazzjoni ta' LaTeX minn ġo KFormula +Name[nb]=LaTeX-eksportfilter for KFormula +Name[nds]=LaTeX-Exportfilter för KFormula +Name[ne]=केडीई सूत्र लाटेक्स निर्यात फिल्टर +Name[nl]=LaTeX-exportfilter voor KFormula +Name[nn]=LaTeX-eksportfilter for KFormula +Name[pl]=Filtr eksportu do formatu LaTeX z KFormula +Name[pt]=Filtro de Exportação de LaTeX para o KFormula +Name[pt_BR]=Filtro de exportação KFormula para o LaTeX +Name[ro]=Filtru exportare KFormula pentru Latex +Name[ru]=Фильтр экспорта формул KFormula в LaTeX +Name[se]=KFormula LaTex-olggosfievrridansilli +Name[sk]=LaTeX filter pre export z KFormula +Name[sl]=Izvozni filter LaTeX za KFormulo +Name[sr]=KFormula-ин филтер за извоз у LaTeX +Name[sr@Latn]=KFormula-in filter za izvoz u LaTeX +Name[sv]=Kformula Latex-exportfilter +Name[ta]=Kformula latex ஏற்றுமதி வடிகட்டி +Name[tg]=KFormula LaTeX Филтри Содирот +Name[th]=ตัวกรองการส่งออกลาเท็กซ์ของสูตรคณิตศาสตร์ K +Name[tr]=KFormula LaTeX Aktarma Filtresi +Name[uk]=Фільтр експорту LaTeX для KFormula +Name[uz]=KFormula LaTeX eksport filteri +Name[uz@cyrillic]=KFormula LaTeX экспорт филтери +Name[xh]=Isihluzi Sokurhweba ngaphandle se KFormula LaTeX +Name[zh_CN]=KFormula LaTeX 导出过滤器 +Name[zh_TW]=KFormula LaTeX 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Library=libkfolatexexport diff --git a/filters/kformula/latex/latexexport.cc b/filters/kformula/latex/latexexport.cc new file mode 100644 index 000000000..20cecdcf4 --- /dev/null +++ b/filters/kformula/latex/latexexport.cc @@ -0,0 +1,96 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "latexexport.h" + + +typedef KGenericFactory LATEXExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkfolatexexport, LATEXExportFactory( "kofficefilters" ) ) + + +LATEXExport::LATEXExport( KoFilter */*parent*/, const char */*name*/, const QStringList& ) + : KoFilter() +{ +} + + +KoFilter::ConversionStatus LATEXExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "text/x-tex" || from != "application/x-kformula" ) + return KoFilter::NotImplemented; + + KoStoreDevice* in = m_chain->storageFile( "root", KoStore::Read ); + if(!in) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Failed to read data." ), i18n( "LaTeX Export Error" ) ); + return KoFilter::StorageCreationError; + } + + QDomDocument dom( "KFORMULA" ); + if ( !dom.setContent( in, false ) ) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Malformed XML data." ), i18n( "LaTeX Export Error" ) ); + return KoFilter::WrongFormat; + } + + QFile f( m_chain->outputFile() ); + if( !f.open( IO_Truncate | IO_ReadWrite ) ) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Failed to write file." ), i18n( "LaTeX Export Error" ) ); + return KoFilter::FileNotFound; + } + + KFormula::DocumentWrapper* wrapper = new KFormula::DocumentWrapper( kapp->config(), 0 ); + KFormula::Document* doc = new KFormula::Document; + wrapper->document( doc ); + KFormula::Container* formula = doc->createFormula(); + if ( !doc->loadXML( dom ) ) { + kdError(30522) << "Failed." << endl; + } + + QTextStream stream(&f); + //stream.setEncoding(QTextStream::UnicodeUTF8); + stream << "\\documentclass{article}\n\\usepackage{amsmath}\n\\begin{document}\n\\[\n" + << formula->texString() + << "\n\\]\n\\end{document}"; + f.close(); + + delete formula; + delete wrapper; + + return KoFilter::OK; +} + +#include "latexexport.moc" diff --git a/filters/kformula/latex/latexexport.h b/filters/kformula/latex/latexexport.h new file mode 100644 index 000000000..af24003dc --- /dev/null +++ b/filters/kformula/latex/latexexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef LATEXEXPORT_H +#define LATEXEXPORT_H + +class QCString; +class QStringList; + +#include + +class LATEXExport : public KoFilter +{ + Q_OBJECT +public: + LATEXExport( KoFilter *parent, const char *name, const QStringList& ); + virtual ~LATEXExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif // LATEXEXPORT_H diff --git a/filters/kformula/mathml/Makefile.am b/filters/kformula/mathml/Makefile.am new file mode 100644 index 000000000..cdd07955a --- /dev/null +++ b/filters/kformula/mathml/Makefile.am @@ -0,0 +1,23 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KFORMULA_INCLUDES) $(all_includes) +libkfomathmlexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkfomathmlexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KFORMULA) +libkfomathmlimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkfomathmlimport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KFORMULA) + +####### Files + +kde_module_LTLIBRARIES = libkfomathmlexport.la libkfomathmlimport.la + +libkfomathmlexport_la_SOURCES = mathmlexport.cc + +libkfomathmlimport_la_SOURCES = mathmlimport.cc + +noinst_HEADERS = mathmlexport.h mathmlimport.h + + +METASOURCES = AUTO + +service_DATA = kformula_mathml_export.desktop kformula_mathml_import.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kformula/mathml/kformula_mathml_export.desktop b/filters/kformula/mathml/kformula_mathml_export.desktop new file mode 100644 index 000000000..1fdc1bf3a --- /dev/null +++ b/filters/kformula/mathml/kformula_mathml_export.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +X-KDE-Export=application/mathml+xml +ExportDescription=MathML +Icon= +X-KDE-Import=application/x-kformula +X-KDE-Weight=1 +ImportDescription=KFormula +Name=KFormula MathML Export Filter +Name[ar]=مِرْشَح تصدير MathML لدى KFormula +Name[bg]=Филтър за експортиране от KFormula в MathML +Name[br]=Sil ezporzh MathML evit KFormula +Name[ca]=Filtre d'exportació MathML per a KFormula +Name[cs]=Exportní filtr formátu MathML pro KFormula +Name[cy]=Hidlen Allforio MathML KFormula +Name[da]=KFormula MathML-eksportfilter +Name[de]=KFormula MathML-Exportfilter +Name[el]=Φίλτρο εξαγωγής MathML του KFormula +Name[eo]=MathML-eksportfiltrilo por KFormula +Name[es]=Filtro de exportación a MathML de KFormula +Name[et]=KFormula MathML'i ekspordifilter +Name[eu]=KFormula-ren MathML esportaziorako iragazkia +Name[fa]=پالایۀ صادرات KFormula MathML +Name[fi]=KFormula MathML -vientisuodin +Name[fr]=Filtre d'exportation MathML de KFormula +Name[fy]=MathML-Eksportfilter foar KFormula +Name[ga]=Scagaire Easpórtála MathML KFormula +Name[gl]=Filtro de Exportación de MathML para KFormula +Name[he]=מסנן ייצוא מ־KFormula ל־MathML +Name[hi]=के-फ़ॉर्मूला मैथएमएल निर्यात फ़िल्टर +Name[hr]=KFormula MathML filtar izvoza +Name[hu]=KFormula MathML exportszűrő +Name[is]=KFormula MathML útflutningssía +Name[it]=Filtro di esportazione MathML per KFormula +Name[ja]=KFormula MathML エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ MathML សម្រាប់ KFormula +Name[lt]=KFormula MathML eksportavimo filtras +Name[lv]=KFormula MathML eksporta filtrs +Name[ms]=Penapis Eksport KFormula MathML +Name[nb]=MathML-eksportfilter for KFormula +Name[nds]=MathML-Exportfilter för KFormula +Name[ne]=केडीई सूत्र हिसाबएमएल निर्यात फिल्टर +Name[nl]=MathML-exportfilter voor KFormula +Name[nn]=MathML-eksportfilter for KFormula +Name[pl]=Filtr eksportu do formatu MathML z KFormula +Name[pt]=Filtro de Exportação de MathML para o KFormula +Name[pt_BR]=Filtro de Exportação KFormula para o MathML +Name[ru]=Фильтр экспорта формул KFormula в MathML +Name[se]=KFormula MathML-olggosfievrridansilli +Name[sk]=MathML filter pre export z KFormula +Name[sl]=Izvozni filter MathML za KFormulo +Name[sr]=KFormula-ин филтер за извоз у MathML +Name[sr@Latn]=KFormula-in filter za izvoz u MathML +Name[sv]=Kformula MathML-exportfilter +Name[ta]=Kformula mathml ஏற்றுமதி வடிகட்டி +Name[tg]=KFormula MathML Филтри Содирот +Name[tr]=KFormula MathML Aktarma Filtresi +Name[uk]=Фільтр експорту MathML для KFormula +Name[uz]=KFormula MathML eksport filteri +Name[uz@cyrillic]=KFormula MathML экспорт филтери +Name[zh_CN]=KFormula MathML 导出过滤器 +Name[zh_TW]=KFormula MathML 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Library=libkfomathmlexport diff --git a/filters/kformula/mathml/kformula_mathml_import.desktop b/filters/kformula/mathml/kformula_mathml_import.desktop new file mode 100644 index 000000000..a6828cb48 --- /dev/null +++ b/filters/kformula/mathml/kformula_mathml_import.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +X-KDE-Export=application/x-kformula +ExportDescription=KFormula +Icon= +X-KDE-Import=application/mathml+xml +X-KDE-Weight=1 +ImportDescription=MathM +Name=KFormula MathML Import Filter +Name[ar]=مِرْشَح استيراد MathML لدى KFormula +Name[bg]=Филтър за импортиране от MathML в KFormula +Name[br]=Sil enporzh MathML evit KFormula +Name[ca]=Filtre d'importació MathML per a KFormula +Name[cs]=Importní filtr formátu MathML pro KFormula +Name[cy]=Hidlen Fewnforio MathML KFormula +Name[da]=KFormula MathML-importfilter +Name[de]=KFormula MathML-Importfilter +Name[el]=Φίλτρο εισαγωγής MathML του KFormula +Name[eo]=MathML-importfiltrilo por KFormula +Name[es]=Filtro de importación a MathML de KFormula +Name[et]=KFormula MathML'i impordifilter +Name[eu]=KFormula-ren MathML inportaziorako iragazkia +Name[fa]=پالایۀ واردات KFormula MathML +Name[fi]=KFormula MathML -tuontisuodin +Name[fr]=Filtre d'importation MathML de KFormula +Name[fy]=MathML Ymportfilter foar KFormula +Name[ga]=Scagaire Iompórtála MathML KFormula +Name[gl]=Filtro de Importación de MathML para KFormula +Name[he]=מסנן ייבוא מ־MathML ל־KFormula +Name[hi]=के-फ़ॉर्मूला मैथएमएल आयात फ़िल्टर +Name[hr]=KFormula MathML filtar uvoza +Name[hu]=KFormula MathML importszűrő +Name[is]=KFormula MathML innflutningssía +Name[it]=Filtro di importazione MathML per KFormula +Name[ja]=KFormula MathML インポートフィルタ +Name[km]=តម្រង​នាំចូល MathML សម្រាប់ KFormula +Name[lt]=KFormula MathML importavimo filtras +Name[lv]=KFormula MathML importa filtrs +Name[ms]=Penapis Import KFormula MathML +Name[nb]=MathML-importfilter for KFormula +Name[nds]=MathML-Importfilter för KFormula +Name[ne]=केडीई सूत्र हिसाबएमएल आयात फिल्टर +Name[nl]=MathML-importfilter voor KFormula +Name[nn]=MathML-importfilter for KFormula +Name[pl]=Filtr importu formatu MathML do KFormula +Name[pt]=Filtro de Importação de MathML para o KFormula +Name[pt_BR]=Filtro de Importação MathML para o KFormula +Name[ru]=Фильтр импорта формул MathML в KFormula +Name[se]=KFormula MathML-sisafievrridansilli +Name[sk]=MathML filter pre import do KFormula +Name[sl]=Uvozni filter MathML za KWord +Name[sr]=KFormula-ин филтер за увоз из MathML-а +Name[sr@Latn]=KFormula-in filter za uvoz iz MathML-a +Name[sv]=Kformula MathML-importfilter +Name[ta]=Kformula mathml இறக்குமதி வடிகட்டி +Name[tg]=KFormula MathML Филтри Воридот +Name[tr]=KFormula MathML Alma Filtresi +Name[uk]=Фільтр імпорту MathML для KFormula +Name[uz]=KFormula MathML import filteri +Name[uz@cyrillic]=KFormula MathML импорт филтери +Name[zh_CN]=KFormula MathML 导入过滤器 +Name[zh_TW]=KFormula MathML 匯入過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Library=libkfomathmlimport diff --git a/filters/kformula/mathml/mathmlexport.cc b/filters/kformula/mathml/mathmlexport.cc new file mode 100644 index 000000000..cbf8489ed --- /dev/null +++ b/filters/kformula/mathml/mathmlexport.cc @@ -0,0 +1,94 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "mathmlexport.h" + + +typedef KGenericFactory MathMLExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkfomathmlexport, MathMLExportFactory( "kofficefilters" ) ) + + +MathMLExport::MathMLExport( KoFilter */*parent*/, const char */*name*/, const QStringList& ) + : KoFilter() +{ +} + + +KoFilter::ConversionStatus MathMLExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "application/mathml+xml" || from != "application/x-kformula" ) + return KoFilter::NotImplemented; + + KoStoreDevice* in = m_chain->storageFile( "root", KoStore::Read ); + if(!in) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Failed to read data." ), i18n( "MathML Export Error" ) ); + return KoFilter::StorageCreationError; + } + + QDomDocument dom; + if ( !dom.setContent( in, false ) ) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Malformed XML data." ), i18n( "MathML Export Error" ) ); + return KoFilter::WrongFormat; + } + + QFile f( m_chain->outputFile() ); + if( !f.open( IO_Truncate | IO_ReadWrite ) ) { + QApplication::restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Failed to write file." ), i18n( "MathML Export Error" ) ); + return KoFilter::FileNotFound; + } + + KFormula::DocumentWrapper* wrapper = new KFormula::DocumentWrapper( kapp->config(), 0 ); + KFormula::Document* doc = new KFormula::Document; + wrapper->document( doc ); + KFormula::Container* formula = doc->createFormula(); + if ( !doc->loadXML( dom ) ) { + kdError() << "Failed." << endl; + } + + QTextStream stream(&f); + stream.setEncoding( QTextStream::UnicodeUTF8 ); + formula->saveMathML( stream ); + f.close(); + + delete formula; + delete wrapper; + + return KoFilter::OK; +} + +#include "mathmlexport.moc" diff --git a/filters/kformula/mathml/mathmlexport.h b/filters/kformula/mathml/mathmlexport.h new file mode 100644 index 000000000..0e15b7a0e --- /dev/null +++ b/filters/kformula/mathml/mathmlexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef MATHMLEXPORT_H +#define MATHMLEXPORT_H + +class QCString; +class QStringList; + +#include + +class MathMLExport : public KoFilter +{ + Q_OBJECT +public: + MathMLExport( KoFilter *parent, const char *name, const QStringList& ); + virtual ~MathMLExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif // MATHMLEXPORT_H diff --git a/filters/kformula/mathml/mathmlimport.cc b/filters/kformula/mathml/mathmlimport.cc new file mode 100644 index 000000000..9ede69cee --- /dev/null +++ b/filters/kformula/mathml/mathmlimport.cc @@ -0,0 +1,111 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "mathmlimport.h" +#include "mathmlimport.moc" + + +typedef KGenericFactory MathMLImportFactory; +K_EXPORT_COMPONENT_FACTORY( libkfomathmlimport, MathMLImportFactory( "kofficefilters" ) ) + + +MathMLImport::MathMLImport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +KoFilter::ConversionStatus MathMLImport::convert( const QCString& from, const QCString& to ) +{ + kdDebug( KFormula::DEBUGID ) << "From: " << from << endl; + kdDebug( KFormula::DEBUGID ) << "To: " << to << endl; + + if(from != "application/mathml+xml" || to != "application/x-kformula") + return KoFilter::NotImplemented; + + KoStore* out = KoStore::createStore(QString(m_chain->outputFile()), KoStore::Write); + if(!out || !out->open("root")) { + KMessageBox::error( 0, i18n( "Unable to open output file." ), i18n( "MathML Import Error" ) ); + delete out; + return KoFilter::FileNotFound; + } + + KFormula::DocumentWrapper* wrapper = new KFormula::DocumentWrapper( kapp->config(), 0 ); + KFormula::Document* doc = new KFormula::Document; + wrapper->document( doc ); + KFormula::Container* formula = doc->createFormula(); + + //formula->loadMathML( m_chain->inputFile() ); + const QString filename( m_chain->inputFile() ); + QFile f( filename ); + if ( !f.open( IO_ReadOnly ) ) { + KMessageBox::error( 0, i18n( "Failed to open input file: %1" ).arg( filename ), i18n( "MathML Import Error" ) ); + delete wrapper; + return KoFilter::FileNotFound; + } + + QDomDocument mathML; + // Error variables for QDomDocument::setContent + QString errorMsg; + int errorLine, errorColumn; + if ( !mathML.setContent( &f, true, &errorMsg, &errorLine, &errorColumn ) ) { + delete wrapper; + QApplication::restoreOverrideCursor(); + kdError(KFormula::DEBUGID) << "Parsing error in " << filename << "! Aborting!" << endl + << " In line: " << errorLine << ", column: " << errorColumn << endl + << " Error message: " << errorMsg << endl; + KMessageBox::error( 0, i18n( "Parsing error in MathML file %4 at line %1, column %2\nError message: %3" ) + .arg( errorLine ).arg( errorColumn ).arg( i18n ( "QXml", errorMsg.utf8() ).arg( filename ) ), i18n( "MathML Import Error" ) ); + return KoFilter::WrongFormat; + } + f.close(); + if ( !formula->loadMathML( mathML ) ) { + delete wrapper; + return KoFilter::StupidError; + } + + // taken from KoDocument::saveToStore + KoStoreDevice dev( out ); + const QCString s = doc->saveXML().toCString(); // utf8 already + const int nwritten = dev.writeBlock( s.data(), s.size()-1 ); + if ( nwritten != (int)s.size()-1 ) { + kdWarning() << "wrote " << nwritten << " - expected " << s.size()-1 << endl; + KMessageBox::error( 0, i18n( "Failed to write formula." ), i18n( "MathML Import Error" ) ); + } + + out->close(); + delete out; + + delete wrapper; + return KoFilter::OK; +} + diff --git a/filters/kformula/mathml/mathmlimport.h b/filters/kformula/mathml/mathmlimport.h new file mode 100644 index 000000000..79f6c052b --- /dev/null +++ b/filters/kformula/mathml/mathmlimport.h @@ -0,0 +1,42 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef MATHMLIMPORT_H +#define MATHMLIMPORT_H + +#include +#include +#include +#include + +#include +#include + +class MathMLImport : public KoFilter +{ + Q_OBJECT +public: + MathMLImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MathMLImport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif /* MATHMLIMPORT_H */ + diff --git a/filters/kformula/png/Makefile.am b/filters/kformula/png/Makefile.am new file mode 100644 index 000000000..8b405c39c --- /dev/null +++ b/filters/kformula/png/Makefile.am @@ -0,0 +1,25 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KFORMULA_INCLUDES) $(all_includes) +libkfopngexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkfopngexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KFORMULA) + +####### Files + +kde_module_LTLIBRARIES = libkfopngexport.la + +libkfopngexport_la_SOURCES = pngexport.cc pngexportdia.cc + +noinst_HEADERS = pngexport.h pngexportdia.h + +######## Debug +#check_PROGRAMS = texlauncher +#texlauncher_SOURCES = texlauncher.cc +#texlauncher_LDADD = liblatexexport.la +#texlauncher_LDFLAGS = $(KDE_RPATH) $(all_libraries) + + +METASOURCES = AUTO + +service_DATA = kformula_png_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kformula/png/kformula_png_export.desktop b/filters/kformula/png/kformula_png_export.desktop new file mode 100644 index 000000000..0ea0856f0 --- /dev/null +++ b/filters/kformula/png/kformula_png_export.desktop @@ -0,0 +1,70 @@ +[Desktop Entry] +X-KDE-Export=image/png +ExportDescription=PNG +Icon= +X-KDE-Import=application/x-kformula +X-KDE-Weight=1 +ImportDescription=KFormula +Name=KFormula PNG Export Filter +Name[af]=Kformula Png Voer uit Filter +Name[ar]=مِرْشَح تصدير PNG لدى KFormula +Name[bg]=Филтър за експортиране от KFormula в PNG +Name[br]=Sil ezporzh PNG evit KFormula +Name[ca]=Filtre d'exportació PNG per a KFormula +Name[cs]=Exportní filtr formátu PNG pro KFormula +Name[cy]=Hidlen Allforio PNG KFormula +Name[da]=KFormula PNG-eksportfilter +Name[de]=KFormula PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του KFormula +Name[eo]=PNG-eksportfiltrilo por KFormula +Name[es]=Filtro de exportación PNG de KFormula +Name[et]=KFormula PNG ekspordifilter +Name[eu]=KFormula-ren PNG esportaziorako iragazkia +Name[fa]=پالایۀ صادرات KFormula PNG +Name[fi]=KFormula PNG -vientisuodin +Name[fr]=Filtre d'exportation PNG de KFormula +Name[fy]=PNG Eksportfilter foar KFormula +Name[ga]=Scagaire Easpórtála PNG KFormula +Name[gl]=Filtro de Exportación de PNG para KFormula +Name[he]=מסנן ייצוא מ־KFormula ל־PNG +Name[hi]=के-फ़ॉर्मूला पीएनजी निर्यात फ़िल्टर +Name[hr]=KFormula PNG filtar izvoza +Name[hu]=KFormula PNG exportszűrő +Name[is]=KFormula PNG útflutningssía +Name[it]=Filtro di esportazione PNG per KFormula +Name[ja]=KFormula PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ KFormula +Name[lo]=ຕົວຕອງການສົ່ງອອກ PNG ຂອງສູດຄະນິດສາດ K +Name[lt]=KFormula PNG eksporto filtras +Name[lv]=KFormula PNG eksporta filtrs +Name[ms]=Penapis Eksport KFormula PNG +Name[mt]=Filtru għall-esportazzjoni ta' PNG minn KFormula +Name[nb]=PNG-eksportfilter for KFormula +Name[nds]=PNG-Exportfilter för KFormula +Name[ne]=केडीई सूत्र पीएनजी निर्यात फिल्टर +Name[nl]=PNG-exportfilter voor KFormula +Name[nn]=PNG-eksportfilter for KFormula +Name[pl]=Filtr eksportu do formatu PNG z KFormula +Name[pt]=Filtro de Exportação de PNG para o KFormula +Name[pt_BR]=Filtro de exportação KFormula PNG +Name[ro]=Filtru exportare KFormula pentru PNG +Name[ru]=Фильтр экспорта формул KFormula в PNG +Name[se]=KFormula PNG-olggosfievrridansilli +Name[sk]=PNG filter pre export z KFormula +Name[sl]=Izvozni filter PNG za KFormulo +Name[sr]=KFormula-ин филтер за извоз у PNG +Name[sr@Latn]=KFormula-in filter za izvoz u PNG +Name[sv]=Kformula PNG-exportfilter +Name[ta]=Kformula png ஏற்றுமதி வடிகட்டி +Name[tg]=KFormula PNG Филтри Содирот +Name[th]=ตัวกรองการส่งออก PNG ของสูตรคณิตศาสตร์ K +Name[tr]=KFormula PNG Aktarma Filtresi +Name[uk]=Фільтр експорту PNG для KFormula +Name[uz]=KFormula PNG eksport filteri +Name[uz@cyrillic]=KFormula PNG экспорт филтери +Name[xh]=Isihluzi Sokurhweba ngaphandle se KFormula PNG +Name[zh_CN]=KFormula PNG 导出过滤器 +Name[zh_TW]=KFormula PNG 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Library=libkfopngexport diff --git a/filters/kformula/png/pngexport.cc b/filters/kformula/png/pngexport.cc new file mode 100644 index 000000000..f51bc1f18 --- /dev/null +++ b/filters/kformula/png/pngexport.cc @@ -0,0 +1,74 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + + +#include "pngexport.h" +#include "pngexportdia.h" + + +typedef KGenericFactory PNGExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkfopngexport, PNGExportFactory( "kofficefilters" ) ) + + +PNGExport::PNGExport( KoFilter */*parent*/, const char */*name*/, const QStringList& ) + : KoFilter() +{ +} + + +KoFilter::ConversionStatus PNGExport::convert( const QCString& from, const QCString& to ) +{ + if ( to != "image/png" || from != "application/x-kformula" ) + return KoFilter::NotImplemented; + + KoStoreDevice* in = m_chain->storageFile( "root", KoStore::Read ); + if(!in) { + kapp->restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Failed to read data." ), i18n( "PNG Export Error" ) ); + return KoFilter::FileNotFound; + } + + QDomDocument dom( "KFORMULA" ); + if ( !dom.setContent( in, false ) ) { + kapp->restoreOverrideCursor(); + KMessageBox::error( 0, i18n( "Malformed XML data." ), i18n( "PNG Export Error" ) ); + return KoFilter::WrongFormat; + } + + PNGExportDia* dialog = new PNGExportDia( dom, m_chain->outputFile() ); + dialog->exec(); + delete dialog; + return KoFilter::OK; +} + +#include "pngexport.moc" diff --git a/filters/kformula/png/pngexport.h b/filters/kformula/png/pngexport.h new file mode 100644 index 000000000..b94254395 --- /dev/null +++ b/filters/kformula/png/pngexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef PNGEXPORT_H +#define PNGEXPORT_H + +class QCString; +class QStringList; + +#include + +class PNGExport : public KoFilter +{ + Q_OBJECT +public: + PNGExport( KoFilter *parent, const char *name, const QStringList& ); + virtual ~PNGExport() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); +}; + +#endif // PNGEXPORT_H diff --git a/filters/kformula/png/pngexportdia.cc b/filters/kformula/png/pngexportdia.cc new file mode 100644 index 000000000..8de33b75c --- /dev/null +++ b/filters/kformula/png/pngexportdia.cc @@ -0,0 +1,242 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "pngexportdia.h" +#include + +PNGExportDia::PNGExportDia( const QDomDocument &dom, const QString &outFile, QWidget *parent, const char *name ) + : KDialogBase( parent, name, true, i18n("PNG Export Filter Parameters" ), Ok|Cancel ), + _fileOut( outFile ) +{ + kapp->restoreOverrideCursor(); + wrapper = new KFormula::DocumentWrapper( kapp->config(), 0 ); + KFormula::Document* doc = new KFormula::Document; + wrapper->document( doc ); + formula = doc->createFormula(); + if ( !doc->loadXML( dom ) ) { + kdError() << "Failed." << endl; + } + + setupGUI(); + + QRect rect = formula->boundingRect(); + realWidth = rect.width(); + realHeight = rect.height(); + widthEdit->setValue( realWidth ); + heightEdit->setValue( realHeight ); + percWidthEdit->setValue( 100 ); + percHeightEdit->setValue( 100 ); + + connectAll(); + connect( proportional, SIGNAL( clicked() ), + this, SLOT( proportionalClicked() ) ); +} + +PNGExportDia::~PNGExportDia() +{ + delete wrapper; +} + +void PNGExportDia::connectAll() +{ + connect( widthEdit, SIGNAL( valueChanged(int) ), + this, SLOT( widthChanged( int ) ) ); + connect( heightEdit, SIGNAL( valueChanged(int) ), + this, SLOT( heightChanged( int ) ) ); + connect( percWidthEdit, SIGNAL( valueChanged(double) ), + this, SLOT( percentWidthChanged( double ) ) ); + connect( percHeightEdit, SIGNAL( valueChanged(double) ), + this, SLOT( percentHeightChanged(double ) ) ); +} + +void PNGExportDia::disconnectAll() +{ + disconnect( widthEdit, SIGNAL( valueChanged(int) ), + this, SLOT( widthChanged( int ) ) ); + disconnect( heightEdit, SIGNAL( valueChanged(int) ), + this, SLOT( heightChanged( int ) ) ); + disconnect( percWidthEdit, SIGNAL( valueChanged(double) ), + this, SLOT( percentWidthChanged( double ) ) ); + disconnect( percHeightEdit, SIGNAL( valueChanged(double) ), + this, SLOT( percentHeightChanged(double ) ) ); +} + +void PNGExportDia::widthChanged( int width ) +{ + disconnectAll(); + width = QMIN( width, realWidth*10 ); + width = QMAX( width, realWidth/10 ); + double percent = 100.*static_cast( width )/static_cast( realWidth ); + percWidthEdit->setValue( percent ); + if ( proportional->isChecked() ) { + percHeightEdit->setValue( percent ); + int height = static_cast( realHeight*percent/100. ); + heightEdit->setValue( height ); + } + connectAll(); +} + +void PNGExportDia::heightChanged( int height ) +{ + disconnectAll(); + height = QMIN( height, realHeight*10 ); + height = QMAX( height, realHeight/10 ); + double percent = 100.*static_cast( height )/static_cast( realHeight ); + percHeightEdit->setValue( percent ); + if ( proportional->isChecked() ) { + percWidthEdit->setValue( percent ); + int width = static_cast( realWidth*percent/100. ); + widthEdit->setValue( width ); + } + connectAll(); +} + +void PNGExportDia::percentWidthChanged( double percent ) +{ + disconnectAll(); + percent = QMIN( percent, 1000 ); + percent = QMAX( percent, 10 ); + int width = static_cast( realWidth*percent/100. ); + widthEdit->setValue( width ); + if ( proportional->isChecked() ) { + int height = static_cast( realHeight*percent/100. ); + heightEdit->setValue( height ); + percHeightEdit->setValue( percent ); + } + connectAll(); +} + +void PNGExportDia::percentHeightChanged( double percent ) +{ + disconnectAll(); + percent = QMIN( percent, 1000 ); + percent = QMAX( percent, 10 ); + if ( proportional->isChecked() ) { + int width = static_cast( realWidth*percent/100. ); + widthEdit->setValue( width ); + percWidthEdit->setValue( percent ); + } + int height = static_cast( realHeight*percent/100. ); + heightEdit->setValue( height ); + connectAll(); +} + +void PNGExportDia::proportionalClicked() +{ + if ( proportional->isChecked() ) { + disconnectAll(); + int width = widthEdit->value( ); + width = QMIN( width, realWidth*10 ); + width = QMAX( width, realWidth/10 ); + double percent = 100.*static_cast( width )/static_cast( realWidth ); + percHeightEdit->setValue( percent ); + int height = static_cast( realHeight*percent/100. ); + heightEdit->setValue( height ); + connectAll(); + } +} + +void PNGExportDia::setupGUI() +{ + QWidget *page = new QWidget( this ); + setMainWidget(page); + + QBoxLayout* mainLayout = new QVBoxLayout( page, KDialog::marginHint(), KDialog::spacingHint() ); + + proportional = new QCheckBox( page, "proportional" ); + proportional->setText( i18n( "Keep ratio" ) ); + proportional->setChecked( true ); + mainLayout->addWidget( proportional ); + + QLabel* height = new QLabel( page, "Height" ); + height->setText( i18n( "Height" ) ); + widthEdit = new KIntNumInput( page, "widthEdit" ); + QLabel* width = new QLabel( page, "Width" ); + width->setText( i18n( "Width" ) ); + heightEdit = new KIntNumInput( page, "heightEdit" ); + + QGridLayout* layout1 = new QGridLayout; + layout1->addWidget( height, 1, 0 ); + layout1->addWidget( widthEdit, 0, 1 ); + layout1->addWidget( width, 0, 0 ); + layout1->addWidget( heightEdit, 1, 1 ); + + mainLayout->addLayout( layout1 ); + + QLabel* percentHeight = new QLabel( page, "PercentHeight" ); + percentHeight->setText( i18n( "Height (%)" ) ); + QLabel* percentWidth = new QLabel( page, "PercentWidth" ); + percentWidth->setText( i18n( "Width (%)" ) ); + percWidthEdit = new KDoubleNumInput( page, "percWidthEdit" ); + percHeightEdit = new KDoubleNumInput( page, "percHeightEdit" ); + + QGridLayout* layout2 = new QGridLayout; + layout2->addWidget( percWidthEdit, 0, 1 ); + layout2->addWidget( percHeightEdit, 1, 1 ); + layout2->addWidget( percentHeight, 1, 0 ); + layout2->addWidget( percentWidth, 0, 0 ); + + mainLayout->addLayout( layout2 ); + + /* Display the main layout */ + mainLayout->addStretch( 5 ); + mainLayout->activate(); +} + + +void PNGExportDia::slotOk() +{ + hide(); + //doc->setZoomAndResolution( 100, 600, 600 ); + //doc->setZoomAndResolution( 1000, QPaintDevice::x11AppDpiX(), QPaintDevice::x11AppDpiY() ); + //doc->newZoomAndResolution( false, false ); + int width = widthEdit->value(); + int height = heightEdit->value(); +// kdDebug( KFormula::DEBUGID ) << k_funcinfo +// << "(" << width << " " << height << ")" +// << endl; +// width = realWidth; +// height = realHeight; + QImage image = formula->drawImage( width, height ); + if ( !image.save( _fileOut, "PNG" ) ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), i18n( "PNG Export Error" ) ); + } + reject(); +} + +#include "pngexportdia.moc" diff --git a/filters/kformula/png/pngexportdia.h b/filters/kformula/png/pngexportdia.h new file mode 100644 index 000000000..3957ef882 --- /dev/null +++ b/filters/kformula/png/pngexportdia.h @@ -0,0 +1,81 @@ +/* This file is part of the KDE project + Copyright (C) 2002 Ulrich Kuettler + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef PNGEXPORTDIA_H +#define PNGEXPORTDIA_H + +class QCheckBox; +class QString; +class KIntNumInput; +class KDoubleNumInput; + +namespace KFormula { + class Container; + class DocumentWrapper; +} + +#include + +#include + + +class PNGExportDia : public KDialogBase +{ + Q_OBJECT + +public: + PNGExportDia( const QDomDocument &dom, const QString &outFile, QWidget *parent=0L, const char *name=0L ); + ~PNGExportDia(); + +public slots: + void slotOk(); + +protected slots: + + void widthChanged( int ); + void heightChanged( int ); + void percentWidthChanged( double ); + void percentHeightChanged( double ); + + void proportionalClicked(); + +private: + + void connectAll(); + void disconnectAll(); + + void setupGUI(); + + int realWidth; + int realHeight; + + QString _fileOut; + QByteArray _arrayOut; + + KFormula::Container* formula; + KFormula::DocumentWrapper* wrapper; + + QCheckBox* proportional; + KIntNumInput* widthEdit; + KIntNumInput* heightEdit; + KDoubleNumInput* percWidthEdit; + KDoubleNumInput* percHeightEdit; +}; + +#endif // PNGEXPORTDIA_H diff --git a/filters/kformula/svg/Makefile.am b/filters/kformula/svg/Makefile.am new file mode 100644 index 000000000..a369e7f03 --- /dev/null +++ b/filters/kformula/svg/Makefile.am @@ -0,0 +1,25 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(KFORMULA_INCLUDES) $(all_includes) +libkfosvgexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkfosvgexport_la_LIBADD = $(KOFFICE_LIBS) $(LIB_KFORMULA) + +####### Files + +kde_module_LTLIBRARIES = libkfosvgexport.la + +libkfosvgexport_la_SOURCES = svgexport.cc + +noinst_HEADERS = svgexport.h + +######## Debug +#check_PROGRAMS = texlauncher +#texlauncher_SOURCES = texlauncher.cc +#texlauncher_LDADD = liblatexexport.la +#texlauncher_LDFLAGS = $(KDE_RPATH) $(all_libraries) + + +METASOURCES = AUTO + +service_DATA = kformula_svg_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kformula/svg/kformula_svg_export.desktop b/filters/kformula/svg/kformula_svg_export.desktop new file mode 100644 index 000000000..5b7a8d120 --- /dev/null +++ b/filters/kformula/svg/kformula_svg_export.desktop @@ -0,0 +1,56 @@ +[Desktop Entry] +X-KDE-Export=image/svg+xml +ExportDescription=SVG +Icon= +X-KDE-Import=application/x-kformula +X-KDE-Weight=1 +ImportDescription=KFormula +Name=KFormula SVG Export Filter +Name[ar]=مرشح تصدير SVG لدى KFormula +Name[bg]=Филтър за експортиране от KFormula в SVG +Name[br]=Sil ezporzh SVG evit KFormula +Name[ca]=Filtre d'exportació SVG per a KFormula +Name[cy]=Hidlen Allforio SVG KFormula +Name[da]=KFormula SVG-eksportfilter +Name[de]=KFormula SVG-Exportfilter +Name[el]=Φίλτρο εξαγωγής SVG του KFormula +Name[eo]=SVG-eksportfiltrilo por KFormula +Name[es]=Filtro de exportación a SVG de KFormula +Name[et]=KFormula SVG ekspordifilter +Name[fa]=پالایۀ صادرات KFormula SVG +Name[fi]=KFormula SVG -vientisuodin +Name[fr]=Filtre d'exportation SVG de KFormula +Name[fy]=SVG-Eksportfilter foar KFormula +Name[ga]=Scagaire Easpórtála SVG KFormula +Name[gl]=Filtro de Exportación de SVG para KFormula +Name[he]=KFormula SVG מסנן יצוא +Name[hr]=KFormula SVG filtar izvoza +Name[hu]=KFormula SVG exportszűrő +Name[is]=KFormula SVG útflutningssía +Name[it]=Filtro di esportazione SVG per KFormula +Name[ja]=KFormula SVG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ SVG សម្រាប់ KFormula +Name[lt]=KFormula SVG eksportavimo filtras +Name[lv]=KFormula SVG eksporta filtrs +Name[nb]=SVG-eksportfilter for KFormula +Name[nds]=SVG-Exportfilter för KFormula +Name[ne]=केडीई सूत्र एसभीजी निर्यात फिल्टर +Name[nl]=SVG-exportfilter voor KFormula +Name[pl]=Filtr eksportu do formatu SVG z KFormula +Name[pt]=Filtro de Exportação de SVG para o KFormula +Name[pt_BR]=Filtro de Exportação de SVG para o KFormula +Name[ru]=Фильтр экспорта формул KFormula в SVG +Name[se]=KFormula SVG-olggosfievrridansilli +Name[sk]=Exportný filter KFormula SVG +Name[sl]=Izvozni filter SVG za KFormulo +Name[sr]=KFormula-ин филтер за извоз у SVG +Name[sr@Latn]=KFormula-in filter za izvoz u SVG +Name[sv]=Kformula SVG-exportfilter +Name[uk]=Фільтр експорту SVG для KFormula +Name[uz]=KFormula SVG eksport filteri +Name[uz@cyrillic]=KFormula SVG экспорт филтери +Name[zh_CN]=KFormula SVG 导出过滤器 +Name[zh_TW]=KFormula SVG 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Library=libkfosvgexport diff --git a/filters/kformula/svg/svgexport.cc b/filters/kformula/svg/svgexport.cc new file mode 100644 index 000000000..46177a9ab --- /dev/null +++ b/filters/kformula/svg/svgexport.cc @@ -0,0 +1,102 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Inge Wallin + Copyright (C) 2005 Fredrik Edemar + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#include +#include + +#include +#include + +#include +#include +//#include +#include + +#include +#include "kformuladocument.h" + +#include "svgexport.h" + + +typedef KGenericFactory SvgExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkfosvgexport, SvgExportFactory( "svgexport" ) ) + +SvgExport::SvgExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +SvgExport::~SvgExport() +{ +} + + +KoFilter::ConversionStatus +SvgExport::convert(const QCString& from, const QCString& to) +{ + // Check for proper conversion. + if ( from != "application/x-kformula" || to != "image/svg+xml" ) + return KoFilter::NotImplemented; + + // Read the contents of the KFormula file + KoStoreDevice* storeIn = m_chain->storageFile( "root", KoStore::Read ); + if ( !storeIn ) { + KMessageBox::error( 0, i18n("Failed to read data." ), + i18n( "SVG Export Error" ) ); + return KoFilter::FileNotFound; + } + + // Get the XML tree. + QDomDocument domIn; + domIn.setContent( storeIn ); + QDomElement docNode = domIn.documentElement(); + + // Read the document from the XML tree. + KFormula::DocumentWrapper* wrapper = new KFormula::DocumentWrapper( kapp->config(), 0 ); + KFormula::Document* kformulaDoc = new KFormula::Document; + wrapper->document( kformulaDoc ); + KFormula::Container* formula = kformulaDoc->createFormula(); + + if ( !kformulaDoc->loadXML( domIn ) ) { + KMessageBox::error( 0, i18n( "Malformed XML data." ), + i18n( "SVG Export Error" ) ); + return KoFilter::WrongFormat; + } + + // Draw the actual bitmap. + QPicture picture; + QPainter painter(&picture); + QRect rect(QPoint(0, 0), QPoint(500, 400)); + formula->draw( painter, rect, false ); + painter.end(); + + // Save the image. + if ( !picture.save( m_chain->outputFile(), "SVG" ) ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "SVG Export Error" ) ); + } + + delete formula; + delete wrapper; + return KoFilter::OK; +} + + +#include diff --git a/filters/kformula/svg/svgexport.h b/filters/kformula/svg/svgexport.h new file mode 100644 index 000000000..085654a02 --- /dev/null +++ b/filters/kformula/svg/svgexport.h @@ -0,0 +1,37 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Inge Wallin + Copyright (C) 2005 Fredrik Edemar + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#ifndef __SVGEXPORT_H__ +#define __SVGEXPORT_H__ + +#include + +class SvgExport : public KoFilter +{ + Q_OBJECT + +public: + SvgExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~SvgExport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // __SVGEXPORT_H__ diff --git a/filters/kivio/Makefile.am b/filters/kivio/Makefile.am new file mode 100644 index 000000000..4130552b2 --- /dev/null +++ b/filters/kivio/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = imageexport \ No newline at end of file diff --git a/filters/kivio/imageexport/Makefile.am b/filters/kivio/imageexport/Makefile.am new file mode 100644 index 000000000..dce78335a --- /dev/null +++ b/filters/kivio/imageexport/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kivio/kiviopart \ + -I$(top_srcdir)/kivio/kiviopart/kiviosdk \ + -I$(top_srcdir)/kivio/kiviopart/config \ + -I$(top_builddir)/kivio/kiviopart/config \ + $(all_includes) + +METASOURCES = AUTO + +kde_module_LTLIBRARIES = libkivioimageexport.la + +libkivioimageexport_la_SOURCES = kivio_imageexport.cpp \ + kivio_imageexportwidget.ui kivio_imageexportdialog.cpp +libkivioimageexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkivioimageexport_la_LIBADD = $(top_builddir)/kivio/kiviopart/libkiviocommon.la $(KOFFICE_LIBS) + +service_DATA = kivio_image_export.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kivio/imageexport/kivio_image_export.desktop b/filters/kivio/imageexport/kivio_image_export.desktop new file mode 100644 index 000000000..ad5a52d92 --- /dev/null +++ b/filters/kivio/imageexport/kivio_image_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=Kivio Image Export Filter +Name[ar]=مرشح تصدير Image لدى Kivio +Name[bg]=Филтър за експортиране на изображения в Kivio +Name[br]=Sil ezporzh skeudenn evit Kivio +Name[ca]=Filtre d'exportació d'imatges per a Kivio +Name[da]=Kivio billedeksportfilter +Name[de]=Kivio Bild-Exportfilter +Name[el]=Φίλτρο εξαγωγής εικόνας του Kivio +Name[eo]=Kivio-bildeksportfiltrilo +Name[es]=Filtro de exportación a imagen de Kivio +Name[et]=Kivio pildi ekspordifilter +Name[fa]=پالایۀ صادرات تصویر Kivio +Name[fi]=Kivio kuva -vientisuodin +Name[fr]=Filtre d'exportation d'images de Kivio +Name[fy]=Kiviofilter foar ôfbylding-eksport +Name[ga]=Scagaire Easpórtála Íomhá Kivio +Name[gl]=Filtro de Exportación de Imaxe para Kivio +Name[he]=Kivio מסנן יצוא תמונה +Name[hr]=Kivio filtar izvoza slika +Name[hu]=Kivio képexportáló szűrő +Name[is]=Kivio mynd útflutningssía +Name[it]=Filtro di esportazione delle immagini di Kivio +Name[ja]=Kivio 画像 エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ​រូបភាព​សម្រាប់ Kivio +Name[lt]=Kivio Image eksportavimo filtras +Name[lv]=Kivio attēla eksporta filtrs +Name[nb]=Bilde-eksportfilter for Kivio +Name[nds]=Bild-Exportfilter för Kivio +Name[ne]=किभियो छवि निर्यात फिल्टर +Name[nl]=Kivio-filter voor afbeeldingsexport +Name[pl]=Filtr eksportu do obrazków z Kivio +Name[pt]=Filtro de Exportação de Imagem para o Kivio +Name[pt_BR]=Filtro de Exportação de Imagem para o Kivio +Name[ru]=Фильтр экспорта схем Kivio +Name[se]=Kivio govvaolggosfievrridansilli +Name[sk]=Exportný filter obrázkov Kivio +Name[sl]=Izvozni filter za slike za Kivio +Name[sr]=Kivio-ов филтер за извоз слика +Name[sr@Latn]=Kivio-ov filter za izvoz slika +Name[sv]=Kivio bildexportfilter +Name[uk]=Фільтр експорту зображення для Kivio +Name[uz]=Kivio rasm eksport filteri +Name[uz@cyrillic]=Kivio расм экспорт филтери +Name[zh_CN]=Kivio 图像导出过滤器 +Name[zh_TW]=Kivio 圖片匯出過濾程式 +X-KDE-Import=application/x-kivio +X-KDE-Export=image/png,image/jpeg,image/x-bmp +X-KDE-Weight=1 +X-KDE-Library=libkivioimageexport +ServiceTypes=KOfficeFilter diff --git a/filters/kivio/imageexport/kivio_imageexport.cpp b/filters/kivio/imageexport/kivio_imageexport.cpp new file mode 100644 index 000000000..e5a6600cd --- /dev/null +++ b/filters/kivio/imageexport/kivio_imageexport.cpp @@ -0,0 +1,178 @@ +/* This file is part of the KDE project + Copyright (C) 2005-2006 Peter Simonsson + Copyright (C) 2006 Kåre Särs + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kivio_imageexport.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "kivio_doc.h" +#include "kivio_page.h" +#include "kivio_map.h" +#include "kivio_screen_painter.h" + +#include "kivio_imageexportdialog.h" + +typedef KGenericFactory KivioImageExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkivioimageexport, KivioImageExportFactory("KivioImageExport") ) + +namespace Kivio +{ + +ImageExport::ImageExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ + KGlobal::locale()->insertCatalogue("kofficefilters"); +} + +KoFilter::ConversionStatus ImageExport::convert(const QCString& from, const QCString& to) +{ + if(from != "application/x-kivio") { + return KoFilter::BadMimeType; + } + + QString format; + + if(to == "image/png") { + format = "PNG"; + } else if(to == "image/jpeg") { + format = "JPEG"; + } else if(to == "image/x-bmp") { + format = "BMP"; + } else if(to == "image/x-eps") { + format = "EPS"; + } else if(to == "image/x-portable-bitmap") { + format = "PBM"; + } else if(to == "image/x-pcx") { + format = "PCX"; + } else if(to == "image/x-portable-pixmap") { + format = "PPM"; + } else if(to == "image/x-rgb") { + format = "RGB"; + } else if(to == "image/x-xpm") { + format = "XPM"; + } else if(to == "image/jp2") { + format = "JP2"; + } else { + return KoFilter::BadMimeType; + } + + KoStoreDevice* storeIn = m_chain->storageFile("root", KoStore::Read); + + if (!storeIn) { + KMessageBox::error(0, i18n("Failed to read data."), i18n( "Export Error" )); + return KoFilter::FileNotFound; + } + + // Get the XML tree. + QDomDocument domIn; + domIn.setContent(storeIn); + + KivioDoc doc; + + if(!doc.loadXML(0, domIn)) { + KMessageBox::error(0, i18n("Malformed XML data."), i18n("Export Error")); + return KoFilter::WrongFormat; + } + + ImageExportDialog dlg; + + QStringList pageNames; + QPtrList pageList = doc.map()->pageList(); + QPtrListIterator it(pageList); + + for(; it.current() != 0; ++it) { + pageNames.append(it.current()->pageName()); + } + + dlg.setPageList(pageNames); + + dlg.setInitialDPI(300); + dlg.setInitialmargin(10); + + if(dlg.exec() != QDialog::Accepted) { + return KoFilter::UserCancelled; + } + + KivioPage* page = doc.map()->findPage(dlg.selectedPage()); + + if(!page) { + kdDebug() << "The page named " << dlg.selectedPage() << " wasn't found!!" << endl; + return KoFilter::InternalError; + } + + float z = (float)dlg.imageDPI()/(float)KoGlobal::dpiX(); + KoZoomHandler zoom; + zoom.setZoomAndResolution(qRound(z * 100), KoGlobal::dpiX(), KoGlobal::dpiY()); + + QSize size; + if(dlg.usePageBorders()) { + size = QSize(zoom.zoomItX(page->paperLayout().ptWidth), zoom.zoomItY(page->paperLayout().ptHeight)); + } else { + size = zoom.zoomSize(page->getRectForAllStencils().size()); + } + + kdDebug() << "KoGlobal::dpiX() " << KoGlobal::dpiX() << " KoGlobal::dpiY() " << KoGlobal::dpiY() << endl; + + int border = dlg.margin(); + + size.setWidth(size.width() + (border * 2)); + size.setHeight(size.height() + (border * 2)); + + QPixmap pixmap = QPixmap(size); + pixmap.fill(Qt::white); + KivioScreenPainter kpainter; + kpainter.start(&pixmap); + + float translationX = border; + float translationY = border; + + if(!dlg.usePageBorders()) { + QPoint point = zoom.zoomPoint(page->getRectForAllStencils().topLeft()); + translationX -= point.x(); + translationY -= point.y(); + } + + kpainter.setTranslation(translationX, translationY); + page->printContent(kpainter, &zoom); + + if(!pixmap.save(m_chain->outputFile(), format.local8Bit())) { + return KoFilter::CreationError; + } + + return KoFilter::OK; +} + +} + +#include "kivio_imageexport.moc" diff --git a/filters/kivio/imageexport/kivio_imageexport.h b/filters/kivio/imageexport/kivio_imageexport.h new file mode 100644 index 000000000..f538ce24f --- /dev/null +++ b/filters/kivio/imageexport/kivio_imageexport.h @@ -0,0 +1,39 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Peter Simonsson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIVIO_IMAGEEXPORT_H +#define KIVIO_IMAGEEXPORT_H + +#include + +namespace Kivio +{ + +class ImageExport : public KoFilter +{ + Q_OBJECT + public: + ImageExport(KoFilter *, const char *, const QStringList&); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +} + +#endif diff --git a/filters/kivio/imageexport/kivio_imageexportdialog.cpp b/filters/kivio/imageexport/kivio_imageexportdialog.cpp new file mode 100644 index 000000000..0ed613974 --- /dev/null +++ b/filters/kivio/imageexport/kivio_imageexportdialog.cpp @@ -0,0 +1,105 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Peter Simonsson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kivio_imageexportdialog.h" + +#include +#include + +#include +#include +#include + +#include "kivio_imageexportwidget.h" + +namespace Kivio +{ + +ImageExportDialog::ImageExportDialog(QWidget* parent, const char* name) + : KDialogBase(parent, name, false, i18n("Export to Image"), Ok|Cancel) +{ + kapp->restoreOverrideCursor(); + m_mainWidget = new ImageExportWidget(this); + setMainWidget(m_mainWidget); +} + +void ImageExportDialog::setPageList(const QStringList& pages) +{ + m_mainWidget->m_pageCombo->clear(); + m_mainWidget->m_pageCombo->insertStringList(pages); +} + +void ImageExportDialog::setInitialDPI(const int dpi) +{ + if (dpi <= 72) m_mainWidget->m_DPIcomboBox->setCurrentItem(0); + else if (dpi <= 96) m_mainWidget->m_DPIcomboBox->setCurrentItem(1); + else if (dpi <= 150) m_mainWidget->m_DPIcomboBox->setCurrentItem(2); + else if (dpi <= 300) m_mainWidget->m_DPIcomboBox->setCurrentItem(3); + else if (dpi <= 600) m_mainWidget->m_DPIcomboBox->setCurrentItem(4); + else if (dpi <= 720) m_mainWidget->m_DPIcomboBox->setCurrentItem(5); + else if (dpi <= 1200) m_mainWidget->m_DPIcomboBox->setCurrentItem(6); +} + +void ImageExportDialog::setInitialmargin(const int margin) +{ + m_mainWidget->m_marginSpinBox->setValue(margin); +} + +QString ImageExportDialog::selectedPage() const +{ + return m_mainWidget->m_pageCombo->currentText(); +} + +int ImageExportDialog::imageDPI() const +{ + switch (m_mainWidget->m_DPIcomboBox->currentItem()) + { + case 0: + return 72; + case 1: + return 96; + case 2: + return 150; + case 3: + return 300; + case 4: + return 600; + case 5: + return 720; + case 6: + return 1200; + default: + return 300; + } +} + +bool ImageExportDialog::usePageBorders() const +{ + return (m_mainWidget->m_exportAreaCombo->currentItem() == 1); +} + + +int ImageExportDialog::margin() const +{ + return m_mainWidget->m_marginSpinBox->value(); +} + +} + +#include "kivio_imageexportdialog.moc" diff --git a/filters/kivio/imageexport/kivio_imageexportdialog.h b/filters/kivio/imageexport/kivio_imageexportdialog.h new file mode 100644 index 000000000..72d1e9ab9 --- /dev/null +++ b/filters/kivio/imageexport/kivio_imageexportdialog.h @@ -0,0 +1,51 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Peter Simonsson + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KIVIO_IMAGEEXPORTDIALOG_H +#define KIVIO_IMAGEEXPORTDIALOG_H + +#include + +namespace Kivio +{ + +class ImageExportWidget; + +class ImageExportDialog : public KDialogBase +{ + Q_OBJECT + public: + ImageExportDialog(QWidget* parent = 0, const char* name = 0); + + void setPageList(const QStringList& pages); + void setInitialDPI(const int dpi); + void setInitialmargin(const int margin); + + QString selectedPage() const; + bool usePageBorders() const; + int imageDPI() const; + int margin() const; + + private: + ImageExportWidget* m_mainWidget; +}; + +} + +#endif diff --git a/filters/kivio/imageexport/kivio_imageexportwidget.ui b/filters/kivio/imageexport/kivio_imageexportwidget.ui new file mode 100644 index 000000000..00241fcf4 --- /dev/null +++ b/filters/kivio/imageexport/kivio_imageexportwidget.ui @@ -0,0 +1,203 @@ + +Kivio::ImageExportWidget + + + Kivio::ImageExportWidget + + + + 0 + 0 + 296 + 132 + + + + + unnamed + + + 0 + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 40 + + + + + + m_pageLabel + + + Page: + + + + + m_exportAreaLabel + + + Area to export: + + + + + m_DPILabel + + + Bitmap DPI: + + + Set the resolution of the resulting bitmap image + + + + + m_marginLabel + + + Margin (Pixels): + + + + + spacer7 + + + Horizontal + + + Expanding + + + + 60 + 21 + + + + + + m_marginSpinBox + + + + + spacer4_2_2 + + + Horizontal + + + Expanding + + + + 70 + 20 + + + + + + + 72 + + + + + 96 + + + + + 150 + + + + + 300 + + + + + 600 + + + + + 720 + + + + + 1200 + + + + m_DPIcomboBox + + + true + + + Set the resolution of the resulting bitmap image + + + + + line1 + + + HLine + + + Sunken + + + Horizontal + + + + + + Objects on Page + + + + + Complete Page + + + + m_exportAreaCombo + + + + + m_pageCombo + + + + + + + + + + kcombobox.h + kcombobox.h + + diff --git a/filters/kpresenter/Makefile.am b/filters/kpresenter/Makefile.am new file mode 100644 index 000000000..83598811c --- /dev/null +++ b/filters/kpresenter/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = libimageexport png bmp xbm xpm mng svg jpeg kword ooimpress diff --git a/filters/kpresenter/bmp/Makefile.am b/filters/kpresenter/bmp/Makefile.am new file mode 100644 index 000000000..ece3480f0 --- /dev/null +++ b/filters/kpresenter/bmp/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresenterbmpexport.la + +libkpresenterbmpexport_la_SOURCES = bmpexport.cpp +libkpresenterbmpexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresenterbmpexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + bmpexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_bmp_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/bmp/bmpexport.cpp b/filters/kpresenter/bmp/bmpexport.cpp new file mode 100644 index 000000000..b2ecfe0f3 --- /dev/null +++ b/filters/kpresenter/bmp/bmpexport.cpp @@ -0,0 +1,81 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "KPrDocument.h" +#include "KPrView.h" +#include "KPrCanvas.h" +#include "bmpexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory bmpExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresenterbmpexport, bmpExportFactory( "bmpexport" ) ) + +BmpExport::BmpExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +BmpExport::~BmpExport() +{ +} + +bool BmpExport::extraImageAttribute() +{ + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + bool ret = false; + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + ret = true; + kdDebug() << "PNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; + return ret; +} + + +bool BmpExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "BMP" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "BMP Export Error" ) ); + } + return ret; +} + +const char * BmpExport::exportFormat() +{ + return "image/x-bmp"; +} + +#include "bmpexport.moc" + diff --git a/filters/kpresenter/bmp/bmpexport.h b/filters/kpresenter/bmp/bmpexport.h new file mode 100644 index 000000000..6e4f29bf9 --- /dev/null +++ b/filters/kpresenter/bmp/bmpexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __BMPEXPORT_H__ +#define __BMPEXPORT_H__ + +#include "imageexport.h" + +class BmpExport : public ImageExport +{ + Q_OBJECT + +public: + BmpExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~BmpExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __PNGEXPORT_H__ + diff --git a/filters/kpresenter/bmp/kpresenter_bmp_export.desktop b/filters/kpresenter/bmp/kpresenter_bmp_export.desktop new file mode 100644 index 000000000..f47dd4eb0 --- /dev/null +++ b/filters/kpresenter/bmp/kpresenter_bmp_export.desktop @@ -0,0 +1,53 @@ +[Desktop Entry] +Type=Service +Name=KPresenter BMP Export Filter +Name[ar]=مرشح تصدير BMP لدى KPresenter +Name[bg]=Филтър за експортиране от KPresenter в BMP +Name[br]=Sil ezporzh BMB evit KPresenter +Name[ca]=Filtre d'exportació BMP per a KPresenter +Name[cy]=Hidlen Allforio BMP KPresenter +Name[da]=KPræsenter BMP-eksportfilter +Name[de]=KPresenter BMP-Exportfilter +Name[el]=Φίλτρο εξαγωγής BMP του KPresenter +Name[eo]=KPresenter BMP-eksportfiltrilo +Name[es]=Filtro de exportación a BMP para KPresenter +Name[et]=KPresenteri BMP ekspordifilter +Name[fa]=پالایۀ صادرات KPresenter BMP +Name[fi]=KPresenter BMP -vientisuodin +Name[fr]=Filtre d'exportation BMP de KPresenter +Name[fy]=BMP-Eksportfilter foarKPresenter +Name[ga]=Scagaire Easpórtála BMP KPresenter +Name[gl]=Filtro de Exportación de BMP para KPresenter +Name[he]=KPresenter מסנן יצוא +Name[hr]=KPresenter BMP filtar izvoza +Name[hu]=KPresenter BMP exportszűrő +Name[is]=KPresenter BMP útflutningssía +Name[it]=Filtro di esportazione BMP per KPresenter +Name[ja]=KPresenter BMP エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ BMP សម្រាប់ KPresenter +Name[lt]=KPresenter BMP eksportavimo filtras +Name[lv]=KPresenter BMP eksporta filtrs +Name[nb]=BMP-eksportfilter for KPresenter +Name[nds]=BMP-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता बीएमपी निर्यात फिल्टर +Name[nl]=BMP-exportfilter voor KPresenter +Name[pl]=Filtr eksportu do formatu BMP z KPresenter +Name[pt]=Filtro de Exportação de BMP para o KPresenter +Name[pt_BR]=Filtro de Exportação de BMP para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в BMP +Name[se]=KPresenter BMP-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter BMP +Name[sl]=Izvozni filter BMP za KPresenter +Name[sr]=KChart-ов филтер за извоз у BMP +Name[sr@Latn]=KChart-ov filter za izvoz u BMP +Name[sv]=Kpresenter BMP-exportfilter +Name[uk]=Фільтр експорту BMP для KPresenter +Name[uz]=KPresenter BMP eksport filteri +Name[uz@cyrillic]=KPresenter BMP экспорт филтери +Name[zh_CN]=KPresenter BMP 导出过滤器 +Name[zh_TW]=KPresenter BMP 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/x-bmp +X-KDE-Weight=1 +X-KDE-Library=libkpresenterbmpexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/jpeg/Makefile.am b/filters/kpresenter/jpeg/Makefile.am new file mode 100644 index 000000000..9f5106c2d --- /dev/null +++ b/filters/kpresenter/jpeg/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresenterjpegexport.la + +libkpresenterjpegexport_la_SOURCES = jpegexport.cpp +libkpresenterjpegexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresenterjpegexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + jpegexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_jpeg_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/jpeg/jpegexport.cpp b/filters/kpresenter/jpeg/jpegexport.cpp new file mode 100644 index 000000000..b62d985d2 --- /dev/null +++ b/filters/kpresenter/jpeg/jpegexport.cpp @@ -0,0 +1,82 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "KPrDocument.h" +#include "KPrView.h" +#include "KPrCanvas.h" +#include "jpegexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory jpegExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresenterjpegexport, jpegExportFactory( "jpegexport" ) ) + +JpegExport::JpegExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +JpegExport::~JpegExport() +{ +} + +bool JpegExport::extraImageAttribute() +{ + bool ret = false; + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + + kdDebug() << "MNG Export: size = [" << width << "," << height << "]" << endl; + ret = true; + } + delete exportDialog; + return ret; +} + + +bool JpegExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "JPEG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "JPEG Export Error" ) ); + } + return ret; +} + +const char * JpegExport::exportFormat() +{ + return "image/jpeg"; +} + +#include "jpegexport.moc" + diff --git a/filters/kpresenter/jpeg/jpegexport.h b/filters/kpresenter/jpeg/jpegexport.h new file mode 100644 index 000000000..873e463ff --- /dev/null +++ b/filters/kpresenter/jpeg/jpegexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class JpegExport : public ImageExport +{ + Q_OBJECT + +public: + JpegExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~JpegExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/kpresenter/jpeg/kpresenter_jpeg_export.desktop b/filters/kpresenter/jpeg/kpresenter_jpeg_export.desktop new file mode 100644 index 000000000..868eac792 --- /dev/null +++ b/filters/kpresenter/jpeg/kpresenter_jpeg_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KPresenter JPEG Export Filter +Name[ar]=مرشح تصدير JPEG لدى KPresenter +Name[bg]=Филтър за експортиране от Kpresenter в JPEG +Name[br]=Sil ezporzh JPEG evit KPresenter +Name[ca]=Filtre d'exportació JPEG per a KPresenter +Name[da]=KPræsenter JPEG-eksportfilter +Name[de]=KPresenter JPEG-Exportfilter +Name[el]=Φίλτρο εξαγωγής JPEG του KPresenter +Name[eo]=KPresenter JPEG-eksportfiltrilo +Name[es]=Filtro de exportación a JPEG para KPresenter +Name[et]=KPresenteri JPEG ekspordifilter +Name[fa]=پالایۀ صادرات KPresenter JPEG +Name[fi]=KPresenter JPEG -vientisuodin +Name[fr]=Filtre d'exportation JPEG de KPresenter +Name[fy]=JPEG-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála JPEG KPresenter +Name[gl]=Filtro de Exportación de JPEG para KPresenter +Name[he]=KPresenter JPEG מסנן יצוא +Name[hr]=KPresenter JPEG filtar izvoza +Name[hu]=KPresenter JPEG exportszűrő +Name[is]=KPresenter JPEG útflutningssía +Name[it]=Filtro di esportazione JPEG per KPresenter +Name[ja]=KPresenter JPEG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ JPEG សម្រាប់ KPresenter +Name[lt]=KPresenter JPEG eksportavimo filtras +Name[lv]=KPresenter JPEG eksporta filtrs +Name[nb]=JPEG-eksportfilter for KPresenter +Name[nds]=JPEG-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता जेपीईजी निर्यात फिल्टर +Name[nl]=JPEG-exportfilter voor KPresenter +Name[pl]=Filtr eksportu do formatu JPEG z KPresenter +Name[pt]=Filtro de Exportação de JPEG para o KPresenter +Name[pt_BR]=Filtro de Exportação de JPEG para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в JPEG +Name[se]=KPresnter JPEG-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter JPEG +Name[sl]=Izvozni filter JPEG za KPresenter +Name[sr]=KChart-ов филтер за извоз у JPEG +Name[sr@Latn]=KChart-ov filter za izvoz u JPEG +Name[sv]=Kpresenter JPEG-exportfilter +Name[uk]=Фільтр експорту JPEG для KPresenter +Name[uz]=KPresenter JPEG eksport filteri +Name[uz@cyrillic]=KPresenter JPEG экспорт филтери +Name[zh_CN]=KPresenter JPEG 导出过滤器 +Name[zh_TW]=KPresenter JPEG 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/jpeg +X-KDE-Weight=1 +X-KDE-Library=libkpresenterjpegexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/kword/Makefile.am b/filters/kpresenter/kword/Makefile.am new file mode 100644 index 000000000..0e579f5cb --- /dev/null +++ b/filters/kpresenter/kword/Makefile.am @@ -0,0 +1,12 @@ +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) $(all_includes) + +kde_module_LTLIBRARIES = libkprkword.la + +libkprkword_la_SOURCES = kprkword.cc +libkprkword_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libkprkword_la_LIBADD = $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = kprkword.desktop +servicedir = $(kde_servicesdir) diff --git a/filters/kpresenter/kword/kprkword.cc b/filters/kpresenter/kword/kprkword.cc new file mode 100644 index 000000000..a0cd7ab4a --- /dev/null +++ b/filters/kpresenter/kword/kprkword.cc @@ -0,0 +1,466 @@ +/* This file is part of the KDE project + Copyright (C) 2001 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory KprKwordFactory; +K_EXPORT_COMPONENT_FACTORY( libkprkword, KprKwordFactory( "kofficefilters" ) ) + +KprKword::KprKword(KoFilter *, const char *, const QStringList&) : + KoFilter(), + outdoc( "DOC" ) +{ +} + +// This filter can act as an import filter for KWord and as an export +// filter for KPresenter (isn't our architecture really nice ? :) +// This is why we use the file-to-file method, not a QDomDoc one. +KoFilter::ConversionStatus KprKword::convert( const QCString& from, const QCString& to ) +{ + if(to!="application/x-kword" || from!="application/x-kpresenter") + return KoFilter::NotImplemented; + + KoStoreDevice* inpdev = m_chain->storageFile( "root", KoStore::Read ); + if ( !inpdev ) + { + kdError(30502) << "Unable to open input stream" << endl; + return KoFilter::StorageCreationError; + } + + inpdoc.setContent( inpdev ); + + + outdoc.appendChild( outdoc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) ); + QDomElement kwdoc = outdoc.createElement( "DOC" ); + kwdoc.setAttribute( "editor", "KprKword converter" ); + kwdoc.setAttribute( "mime", "application/x-kword" ); + kwdoc.setAttribute( "syntaxVersion", 1 ); + outdoc.appendChild( kwdoc ); + + QDomElement paper = outdoc.createElement( "PAPER" ); + kwdoc.appendChild( paper ); + paper.setAttribute( "format", 1 ); // A4. How on earth could I know what the user really wants ? :) + paper.setAttribute( "width", 595 ); + paper.setAttribute( "height", 841 ); + QDomElement borders = outdoc.createElement( "PAPERBORDERS" ); + paper.appendChild( borders ); + borders.setAttribute( "left", 28 ); + borders.setAttribute( "top", 42 ); + borders.setAttribute( "right", 28 ); + borders.setAttribute( "bottom", 42 ); + + QDomElement framesets = outdoc.createElement( "FRAMESETS" ); + kwdoc.appendChild( framesets ); + + frameset = outdoc.createElement( "FRAMESET" ); + framesets.appendChild( frameset ); + frameset.setAttribute( "frameType", 1 ); // text + frameset.setAttribute( "frameInfo", 0 ); // body + QDomElement frame = outdoc.createElement( "FRAME" ); + frameset.appendChild( frame ); + frame.setAttribute( "left", 28 ); + frame.setAttribute( "top", 42 ); + frame.setAttribute( "right", 566 ); + frame.setAttribute( "bottom", 798 ); + frame.setAttribute( "autoCreateNewFrame", 1 ); + frame.setAttribute( "newFrameBehaviour", 0 ); + + titleStyleName = i18n("Slide Title"); + + // Convert ! + + convert(); + + // Create a style for the slide titles + + QDomElement styles = outdoc.createElement( "STYLES" ); + kwdoc.appendChild( styles ); + + QDomElement style = outdoc.createElement( "STYLE" ); + styles.appendChild( style ); + QDomElement elem = outdoc.createElement( "NAME" ); + style.appendChild( elem ); + elem.setAttribute( "value", titleStyleName ); + elem = outdoc.createElement( "FOLLOWING" ); + style.appendChild( elem ); + elem.setAttribute( "name", "Standard" ); // no i18n here! + + QDomElement counter = outdoc.createElement( "COUNTER" ); + style.appendChild( counter ); + counter.setAttribute( "type", 1 ); // numbered + counter.setAttribute( "depth", 0 ); + counter.setAttribute( "start", 1 ); + counter.setAttribute( "numberingtype", 1 ); // chapter + counter.setAttribute( "righttext", "." ); + + QDomElement format = outdoc.createElement( "FORMAT" ); + style.appendChild( format ); + QDomElement font = outdoc.createElement( "FONT" ); + format.appendChild( font ); + font.setAttribute( "name", titleFont ); // found when reading the first title + QDomElement size = outdoc.createElement( "SIZE" ); + format.appendChild( size ); + size.setAttribute( "value", 24 ); + QDomElement bold = outdoc.createElement( "WEIGHT" ); + format.appendChild( bold ); + bold.setAttribute( "value", 75 ); + + // Create the standard style + style = outdoc.createElement( "STYLE" ); + styles.appendChild( style ); + elem = outdoc.createElement( "NAME" ); + style.appendChild( elem ); + elem.setAttribute( "value", "Standard" ); // no i18n here! + format = outdoc.createElement( "FORMAT" ); + style.appendChild( format ); // empty format == use defaults + + // Write output file + + KoStoreDevice* out = m_chain->storageFile( "root", KoStore::Write ); + if(!out) { + kdError(30502) << "Unable to open output file!" << endl; + return KoFilter::StorageCreationError; + } + QCString cstring = outdoc.toCString(); // utf-8 already + out->writeBlock( cstring.data(), cstring.length() ); + return KoFilter::OK; +} + +// This class is used to sort the objects by y position +class KprObject { + public: + double y; + QDomElement elem; + bool operator < ( const KprObject & c ) const + { + return y < c.y; + } + bool operator == ( const KprObject & c ) const + { + return y == c.y; + } +}; + +void KprKword::convert() +{ + QDomElement docElem = inpdoc.documentElement(); + QDomElement paper = docElem.namedItem( "PAPER" ).toElement(); + int ptPageHeight = paper.attribute( "ptHeight" ).toInt(); + + QDomElement objects = docElem.namedItem( "OBJECTS" ).toElement(); + if ( objects.isNull() ) + return; + + QSortedList< KprObject > objList; + objList.setAutoDelete( true ); + + QDomNodeList lst = objects.elementsByTagName( "OBJECT" ); + uint lstcount = lst.count(); + for ( uint item = 0 ; item < lstcount ; ++item ) + { + QDomElement object = lst.item( item ).toElement(); + if ( object.attribute( "type" ).toInt() == 4 ) // we only care about text objs + { + QDomElement orig = object.namedItem( "ORIG" ).toElement(); + if ( !orig.isNull() ) + { + KprObject * obj = new KprObject; + obj->y = orig.attribute( "y" ).toDouble(); + obj->elem = object; + objList.inSort( obj ); + } + } + } + + int curPage = -1; + //kdDebug() << "found " << objList.count() << " objects" << endl; + + for ( QPtrListIterator it(objList); it.current(); ++it ) + { + QDomElement elem = it.current()->elem; + // Detect the first object of each page + int page = int( it.current()->y / ptPageHeight ); + bool isTitle = ( page > curPage ); + //kdDebug() << "KprKword::convert y=" << it.current()->y << " ptPageHeight=" << ptPageHeight + // << " isTitle=" << isTitle << endl; + curPage = page; + + QDomElement textObj = elem.namedItem( "TEXTOBJ" ).toElement(); + if (textObj.isNull()) + continue; + // For each paragraph in this text object... + QDomNodeList lst = textObj.elementsByTagName( "P" ); + uint lstcount = lst.count(); + for ( uint item = 0; item < lstcount ; ++item ) + { + QDomElement p = lst.item( item ).toElement(); + + // Create paragraph in KWord doc + QDomElement parag = outdoc.createElement( "PARAGRAPH" ); + frameset.appendChild( parag ); + + QDomElement outFormatsElem = outdoc.createElement( "FORMATS" ); + + QString text; + // For each text element in the paragraph... + QDomElement textElem = p.firstChild().toElement(); + + QDomElement counter = p.namedItem( "COUNTER" ).toElement(); + QDomElement indent=p.namedItem("INDENTS").toElement(); + QDomElement lineSpacing=p.namedItem( "LINESPACING" ).toElement(); + QDomElement offset=p.namedItem("OFFSETS").toElement(); + QDomElement leftBorder = p.namedItem( "LEFTBORDER" ).toElement(); + QDomElement rightBorder = p.namedItem( "RIGHTBORDER" ).toElement(); + QDomElement topBorder = p.namedItem( "TOPBORDER" ).toElement(); + QDomElement bottomBorder = p.namedItem( "BOTTOMBORDER" ).toElement(); + + QDomElement shadow=p.namedItem("SHADOW").toElement(); + + for ( ; !textElem.isNull() ; textElem = textElem.nextSibling().toElement() ) + { + int oldLen = text.length(); + text += textElem.text(); + //kdDebug() << "KprKword::convert text now " << text << endl; + QDomElement outFormatElem = outdoc.createElement( "FORMAT" ); + + if ( textElem.attribute( "italic" ).toInt() ) + { + QDomElement e = outdoc.createElement("ITALIC"); + e.setAttribute( "value", 1 ); + outFormatElem.appendChild( e ); + } + QColor underlineColor; + if ( textElem.hasAttribute("underlinecolor" )) + { + underlineColor =QColor(textElem.attribute("underlinecolor" )); + } + QString underlineStyleLine; + if ( textElem.hasAttribute("underlinestyleline")) + { + underlineStyleLine = textElem.attribute("underlinestyleline"); + } + if ( textElem.hasAttribute("underline" )) + { + QDomElement e = outdoc.createElement("UNDERLINE"); + QString value = textElem.attribute( "underline" ); + if ( value == "double" ) + { + e.setAttribute( "value", "double" ); + } + else if ( value == "single" ) + { + e.setAttribute( "value", "double" ); + } + else + { + e.setAttribute( "value", (bool)value.toInt() ? "1" :"0" ); + } + if ( underlineColor.isValid()) + { + e.setAttribute("underlinecolor", underlineColor.name()); + } + if ( !underlineStyleLine.isEmpty() ) + e.setAttribute("styleline", underlineStyleLine); + outFormatElem.appendChild( e ); + + } + + QString strikeOutStyleLine; + if ( textElem.hasAttribute("strikeoutstyleline")) + { + strikeOutStyleLine = textElem.attribute("strikeoutstyleline"); + } + QString strikeOutValue; + if ( textElem.hasAttribute("strikeOut")) + { + strikeOutValue = textElem.attribute("strikeOut"); + } + + if( !strikeOutValue.isEmpty()) + { + QDomElement e = outdoc.createElement("STRIKEOUT"); + e.setAttribute( "value", strikeOutValue ); + if ( !strikeOutStyleLine.isEmpty()) + e.setAttribute("styleline", strikeOutStyleLine); + outFormatElem.appendChild( e ); + } + /*if ( textElem.attribute( "bold" ).toInt() ) + { + QDomElement e = outdoc.createElement("WEIGHT"); + e.setAttribute( "value", 75 ); + outFormatElem.appendChild( e ); + }*/ // doesn't look good + if ( titleFont.isEmpty() && isTitle ) + titleFont = textElem.attribute( "family" ); + + // Family and point size are voluntarily NOT passed over. + if ( !textElem.attribute( "color" ).isEmpty()) + { + QColor col; + col.setNamedColor(textElem.attribute( "color" )); + QDomElement e = outdoc.createElement("COLOR"); + e.setAttribute( "red", col.red() ); + e.setAttribute( "green", col.green() ); + e.setAttribute( "blue", col.blue() ); + outFormatElem.appendChild( e ); + } + if ( !textElem.attribute("textbackcolor").isEmpty()) + { + QColor col; + col.setNamedColor(textElem.attribute( "textbackcolor" )); + QDomElement e = outdoc.createElement("TEXTBACKGROUNDCOLOR"); + e.setAttribute( "red", col.red() ); + e.setAttribute( "green", col.green() ); + e.setAttribute( "blue", col.blue() ); + outFormatElem.appendChild( e ); + } + + //before VERTICAL align + double relative = 0; + if( textElem.attribute("relativetextsize").toDouble()) + { + relative = textElem.attribute("relativetextsize").toDouble(); + } + + + if( textElem.attribute("VERTALIGN").toInt()) + { + QDomElement e = outdoc.createElement("VERTALIGN"); + e.setAttribute( "value", textElem.attribute("VERTALIGN").toInt() ); + if ( relative != 0) + e.setAttribute( "relativetextsize", relative ); + outFormatElem.appendChild( e ); + } + + if( textElem.hasAttribute("shadowtext")) + { + QDomElement e = outdoc.createElement("SHADOWTEXT"); + e.setAttribute( "value", textElem.attribute("shadowtext").toInt() ); + outFormatElem.appendChild( e ); + } + + if( textElem.hasAttribute("offsetfrombaseline")) + { + QDomElement e = outdoc.createElement("OFFSETFROMBASELINE"); + e.setAttribute( "value", textElem.attribute("offsetfrombaseline").toInt() ); + outFormatElem.appendChild( e ); + } + + if( textElem.hasAttribute("wordbyword")) + { + QDomElement e = outdoc.createElement("WORDBYWORD"); + e.setAttribute( "value", textElem.attribute("wordbyword").toInt() ); + outFormatElem.appendChild( e ); + } + + if( textElem.hasAttribute("fontattribute")) + { + QDomElement e = outdoc.createElement("FONTATTRIBUTE"); + e.setAttribute( "value", textElem.attribute("fontattribute") ); + outFormatElem.appendChild( e ); + } + if( textElem.hasAttribute("language")) + { + QDomElement e = outdoc.createElement("LANGUAGE"); + e.setAttribute( "value", textElem.attribute("language") ); + outFormatElem.appendChild( e ); + } + if ( !outFormatElem.firstChild().isNull() ) + { + outFormatElem.setAttribute( "id", 1 ); // normal exte + outFormatElem.setAttribute( "pos", oldLen ); + outFormatElem.setAttribute( "len", text.length() - oldLen ); + outFormatsElem.appendChild( outFormatElem ); + } + + } // end "for each text element" + + // KPresenter seems to save a trailing space (bug!) + int len = text.length(); + if ( len > 0 && text[ len - 1 ] == ' ' ) + text.truncate( len - 1 ); + + QDomElement outTextElem = outdoc.createElement( "TEXT" ); + parag.appendChild( outTextElem ); + outTextElem.appendChild( outdoc.createTextNode( text ) ); + + if ( !outFormatsElem.firstChild().isNull() ) // Do we have formats to save ? + parag.appendChild( outFormatsElem ); + + QDomElement layoutElem = outdoc.createElement( "LAYOUT" ); + parag.appendChild( layoutElem ); + QDomElement nameElem = outdoc.createElement( "NAME" ); + layoutElem.appendChild( nameElem ); + nameElem.setAttribute( "value", isTitle ? titleStyleName : QString("Standard") ); + QDomElement align=outdoc.createElement("FLOW"); + if(p.hasAttribute("align")) + { + switch(p.attribute( "align" ).toInt()) + { + case 1: + align.setAttribute( "align","left"); + break; + case 2: + align.setAttribute( "align","right"); + break; + case 4: + align.setAttribute( "align","center"); + break; + case 8: + align.setAttribute( "align","justify"); + break; + } + } + if(!counter.isNull() ) + layoutElem.appendChild( counter ); + if(!indent.isNull()) + layoutElem.appendChild( indent ); + if(!lineSpacing.isNull()) + layoutElem.appendChild( lineSpacing ); + if(!offset.isNull()) + layoutElem.appendChild( offset); + if(!leftBorder.isNull()) + layoutElem.appendChild(leftBorder); + if(!rightBorder.isNull()) + layoutElem.appendChild(rightBorder); + if(!topBorder.isNull()) + layoutElem.appendChild(topBorder); + if(!bottomBorder.isNull()) + layoutElem.appendChild(bottomBorder); + if(!align.isNull()) + layoutElem.appendChild(align); + if(!shadow.isNull()) + layoutElem.appendChild(shadow); + // Only the first parag of the top text object is set to the 'title' style + isTitle = false; + } + } +} + +#include diff --git a/filters/kpresenter/kword/kprkword.desktop b/filters/kpresenter/kword/kprkword.desktop new file mode 100644 index 000000000..bf4ff228f --- /dev/null +++ b/filters/kpresenter/kword/kprkword.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Type=Service +Name=KPresenter KWord Filter +Name[ar]=مِرْشَح KPresenter->KWord +Name[bg]=Филтър KPresenter-> KWord +Name[br]=Sil KWord KPresenter +Name[ca]=Filtre de KWord per a KPresenter +Name[cs]=Filtr pro převod KPresenter->KWord +Name[cy]=Hidlen KWord KPresenter +Name[da]=KPræsenter KWord-filter +Name[de]=KPresenter KWord-Filter +Name[el]=KPresenter KWord φίλτρο +Name[eo]=KPresenter KWord-filtrilo +Name[es]=Filtro de KWord para KPresenter +Name[et]=KPresenteri KWordi filter +Name[eu]=KPresenter-en KWord iragazkia +Name[fa]=پالایۀ KPresenter KWord +Name[fi]=KPresenter KWord -suodin +Name[fr]=Filtre KWord pour KPresenter +Name[fy]=KWord-filter foar KPresenter +Name[ga]=Scagaire KWord KPresenter +Name[gl]=Filtro de KWord para KPresenter +Name[he]=מסנן ייבוא מ־KWord ל־KPresenter +Name[hr]=KPresenter filtar za KWord +Name[hu]=KPresenter KWord szűrő +Name[is]=KPresenter KWord sía +Name[it]=Filtro da KPresenter a KWord +Name[ja]=KPresenter KWord フィルタ +Name[km]=តម្រង KWord សម្រាប់ KPresenter +Name[lt]=KPresenter KWord filtras +Name[lv]=KPresenter KWord filtrs +Name[ms]=Penapis KPresenter KWord +Name[nb]=KPresenter KWord-filter +Name[nds]=KWord-Filter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता केडीई शब्द फिल्टर +Name[nl]=KWord-filter voor KPresenter +Name[nn]=KWord-filter for KPresenter +Name[pl]=Filtr KPresenter formatu KWord +Name[pt]=Filtro de KWord para o KPresenter +Name[pt_BR]=Filtro do KPresenter->KWord +Name[ru]=Фильтр экспорта документов KWord в KPresenter +Name[se]=KPresentera KWord-silli +Name[sk]=Filter pre prevod KPresenter- KWord +Name[sl]=Filter za KPresenter v KWord +Name[sr]=KPresenter-ов филтер за KWord +Name[sr@Latn]=KPresenter-ov filter za KWord +Name[sv]=Kpresenter Kword-filter +Name[uk]=Фільтр KWord для KPresenter +Name[uz]=KPresenter uchun KWord filteri +Name[uz@cyrillic]=KPresenter учун KWord филтери +Name[zh_CN]=KPresenter KWord 过滤器 +Name[zh_TW]=KPresenter KWord 過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Weight=1 +X-KDE-Export=application/x-kword +X-KDE-Library=libkprkword +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/kword/kprkword.h b/filters/kpresenter/kword/kprkword.h new file mode 100644 index 000000000..5e0aed2d6 --- /dev/null +++ b/filters/kpresenter/kword/kprkword.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2001 David Faure + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KPRKWORD_H +#define KPRKWORD_H + +#include +#include + +class KprKword : public KoFilter { + + Q_OBJECT + +public: + KprKword(KoFilter *parent, const char *name, const QStringList&); + + virtual ~KprKword() {} + + virtual KoFilter::ConversionStatus convert( const QCString& from, const QCString& to ); + +protected: + void convert(); + QDomDocument inpdoc; + QDomDocument outdoc; + QDomElement frameset; + QString titleStyleName; + QString titleFont; +}; +#endif // KPRKWORD_H diff --git a/filters/kpresenter/kword/status.html b/filters/kpresenter/kword/status.html new file mode 100644 index 000000000..2c669e0c7 --- /dev/null +++ b/filters/kpresenter/kword/status.html @@ -0,0 +1,88 @@ + + + + + KOffice filters status: ASCII FILTER + + +  + +
    +
    +

    + KOffice filters status:   KPRESENTER->KWORD FILTER +

    +
    + +
    + + + Export + + +
    + +
    + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Export KPresenter to KWord.
    + This can be useful as a starting point for writing a document + about a presentation.
    +
    +
    Last update10 Apr 2001
    FeaturesExport a presentation into a KWord text document
    Todo-
    History + 10 Apr 2001 Initial version
    +
    Authors + David Faure   +
    Links-
    Progress report -
    +
    +
    +Up + + + diff --git a/filters/kpresenter/libimageexport/Makefile.am b/filters/kpresenter/libimageexport/Makefile.am new file mode 100644 index 000000000..a4eb60103 --- /dev/null +++ b/filters/kpresenter/libimageexport/Makefile.am @@ -0,0 +1,20 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + $(all_includes) + +####### Files + +lib_LTLIBRARIES = libkpresenterimageexport.la + +libkpresenterimageexport_la_SOURCES = imageexport.cpp +libkpresenterimageexport_la_LDFLAGS = $(all_libraries) -version-info 4:0 -no-undefined +libkpresenterimageexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + imageexport.h + +METASOURCES = AUTO + + diff --git a/filters/kpresenter/libimageexport/imageexport.cpp b/filters/kpresenter/libimageexport/imageexport.cpp new file mode 100644 index 000000000..7611a9367 --- /dev/null +++ b/filters/kpresenter/libimageexport/imageexport.cpp @@ -0,0 +1,99 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "KPrDocument.h" +#include "KPrView.h" +#include "KPrCanvas.h" +#include "imageexport.h" + +ImageExport::ImageExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +ImageExport::~ImageExport() +{ +} + + +KoFilter::ConversionStatus +ImageExport::convert(const QCString& from, const QCString& to) +{ + KoDocument * document = m_chain->inputDocument(); + + if ( !document ) + return KoFilter::StupidError; + + if ( strcmp(document->className(), "KPrDocument") != 0) + { + kdWarning() << "document isn't a KPrDocument but a " + << document->className() << endl; + return KoFilter::NotImplemented; + } + + // Check for proper conversion. + if ( from != "application/x-kpresenter" || to != exportFormat() ) + { + kdWarning() << "Invalid mimetypes " << to << " " << from << endl; + return KoFilter::NotImplemented; + } + KPrDocument * kpresenterdoc = const_cast(static_cast(document)); + + if ( kpresenterdoc->mimeType() != "application/x-kpresenter" ) + { + kdWarning() << "Invalid document mimetype " << kpresenterdoc->mimeType() << endl; + return KoFilter::NotImplemented; + } + KoPageLayout layoutPage= kpresenterdoc->pageLayout(); + width = int( layoutPage.ptWidth ); + height = int( layoutPage.ptHeight ); + if (extraImageAttribute()) + { + KPrView* view = static_cast( kpresenterdoc->views().getFirst()); + if ( view ) // no view if embedded document + { + KPrCanvas * canvas = view->getCanvas(); + canvas->drawPageInPix( pixmap, view->getCurrPgNum()-1, 0, true, width,height ); + } + else //when it's embedded we use just it. + { + pixmap = QPixmap(width, height); + QPainter painter(&pixmap); + kpresenterdoc->paintContent(painter, pixmap.rect(), false); + } + if( !saveImage( m_chain->outputFile())) + return KoFilter::CreationError; + return KoFilter::OK; + } + return KoFilter::UserCancelled; +} + + +#include "imageexport.moc" + diff --git a/filters/kpresenter/libimageexport/imageexport.h b/filters/kpresenter/libimageexport/imageexport.h new file mode 100644 index 000000000..e5dfeb819 --- /dev/null +++ b/filters/kpresenter/libimageexport/imageexport.h @@ -0,0 +1,45 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __IMAGEEXPORT_H__ +#define __IMAGEEXPORT_H__ + +#include + +class QPixmap; +class ImageExport : public KoFilter +{ + Q_OBJECT + +public: + ImageExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~ImageExport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + virtual bool extraImageAttribute() { return true;}; + virtual bool saveImage( QString fileName) = 0; + virtual const char* exportFormat() = 0; +protected: + int width; + int height; + QPixmap pixmap; +}; + +#endif // __IMAGEEXPORT_H__ + diff --git a/filters/kpresenter/magicpoint/Makefile.am b/filters/kpresenter/magicpoint/Makefile.am new file mode 100644 index 000000000..a7b01aded --- /dev/null +++ b/filters/kpresenter/magicpoint/Makefile.am @@ -0,0 +1,5 @@ +bin_SCRIPTS = mgp2kpr.py + +service_DATA = kpresenter_magicpoint_import.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/kpresenter/magicpoint/kpresenter_magicpoint_import.desktop b/filters/kpresenter/magicpoint/kpresenter_magicpoint_import.desktop new file mode 100644 index 000000000..947c6ba75 --- /dev/null +++ b/filters/kpresenter/magicpoint/kpresenter_magicpoint_import.desktop @@ -0,0 +1,62 @@ +[Desktop Entry] +Type=Service +Exec=mgp2kpr.py +Name=Magicpoint Import Filter for KPresenter +Name[ar]=مِرْشَح استيراد Magicpoint لدى KPresenter +Name[bg]=Филтър за импортиране от Magicpoint в KPresenter +Name[br]=Sil enporzh Magicpoint evit KPresenter +Name[ca]=Filtre d'importació Magicpoint per a KPresenter +Name[cs]=Importní filtr Magicpoint pro KPresenter +Name[cy]=Hidlen Fewnforio Magicpoint i KPresenter +Name[da]=Magicpoint import-filter for KPresenter +Name[de]=KPresenter Magicpoint-Importfilter +Name[el]=Φίλτρο εισαγωγής Magicpoint για το KPresenter +Name[eo]=Magicpoint-importfiltrilo por KPresenter +Name[es]=Filtro de importación de Magicpoint para KPresenter +Name[et]=KPresenteri Magicpoint'i impordifilter +Name[eu]=KPresenter-en Magicpoint inportaziorako iragazkia +Name[fa]=پالایۀ واردات Magicpoint برای KPresenter +Name[fi]=Magicpoint-tuontisuodin KPresenterille +Name[fr]=Filtre d'importation Magicpoint pour KPresenter +Name[fy]=Magicpoint-Ymportfilter foar Kpresenter +Name[gl]=Filtro de Importación de Magicpoint para KPresenter +Name[he]=מסנן ייבוא מ־MagicPoint ל־KPresenter +Name[hi]=के-प्रेज़ेन्टर के लिए मैजिक पाइन्ट आयात छननी +Name[hr]=Magicpoint filtar uvoza za KPresenter +Name[hu]=Magicpoint importszűrő a KPresenterhez +Name[is]=Magicpoint innflutningssía fyrir KPresenter +Name[it]=Filtro di importazione Magicpoint per KPresenter +Name[ja]=KPresenter Magicpoint インポートフィルタ +Name[km]=តម្រង​នាំចូល Magicpoint សម្រាប់ KPresenter +Name[lo]= ຕົວຕອງການນຳເຂົ້າ CSV ຂອງກະດາດຄຳນວນ K +Name[lt]=Magicpoint importavimo filtras skirtas KPresenter +Name[lv]=Magicpoint importa filtrs priekš KPresenter +Name[ms]=Penapis Import Magicpoint bagi KPresenter +Name[nb]=Magicpoint-importfilter for KPresenter +Name[nds]=Magicpoint-Importfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि म्याजिकबिन्दु निर्यात फिल्टर +Name[nl]=Magicpoint-importfilter voor KPresenter +Name[nn]=Magicpoint-importfilter for KPresenter +Name[pl]=Filtr importu z Magicpoint dla KPresenter +Name[pt]=Filtro de Importação de Magicpoint para o KPresenter +Name[pt_BR]=Filtro de Importação Magicpoint para o KPresenter +Name[ru]=Фильтр импорта презентаций Magicpoint в KPresenter +Name[se]=KPresenter:a Magicpoint-sisafievrridansilli +Name[sk]=Filter pre import Magicpoint pre KPresenter +Name[sl]=Uvozni filter Magicpoint za KPresenter +Name[sr]=KPresenter-ов филтер за увоз из Magicpoint-а +Name[sr@Latn]=KPresenter-ov filter za uvoz iz Magicpoint-a +Name[sv]=Magicpoint-importfilter för Kpresenter +Name[ta]=மாயப்புள்ளி ஏற்றுமதி வடிகட்டி kpresenter +Name[tg]=Филтри Воридоти Magicpoint барои KPresenter +Name[tr]=KPresenter için Magicpoint Alma Filtresi +Name[uk]=Фільтр імпорту Magicpoint для KPresenter +Name[uz]=KPresenter uchun Magicpoint import filteri +Name[uz@cyrillic]=KPresenter учун Magicpoint импорт филтери +Name[wa]=Passete Magicpoint d' intrêye po KPresenter +Name[xh]=Isihluzi Sokurhweba ngaphakathi kwi Magicpoint ye KPresenter +Name[zh_CN]=KPresenter 的 Magicpoint 导入过滤器 +Name[zh_TW]=KPresenter 的 Magicpoint Import 匯入過濾程式 +X-KDE-Wrapper-Export=application/x-kpresenter +X-KDE-Wrapper-Import=application/x-magicpoint +ServiceTypes=KOfficeGenericFilter diff --git a/filters/kpresenter/magicpoint/mgp2kpr.py b/filters/kpresenter/magicpoint/mgp2kpr.py new file mode 100755 index 000000000..975274710 --- /dev/null +++ b/filters/kpresenter/magicpoint/mgp2kpr.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python + +"""This script converts a Magicpoint presentation and outputs +a KPresenter document (XML). + +Magicpoint's homepage: http://www.mew.org/mgp/ +KPresenter's homepage: http://www.koffice.org/kpresenter + +This is free software, released under GPL v2. +Author: Lukas Tinkl , 2002 + +TODO (in order of priority): +DONE: support linespacing +DONE: support bullets +DONE: support bold/italic faces +- support parsing the document defaults (%default and %tab) +- support horizontal bars (hard to position them properly) +- make it use the ZIP store instead of a plain XML file (needed for images below) +- support images +- support for MNG animations (KPresenter doesn't know about them ATM) + +$Id: mgp2kpr.py 186390 2002-10-29 15:39:40Z lukas $ +""" + +import os, sys +import fileinput +import string +from xml.dom.DOMImplementation import implementation +from xml.dom import Document +from xml.dom import Element +from xml.dom.ext import PrettyPrint + +def getYDpi(): + """Utility function; parses xdpyinfo output and returns the vertical DPI of the X display. + Needed to transform the %-like font size into real font point size. + """ + pipe=os.popen("(xdpyinfo | grep dot | cut -b21-22) 2>/dev/null", "r") + if pipe: + dpi=pipe.read().strip() + if dpi: + return dpi + return 75 + +PAGE_WIDTH=680 +Y_OFFSET=510 + +class MgpImporter: + def __init__(self): + "Constructor" + self.charset="iso8859-1" + self.pageCount=-1 #page counter + self.defFonts={} #default (symbolic) font names + self.useDefaults=1 #use page default values? + self.ydpi=int(getYDpi()) #Y DPI + + self.__reset() #init properties + + def __reset(self): + self.alignment="1" #text alignment, left + self.vgap=1 #line spacing + + #font properties + self.fontName="standard" + self.fontItalic=0 + self.fontBold=0 + self.fontSize=24 #default (approximated) font size (5%) + self.textColor="white" + + # background properties + self.backtype="0" + self.backview="0" + self.bctype="0" #single color (0) or gradient (>0) + self.color1="black" + self.color2="white" + + def __setFontSize(self, command): + tokens=string.split(command,' ') + self.fontSize=int(Y_OFFSET/self.ydpi*72*float(tokens[1].strip())/100) + #print self.fontSize + + def __setLineSpacing(self, command): + tokens=string.split(command,' ') + self.vgap=int(tokens[1].strip()) + + def __setupDefaultFonts(self,command): + tokens=string.split(command,' ') + _key=string.replace(tokens[1], '"', '') + _val=string.replace(tokens[3], '"', '') + self.defFonts[_key]=_val + #print self.defFonts + + def __setFontIndirect(self,command): + tokens=string.split(command,' ') + _font=string.replace(tokens[1], '"', '') + if _font in self.defFonts.keys(): #we have a "default" font, find it in the map + self.__setFont(None,self.defFonts[_font]) + #print self.defFonts[_font] + + def __setFont(self,command,font=""): + if command: + tokens=string.split(command,' ') + font=string.replace(tokens[1], '"', '').strip() #XLFD-like, eg: mincho-medium-r (family-weight-slant) + + _numDash=string.find(font,"-") #find dashes + + if (_numDash==-1): #mincho + self.fontName=font + return + else: #mincho-medium-r + _xlfd=string.split(font, "-") + self.fontName=_xlfd[0] + if (_xlfd[1]=="bold" or _xlfd[1]=="semibold" or _xlfd[1]=="demibold" or _xlfd[1]=="demi bold"): #this sucks :) + self.fontBold=1 + else: + self.fontBold=0 + + if (_xlfd[2]=="i"): + self.fontItalic=1 + else: + self.fontItalic=0 + + #print self.fontName + + def __setBgColor(self, command): + tokens=string.split(command,' ') + self.bctype="0" + self.color1=string.replace(tokens[1].strip(),'"', '') #strip quotes and \n + + def __setBgGradient(self, command): + tokens=string.split(command,' ') + #xsize=tokens[1] + #ysize=tokens[2] + #numcolors=tokens[3] or "256" + #zoomflag=tokens[5] or "0" + + try: + dir=tokens[4] + self.color1=string.replace(tokens[6].strip(),'"', '') #strip quotes and \n + self.color2=string.replace(tokens[7].strip(),'"', '') + except: + self.bctype="0" + self.color1="black" + self.color2="white" + return + + if (dir=="0"): #vertical + value="1" + elif (dir=="90"): #horizontal + value="2" + elif (dir=="180"): #vertical, swapped colors + value="1" + self.color1,self.color2=self.color2,self.color1 + elif (dir=="270"): #horizontal, swapped colors + value="2" + self.color1,self.color2=self.color2,self.color1 + elif (dir=="45"): #diagonal 1 + value="3" + elif (dir=="135"): #diagonal 2 + value="4" #TODO swap colors for diagonals too? + elif (dir=="-45"): #circular, what an easter egg ;) + value="5" + else: + value="1" + + self.bctype=value + + def __setAlign(self,command): + tokens=string.split(command,' ') + if (tokens[0]=='leftfill'): #justify + self.alignment="8" + elif (tokens[0]=='right'): + self.alignment="2" + elif (tokens[0]=='center'): + self.alignment="4" + else: + self.alignment="1" #left + #print self.alignment + + def __setBackground(self,parent): + pageElem=self.document.createElement("PAGE") + + elem=self.document.createElement("BACKTYPE") #color + elem.setAttribute("value", self.backtype) + pageElem.appendChild(elem) + + elem=self.document.createElement("BACKVIEW") #always zoomed + elem.setAttribute("value", self.backview) + pageElem.appendChild(elem) + + elem=self.document.createElement("BCTYPE") #single color + elem.setAttribute("value", self.bctype) + pageElem.appendChild(elem) + + elem=self.document.createElement("BACKCOLOR1") #1st color + elem.setAttribute("color", self.color1) + pageElem.appendChild(elem) + + if (self.bctype!="0"): + elem=self.document.createElement("BACKCOLOR2") #2nd color + elem.setAttribute("color", self.color2) + pageElem.appendChild(elem) + + parent.appendChild(pageElem) + + def __handlePage(self,parent,bgParent): + if (self.pageCount!=-1): + self.__setBackground(bgParent) #set the background for this page + + self.pageCount=self.pageCount+1 + objElem=self.document.createElement("OBJECT") #KPresenter text object + objElem.setAttribute("type", "4") + + elem=self.document.createElement("ORIG") #object position + elem.setAttribute("x", "30") + elem.setAttribute("y", str(self.pageCount*Y_OFFSET+30)) + objElem.appendChild(elem) + + elem=self.document.createElement("SIZE") #object size + elem.setAttribute("width", "610") + elem.setAttribute("height", "440") + objElem.appendChild(elem) + + self.textElem=self.document.createElement("TEXTOBJ") #text object + ### para comes here + + objElem.appendChild(self.textElem) + parent.appendChild(objElem) + + self.useDefaults=1 + self.__reset() + + def __handleText(self,line): + indent=-1 + + pElem=self.document.createElement("P") #paragraph + pElem.setAttribute("align", self.alignment) + + elem=self.document.createElement("NAME") #style name + elem.setAttribute("value", "Standard") ###is this needed at all? + pElem.appendChild(elem) + + if (self.useDefaults==0): + elem=self.document.createElement("LINESPACING") #linespacing + elem.setAttribute("type", "custom") + elem.setAttribute("spacingvalue", str(self.fontSize * self.vgap / 100.0)) + pElem.appendChild(elem) + + if (line.startswith('\t\t\t\t')): #bullets + indent=85 + type=8 + elif (line.startswith('\t\t\t')): + indent=56.6 + type=11 + elif (line.startswith('\t\t')): + indent=28.3 + type=9 + elif (line.startswith('\t')): + indent=0 + type=10 + + if not indent==-1: + line=string.lstrip(line) + + elem=self.document.createElement("INDENTS") #indentation (for bullet) + elem.setAttribute("left", str(indent)) + pElem.appendChild(elem) + + elem=self.document.createElement("COUNTER") #counter (for bullet) + elem.setAttribute("numberingtype", "0") #bullet numbering + elem.setAttribute("type", str(type)) #bullet type + #elem.setAttribute("depth", "0") #??? + pElem.appendChild(elem) + + elem=self.document.createElement("TEXT") #paragraph text + #elem.setAttribute("VERTALIGN", "0") + elem.setAttribute("family", self.fontName) + elem.setAttribute("pointSize", str(self.fontSize)) + elem.setAttribute("color", self.textColor) + + if (self.fontBold!=0): + elem.setAttribute("bold", "1") + + if (self.fontItalic!=0): + elem.setAttribute("italic", "1") + + text=self.document.createTextNode(unicode(line, self.charset, 'ignore')) + elem.appendChild(text) + pElem.appendChild(elem) + self.textElem.appendChild(pElem) + + #print "*** text: " + line + + def __setCharset(self,command): + tokens=string.split(command,' ') + self.charset=tokens[1].strip() + + def __setTextColor(self,command): + tokens=string.split(command,' ') + self.textColor=string.replace(tokens[1].strip(),'"', '') #strip quotes + #print self.textColor + + def __handleBar(self,command): + tokens=string.split(command,' ') + + try: + color=string.replace(tokens[1].strip(),'"', '') #strip quotes and \n + width=tokens[2].strip()/1000*Y_OFFSET #in per mils of display height + start=tokens[3].strip()/100*PAGE_WIDTH #start position percent of display width + length=tokens[4].strip()/100*PAGE_WIDTH #length percent of display width + except: #default values + color=self.textColor + width=0.01*Y_OFFSET + start=0 + length=PAGE_WIDTH + + + def __setPaper(self,parent): + paperElem=self.document.createElement("PAPER") + paperElem.setAttribute("ptWidth", str(PAGE_WIDTH)) + paperElem.setAttribute("ptHeight", str(Y_OFFSET)) + paperElem.setAttribute("orientation", "0") #landscape + paperElem.setAttribute("format", "5") #screen + paperElem.setAttribute("unit", "0") #mm + + borderElem=self.document.createElement("PAPERBORDERS") + borderElem.setAttribute("ptLeft","0") + borderElem.setAttribute("ptRight","0") + borderElem.setAttribute("ptTop","0") + borderElem.setAttribute("ptBottom","0") + + paperElem.appendChild(borderElem) + + parent.appendChild(paperElem) + + def convert(self, fileIn, fileOut=None): + """Parses the Magicpoint document and returns a KPresenter XML document. + + fileIn: path to the input file + fileOut: path to the output file, or sys.stdout if omitted + """ + doctype=implementation.createDocumentType("DOC", "-//KDE//DTD kpresenter 1.2//EN", + "http://www.koffice.org/DTD/kpresenter-1.2.dtd") + self.document=implementation.createDocument("http://www.koffice.org/DTD/kpresenter", "DOC", doctype) + + rootElem=self.document.documentElement #the root "DOC" element + rootElem.setAttribute("mime", "application/x-kpresenter") + rootElem.setAttribute("syntaxVersion", "2") + rootElem.setAttribute("editor", "mgp2kpr import filter, (c) Lukas Tinkl, 2002") + + self.__setPaper(rootElem) + bgElem=self.document.createElement("BACKGROUND") + objsElem=self.document.createElement("OBJECTS") + + self.textElem=self.document.createElement("TEXTOBJ") #default text object + + for line in fileinput.input(fileIn): + if (line.startswith('#') or line.startswith('%%')): #skip comments + continue + elif (line.startswith('%')): #commands + commands=string.split(string.replace(line, '%', ''),',') #list of commands, comma separated, remove '%' + for command in commands: + command=command.strip().lower() + #print command + if (command.lower().startswith('page')): #new page + self.__handlePage(objsElem, bgElem) + elif (command.startswith('bgrad')): #background gradient + self.__setBgGradient(command) + elif (command.startswith('deffont')): #default fonts + self.__setupDefaultFonts(command) + elif (command.startswith('default')): #document defaults TODO!!! + pass + elif (command.startswith('xfont')): #font + self.__setFont(command) + elif (command.startswith('font')): #font from default fonts + self.__setFontIndirect(command) + elif (command.startswith('size')): #font size + self.__setFontSize(command) + elif (command.startswith('left') or + command.startswith('center') or + command.startswith('right')): #text alignment + self.__setAlign(command) + elif (command.startswith('charset')): #charset + self.__setCharset(command) + elif (command.startswith('fore')): #font color + self.__setTextColor(command) + elif (command.startswith('back')): #background color + self.__setBgColor(command) + elif (command.startswith('bar')): #horizontal line + self.__handleBar(command) + elif (command.startswith('vgap')): #line spacing + self.__setLineSpacing(command) + elif (command.startswith('nodefault')): #use default page values? + self.useDefaults=0 + else: + continue + else: + self.__handleText(line) #text + + self.__setBackground(bgElem) #flush the background + + rootElem.appendChild(bgElem) + rootElem.appendChild(objsElem) + self.document.appendChild(rootElem) + + if fileOut: + PrettyPrint(self.document, open(fileOut[0], "w")) + else: + PrettyPrint(self.document, sys.stdout) + +if __name__ == '__main__': + if (len(sys.argv)==1 or len(sys.argv)>3): + print """Magicpoint to KPresenter converter, (c) Lukas Tinkl , 2002 + Usage: mgp2kpr infile.mgp [outfile.kpr] + If you give only one parameter, it will output to stdout.""" + else: + importer=MgpImporter() + importer.convert(sys.argv[1], sys.argv[2:]) diff --git a/filters/kpresenter/mng/Makefile.am b/filters/kpresenter/mng/Makefile.am new file mode 100644 index 000000000..92cc0f3d6 --- /dev/null +++ b/filters/kpresenter/mng/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresentermngexport.la + +libkpresentermngexport_la_SOURCES = mngexport.cpp +libkpresentermngexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresentermngexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + mngexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_mng_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/mng/kpresenter_mng_export.desktop b/filters/kpresenter/mng/kpresenter_mng_export.desktop new file mode 100644 index 000000000..ebb619b67 --- /dev/null +++ b/filters/kpresenter/mng/kpresenter_mng_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KPresenter MNG Export Filter +Name[ar]=مرشح تصدير MNG لدى KPresenter +Name[bg]=Филтър за експортиране от Kpresenter в MNG +Name[br]=Sil ezporzh MNG evit KPresenter +Name[ca]=Filtre d'exportació MNG per a KPresenter +Name[da]=KPræsenter MNG-eksportfilter +Name[de]=KPresenter MNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής MNG του KPresenter +Name[eo]=KPresenter MNG-eksportfiltrilo +Name[es]=Filtro de exportación a MNG para KPresenter +Name[et]=KPresenteri MNG ekspordifilter +Name[fa]=پالایۀ صادرات KPresenter MNG +Name[fi]=KPresenter MNG -vientisuodin +Name[fr]=Filtre d'exportation MNG de KPresenter +Name[fy]=MNG-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála MNG KPresenter +Name[gl]=Filtro de Exportación de MNG para KPresenter +Name[he]=KPresenter MNG מסנן יצוא +Name[hr]=KPresenter MNG filtar izvoza +Name[hu]=KPresenter MNG exportszűrő +Name[is]=KPresenter MNG útflutningssía +Name[it]=Filtro di esportazione MNG per KPresenter +Name[ja]=KPresenter MNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ MNG សម្រាប់ KPresenter +Name[lt]=KPresenter MNG eksportavimo filtras +Name[lv]=KPresenter MNG eksporta filtrs +Name[nb]=MNG-eksportfilter for KPresenter +Name[nds]=MNG-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता एमएनजी निर्यात फिल्टर +Name[nl]=MNG-exportfilter voor KPresenter +Name[pl]=Filtr eksportu do formatu MNG z KPresenter +Name[pt]=Filtro de Exportação de MNG para o KPresenter +Name[pt_BR]=Filtro de Exportação de MNG para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в MNG +Name[se]=KPresenter MNG-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter MNG +Name[sl]=Izvozni filter MNG za KPresenter +Name[sr]=KChart-ов филтер за извоз у MNG +Name[sr@Latn]=KChart-ov filter za izvoz u MNG +Name[sv]=Kpresenter MNG-exportfilter +Name[uk]=Фільтр експорту MNG для KPresenter +Name[uz]=KPresenter MNG eksport filteri +Name[uz@cyrillic]=KPresenter MNG экспорт филтери +Name[zh_CN]=KPresenter MNG 导出过滤器 +Name[zh_TW]=KPresenter MNG 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=video/x-mng +X-KDE-Weight=1 +X-KDE-Library=libkpresentermngexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/mng/mngexport.cpp b/filters/kpresenter/mng/mngexport.cpp new file mode 100644 index 000000000..f56f4c773 --- /dev/null +++ b/filters/kpresenter/mng/mngexport.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "mngexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory mngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresentermngexport, mngExportFactory( "mngexport" ) ) + +MngExport::MngExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +MngExport::~MngExport() +{ +} + +bool MngExport::extraImageAttribute() +{ + bool ret = false; + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + ret = true; + kdDebug() << "MNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; + return ret; +} + + +bool MngExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "MNG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "MNG Export Error" ) ); + } + return ret; +} + +const char * MngExport::exportFormat() +{ + return "video/x-mng"; +} + +#include "mngexport.moc" + diff --git a/filters/kpresenter/mng/mngexport.h b/filters/kpresenter/mng/mngexport.h new file mode 100644 index 000000000..c479b1e0f --- /dev/null +++ b/filters/kpresenter/mng/mngexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class MngExport : public ImageExport +{ + Q_OBJECT + +public: + MngExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MngExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/kpresenter/ooimpress/Makefile.am b/filters/kpresenter/ooimpress/Makefile.am new file mode 100644 index 000000000..b69dc04cf --- /dev/null +++ b/filters/kpresenter/ooimpress/Makefile.am @@ -0,0 +1,21 @@ +####### General stuff + +INCLUDES= -I$(srcdir)/../../liboofilter $(KOFFICE_INCLUDES) $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libooimpressimport.la libooimpressexport.la + + +libooimpressimport_la_SOURCES = ooimpressimport.cc +libooimpressimport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libooimpressimport_la_LIBADD = ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +libooimpressexport_la_SOURCES = ooimpressexport.cc stylefactory.cc +libooimpressexport_la_LDFLAGS = $(all_libraries) -module -avoid-version -no-undefined +libooimpressexport_la_LIBADD = ../../liboofilter/liboofilter.la $(KOFFICE_LIBS) + +METASOURCES = AUTO + +service_DATA = kpresenter_ooimpress_import.desktop kpresenter_ooimpress_export.desktop + +servicedir = $(kde_servicesdir) diff --git a/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop b/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop new file mode 100644 index 000000000..d645efbf1 --- /dev/null +++ b/filters/kpresenter/ooimpress/kpresenter_ooimpress_export.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Impress Export Filter for KPresenter +Name[ar]=مِرْشَح استيراد OpenOffice.org Impress لدى KPresenter +Name[bg]=Филтър за експортиране от OpenOffice.org Impress в KPresenter +Name[br]=Sil ezporzh OpenOffice.org Impress evit KPresenter +Name[ca]=Filtre d'exportació OpenOffice.org Impress per a KPresenter +Name[cs]=OpenOffice.org Impress exportní filtr pro KPresenter +Name[cy]=Hidlen Allforio Impress OpenOffice.org ar gyfer KPresenter +Name[da]=OpenOffice.org Impress eksport-filter for KPresenter +Name[de]=KPresenter OpenOffice.org-Impress-Exportfilter +Name[el]=Φίλτρο εξαγωγής OpenOffice.org Impress για το KPresenter +Name[es]=Filtro de importación de OpenOffice.org Impress para KPresenter +Name[et]=KPresenteri OpenOffice.org Impress'i ekspordifilter +Name[eu]=KPresenter-en OpenOffice.org Impress esportaziorako iragazkia +Name[fa]=پالایۀ صادرات OpenOffice.org Impress برای KPresenter +Name[fi]=OpenOffice.org Impress -vientisuodin KPresenterille +Name[fr]=Filtre d'exportation OpenOffice.org Impress pour KPresenter +Name[fy]=OpenOffice.org Impress-Eksportfilter foar KPresenter +Name[gl]=Filtro de Exportación de OpenOffice.org Impress para KPresenter +Name[he]=מסנן ייצוא מ־KPresenter ל־OpenOffice.org Impress +Name[hi]=के-प्रेज़ेन्टर के लिए ओपन-ऑफ़िस.ऑर्ग इम्प्रेस निर्यात छननी +Name[hr]=OpenOffice.org Impress filtar izvoza za KPresenter +Name[hu]=OpenOffice.org Impress exportszűrő a KPresenterhez +Name[is]=OpenOffice.org Impress útflutningssía fyrir KPresenter +Name[it]=Filtro di esportazione OpenOffice.org Impress per KPresenter +Name[ja]=KPresenter OpenOffice.org Impress エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ OpenOffice.org Impress សម្រាប់ KPresenter +Name[lt]=OpenOffice.org Impress eksportavimo filtras skirtas KPresenter +Name[lv]=OpenOffice.org Impress eksporta filtrs priekš KPresenter +Name[ms]=Penapis Eksport OpenOffice.org Impress bagi KPresenter +Name[nb]=OpenOffice.org Impress-eksportfilter for KPresenter +Name[nds]="OpenOffice.org Impress"-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि OpenOffice.org इम्प्रेस निर्यात फिल्टर +Name[nl]=OpenOffice.org Impress-exportfilter voor KPresenter +Name[nn]=OpenOffice.org Impress-eksportfilter for KPresenter +Name[pl]=Filtr eksportu do OpenOffice.org Impress dla KPresenter +Name[pt]=Filtro de Exportação de OpenOffice.org Impress para o KPresenter +Name[pt_BR]=Filtro de Exportação OpenOffice.org Impress para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в OpenOffice.org Impress +Name[se]=KPresenter:a OpenOffice.org Impress-olggosfievrridansilli +Name[sk]=Filter pre import OpenOffice.org Impress pre KPresenter +Name[sl]=Izvozni filter OpenOffice.org Impress za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у OpenOffice Impress +Name[sr@Latn]=KPresenter-ov filter za izvoz u OpenOffice Impress +Name[sv]=OpenOffice.org Impress-exportfilter för Kpresenter +Name[ta]=openoffice.org Impress ஏற்றுமதி வடிகட்டி kpresenter +Name[tg]=Филтри Содироти OpenOffice.org Impress барои KPresenter +Name[tr]=KPresenter için OpenOffice.org Impress Alma Filtresi +Name[uk]=Фільтр експорту презентацій OpenOffice.org для KPresenter +Name[uz]=KPresenter uchun OpenOffice.org Impress eksport filteri +Name[uz@cyrillic]=KPresenter учун OpenOffice.org Impress экспорт филтери +Name[wa]=Passete OpenOffice.org Impress di rexhowe po KPresenter +Name[zh_CN]=KPresenter 的 OpenOffice.org Impress 导出过滤器 +Name[zh_TW]=KPresenter 的 OpenOffice.org Impress 匯出過濾程式 +X-KDE-Export=application/vnd.sun.xml.impress +X-KDE-Import=application/x-kpresenter +X-KDE-Weight=1 +X-KDE-Library=libooimpressexport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop b/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop new file mode 100644 index 000000000..b5b5a79f3 --- /dev/null +++ b/filters/kpresenter/ooimpress/kpresenter_ooimpress_import.desktop @@ -0,0 +1,64 @@ +[Desktop Entry] +Type=Service +Name=OpenOffice.org Impress Import Filter for KPresenter +Name[ar]=مِرْشَح استيراد OpenOffice.org Impress لدى KPresenter +Name[bg]=Филтър за импортиране от OpenOffice.org Impress в KPresenter +Name[br]=Sil enporzh OpenOffice.org Impress evit KPresenter +Name[ca]=Filtre d'importació OpenOffice.org Impress per a KPresenter +Name[cs]=OpenOffice.org Impress importní filtr pro KPresenter +Name[cy]=Hidlen Fewnforio OpenOffice.org Impress i KPresenter +Name[da]=OpenOffice.org Impress import-filter for KPresenter +Name[de]=KPresenter OpenOffice.org-Impress-Importfilter +Name[el]=Φίλτρο εισαγωγής OpenOffice.org Impress για το KPresenter +Name[es]=Filtro de importación de Impress para KPresenter +Name[et]=KPresenteri OpenOffice.org Impress'i impordifilter +Name[eu]=KPresenter-en OpenOffice.org Impress inportaziorako iragazkia +Name[fa]=پالایۀ صادرات OpenOffice.org Impress برای KPresenter +Name[fi]=OpenOffice.org Impress -tuontisuodin KPresenterille +Name[fr]=Filtre d'importation OpenOffice.org Impress pour KPresenter +Name[fy]=OpenOffice.org Impress-Ymportfilter foar KPresenter +Name[gl]=Filtro de Importación de OpenOffice.org Impress para KPresenter +Name[he]=מסנן ייבוא מ־OpenOffice.org Impress ל־KPresenter +Name[hi]=के-प्रेज़ेन्टर के लिए ओपन-ऑफ़िस.ऑर्ग इम्प्रेस आयात छननी +Name[hr]=OpenOffice.org Impress filtar uvoza za KPresenter +Name[hu]=OpenOffice Impress importszűrő a KPresenterhez +Name[is]=OpenOffice.org Impress innflutningssía fyrir KPresenter +Name[it]=Filtro di importazione OpenOffice.org Impress per KPresenter +Name[ja]=KPresenter OpenOffice.org Impress インポートフィルタ +Name[km]=តម្រង​នាំចូល OpenOffice.org Impress សម្រាប់ KPresenter +Name[lo]= ຕົວຕອງການນຳເຂົ້າ CSV ຂອງກະດາດຄຳນວນ K +Name[lt]=OpenOffice.org Impress importavimo filtras skirtas KPresenter +Name[lv]=OpenOffice.org Impress importa filtrs priekš KPresenter +Name[ms]=Penapis Import OpenOffice.org Impress bagi KPresenter +Name[nb]=OpenOffice.org Impress-importfilter for KPresenter +Name[nds]="OpenOffice.org Impress"-Importfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि OpenOffice.org इम्प्रेस निर्यात फिल्टर +Name[nl]=OpenOffice.org Impress-importfilter voor KPresenter +Name[nn]=OpenOffice.org Impress-importfilter for KPresenter +Name[pl]=Filtr importu z OpenOffice.org Impress dla KSpread +Name[pt]=Filtro de Importação de OpenOffice.org Impress para o KPresenter +Name[pt_BR]=Filtro de Importação OpenOffice.org Impress para o KPresenter +Name[ru]=Фильтр импорта презентаций OpenOffice.org Impress в KPresenter +Name[se]=KPresenter:a OpenOffice.org Impress-sisafievrridansilli +Name[sk]=Filter pre import OpenOffice.org Impress pre KPresenter +Name[sl]=Uvozni filter OpenOffice.org Impress za KPresenter +Name[sr]=KPresenter-ов филтер за увоз из OpenOffice Impress-а +Name[sr@Latn]=KPresenter-ov filter za uvoz iz OpenOffice Impress-a +Name[sv]=OpenOffice Impress-importfilter för Kpresenter +Name[ta]=openoffice.org impress இறக்குமதி வடிகட்டி for kpresenter +Name[tg]=Филтри Воридоти OpenOffice.org Impress барои KPresenter +Name[tr]=KPresenter için OpenOffice.org Impress Alma Filtresi +Name[uk]=Фільтр імпорту презентацій OpenOffice.org для KPresenter +Name[uz]=KPresenter uchun OpenOffice.org Impress import filteri +Name[uz@cyrillic]=KPresenter учун OpenOffice.org Impress импорт филтери +Name[xh]=OpenOffice.org Iphawula Isihluzi Sorhwebo se KPresenter +Name[zh_CN]=KPresenter 的 OpenOffice.org Impress 导入过滤器 +Name[zh_TW]=KPresenter 的 OpenOffice.org Impress 匯入過濾程式 +X-KDE-Export=application/x-kpresenter +X-KDE-Import=application/vnd.sun.xml.impress,application/vnd.sun.xml.impress.template +X-KDE-Weight=1 +X-KDE-Library=libooimpressimport +X-KDE-LibraryMajor=1 +X-KDE-LibraryMinor=0 +X-KDE-LibraryDependencies= +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/ooimpress/ooimpressexport.cc b/filters/kpresenter/ooimpress/ooimpressexport.cc new file mode 100644 index 000000000..27d0781da --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressexport.cc @@ -0,0 +1,1160 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "ooimpressexport.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +typedef KGenericFactory OoImpressExportFactory; +K_EXPORT_COMPONENT_FACTORY( libooimpressexport, OoImpressExportFactory( "kofficefilters" ) ) + + +OoImpressExport::OoImpressExport( KoFilter *, const char *, const QStringList & ) + : KoFilter() + , m_currentPage( 0 ) + , m_objectIndex( 0 ) + , m_pageHeight( 0 ) + , m_activePage( 0 ) + , m_gridX( -1.0 ) + , m_gridY( -1.0 ) + , m_snapToGrid( false ) + , m_pictureIndex( 0 ) + , m_storeinp( 0L ) + , m_storeout( 0L ) +{ +} + +OoImpressExport::~OoImpressExport() +{ + delete m_storeout; + delete m_storeinp; +} + +KoFilter::ConversionStatus OoImpressExport::convert( const QCString & from, + const QCString & to ) +{ + kdDebug(30518) << "Entering Ooimpress Export filter: " << from << " - " << to << endl; + + if ( ( to != "application/vnd.sun.xml.impress") || (from != "application/x-kpresenter" ) ) + { + kdWarning(30518) << "Invalid mimetypes " << to << " " << from << endl; + return KoFilter::NotImplemented; + } + + // read in the KPresenter file + KoFilter::ConversionStatus preStatus = openFile(); + + if ( preStatus != KoFilter::OK ) + return preStatus; + + QDomImplementation impl; + QDomDocument meta( impl.createDocumentType( "office:document-meta", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentMeta( meta ); + + // store document meta + m_storeout = KoStore::createStore( m_chain->outputFile(), KoStore::Write, "", KoStore::Zip ); + + if ( !m_storeout ) + { + kdWarning(30518) << "Couldn't open the requested file." << endl; + return KoFilter::FileNotFound; + } + + if ( !m_storeout->open( "meta.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'meta.xml'." << endl; + return KoFilter::CreationError; + } + + QCString metaString = meta.toCString(); + //kdDebug(30518) << "meta :" << metaString << endl; + m_storeout->write( metaString , metaString.length() ); + m_storeout->close(); + + QDomDocument content( impl.createDocumentType( "office:document-content", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentContent( content ); + + // add the automatic styles + m_styleFactory.addAutomaticStyles( content, m_styles ); + + // store document content + if ( !m_storeout->open( "content.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'content.xml'." << endl; + return KoFilter::CreationError; + } + + QCString contentString = content.toCString(); + //kdDebug(30518) << "content :" << contentString << endl; + m_storeout->write( contentString , contentString.length() ); + m_storeout->close(); + + QDomDocument settings( impl.createDocumentType( "office:document-content", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentSettings( settings ); + + // store document content + if ( !m_storeout->open( "settings.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'settings.xml'." << endl; + return KoFilter::CreationError; + } + + QCString settingsString = settings.toCString(); + //kdDebug(30518) << "content :" << settingsString << endl; + m_storeout->write( settingsString , settingsString.length() ); + m_storeout->close(); + + + QDomDocument styles( impl.createDocumentType( "office:document-styles", + "-//OpenOffice.org//DTD OfficeDocument 1.0//EN", + "office.dtd" ) ); + + createDocumentStyles( styles ); + + // store document styles + if ( !m_storeout->open( "styles.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'styles.xml'." << endl; + return KoFilter::CreationError; + } + + QCString stylesString = styles.toCString(); + //kdDebug(30518) << "styles :" << stylesString << endl; + m_storeout->write( stylesString , stylesString.length() ); + m_storeout->close(); + + QDomDocument manifest( impl.createDocumentType( "manifest:manifest", + "-//OpenOffice.org//DTD Manifest 1.0//EN", + "Manifest.dtd" ) ); + + createDocumentManifest( manifest ); + + // store document manifest + m_storeout->enterDirectory( "META-INF" ); + if ( !m_storeout->open( "manifest.xml" ) ) + { + kdWarning(30518) << "Couldn't open the file 'META-INF/manifest.xml'." << endl; + return KoFilter::CreationError; + } + + QCString manifestString = manifest.toCString(); + //kdDebug(30518) << "manifest :" << manifestString << endl; + m_storeout->write( manifestString , manifestString.length() ); + m_storeout->close(); + + return KoFilter::OK; +} + +KoFilter::ConversionStatus OoImpressExport::openFile() +{ + m_storeinp = KoStore::createStore( m_chain->inputFile(), KoStore::Read ); + + if ( !m_storeinp ) + { + kdWarning(30518) << "Couldn't open the requested file." << endl; + return KoFilter::FileNotFound; + } + + if ( !m_storeinp->open( "maindoc.xml" ) ) + { + kdWarning(30518) << "This file doesn't seem to be a valid KPresenter file" << endl; + return KoFilter::WrongFormat; + } + + m_maindoc.setContent( m_storeinp->device() ); + m_storeinp->close(); + + if ( m_storeinp->open( "documentinfo.xml" ) ) + { + m_documentinfo.setContent( m_storeinp->device() ); + m_storeinp->close(); + } + else + kdWarning(30518) << "Documentinfo do not exist!" << endl; + + emit sigProgress( 10 ); + + return KoFilter::OK; +} + +void OoImpressExport::createDocumentMeta( QDomDocument & docmeta ) +{ + docmeta.appendChild( docmeta.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = docmeta.createElement( "office:document-meta" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:dc", "http://purl.org/dc/elements/1.1/" ); + content.setAttribute( "xmlns:meta", "http://openoffice.org/2000/meta" ); + content.setAttribute( "office:version", "1.0" ); + + QDomNode meta = docmeta.createElement( "office:meta" ); + + QDomElement generator = docmeta.createElement( "meta:generator" ); + generator.appendChild( docmeta.createTextNode( "KPresenter 1.5" ) ); + meta.appendChild( generator ); + + QDomNode i = m_documentinfo.namedItem( "document-info" ); + if ( !i.isNull() ) + { + QDomNode n = i.namedItem( "author" ).namedItem( "full-name" ); + if ( !n.isNull() ) + { + QDomElement fullName = n.toElement(); + QDomElement creator = docmeta.createElement( "meta:initial-creator" ); + creator.appendChild( docmeta.createTextNode( fullName.text() ) ); + meta.appendChild( creator ); + + creator = docmeta.createElement( "meta:creator" ); + creator.appendChild( docmeta.createTextNode( fullName.text() ) ); + meta.appendChild( creator ); + } + n = i.namedItem( "about" ).namedItem( "abstract" ); + if ( !n.isNull() ) + { + QDomElement user = docmeta.createElement( "dc:description" ); + user.appendChild( n.firstChild() ); + meta.appendChild( user ); + } + n = i.namedItem( "about" ).namedItem( "keyword" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement key = docmeta.createElement( "meta:keywords" ); + QDomElement keyword = docmeta.createElement( "meta:keyword" ); + key.appendChild( keyword ); + keyword.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( key ); + } + n = i.namedItem( "about" ).namedItem( "subject" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement subjet = docmeta.createElement( "dc:subject" ); + subjet.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( subjet ); + } + n = i.namedItem( "about" ).namedItem( "title" ); + if ( !n.isNull() ) + { + QDomElement text = n.toElement(); + QDomElement title = docmeta.createElement( "dc:title" ); + title.appendChild( docmeta.createTextNode( text.text() ) ); + meta.appendChild( title ); + } + } + +// QDomElement statistic = docmeta.createElement( "meta:document-statistic" ); +// statistic.setAttribute( "meta:object-count", 0 ); +// meta.appendChild( data ); + + content.appendChild( meta ); + docmeta.appendChild( content ); +} + +void OoImpressExport::createDocumentStyles( QDomDocument & docstyles ) +{ + docstyles.appendChild( docstyles.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = docstyles.createElement( "office:document-content" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office" ); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "office:version", "1.0" ); + + // order important here! + QDomElement styles = docstyles.createElement( "office:styles" ); + m_styleFactory.addOfficeStyles( docstyles, styles ); + content.appendChild( styles ); + + QDomElement automatic = docstyles.createElement( "office:automatic-styles" ); + m_styleFactory.addOfficeAutomatic( docstyles, automatic ); + content.appendChild( automatic ); + + QDomElement master = docstyles.createElement( "office:master-styles" ); + m_styleFactory.addOfficeMaster( docstyles, master ); + content.appendChild( master ); + + docstyles.appendChild( content ); +} + +void OoImpressExport::createDocumentSettings( QDomDocument & docsetting ) +{ + docsetting.appendChild( docsetting.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement setting = docsetting.createElement( "office:document-settings" ); + setting.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + setting.setAttribute( "xmlns:config", "http://openoffice.org/2001/config" ); + setting.setAttribute( "office:class", "presentation" ); + setting.setAttribute( "office:version", "1.0" ); + + QDomElement begin = docsetting.createElement( "office:settings" ); + + QDomElement configItem = docsetting.createElement("config:config-item-set" ); + configItem.setAttribute( "config:name", "view-settings" ); + + QDomElement mapIndexed = docsetting.createElement( "config:config-item-map-indexed" ); + mapIndexed.setAttribute("config:name", "Views" ); + configItem.appendChild( mapIndexed ); + + // + + QDomElement mapItem = docsetting.createElement("config:config-item-map-entry" ); + + QDomElement attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "SnapLinesDrawing" ); + attribute.setAttribute( "config:type", "string" ); + attribute.appendChild( docsetting.createTextNode( m_helpLine ) ); + mapItem.appendChild( attribute ); + //H5983V700V10777H4518V27601P50000,9000P8021,2890 + + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "IsSnapToGrid" ); + attribute.setAttribute( "config:type", "boolean" ); + attribute.appendChild( docsetting.createTextNode( m_snapToGrid ? "true" : "false" ) ); + mapItem.appendChild( attribute ); + + if ( m_gridX >=0 ) + { + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "GridFineWidth" ); + attribute.setAttribute( "config:type", "int" ); + attribute.appendChild( docsetting.createTextNode( QString::number( ( int ) ( KoUnit::toMM( ( m_gridX ) )*100 ) ) ) ); + mapItem.appendChild( attribute ); + } + + if ( m_gridY >=0 ) + { + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "GridFineHeight" ); + attribute.setAttribute( "config:type", "int" ); + attribute.appendChild( docsetting.createTextNode( QString::number( ( int ) ( KoUnit::toMM( ( m_gridY ) )*100 ) ) ) ); + mapItem.appendChild( attribute ); + } + + attribute = docsetting.createElement("config:config-item" ); + attribute.setAttribute( "config:name", "SelectedPage" ); + attribute.setAttribute( "config:type", "short" ); + attribute.appendChild( docsetting.createTextNode( QString::number( m_activePage ) ) ); + mapItem.appendChild( attribute ); + + + mapIndexed.appendChild( mapItem ); + + begin.appendChild( configItem ); + + setting.appendChild( begin ); + + + docsetting.appendChild( setting ); + +} + +void OoImpressExport::createDocumentContent( QDomDocument & doccontent ) +{ + doccontent.appendChild( doccontent.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement content = doccontent.createElement( "office:document-content" ); + content.setAttribute( "xmlns:office", "http://openoffice.org/2000/office"); + content.setAttribute( "xmlns:style", "http://openoffice.org/2000/style" ); + content.setAttribute( "xmlns:text", "http://openoffice.org/2000/text" ); + content.setAttribute( "xmlns:table", "http://openoffice.org/2000/table" ); + content.setAttribute( "xmlns:draw", "http://openoffice.org/2000/drawing" ); + content.setAttribute( "xmlns:fo", "http://www.w3.org/1999/XSL/Format" ); + content.setAttribute( "xmlns:xlink", "http://www.w3.org/1999/xlink" ); + content.setAttribute( "xmlns:number", "http://openoffice.org/2000/datastyle" ); + content.setAttribute( "xmlns:svg", "http://www.w3.org/2000/svg" ); + content.setAttribute( "xmlns:chart", "http://openoffice.org/2000/chart" ); + content.setAttribute( "xmlns:dr3d", "http://openoffice.org/2000/dr3d" ); + content.setAttribute( "xmlns:math", "http://www.w3.org/1998/Math/MathML" ); + content.setAttribute( "xmlns:form", "http://openoffice.org/2000/form" ); + content.setAttribute( "xmlns:script", "http://openoffice.org/2000/script" ); + content.setAttribute( "xmlns:presentation", "http://openoffice.org/2000/presentation" ); + content.setAttribute( "office:class", "presentation" ); + content.setAttribute( "office:version", "1.0" ); + + QDomElement script = doccontent.createElement( "office:script" ); + content.appendChild( script ); + + m_styles = doccontent.createElement( "office:automatic-styles" ); + content.appendChild( m_styles ); + + QDomElement body = doccontent.createElement( "office:body" ); + exportBody( doccontent, body ); + content.appendChild( body ); + + doccontent.appendChild( content ); +} + +void OoImpressExport::createDocumentManifest( QDomDocument & docmanifest ) +{ + docmanifest.appendChild( docmanifest.createProcessingInstruction( "xml","version=\"1.0\" encoding=\"UTF-8\"" ) ); + + QDomElement manifest = docmanifest.createElement( "manifest:manifest" ); + manifest.setAttribute( "xmlns:manifest", "http://openoffice.org/2001/manifest" ); + + QDomElement entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "application/vnd.sun.xml.impress" ); + entry.setAttribute( "manifest:full-path", "/" ); + manifest.appendChild( entry ); + + QMap::Iterator it; + for ( it = m_pictureLst.begin(); it != m_pictureLst.end(); ++it ) + { + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", it.data() ); + entry.setAttribute( "manifest:full-path", it.key() ); + manifest.appendChild( entry ); + } + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "content.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "styles.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "meta.xml" ); + manifest.appendChild( entry ); + + entry = docmanifest.createElement( "manifest:file-entry" ); + entry.setAttribute( "manifest:media-type", "text/xml" ); + entry.setAttribute( "manifest:full-path", "settings.xml" ); + manifest.appendChild( entry ); + + docmanifest.appendChild( manifest ); +} + +QString OoImpressExport::pictureKey( QDomElement &elem ) +{ + // Default date/time is the *nix epoch: 1970-01-01 00:00:00,000 + int year=1970, month=1, day=1; + int hour=0, minute=0, second=0, msec=0; // We must initialize to zero, as not all compilers are C99-compliant + if ( elem.tagName() == "KEY" ) + { + if( elem.hasAttribute( "year" ) ) + year=elem.attribute( "year" ).toInt(); + if( elem.hasAttribute( "month" ) ) + month=elem.attribute( "month" ).toInt(); + if( elem.hasAttribute( "day" ) ) + day=elem.attribute( "day" ).toInt(); + if( elem.hasAttribute( "hour" ) ) + hour=elem.attribute( "hour" ).toInt(); + if( elem.hasAttribute( "minute" ) ) + minute=elem.attribute( "minute" ).toInt(); + if( elem.hasAttribute( "second" ) ) + second=elem.attribute( "second" ).toInt(); + if( elem.hasAttribute( "msec" ) ) + msec=elem.attribute( "msec" ).toInt(); + } + QDateTime key; + key.setDate( QDate( year, month, day ) ); + key.setTime( QTime( hour, minute, second, msec ) ); + return key.toString(); +} + +void OoImpressExport::createPictureList( QDomNode &pictures ) +{ + pictures = pictures.firstChild(); + for( ; !pictures.isNull(); pictures = pictures.nextSibling() ) + { + if ( pictures.isElement() ) + { + QDomElement element = pictures.toElement(); + if ( element.tagName() == "KEY" ) + { + //kdDebug(30518)<<"element.attribute( name ) :"<= m_pageHeight * m_currentPage ) + continue; // object not on current page + + switch( o.attribute( "type" ).toInt() ) + { + case 0: // image + appendPicture( doccontent, o, drawPage ); + break; + case 1: // line + appendLine( doccontent, o, drawPage ); + break; + case 2: // rectangle + appendRectangle( doccontent, o, drawPage ); + break; + case 3: // circle, ellipse + appendEllipse( doccontent, o, drawPage ); + break; + case 4: // textbox + appendTextbox( doccontent, o, drawPage ); + break; + case 5: + kdDebug(30518)<<" autoform not implemented\n"; + break; + case 6: + kdDebug(30518)<<" clipart not implemented\n"; + break; + case 8: // pie, chord, arc + appendEllipse( doccontent, o, drawPage, true ); + break; + case 9: //part + kdDebug(30518)<<" part object not implemented \n"; + break; + case 10: + appendGroupObject( doccontent, o, drawPage ); + break; + case 11: + kdDebug(30518)<<" free hand not implemented\n"; + break; + case 12: // polyline + appendPolyline( doccontent, o, drawPage ); + break; + case 13: //OT_QUADRICBEZIERCURVE = 13 + case 14: //OT_CUBICBEZIERCURVE = 14 + //todo + // "draw:path" + break; + case 15: // polygon + case 16: // close polygone + appendPolyline( doccontent, o, drawPage, true /*polygon*/ ); + break; + } + ++m_objectIndex; + } + +} + +void OoImpressExport::appendGroupObject( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement groupElement = doc.createElement( "draw:g" ); + QDomNode objects = source.namedItem( "OBJECTS" ); + appendObjects( doc, objects, groupElement); + target.appendChild( groupElement ); +} + +void OoImpressExport::appendNote( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QString noteText = source.attribute("note"); + //kdDebug(30518)<<"noteText :"< + + QStringList text = QStringList::split( "\n", noteText ); + for ( QStringList::Iterator it = text.begin(); it != text.end(); ++it ) { + QDomElement tmp = doc.createElement( "text:p" ); + tmp.appendChild( doc.createTextNode( *it ) ); + noteTextBox.appendChild( tmp ); + } + noteElement.appendChild( noteTextBox ); + target.appendChild( noteElement ); +} + +void OoImpressExport::appendTextbox( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement textbox = doc.createElement( "draw:text-box" ); + + QDomNode textobject = source.namedItem( "TEXTOBJ" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + textbox.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, textbox ); + + // parse every paragraph + for ( QDomNode paragraph = textobject.firstChild(); !paragraph.isNull(); + paragraph = paragraph.nextSibling() ) + { + QDomElement p = paragraph.toElement(); + appendParagraph( doc, p, textbox ); + } + + target.appendChild( textbox ); +} + +void OoImpressExport::appendParagraph( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement paragraph = doc.createElement( "text:p" ); + + // create the paragraph style + QString ps = m_styleFactory.createParagraphStyle( source ); + paragraph.setAttribute( "text:style-name", ps ); + + // parse every text element + for ( QDomNode text = source.firstChild(); !text.isNull(); + text = text.nextSibling() ) + { + if ( text.nodeName() == "TEXT" ) + { + QDomElement t = text.toElement(); + appendText( doc, t, paragraph ); + } + } + + // take care of lists + QDomNode counter = source.namedItem( "COUNTER" ); + if ( !counter.isNull() ) + { + QDomElement c = counter.toElement(); + int type = c.attribute( "type" ).toInt(); + + int level = 1; + if ( c.hasAttribute( "depth" ) ) + level = c.attribute( "depth" ).toInt() + 1; + + QDomElement endOfList = target; + for ( int l = 0; l < level; l++ ) + { + QDomElement list; + if ( type == 1 ) + { + list = doc.createElement( "text:ordered-list" ); + list.setAttribute( "text:continue-numbering", "true" ); + } + else + list = doc.createElement( "text:unordered-list" ); + + if ( l == 0 ) + { + // create the list style + QString ls = m_styleFactory.createListStyle( c ); + list.setAttribute( "text:style-name", ls ); + } + + QDomElement item = doc.createElement( "text:list-item" ); + list.appendChild( item ); + endOfList.appendChild( list ); + endOfList = item; + } + + endOfList.appendChild( paragraph ); + } + else + target.appendChild( paragraph ); +} + +void OoImpressExport::appendText( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement textspan = doc.createElement( "text:span" ); + + // create the text style + QString ts = m_styleFactory.createTextStyle( source ); + textspan.setAttribute( "text:style-name", ts ); + + textspan.appendChild( doc.createTextNode( source.text() ) ); + target.appendChild( textspan ); +} + +void OoImpressExport::appendPicture( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement image = doc.createElement( "draw:image" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + image.setAttribute( "draw:style-name", gs ); + QDomElement key = source.namedItem( "KEY" ).toElement(); + + QString pictureName = QString( "Picture/Picture%1" ).arg( m_pictureIndex ); + + image.setAttribute( "xlink:type", "simple" ); + image.setAttribute( "xlink:show", "embed" ); + image.setAttribute( "xlink:actuate", "onLoad"); + + if ( !key.isNull() ) + { + QString str = pictureKey( key ); + QString returnstr = m_kpresenterPictureLst[str]; + const int pos=returnstr.findRev('.'); + if (pos!=-1) + { + const QString extension( returnstr.mid(pos+1) ); + pictureName +="."+extension; + } + + if ( m_storeinp->open( returnstr ) ) + { + if ( m_storeout->open( pictureName ) ) + { + QByteArray data(8*1024); + uint total = 0; + for ( int block = 0; ( block = m_storeinp->read(data.data(), data.size()) ) > 0; + total += block ) + m_storeout->write(data.data(), data.size()); + m_storeout->close(); + m_storeinp->close(); + } + } + } + image.setAttribute( "xlink:href", "#" + pictureName ); + +// set the geometry + set2DGeometry( source, image ); + target.appendChild( image ); + + m_pictureLst.insert( pictureName , "image/png" ); + + ++m_pictureIndex; +} + + +void OoImpressExport::appendLine( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement line = doc.createElement( "draw:line" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + line.setAttribute( "draw:style-name", gs ); + + // set the geometry + setLineGeometry( source, line ); + + target.appendChild( line ); +} + +void OoImpressExport::appendRectangle( QDomDocument & doc, QDomElement & source, QDomElement & target ) +{ + QDomElement rectangle = doc.createElement( "draw:rect" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + rectangle.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, rectangle ); + + target.appendChild( rectangle ); +} + +void OoImpressExport::appendPolyline( QDomDocument & doc, QDomElement & source, QDomElement & target, bool _poly) +{ + QDomElement polyline = doc.createElement( _poly ? "draw:polygon" : "draw:polyline" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + polyline.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, polyline, false, true /*multipoint*/ ); + + target.appendChild( polyline ); +} + +void OoImpressExport::appendEllipse( QDomDocument & doc, QDomElement & source, QDomElement & target, bool pieObject ) +{ + QDomElement size = source.namedItem( "SIZE" ).toElement(); + + double width = size.attribute( "width" ).toDouble(); + double height = size.attribute( "height" ).toDouble(); + + QDomElement ellipse = doc.createElement( (width == height) ? "draw:circle" : "draw:ellipse" ); + + // create the graphic style + QString gs = m_styleFactory.createGraphicStyle( source ); + ellipse.setAttribute( "draw:style-name", gs ); + + // set the geometry + set2DGeometry( source, ellipse, pieObject ); + + target.appendChild( ellipse ); +} + +void OoImpressExport::set2DGeometry( QDomElement & source, QDomElement & target, bool pieObject, bool multiPoint ) +{ + QDomElement orig = source.namedItem( "ORIG" ).toElement(); + QDomElement size = source.namedItem( "SIZE" ).toElement(); + QDomElement name = source.namedItem( "OBJECTNAME").toElement(); + float y = orig.attribute( "y" ).toFloat(); + y -= m_pageHeight * ( m_currentPage - 1 ); + + QDomElement angle = source.namedItem( "ANGLE").toElement(); + if ( !angle.isNull() ) + { + QString returnAngle = rotateValue( angle.attribute( "value" ).toDouble() ); + if ( !returnAngle.isEmpty() ) + target.setAttribute("draw:transform",returnAngle ); + } + + target.setAttribute( "draw:id", QString::number( m_objectIndex ) ); + target.setAttribute( "svg:x", StyleFactory::toCM( orig.attribute( "x" ) ) ); + target.setAttribute( "svg:y", QString( "%1cm" ).arg( KoUnit::toCM( y ) ) ); + target.setAttribute( "svg:width", StyleFactory::toCM( size.attribute( "width" ) ) ); + target.setAttribute( "svg:height", StyleFactory::toCM( size.attribute( "height" ) ) ); + QString nameStr = name.attribute("objectName"); + if( !nameStr.isEmpty() ) + target.setAttribute( "draw:name", nameStr ); + if ( pieObject ) + { + QDomElement pie = source.namedItem( "PIETYPE").toElement(); + if( !pie.isNull() ) + { + int typePie = pie.attribute("value").toInt(); + switch( typePie ) + { + case 0: + target.setAttribute( "draw:kind", "section"); + break; + case 1: + target.setAttribute( "draw:kind", "arc"); + break; + case 2: + target.setAttribute( "draw:kind", "cut"); + break; + default: + kdDebug(30518)<<" type unknown : "< + +#include + +class QDomElement; +class KoStore; + +class OoImpressExport : public KoFilter +{ + Q_OBJECT +public: + OoImpressExport( KoFilter * parent, const char * name, const QStringList & ); + virtual ~OoImpressExport(); + + virtual KoFilter::ConversionStatus convert( const QCString & from, + const QCString & to ); + +private: + KoFilter::ConversionStatus openFile(); + + void exportBody( QDomDocument & doccontent, QDomElement & body ); + void createDocumentMeta( QDomDocument & docmeta ); + void createDocumentStyles( QDomDocument & docstyles ); + void createDocumentContent( QDomDocument & doccontent ); + void createDocumentManifest( QDomDocument & docmanifest ); + void createDocumentSettings( QDomDocument & docsetting ); + void appendTextbox( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendParagraph( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendText( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendLine( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendRectangle( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendEllipse( QDomDocument & doc, QDomElement & source, QDomElement & target, bool pieObject = false ); + void set2DGeometry( QDomElement & source, QDomElement & target, bool pieObject = false, bool multiPoint = false ); + void setLineGeometry( QDomElement & source, QDomElement & target ); + void appendPolyline( QDomDocument & doc, QDomElement & source, QDomElement & target, bool polygone = false); + void appendPicture( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void createPictureList( QDomNode &pictures ); + void appendNote( QDomDocument & doc, QDomElement & source, QDomElement & target ); + void appendGroupObject( QDomDocument & doc, QDomElement & source, QDomElement & target ); + QString rotateValue( double val ); + QString pictureKey( QDomElement &element ); + void createHelpLine( QDomNode &helpline ); + void createAttribute( QDomNode &attributeValue ); + void appendObjects(QDomDocument & doccontent, QDomNode &objects, QDomElement &drawPage); + + int m_currentPage; + int m_objectIndex; + float m_pageHeight; + StyleFactory m_styleFactory; + QString m_masterPageStyle; + QDomElement m_styles; + QDomDocument m_maindoc; + QDomDocument m_documentinfo; + QMap m_pictureLst; + + QString m_helpLine; + int m_activePage; + double m_gridX, m_gridY; + bool m_snapToGrid; + + //load from kpresenter file format + QMap m_kpresenterPictureLst; + int m_pictureIndex; + KoStore *m_storeinp; + KoStore *m_storeout; +}; + +#endif diff --git a/filters/kpresenter/ooimpress/ooimpressimport.cc b/filters/kpresenter/ooimpress/ooimpressimport.cc new file mode 100644 index 000000000..be6c094d5 --- /dev/null +++ b/filters/kpresenter/ooimpress/ooimpressimport.cc @@ -0,0 +1,2433 @@ +// -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*- +/* This file is part of the KDE project + Copyright (C) 2002 Laurent Montel + Copyright (c) 2003 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "ooimpressimport.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory OoImpressImportFactory; +K_EXPORT_COMPONENT_FACTORY( libooimpressimport, OoImpressImportFactory( "kofficefilters" ) ) + + +OoImpressImport::OoImpressImport( KoFilter *, const char *, const QStringList & ) + : KoFilter(), + m_numPicture( 1 ), + m_numSound(1), + m_styles( 23, true ), + m_styleStack( ooNS::style, ooNS::fo ) +{ + m_styles.setAutoDelete( true ); + m_listStyles.setAutoDelete( true ); +} + +OoImpressImport::~OoImpressImport() +{ + QDictIterator it( m_animations ); // See QDictIterator + for( ; it.current(); ++it ) + { + delete it.current()->element; + } + m_animations.clear(); +} + +KoFilter::ConversionStatus OoImpressImport::convert( QCString const & from, QCString const & to ) +{ + kdDebug(30518) << "Entering Ooimpress Import filter: " << from << " - " << to << endl; + + if ( (from != "application/vnd.sun.xml.impress" && from != "application/vnd.sun.xml.impress.template" ) + || to != "application/x-kpresenter" ) + { + kdWarning(30518) << "Invalid mimetypes " << from << " " << to << endl; + return KoFilter::NotImplemented; + } + + m_zip = new KZip( m_chain->inputFile() ); + + if ( !m_zip->open( IO_ReadOnly ) ) + { + kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl; + delete m_zip; + return KoFilter::FileNotFound; + } + + KoFilter::ConversionStatus preStatus = openFile(); + + if ( preStatus != KoFilter::OK ) + { + m_zip->close(); + delete m_zip; + return preStatus; + } + + QDomDocument docinfo; + createDocumentInfo( docinfo ); + + // store document info + KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write ); + if( out ) + { + QCString info = docinfo.toCString(); + //kdDebug(30518) << " info :" << info << endl; + // WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end. + out->writeBlock( info , info.length() ); + } + + QDomDocument doccontent; + createDocumentContent( doccontent ); + + // store document content + out = m_chain->storageFile( "maindoc.xml", KoStore::Write ); + if( out ) + { + QCString content = doccontent.toCString(); + kdDebug(30518) << " content :" << content << endl; + out->writeBlock( content , content.length() ); + } + + m_zip->close(); + delete m_zip; + + kdDebug(30518) << "######################## OoImpressImport::convert done ####################" << endl; + return KoFilter::OK; +} + +// Very related to OoWriterImport::openFile() +KoFilter::ConversionStatus OoImpressImport::openFile() +{ + KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content ); + if ( status != KoFilter::OK ) + { + kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl; + return status; + } + + // We do not stop if the following calls fail. + QDomDocument styles; + loadAndParse( "styles.xml", styles ); + loadAndParse( "meta.xml", m_meta ); + loadAndParse( "settings.xml", m_settings ); + + emit sigProgress( 10 ); + createStyleMap( styles ); + + return KoFilter::OK; +} + +KoFilter::ConversionStatus OoImpressImport::loadAndParse(const QString& filename, QDomDocument& doc) +{ + return OoUtils::loadAndParse( filename, doc, m_zip); +} + +// Very related to OoWriterImport::createDocumentInfo +void OoImpressImport::createDocumentInfo( QDomDocument &docinfo ) +{ + docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" ); + + OoUtils::createDocumentInfo(m_meta, docinfo); + //kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl; +} + +void OoImpressImport::createDocumentContent( QDomDocument &doccontent ) +{ + QDomDocument doc = KoDocument::createDomDocument( "kpresenter", "DOC", "1.2" ); + QDomElement docElement = doc.documentElement(); + docElement.setAttribute( "editor", "KPresenter" ); + docElement.setAttribute( "mime", "application/x-kpresenter" ); + docElement.setAttribute( "syntaxVersion", "2" ); + + QDomElement content = m_content.documentElement(); + + // content.xml contains some automatic-styles that we need to store + QDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" ); + if ( !automaticStyles.isNull() ) + insertStyles( automaticStyles.toElement() ); + + QDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" ); + if ( body.isNull() ) + return; + + QDomElement customSlideShow = doc.createElement( "CUSTOMSLIDESHOWCONFIG" ); + + // presentation settings + QDomElement settings = KoDom::namedItemNS( body, ooNS::presentation, "settings"); + if (!settings.isNull()) + { + if (settings.attributeNS( ooNS::presentation, "endless", QString::null)=="true") + { + QDomElement infElem = doc.createElement("INFINITLOOP"); + infElem.setAttribute("value", 1); + docElement.appendChild(infElem); + } + + if (settings.attributeNS( ooNS::presentation, "show-end-of-presentation-slide", QString::null)=="true") + { + QDomElement infElem = doc.createElement("SHOWENDOFPRESENTATIONSLIDE"); + infElem.setAttribute("value", 1); + docElement.appendChild(infElem); + } + + if (settings.attributeNS( ooNS::presentation, "force-manual", QString::null)=="true") + { + QDomElement manualElem = doc.createElement("MANUALSWITCH"); + manualElem.setAttribute("value", 1); + docElement.appendChild(manualElem); + } + if ( settings.hasAttributeNS( ooNS::presentation, "show") ) + { + QDomElement defaultPage = doc.createElement("DEFAULTCUSTOMSLIDESHOWNAME"); + defaultPage.setAttribute("name", settings.attributeNS( ooNS::presentation, "show", QString::null) ); + docElement.appendChild(defaultPage); + } + } + + QDomElement presentationShow; + forEachElement( presentationShow, settings ) + { + if ( presentationShow.localName()=="show" && presentationShow.namespaceURI() == ooNS::presentation ) + { + if ( presentationShow.hasAttributeNS( ooNS::presentation, "pages") && + presentationShow.hasAttributeNS( ooNS::presentation, "name")) + { + QDomElement slide=doc.createElement("CUSTOMSLIDESHOW"); + slide.setAttribute( "pages", presentationShow.attributeNS( ooNS::presentation, "pages", QString::null )); + slide.setAttribute( "name", presentationShow.attributeNS( ooNS::presentation, "name", QString::null )); + customSlideShow.appendChild( slide ); + } + } + } + // it seems that ooimpress has different paper-settings for every slide. + // we take the settings of the first slide for the whole document. + QDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" ); + if ( drawPage.isNull() ) // no slides? give up. + return; + + QDomElement objectElement = doc.createElement( "OBJECTS" ); + QDomElement pictureElement = doc.createElement( "PICTURES" ); + QDomElement pageTitleElement = doc.createElement( "PAGETITLES" ); + QDomElement pageNoteElement = doc.createElement( "PAGENOTES" ); + QDomElement backgroundElement = doc.createElement( "BACKGROUND" ); + QDomElement soundElement = doc.createElement( "SOUNDS" ); + QDomElement selSlideElement = doc.createElement( "SELSLIDES" ); + QDomElement helpLineElement = doc.createElement( "HELPLINES" ); + QDomElement attributeElement = doc.createElement( "ATTRIBUTES" ); + QDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", QString::null )]; + + appendObject(*master, doc, soundElement,pictureElement,pageNoteElement,objectElement, 0, true); + + QDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", QString::null )]; + QDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" ); + //kdDebug(30518)<<" master->attribute( draw:style-name ) :"<attributeNS( ooNS::draw, "style-name", QString::null )<attributeNS( ooNS::draw, "style-name", QString::null ).isEmpty() ? "Standard-background" : master->attributeNS( ooNS::draw, "style-name", QString::null ) ]; + + //kdDebug(30518)<<" backgroundStyle :"<V7939H1139 + //by default show line + + if ( !firstView.isNull() ) + { + QString str = firstView.parseConfigItemString( "SnapLinesDrawing" ); + if ( !str.isEmpty() ) + { + parseHelpLine( doc, helpLineElement, str ); + //display it by default + helpLineElement.setAttribute( "show", true ); + foundElement = true; + } + + int gridX = firstView.parseConfigItemInt( "GridFineWidth" ); + int gridY = firstView.parseConfigItemInt( "GridFineHeight" ); + bool snapToGrid = firstView.parseConfigItemBool( "IsSnapToGrid" ); + int selectedPage = firstView.parseConfigItemInt( "SelectedPage" ); + + attributeElement.setAttribute( "activePage", selectedPage ); + attributeElement.setAttribute( "gridx", MM_TO_POINT( gridX / 100.0 ) ); + attributeElement.setAttribute( "gridy", MM_TO_POINT( gridY / 100.0 ) ); + attributeElement.setAttribute( "snaptogrid", (int)snapToGrid ); + + } + + //kdDebug(30518)<<" gridX :"<=0;--pos ) + { + if ( text[pos]=='P' ) + { + + //point + str = text.mid( pos+1, ( newPos-pos ) ); + QDomElement point=doc.createElement("HelpPoint"); + + //kdDebug(30518)<<" point element :"<< str < x2 && y1 > y2 ) ) + linetype.setAttribute( "value", 2 ); + else + linetype.setAttribute( "value", 3 ); + + e.appendChild( linetype ); + return (x1 < x2); +} + +void OoImpressImport::appendPen( QDomDocument& doc, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" )) + { + QDomElement pen = doc.createElement( "PEN" ); + if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" ) + pen.setAttribute( "style", 0 ); + else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" ) + pen.setAttribute( "style", 1 ); + else if ( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" ) + { + QString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" ); + if ( style == "Ultrafine Dashed" || style == "Fine Dashed" || + style == "Fine Dashed (var)" || style == "Dashed (var)" ) + pen.setAttribute( "style", 2 ); + else if ( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" || + style == "Line with Fine Dots" ) + pen.setAttribute( "style", 3 ); + else if ( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" ) + pen.setAttribute( "style", 4 ); + else if ( style == "2 Dots 1 Dash" ) + pen.setAttribute( "style", 5 ); + } + + if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) ) + pen.setAttribute( "width", (int) KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) ) ); + if ( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) ) + pen.setAttribute( "color", m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) ); + e.appendChild( pen ); + } +} + +void OoImpressImport::appendBrush( QDomDocument& doc, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) ) + { + const QString fill = m_styleStack.attributeNS( ooNS::draw, "fill" ); + //kdDebug(30518)<<"void OoImpressImport::appendBrush( QDomDocument& doc, QDomElement& e ) :"<= 94 && value <= 99 ) + { + brush.setAttribute( "style", 2 ); + } + else if ( value>=64 && value <= 93 ) + { + brush.setAttribute( "style", 3 ); + } + else if ( value>=51 && value <= 63 ) + { + brush.setAttribute( "style", 4 ); + } + else if ( value>=38 && value <= 50 ) + { + brush.setAttribute( "style", 5 ); + } + else if ( value>=13 && value <= 37 ) + { + brush.setAttribute( "style", 6 ); + } + else if ( value>=7 && value <= 12 ) + { + brush.setAttribute( "style", 7 ); + } + else if ( value>=1 && value <= 6 ) + { + brush.setAttribute( "style", 8 ); + } + } + else + brush.setAttribute( "style", 1 ); + if ( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) ) + brush.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "fill-color" ) ); + e.appendChild( brush ); + } + else if ( fill == "hatch" ) + { + QDomElement brush = doc.createElement( "BRUSH" ); + QString style = m_styleStack.attributeNS( ooNS::draw, "fill-hatch-name" ); + QDomElement* draw = m_draws[style]; + if ( draw ) + { + if( draw->hasAttributeNS( ooNS::draw, "color" ) ) + brush.setAttribute( "color", draw->attributeNS( ooNS::draw, "color", QString::null ) ); + int angle = 0; + if( draw->hasAttributeNS( ooNS::draw, "rotation" )) + { + angle = (draw->attributeNS( ooNS::draw, "rotation", QString::null ).toInt())/10; + kdDebug(30518)<<"angle :"<hasAttributeNS( ooNS::draw, "style" )) + { + QString styleHash = draw->attributeNS( ooNS::draw, "style", QString::null ); + if( styleHash == "single") + { + switch( angle ) + { + case 0: + case 180: + brush.setAttribute( "style", 9 ); + break; + case 45: + case 225: + brush.setAttribute( "style", 12 ); + break; + case 90: + case 270: + brush.setAttribute( "style", 10 ); + break; + case 135: + case 315: + brush.setAttribute( "style", 13 ); + break; + default: + //todo fixme when we will have a kopaint + kdDebug(30518)<<" draw:rotation 'angle' : "<attributeNS( ooNS::draw, "start-color", QString::null ) ); + gradient.setAttribute( "color2", draw->attributeNS( ooNS::draw, "end-color", QString::null ) ); + + QString type = draw->attributeNS( ooNS::draw, "style", QString::null ); + //kdDebug(30518)<<" type !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :"<attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if ( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + kdDebug(30518)<<"nearAngle :"<hasAttributeNS( ooNS::draw, "cx" ) ) + x = draw->attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt(); + else + x = 50; + + if ( draw->hasAttributeNS( ooNS::draw, "cy" ) ) + y = draw->attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt(); + else + y = 50; + + if ( x == 50 && y == 50 ) + { + gradient.setAttribute( "unbalanced", 0 ); + gradient.setAttribute( "xfactor", 100 ); + gradient.setAttribute( "yfactor", 100 ); + } + else + { + gradient.setAttribute( "unbalanced", 1 ); + // map 0 - 100% to -200 - 200 + gradient.setAttribute( "xfactor", 4 * x - 200 ); + gradient.setAttribute( "yfactor", 4 * y - 200 ); + } + } + e.appendChild( gradient ); + + QDomElement fillType = doc.createElement( "FILLTYPE" ); + fillType.setAttribute( "value", 1 ); + e.appendChild( fillType ); + } + } +} + +void OoImpressImport::appendPie( QDomDocument& doc, QDomElement& e, const QDomElement& object ) +{ + QDomElement angle = doc.createElement( "PIEANGLE" ); + int start = (int) ( object.attributeNS( ooNS::draw, "start-angle", QString::null ).toDouble() ); + angle.setAttribute( "value", start * 16 ); + e.appendChild( angle ); + + QDomElement length = doc.createElement( "PIELENGTH" ); + int end = (int) ( object.attributeNS( ooNS::draw, "end-angle", QString::null ).toDouble() ); + if ( end < start ) + length.setAttribute( "value", ( 360 - start + end ) * 16 ); + else + length.setAttribute( "value", ( end - start ) * 16 ); + e.appendChild( length ); +} + +void OoImpressImport::appendImage( QDomDocument& doc, QDomElement& e, QDomElement& p, + const QDomElement& object ) +{ + QString fileName = storeImage( object ); + + // create a key for the picture + QTime time = QTime::currentTime(); + QDate date = QDate::currentDate(); + + QDomElement image = doc.createElement( "KEY" ); + image.setAttribute( "msec", time.msec() ); + image.setAttribute( "second", time.second() ); + image.setAttribute( "minute", time.minute() ); + image.setAttribute( "hour", time.hour() ); + image.setAttribute( "day", date.day() ); + image.setAttribute( "month", date.month() ); + image.setAttribute( "year", date.year() ); + image.setAttribute( "filename", fileName ); + e.appendChild( image ); + + QDomElement settings = doc.createElement( "PICTURESETTINGS" ); + if ( m_styleStack.hasAttributeNS( ooNS::draw, "color-mode" ) && ( m_styleStack.attributeNS( ooNS::draw, "color-mode" )=="greyscale" ) ) + settings.setAttribute( "grayscal", 1 ); + else + settings.setAttribute( "grayscal", 0 ); + + if ( m_styleStack.hasAttributeNS( ooNS::draw, "luminance" ) ) + { + QString str( m_styleStack.attributeNS( ooNS::draw, "luminance" ) ); + str = str.remove( '%' ); + settings.setAttribute( "bright", str ); + } + else + settings.setAttribute( "bright", 0 ); + + settings.setAttribute( "mirrorType", 0 ); + settings.setAttribute( "swapRGB", 0 ); + settings.setAttribute( "depth", 0 ); + e.appendChild( settings ); + + QDomElement effects = doc.createElement( "EFFECTS" ); + bool hasEffect = false; + if ( m_styleStack.hasAttributeNS( ooNS::draw, "contrast" ) ) + { + QString str( m_styleStack.attributeNS( ooNS::draw, "contrast" ) ); + str = str.remove( '%' ); + int val = str.toInt(); + val = ( int )( 255.0 *val/100.0 ); + effects.setAttribute( "type", "5" ); + effects.setAttribute( "param1", QString::number( val ) ); + hasEffect = true; + } + if ( hasEffect ) + e.appendChild( effects ); + + QDomElement key = image.cloneNode().toElement(); + key.setAttribute( "name", "pictures/" + fileName ); + p.appendChild( key ); +} + +void OoImpressImport::appendBackgroundImage( QDomDocument& doc, QDomElement& e, + QDomElement& p, const QDomElement& object ) +{ + QString fileName = storeImage( object ); + + // create a key for the picture + QTime time = QTime::currentTime(); + QDate date = QDate::currentDate(); + + QDomElement image = doc.createElement( "BACKPICTUREKEY" ); + image.setAttribute( "msec", time.msec() ); + image.setAttribute( "second", time.second() ); + image.setAttribute( "minute", time.minute() ); + image.setAttribute( "hour", time.hour() ); + image.setAttribute( "day", date.day() ); + image.setAttribute( "month", date.month() ); + image.setAttribute( "year", date.year() ); + image.setAttribute( "filename", fileName ); + e.appendChild( image ); + + QDomElement key = image.cloneNode().toElement(); + key.setTagName( "KEY" ); + key.setAttribute( "name", "pictures/" + fileName ); + p.appendChild( key ); +} + +void OoImpressImport::appendBackgroundGradient( QDomDocument& doc, QDomElement& e, + const QDomElement& object ) +{ + QDomElement backColor1 = doc.createElement( "BACKCOLOR1" ); + backColor1.setAttribute( "color", object.attributeNS( ooNS::draw, "start-color", QString::null ) ); + e.appendChild( backColor1 ); + + QDomElement backColor2 = doc.createElement( "BACKCOLOR2" ); + backColor2.setAttribute( "color", object.attributeNS( ooNS::draw, "end-color", QString::null ) ); + e.appendChild( backColor2 ); + + QDomElement backType = doc.createElement( "BACKTYPE" ); + backType.setAttribute( "value", 0 ); // color/gradient + e.appendChild( backType ); + + QDomElement bcType = doc.createElement( "BCTYPE" ); + QString type = object.attributeNS( ooNS::draw, "style", QString::null ); + if ( type == "linear" ) + { + int angle = object.attributeNS( ooNS::draw, "angle", QString::null ).toInt() / 10; + + // make sure the angle is between 0 and 359 + angle = abs( angle ); + angle -= ( (int) ( angle / 360 ) ) * 360; + + // What we are trying to do here is to find out if the given + // angle belongs to a horizontal, vertical or diagonal gradient. + int lower, upper, nearAngle = 0; + for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 ) + { + if ( upper >= angle ) + { + int distanceToUpper = abs( angle - upper ); + int distanceToLower = abs( angle - lower ); + nearAngle = distanceToUpper > distanceToLower ? lower : upper; + break; + } + } + + // nearAngle should now be one of: 0, 45, 90, 135, 180... + if ( nearAngle == 0 || nearAngle == 180 ) + bcType.setAttribute( "value", 1 ); // horizontal + else if ( nearAngle == 90 || nearAngle == 270 ) + bcType.setAttribute( "value", 2 ); // vertical + else if ( nearAngle == 45 || nearAngle == 225 ) + bcType.setAttribute( "value", 3 ); // diagonal 1 + else if ( nearAngle == 135 || nearAngle == 315 ) + bcType.setAttribute( "value", 4 ); // diagonal 2 + } + else if ( type == "radial" || type == "ellipsoid" ) + bcType.setAttribute( "value", 5 ); // circle + else if ( type == "square" || type == "rectangular" ) + bcType.setAttribute( "value", 6 ); // rectangle + else if ( type == "axial" ) + bcType.setAttribute( "value", 7 ); // pipecross + + e.appendChild( bcType ); + + QDomElement bGradient = doc.createElement( "BGRADIENT" ); + + // Hard to map between x- and y-center settings of ooimpress + // and (un-)balanced settings of kpresenter. Let's try it. + int x, y; + if ( object.hasAttributeNS( ooNS::draw, "cx" ) ) + x = object.attributeNS( ooNS::draw, "cx", QString::null ).remove( '%' ).toInt(); + else + x = 50; + + if ( object.hasAttributeNS( ooNS::draw, "cy" ) ) + y = object.attributeNS( ooNS::draw, "cy", QString::null ).remove( '%' ).toInt(); + else + y = 50; + + if ( x == 50 && y == 50 ) + { + bGradient.setAttribute( "unbalanced", 0 ); + bGradient.setAttribute( "xfactor", 100 ); + bGradient.setAttribute( "yfactor", 100 ); + } + else + { + bGradient.setAttribute( "unbalanced", 1 ); + // map 0 - 100% to -200 - 200 + bGradient.setAttribute( "xfactor", 4 * x - 200 ); + bGradient.setAttribute( "yfactor", 4 * y - 200 ); + } + + e.appendChild( bGradient ); +} + +void OoImpressImport::appendRounding( QDomDocument& doc, QDomElement& e, const QDomElement& object ) +{ + if ( object.hasAttributeNS( ooNS::draw, "corner-radius" ) ) + { + // kpresenter uses percent, ooimpress uses cm ... hmm? + QDomElement rounding = doc.createElement( "RNDS" ); + int corner = static_cast(KoUnit::parseValue(object.attributeNS( ooNS::draw, "corner-radius", QString::null))); + rounding.setAttribute( "x", corner ); + rounding.setAttribute( "y", corner ); + e.appendChild( rounding ); + } +} + +void OoImpressImport::appendShadow( QDomDocument& doc, QDomElement& e ) +{ + // Note that ooimpress makes a difference between shadowed text and + // a shadowed object while kpresenter only knows the attribute 'shadow'. + // This means that a shadowed textobject in kpresenter will always show + // a shadowed text but no shadow for the object itself. + + // make sure this is a textobject or textspan + if ( !e.hasAttribute( "type" ) || + ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "4" ) ) + { + if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-shadow" ) && + m_styleStack.attributeNS( ooNS::fo, "text-shadow" ) != "none" ) + { + // use the shadow attribute to indicate a text-shadow + QDomElement shadow = doc.createElement( "SHADOW" ); + QString distance = m_styleStack.attributeNS( ooNS::fo, "text-shadow" ); + distance.truncate( distance.find( ' ' ) ); + shadow.setAttribute( "distance", KoUnit::parseValue( distance ) ); + shadow.setAttribute( "direction", 5 ); + shadow.setAttribute( "color", "#a0a0a0" ); + e.appendChild( shadow ); + } + } + else if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow" ) && + m_styleStack.attributeNS( ooNS::draw, "shadow" ) == "visible" ) + { + // use the shadow attribute to indicate an object-shadow + QDomElement shadow = doc.createElement( "SHADOW" ); + double x = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-x" ) ); + double y = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::draw, "shadow-offset-y" ) ); + + if ( x < 0 && y < 0 ) + { + shadow.setAttribute( "direction", 1 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x == 0 && y < 0 ) + { + shadow.setAttribute( "direction", 2 ); + shadow.setAttribute( "distance", (int) fabs ( y ) ); + } + else if ( x > 0 && y < 0 ) + { + shadow.setAttribute( "direction", 3 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x > 0 && y == 0 ) + { + shadow.setAttribute( "direction", 4 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x > 0 && y > 0 ) + { + shadow.setAttribute( "direction", 5 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x == 0 && y > 0 ) + { + shadow.setAttribute( "direction", 6 ); + shadow.setAttribute( "distance", (int) fabs ( y ) ); + } + else if ( x < 0 && y > 0 ) + { + shadow.setAttribute( "direction", 7 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + else if ( x < 0 && y == 0 ) + { + shadow.setAttribute( "direction", 8 ); + shadow.setAttribute( "distance", (int) fabs ( x ) ); + } + + if ( m_styleStack.hasAttributeNS( ooNS::draw, "shadow-color" ) ) + shadow.setAttribute( "color", m_styleStack.attributeNS( ooNS::draw, "shadow-color" ) ); + + e.appendChild( shadow ); + } + if ( m_styleStack.hasAttributeNS( ooNS::draw, "size-protect" ) || m_styleStack.hasAttributeNS( ooNS::draw, "move-protect" ) ) + { + bool b = ( m_styleStack.attributeNS( ooNS::draw, "size-protect" ) == "true" ) || ( m_styleStack.attributeNS( ooNS::draw, "move-protect" ) == "true" ); + if ( b ) + { + QDomElement protect = doc.createElement( "PROTECT" ); + protect.setAttribute("state" , b); + e.appendChild(protect); + } + } +} + +void OoImpressImport::appendLineEnds( QDomDocument& doc, QDomElement& e, bool orderEndStartLine) +{ + const char* attr = orderEndStartLine ? "marker-start" : "marker-end"; + if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) ) + { + QDomElement lineBegin = doc.createElement( "LINEBEGIN" ); + QString type = m_styleStack.attributeNS( ooNS::draw, attr ); + if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" || + type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" ) + lineBegin.setAttribute( "value", 1 ); + else if ( type == "Square" ) + lineBegin.setAttribute( "value", 2 ); + else if ( type == "Circle" || type == "Square 45" ) + lineBegin.setAttribute( "value", 3 ); + else if ( type == "Line Arrow" ) + lineBegin.setAttribute( "value", 4 ); + else if ( type == "Dimension Lines" ) + lineBegin.setAttribute( "value", 5 ); + else if ( type == "Double Arrow" ) + lineBegin.setAttribute( "value", 6 ); + e.appendChild( lineBegin ); + } + attr = orderEndStartLine ? "marker-end" : "marker-start"; + if ( m_styleStack.hasAttributeNS( ooNS::draw, attr ) ) + { + QDomElement lineEnd = doc.createElement( "LINEEND" ); + QString type = m_styleStack.attributeNS( ooNS::draw, attr ); + if ( type == "Arrow" || type == "Small Arrow" || type == "Rounded short Arrow" || + type == "Symmetric Arrow" || type == "Rounded large Arrow" || type == "Arrow concave" ) + lineEnd.setAttribute( "value", 1 ); + else if ( type == "Square" ) + lineEnd.setAttribute( "value", 2 ); + else if ( type == "Circle" || type == "Square 45" ) + lineEnd.setAttribute( "value", 3 ); + else if ( type == "Line Arrow" ) + lineEnd.setAttribute( "value", 4 ); + else if ( type == "Dimension Lines" ) + lineEnd.setAttribute( "value", 5 ); + else if ( type == "Double Arrow" ) + lineEnd.setAttribute( "value", 6 ); + e.appendChild( lineEnd ); + } +} + +void OoImpressImport::appendTextObjectMargin( QDomDocument& /*doc*/, QDomElement& e ) +{ + if ( m_styleStack.hasAttributeNS( ooNS::fo, "padding" ) ) + { + double tmpValue = KoUnit::parseValue(m_styleStack.attributeNS( ooNS::fo, "padding" ) ); + e.setAttribute( "btoppt", tmpValue ); + e.setAttribute( "bbottompt", tmpValue ); + e.setAttribute( "bleftpt", tmpValue ); + e.setAttribute( "brightpt", tmpValue ); + } + else + { + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-top" ) ) + e.setAttribute( "btoppt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-top" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-bottom" ) ) + e.setAttribute( "bbottompt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-bottom" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-left" ) ) + e.setAttribute( "bleftpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-left" ) ) ); + if( m_styleStack.hasAttributeNS( ooNS::fo, "padding-right" ) ) + e.setAttribute( "brightpt", KoUnit::parseValue( m_styleStack.attributeNS( ooNS::fo, "padding-right" ) ) ); + } +} + +QDomElement OoImpressImport::parseTextBox( QDomDocument& doc, const QDomElement& textBox ) +{ + QDomElement textObjectElement = doc.createElement( "TEXTOBJ" ); + appendTextObjectMargin( doc, textObjectElement ); + + // vertical alignment + if ( m_styleStack.hasAttributeNS( ooNS::draw, "textarea-vertical-align" ) ) + { + QString alignment = m_styleStack.attributeNS( ooNS::draw, "textarea-vertical-align" ); + if ( alignment == "top" ) + textObjectElement.setAttribute( "verticalAlign", "top" ); + else if ( alignment == "middle" ) + textObjectElement.setAttribute( "verticalAlign", "center" ); + else if ( alignment == "bottom" ) + textObjectElement.setAttribute( "verticalAlign", "bottom" ); + + textObjectElement.setAttribute("verticalValue", 0.0); + } + + parseParagraphs( doc, textObjectElement, textBox ); + + return textObjectElement; +} + +void OoImpressImport::parseParagraphs( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& parent ) +{ + QDomElement t; + forEachElement( t, parent ) + { + m_styleStack.save(); + const QString localName = t.localName(); + const QString ns = t.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + + QDomElement e; + if ( isTextNS && localName == "p" ) // text paragraph + e = parseParagraph( doc, t ); + else if ( isTextNS && localName == "h" ) // heading - can this happen in ooimpress? + { + e = parseParagraph( doc, t ); + } + else if ( isTextNS && ( localName == "unordered-list" || localName == "ordered-list" ) ) + { + parseList( doc, textObjectElement, t ); + m_styleStack.restore(); + continue; + } + // TODO text:sequence-decls + else + { + kdDebug(30518) << "Unsupported texttype '" << localName << "'" << endl; + } + + if ( !e.isNull() ) + textObjectElement.appendChild( e ); + m_styleStack.restore(); // remove the styles added by the paragraph or list + } +} + +void OoImpressImport::applyListStyle( QDomElement& paragraph ) +{ + // Spec: see 3.3.5 p137 + if ( m_listStyleStack.hasListStyle() && m_nextItemIsListItem ) { + //const QDomElement listStyle = m_listStyleStack.currentListStyle(); + //bool heading = paragraph.localName() == "h"; + m_nextItemIsListItem = false; + /*int level = heading ? paragraph.attributeNS( ooNS::text, "level", QString::null ).toInt() + : m_listStyleStack.level();*/ + + QDomElement counter = paragraph.ownerDocument().createElement( "COUNTER" ); + counter.setAttribute( "numberingtype", 0 ); + counter.setAttribute( "depth", 0 ); + + if ( m_insideOrderedList ) + counter.setAttribute( "type", 1 ); + else + counter.setAttribute( "type", 10 ); // a disc bullet + paragraph.appendChild( counter ); + } +} + +static QDomElement findListLevelStyle( QDomElement& fullListStyle, int level ) +{ + QDomElement listLevelItem; + forEachElement( listLevelItem, fullListStyle ) + { + if ( listLevelItem.attributeNS( ooNS::text, "level", QString::null ).toInt() == level ) + return listLevelItem; + } + return QDomElement(); +} + +bool OoImpressImport::pushListLevelStyle( const QString& listStyleName, int level ) +{ + QDomElement* fullListStyle = m_listStyles[listStyleName]; + if ( !fullListStyle ) { + kdWarning(30518) << "List style " << listStyleName << " not found!" << endl; + return false; + } + else + return pushListLevelStyle( listStyleName, *fullListStyle, level ); +} + +bool OoImpressImport::pushListLevelStyle( const QString& listStyleName, // for debug only + QDomElement& fullListStyle, int level ) +{ + // Find applicable list-level-style for level + int i = level; + QDomElement listLevelStyle; + while ( i > 0 && listLevelStyle.isNull() ) { + listLevelStyle = findListLevelStyle( fullListStyle, i ); + --i; + } + if ( listLevelStyle.isNull() ) { + kdWarning(30518) << "List level style for level " << level << " in list style " << listStyleName << " not found!" << endl; + return false; + } + kdDebug(30518) << "Pushing list-level-style from list-style " << listStyleName << " level " << level << endl; + m_listStyleStack.push( listLevelStyle ); + return true; +} + +void OoImpressImport::parseList( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& list ) +{ + //kdDebug(30518) << k_funcinfo << "parseList"<< endl; + + m_insideOrderedList = ( list.localName() == "ordered-list" ); + QString oldListStyleName = m_currentListStyleName; + if ( list.hasAttributeNS( ooNS::text, "style-name" ) ) + m_currentListStyleName = list.attributeNS( ooNS::text, "style-name", QString::null ); + bool listOK = !m_currentListStyleName.isEmpty(); + const int level = m_listStyleStack.level() + 1; + //kdDebug(30518) << k_funcinfo << " listOK=" << listOK << " level=" << level << endl; + if ( listOK ) + listOK = pushListLevelStyle( m_currentListStyleName, level ); + + // Iterate over list items + QDomElement listItem; + forEachElement( listItem, list ) + { + // It's either list-header (normal text on top of list) or list-item + m_nextItemIsListItem = ( listItem.localName() != "list-header" ); + m_restartNumbering = -1; + if ( listItem.hasAttributeNS( ooNS::text, "start-value" ) ) + m_restartNumbering = listItem.attributeNS( ooNS::text, "start-value", QString::null ).toInt(); + // ### Oasis: can be p h or list only. + parseParagraphs( doc, textObjectElement, listItem ); + m_restartNumbering = -1; + } + if ( listOK ) + m_listStyleStack.pop(); + m_currentListStyleName = oldListStyleName; +} + +QDomElement OoImpressImport::parseParagraph( QDomDocument& doc, const QDomElement& paragraph ) +{ + QDomElement p = doc.createElement( "P" ); + + // parse the paragraph-properties + fillStyleStack( paragraph ); + + // Style name + QString styleName = m_styleStack.userStyleName("paragraph"); + if ( !styleName.isEmpty() ) + { + QDomElement nameElem = doc.createElement("NAME"); + nameElem.setAttribute("value", styleName); + p.appendChild(nameElem); + } + + // Paragraph alignment + if ( m_styleStack.hasAttributeNS( ooNS::fo, "text-align" ) ) + { + QString align = m_styleStack.attributeNS( ooNS::fo, "text-align" ); + if ( align == "center" ) + p.setAttribute( "align", 4 ); + else if ( align == "justify" ) + p.setAttribute( "align", 8 ); + else if ( align == "start" ) + p.setAttribute( "align", 0 ); + else if ( align == "end" ) + p.setAttribute( "align", 2 ); + } + else + p.setAttribute( "align", 0 ); // use left aligned as default + + + // Offset before and after paragraph + OoUtils::importTopBottomMargin( p, m_styleStack ); + + // Indentation (margins) + OoUtils::importIndents( p, m_styleStack ); + + // Line spacing + OoUtils::importLineSpacing( p, m_styleStack ); + + // Tabulators + OoUtils::importTabulators( p, m_styleStack ); + + // Borders + OoUtils::importBorders( p, m_styleStack ); + + applyListStyle( p ); + + uint pos = 0; + + m_styleStack.save(); + // parse every childnode of the paragraph + parseSpanOrSimilar( doc, paragraph, p, pos); + m_styleStack.restore(); // remove possible garbage (should not be needed) + + return p; +} + +void OoImpressImport::parseSpanOrSimilar( QDomDocument& doc, const QDomElement& parent, + QDomElement& outputParagraph, uint& pos) +{ + // Parse every child node of the parent + // Can't use forEachElement here since we also care about text nodes + for( QDomNode node = parent.firstChild(); !node.isNull(); node = node.nextSibling() ) + { + QDomElement ts = node.toElement(); + QString textData; + const QString localName( ts.localName() ); + const QString ns = ts.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + QDomText t = node.toText(); + + // Try to keep the order of the tag names by probability of happening + if ( isTextNS && localName == "span" ) // text:span + { + m_styleStack.save(); + fillStyleStack( ts ); + parseSpanOrSimilar( doc, ts, outputParagraph, pos); + m_styleStack.restore(); + } + else if ( isTextNS && localName == "s" ) // text:s + { + textData = OoUtils::expandWhitespace(ts); + } + else if ( isTextNS && localName == "tab-stop" ) // text:tab-stop + { + // KPresenter currently uses \t. + // Known bug: a line with only \t\t\t\t isn't loaded - XML (QDom) strips out whitespace. + // One more good reason to switch to instead... + textData = '\t'; + } + else if ( isTextNS && localName == "line-break" ) + { + textData = '\n'; + } + else if ( localName == "image" && ns == ooNS::draw ) + { + textData = '#'; // anchor placeholder + // TODO + } + else if ( isTextNS && localName == "a" ) + { + m_styleStack.save(); + QString href( ts.attributeNS( ooNS::xlink, "href", QString::null) ); + if ( href.startsWith("#") ) + { + // We have a reference to a bookmark (### TODO) + // As we do not support it now, treat it as a without formatting + parseSpanOrSimilar( doc, ts, outputParagraph, pos); + } + else + { +#if 0 // TODO + // The problem is that KPresenter's hyperlink text is not inside the normal text, but for OOWriter it is nearly a + // So we have to fake. + QDomElement fakeParagraph, fakeFormats; + uint fakePos=0; + QString text; + parseSpanOrSimilar( doc, ts, fakeParagraph, fakeFormats, text, fakePos); + textData = '#'; // hyperlink placeholder + QDomElement linkElement (doc.createElement("LINK")); + linkElement.setAttribute("hrefName",ts.attributeNS( ooNS::xlink, "href", QString::null)); + linkElement.setAttribute("linkName",text); + appendVariable(doc, ts, pos, "STRING", 9, text, linkElement); +#endif + } + m_styleStack.restore(); + } + else if ( isTextNS && + (localName == "date" // fields + || localName == "time" + || localName == "page-number" + || localName == "file-name" + || localName == "author-name" + || localName == "author-initials" ) ) + { + textData = "#"; // field placeholder + appendField(doc, outputParagraph, ts, pos); + } + else if ( t.isNull() ) // no textnode, we must ignore + { + kdWarning(30518) << "Ignoring tag " << ts.tagName() << endl; + continue; + } + else + textData = t.data(); + + pos += textData.length(); + + QDomElement text = saveHelper(textData, doc); + + kdDebug(30518) << k_funcinfo << "Para text is: " << textData << endl; + + if (m_styleStack.hasAttributeNS( ooNS::fo, "language" )) { + QString lang = m_styleStack.attributeNS( ooNS::fo, "language" ); + if (lang=="en") + text.setAttribute("language", "en_US"); + else + text.setAttribute("language", lang); + } + + // parse the text-properties + if ( m_styleStack.hasAttributeNS( ooNS::fo, "color" ) ) { + kdDebug(30518) << "color=" << m_styleStack.attributeNS( ooNS::fo, "color" ) << endl; + text.setAttribute( "color", m_styleStack.attributeNS( ooNS::fo, "color" ) ); + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-family" ) // 3.10.9 + || m_styleStack.hasAttributeNS( ooNS::style, "font-name") )//3.10.8 + { + // 'Thorndale/Albany' are not known outside OpenOffice so we substitute them + // with 'Times New Roman/Arial' that look nearly the same. + if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Thorndale" ) + text.setAttribute( "family", "Times New Roman" ); + else if ( m_styleStack.attributeNS( ooNS::fo, "font-family" ) == "Albany" ) + text.setAttribute( "family", "Arial" ); + else + text.setAttribute( "family", m_styleStack.attributeNS( ooNS::fo, "font-family" ).remove( "'" ) ); + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-size" ) ) + { + double pointSize = m_styleStack.fontSize(); + text.setAttribute( "pointSize", qRound(pointSize) ); // KPresenter uses toInt()! + } + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-weight" ) ) // 3.10.24 + if ( m_styleStack.attributeNS( ooNS::fo, "font-weight" ) == "bold" ) + text.setAttribute( "bold", 1 ); + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-style" ) ) + if ( m_styleStack.attributeNS( ooNS::fo, "font-style" ) == "italic" ) + text.setAttribute( "italic", 1 ); + + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-position" ) ) // 3.10.17 + { + QString text_position = m_styleStack.attributeNS( ooNS::style, "text-position"); + QString value; + QString relativetextsize; + OoUtils::importTextPosition( text_position, value, relativetextsize ); + text.setAttribute( "VERTALIGN", value ); + if ( !relativetextsize.isEmpty() ) + text.setAttribute( "relativetextsize", relativetextsize ); + } + + bool wordByWord = (m_styleStack.hasAttributeNS( ooNS::fo, "score-spaces"))// 3.10.25 + && (m_styleStack.attributeNS( ooNS::fo, "score-spaces") == "false"); + + // strikeout + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-crossing-out")// 3.10.6 + && m_styleStack.attributeNS( ooNS::style, "text-crossing-out") != "none") + { + QString strikeOutType = m_styleStack.attributeNS( ooNS::style, "text-crossing-out" ); + if ( strikeOutType =="double-line" ) + { + text.setAttribute( "strikeOut", "double" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + else if ( strikeOutType =="thick-line" ) + { + text.setAttribute( "strikeOut", "single-bold" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + else //if ( strikeOutType == "single-line" ) //fall back to the default strikeout + { + text.setAttribute( "strikeOut", "single" ); + text.setAttribute( "strikeoutstyleline", "solid" ); + } + + if (wordByWord) + text.setAttribute("wordbyword", 1); + } + + // underlining + if ( m_styleStack.hasAttributeNS( ooNS::style, "text-underline" ) ) // 3.10.22 + { + QString underline; + QString styleline; + OoUtils::importUnderline( m_styleStack.attributeNS( ooNS::style, "text-underline" ), + underline, styleline ); + QString underLineColor = m_styleStack.attributeNS( ooNS::style, "text-underline-color" );// 3.10.23 + + text.setAttribute( "value", underline ); + text.setAttribute( "styleline", styleline ); + + if ( !underLineColor.isEmpty() && underLineColor != "font-color" ) + text.setAttribute("underlinecolor", underLineColor); + if ( wordByWord ) + text.setAttribute("wordbyword", 1); + } +#if 0 // strange ooimpress doesn't implement it + // Small caps, lowercase, uppercase + if ( m_styleStack.hasAttributeNS( ooNS::fo, "font-variant" ) // 3.10.1 + || m_styleStack.hasAttributeNS( ooNS::fo, "text-transform" ) ) // 3.10.2 + { + QDomElement fontAttrib( doc.createElement( "FONTATTRIBUTE" ) ); + bool smallCaps = m_styleStack.attributeNS( ooNS::fo, "font-variant" ) == "small-caps"; + if ( smallCaps ) + { + text.setAttribute( "fontattribute", "smallcaps" ); + } else + { + // Both KWord/KPresenter and OO use "uppercase" and "lowercase". + // TODO in KWord: "capitalize". + text.setAttribute( "fontattribute", m_styleStack.attributeNS( ooNS::fo, "text-transform" ) ); + } + } +#endif + // background color (property of the paragraph in OOo, of the text in kword/kpresenter) + if (m_styleStack.hasAttributeNS( ooNS::fo, "background-color" )) + { + QString bgColor = m_styleStack.attributeNS( ooNS::fo, "background-color"); + if (bgColor != "transparent") + text.setAttribute("textbackcolor", bgColor); + } + + appendShadow( doc, outputParagraph ); // this is necessary to take care of shadowed paragraphs + outputParagraph.appendChild( text ); + } // for each text span +} + +void OoImpressImport::createStyleMap( QDomDocument &docstyles ) +{ + QDomElement styles = docstyles.documentElement(); + if ( styles.isNull() ) + return; + + QDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" ); + if ( !fixedStyles.isNull() ) + { + insertDraws( fixedStyles.toElement() ); + insertStyles( fixedStyles.toElement() ); + insertStylesPresentation( fixedStyles.toElement() ); + } + + QDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" ); + if ( !automaticStyles.isNull() ) + { + insertStyles( automaticStyles.toElement() ); + insertStylesPresentation( automaticStyles.toElement() ); + } + QDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" ); + if ( !masterStyles.isNull() ) + insertStyles( masterStyles.toElement() ); +} + +void OoImpressImport::insertDraws( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + if ( !e.hasAttributeNS( ooNS::draw, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::draw, "name", QString::null ); + m_draws.insert( name, new QDomElement( e ) ); + } +} + +void OoImpressImport::insertStyles( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + const QString localName = e.localName(); + const QString ns = e.namespaceURI(); + if ( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + const QString name = e.attributeNS( ooNS::style, "name", QString::null ); + if ( localName == "list-style" && ns == ooNS::text ) { + QDomElement* ep = new QDomElement( e ); + m_listStyles.insert( name, ep ); + kdDebug(30518) << "List style: '" << name << "' loaded " << endl; + } + else + { + m_styles.insert( name, new QDomElement( e ) ); + kdDebug(30518) << "Style: '" << name << "' loaded " << endl; + } + } +} + +void OoImpressImport::insertStylesPresentation( const QDomElement& styles ) +{ + QDomElement e; + forEachElement( e, styles ) + { + if ( !e.hasAttributeNS( ooNS::style, "name" ) ) + continue; + + QString name = e.attributeNS( ooNS::style, "name", QString::null ); + m_stylesPresentation.insert( name, new QDomElement( e ) ); + //kdDebug(30518) << "Style: '" << name << "' loaded " << endl; + } +} + +void OoImpressImport::fillStyleStack( const QDomElement& object, bool sticky ) +{ + // find all styles associated with an object and push them on the stack + if ( object.hasAttributeNS( ooNS::presentation, "style-name" ) ) + { + kdDebug(30518)<<" presentation:style-name **************************** :"<attributeNS( ooNS::style, "name", QString::null ) <hasAttributeNS( ooNS::style, "parent-style-name" ) ) + { + //kdDebug(30518)<<"m_styles[style->attribute( style:parent-style-name )] :"<attributeNS( ooNS::style, "parent-style-name", QString::null )]<attributeNS( ooNS::style, "parent-style-name", QString::null )] ); + } + //kdDebug(30518)<<" void OoImpressImport::addStyles( const QDomElement* style ) :"<directory()->entry( url ); + + QString extension = url.mid( url.find( '.' ) ); + QString fileName = QString( "picture%1" ).arg( m_numPicture++ ) + extension; + KoStoreDevice* out = m_chain->storageFile( "pictures/" + fileName, KoStore::Write ); + + if ( file && out ) + { + QByteArray buffer = file->data(); + out->writeBlock( buffer.data(), buffer.size() ); + } + + return fileName; +} + +QString OoImpressImport::storeSound(const QDomElement & object, QDomElement & p, QDomDocument & doc) +{ + QFileInfo fi(m_chain->inputFile()); // handle relative URLs + QDir::setCurrent(fi.dirPath(true)); + fi.setFile(object.attributeNS( ooNS::xlink, "href", QString::null)); + QString url = fi.absFilePath(); + + //kdDebug(30518) << "Sound URL: " << url << endl; + + QFile file(url); + if (!file.exists()) + return QString::null; + + QString extension = url.mid( url.find( '.' ) ); + QString fileName = QString( "sound%1" ).arg( m_numSound++ ) + extension; + fileName = "sounds/" + fileName; + KoStoreDevice* out = m_chain->storageFile( fileName, KoStore::Write ); + + if (out) + { + if (!file.open(IO_ReadOnly)) + return QString::null; + + QByteArray data(8*1024); + + uint total = 0; + for ( int block = 0; ( block = file.readBlock(data.data(), data.size()) ) > 0; + total += block ) + out->writeBlock(data.data(), data.size()); + + Q_ASSERT(total == fi.size()); + + file.close(); + } + else + return QString::null; + + QDomElement key = doc.createElement("FILE"); + key.setAttribute("name", fileName); + key.setAttribute("filename", url); + p.appendChild(key); + + return url; +} + +QDomElement OoImpressImport::saveHelper(const QString &tmpText, QDomDocument &doc) +{ + QDomElement element=doc.createElement("TEXT"); + + if(tmpText.stripWhiteSpace().isEmpty()) // ### careful, this also strips \t and \n .... + // working around a bug in QDom + element.setAttribute("whitespace", tmpText.length()); + + element.appendChild(doc.createTextNode(tmpText)); + return element; +} + +void OoImpressImport::appendPoints(QDomDocument& doc, QDomElement& e, const QDomElement& object) +{ + QDomElement ptsElem = doc.createElement("POINTS"); + + QStringList ptList = QStringList::split(' ', object.attributeNS( ooNS::draw, "points", QString::null)); + + QString pt_x, pt_y; + double tmp_x, tmp_y; + for (QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it) + { + QDomElement point = doc.createElement("Point"); + + tmp_x = (*it).section(',',0,0).toInt() / 100; + tmp_y = (*it).section(',',1,1).toInt() / 100; + + pt_x.setNum(tmp_x); + pt_x+="mm"; + + pt_y.setNum(tmp_y); + pt_y+="mm"; + + point.setAttribute("point_x", KoUnit::parseValue(pt_x)); + point.setAttribute("point_y", KoUnit::parseValue(pt_y)); + ptsElem.appendChild(point); + } + + e.appendChild(ptsElem); +} + +void OoImpressImport::appendField(QDomDocument& doc, QDomElement& e, const QDomElement& object, uint pos) +{ + const QString tag = object.localName(); + const QString ns = object.namespaceURI(); + const bool isTextNS = ns == ooNS::text; + + QDomElement custom = doc.createElement("CUSTOM"); + custom.setAttribute("pos", pos); + QDomElement variable = doc.createElement("VARIABLE"); + + if (isTextNS && tag == "date") + { + QDateTime dt(QDate::fromString(object.attributeNS( ooNS::text, "date-value", QString::null), Qt::ISODate)); + + bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true"); + + if (!dt.isValid()) { + dt = QDateTime::currentDateTime(); // OOo docs say so :) + fixed = false; + } + + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "DATE0locale"); // ### find out the correlation between KOffice and OOo date/time types + typeElem.setAttribute("type", 0); // VT_DATE + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + const QDate date(dt.date()); + const QTime time(dt.time()); + QDomElement dateElement = doc.createElement("DATE"); + dateElement.setAttribute("subtype", fixed ? 0 : 1); // VST_DATE_FIX, VST_DATE_CURRENT + dateElement.setAttribute("fix", fixed ? 1 : 0); + dateElement.setAttribute("day", date.day()); + dateElement.setAttribute("month", date.month()); + dateElement.setAttribute("year", date.year()); + dateElement.setAttribute("hour", time.hour()); + dateElement.setAttribute("minute", time.minute()); + dateElement.setAttribute("second", time.second()); + if (object.hasAttributeNS( ooNS::text, "date-adjust")) + dateElement.setAttribute("correct", object.attributeNS( ooNS::text, "date-adjust", QString::null)); + + variable.appendChild(dateElement); + } + else if (isTextNS && tag == "time") + { + // Use QDateTime to work around a possible problem of QTime::FromString in Qt 3.2.2 + QDateTime dt(QDateTime::fromString(object.attributeNS( ooNS::text, "time-value", QString::null), Qt::ISODate)); + + bool fixed = (object.hasAttributeNS( ooNS::text, "fixed") && object.attributeNS( ooNS::text, "fixed", QString::null)=="true"); + + if (!dt.isValid()) { + dt = QDateTime::currentDateTime(); // OOo docs say so :) + fixed = false; + } + + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "TIMElocale"); // ### find out the correlation between KOffice and OOo date/time types + typeElem.setAttribute("type", 2); // VT_TIME + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + const QTime time(dt.time()); + QDomElement timeElement = doc.createElement("TIME"); + timeElement.setAttribute("subtype", fixed ? 0 : 1); // VST_TIME_FIX, VST_TIME_CURRENT + timeElement.setAttribute("fix", fixed ? 1 : 0); + timeElement.setAttribute("hour", time.hour()); + timeElement.setAttribute("minute", time.minute()); + timeElement.setAttribute("second", time.second()); + /*if (object.hasAttributeNS( ooNS::text, "time-adjust")) + timeElem.setAttribute("correct", object.attributeNS( ooNS::text, "time-adjust", QString::null));*/ // ### TODO + + variable.appendChild(timeElement); + } + else if (isTextNS && tag == "page-number") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "NUMBER"); + typeElem.setAttribute("type", 4); // VT_PGNUM + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + QDomElement pgNumElem = doc.createElement("PGNUM"); + + int subtype = 0; // VST_PGNUM_CURRENT + + if (object.hasAttributeNS( ooNS::text, "select-page")) + { + const QString select = object.attributeNS( ooNS::text, "select-page", QString::null); + + if (select == "previous") + subtype = 3; // VST_PGNUM_PREVIOUS + else if (select == "next") + subtype = 4; // VST_PGNUM_NEXT + else + subtype = 0; // VST_PGNUM_CURRENT + } + + pgNumElem.setAttribute("subtype", subtype); + pgNumElem.setAttribute("value", object.text()); + + variable.appendChild(pgNumElem); + } + else if (isTextNS && tag == "file-name") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "STRING"); + typeElem.setAttribute("type", 8); // VT_FIELD + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + int subtype = 5; + + if (object.hasAttributeNS( ooNS::text, "display")) + { + const QString display = object.attributeNS( ooNS::text, "display", QString::null); + + if (display == "path") + subtype = 1; // VST_DIRECTORYNAME + else if (display == "name") + subtype = 6; // VST_FILENAMEWITHOUTEXTENSION + else if (display == "name-and-extension") + subtype = 0; // VST_FILENAME + else + subtype = 5; // VST_PATHFILENAME + } + + QDomElement fileNameElem = doc.createElement("FIELD"); + fileNameElem.setAttribute("subtype", subtype); + fileNameElem.setAttribute("value", object.text()); + + variable.appendChild(fileNameElem); + } + else if (isTextNS && tag == "author-name" + || isTextNS && tag == "author-initials") + { + QDomElement typeElem = doc.createElement("TYPE"); + typeElem.setAttribute("key", "STRING"); + typeElem.setAttribute("type", 8); // VT_FIELD + typeElem.setAttribute("text", object.text()); + + variable.appendChild(typeElem); + + int subtype = 2; // VST_AUTHORNAME + + if (isTextNS && tag == "author-initials") + subtype = 16; // VST_INITIAL + + QDomElement authorElem = doc.createElement("FIELD"); + authorElem.setAttribute("subtype", subtype); + authorElem.setAttribute("value", object.text()); + + variable.appendChild(authorElem); + } + + custom.appendChild(variable); + e.appendChild(custom); +} + +void OoImpressImport::createPresentationAnimation(const QDomElement& element) +{ + int order = 0; + QDomElement e; + forEachElement( e, element ) + { + const QString localName = e.localName(); + const QString ns = e.namespaceURI(); + if ( ns == ooNS::presentation && localName == "show-shape" && e.hasAttributeNS( ooNS::draw, "shape-id" ) ) + { + QString name = e.attributeNS( ooNS::draw, "shape-id", QString::null ); + //kdDebug(30518)<<" insert animation style : name :"<element = ep; + lst->order = order; + m_animations.insert( name, lst ); + ++order; + } + } +} + +QDomElement OoImpressImport::findAnimationByObjectID(const QString & id, int & order) +{ + kdDebug(30518)<<"QDomElement OoImpressImport::findAnimationByObjectID(const QString & id) :"<element ); !node.isNull(); node = node.nextSibling()) + { + QDomElement e = node.toElement(); + order = animation->order; + kdDebug(30518)<<"e.tagName() :"< + Copyright (c) 2003 Lukas Tinkl + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef OoImpress_IMPORT_H__ +#define OoImpress_IMPORT_H__ + +#include +#include + +#include +#include +#include +#include +#include + +class KZip; + +struct animationList +{ + QDomElement *element; + int order; +}; + +class OoImpressImport : public KoFilter +{ + Q_OBJECT +public: + OoImpressImport( KoFilter * parent, const char * name, const QStringList & ); + virtual ~OoImpressImport(); + + virtual KoFilter::ConversionStatus convert( QCString const & from, QCString const & to ); + +private: + void createDocumentInfo( QDomDocument &docinfo ); + void createDocumentContent( QDomDocument &doccontent ); + void createStyleMap( QDomDocument &docstyles ); + void insertDraws( const QDomElement& styles ); + void insertStyles( const QDomElement& styles ); + void insertStylesPresentation( const QDomElement& styles ); + + void fillStyleStack( const QDomElement& object,bool sticky = false ); + void addStyles( const QDomElement* style ); + void appendName(QDomDocument& doc, QDomElement& e, const QDomElement& object); + void append2DGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ); + bool appendLineGeometry( QDomDocument& doc, QDomElement& e, const QDomElement& object, int offset ); + void appendPoints(QDomDocument& doc, QDomElement& e, const QDomElement& object); + void appendPie( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendImage( QDomDocument& doc, QDomElement& e, QDomElement& p, const QDomElement& object ); + void appendBackgroundImage( QDomDocument& doc, QDomElement& e, QDomElement& p, const QDomElement& object ); + void appendBackgroundGradient( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendRounding( QDomDocument& doc, QDomElement& e, const QDomElement& object ); + void appendPen( QDomDocument& doc, QDomElement& e ); + void appendBrush( QDomDocument& doc, QDomElement& e ); + void appendShadow( QDomDocument& doc, QDomElement& e ); + void appendLineEnds( QDomDocument& doc, QDomElement& e, bool _orderEndStartLine = true ); + void appendTextObjectMargin( QDomDocument& doc, QDomElement& e ); + void appendField(QDomDocument& doc, QDomElement& e, const QDomElement& object, uint pos); + void createPresentationAnimation(const QDomElement& element); + QDomElement findAnimationByObjectID(const QString & id, int & order); + + void appendObjectEffect(QDomDocument& doc, QDomElement& e, const QDomElement& object, QDomElement& sound); + void appendBackgroundPage( QDomDocument &doc, QDomElement &e,QDomElement & pictureElement, QDomElement &soundElement ); + + QDomElement saveHelper(const QString &tmpText, QDomDocument &doc); + void appendObject(QDomNode & drawPage, QDomDocument & doc, QDomElement & soundElement, QDomElement & pictureElement, QDomElement & pageNoteElement, QDomElement &objectElement,double offset, bool sticky = false); + + QString storeImage( const QDomElement& object ); + QString storeSound(const QDomElement & object, QDomElement & p, QDomDocument & doc); + QDomElement parseTextBox( QDomDocument& doc, const QDomElement& textBox ); + bool pushListLevelStyle( const QString& listStyleName, int level ); + bool pushListLevelStyle( const QString& listStyleName, QDomElement& fullListStyle, int level ); + void applyListStyle( QDomElement& paragraph ); + void parseList( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& list ); + void parseParagraphs( QDomDocument& doc, QDomElement& textObjectElement, const QDomElement& textBox ); + QDomElement parseParagraph( QDomDocument& doc, const QDomElement& paragraph ); + void parseSpanOrSimilar( QDomDocument& doc, const QDomElement& parent, + QDomElement& outputParagraph, uint& pos); + bool parseSettings( QDomDocument &doc, QDomElement &helpLineElement, QDomElement &attributeElement ); + void parseHelpLine( QDomDocument &doc,QDomElement &helpLineElement, const QString &text ); + + KoFilter::ConversionStatus openFile(); + KoFilter::ConversionStatus loadAndParse(const QString& filename, QDomDocument& doc); + + int m_numPicture; + int m_numSound; + QDomDocument m_content; + QDomDocument m_meta; + QDomDocument m_settings; + QDict m_styles, m_draws, m_stylesPresentation; + QDict m_listStyles; + QDict m_animations; + + bool m_insideOrderedList; + bool m_nextItemIsListItem; // only the first elem inside list-item is numbered + int m_restartNumbering; + QString m_currentListStyleName; + + KZip * m_zip; + KoStyleStack m_styleStack; + ListStyleStack m_listStyleStack; +}; + +#endif diff --git a/filters/kpresenter/ooimpress/status.html b/filters/kpresenter/ooimpress/status.html new file mode 100644 index 000000000..b0062c047 --- /dev/null +++ b/filters/kpresenter/ooimpress/status.html @@ -0,0 +1,227 @@ + + + + + KOffice filters status: OpenOffice.org Impress Filter + + +  + +
    +
    +

    + KOffice filters status:   OpenOffice.org Impress Filter +

    +
    + +
    + + + Import | + Export + + +


    +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    + Import OpenOffice.org Impress for KPresenter
    +
    +
    +
    Last updateMarch 06, 2005
    Features + - Objects: text (including list), circle, ellipse (including pie, arc and chord), + rectangle, line, image, polyline, polygon
    + - Slide titles
    + - Paper settings
    + - Notes
    + - Slide background (solid, gradient and image)
    + - Line settings (width, style and color)
    + - Fill settings (solid, gradient)
    + - Line ends (arrows)
    + - Rounding (for rectangles)
    + - Shadow
    + - Text margins
    + - Vertical alignment for text
    + - Text style (underline, sub/super script, bold, italic, strikeout, background color)
    + - Paragraph style (line spacing, offset before/after paragraph, indent first/right/left, borders)
    + - Presentation settings
    + - Slide transitions
    + - Sound
    + - Fields (number of pages, author, date & time)
    + - Effects (for objects) and order effect
    + - Slide duration transition
    + - Picture effect
    + - Animation object order
    + - HelpLine
    + - Custom Slide Show
    +
    Todo + - Video (not supported by KPresenter)
    + - Embedded documents
    + - Objects: path, 3D objects (not supported by KPresenter)
    + - Load Layer (kpresenter doesn't support it but we can d�ine it as sticky object
    +
    HistoryJanuary 11, 2003: Initial Revision
    AuthorsPercy Leonhardt
    + Laurent Montel
    + Lukáš Tinkl +
    Links + KPresenter homepage
    + xml.openoffice.org +
    Progress report -
    +
    +
    +Up + +


    + +
    +


    + + +
    + +
    + +Up +
    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    +
    Export KPresenter to OpenOffice.org Impress

    +
    +
    Last updateMarch 06, 2005
    Features + - Objects: text (including list), circle, ellipse, rectangle, line, image, pie, arc, chord, polyline, polygon
    + - Slide titles
    + - Paper settings
    + - Slide background (solid)
    + - Line settings (width, style and color)
    + - Fill settings (solid, gradient)
    + - Rounding (for rectangles)
    + - Shadow
    + - Text style (underline, sub/super script, bold, italic, strikeout, background color)
    + - Paragraph style (line spacing, offset before/after paragraph, indent first/right/left, borders)
    + - Slide transitions
    + - Object rotate
    + - Slide duration transition
    + - Objects: image
    + - Settings element (snap line drawing)
    + - Export Transparency
    + - Export Group Object
    + - Vertical alignment for text
    + - Text margins
    + - Export title/keyword/subject
    + - Custom Slide Show
    +
    Todo + - Presentation settings
    + - Slide background (gradient and image)
    + - Line ends (arrows)
    + - Notes
    + - Sound
    + - Fields (number of pages, author, date & time)
    + - Effects (for objects)
    + - Video (not supported by KPresenter)
    + - Embedded documents
    + - Objects: path, 3D objects (not supported by KPresenter)
    +
    HistoryJuly 01, 2003: Initial Revision
    Authors + Percy Leonhardt
    + Montel Laurent
    +
    Links + KPresenter homepage
    + xml.openoffice.org +
    Progress report ---
    +
    +
    +Up + + + diff --git a/filters/kpresenter/ooimpress/stylefactory.cc b/filters/kpresenter/ooimpress/stylefactory.cc new file mode 100644 index 000000000..0c7d9a2cb --- /dev/null +++ b/filters/kpresenter/ooimpress/stylefactory.cc @@ -0,0 +1,1629 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "stylefactory.h" + +#include +#include +#include +#include + +StyleFactory::StyleFactory() +{ + m_strokeDashStyles.setAutoDelete( true ); + m_gradientStyles.setAutoDelete( true ); + m_hatchStyles.setAutoDelete( true ); + m_markerStyles.setAutoDelete( true ); + m_fillImageStyles.setAutoDelete( true ); + m_listStyles.setAutoDelete( true ); + m_pageStyles.setAutoDelete( true ); + m_textStyles.setAutoDelete( true ); + m_graphicStyles.setAutoDelete( true ); + m_paragraphStyles.setAutoDelete( true ); + m_pageMasterStyles.setAutoDelete( true ); + + // create standard graphic style + GraphicStyle * graphicStyle; + graphicStyle = new GraphicStyle ( "standard", "solid", "0cm", "0x000000", + "hidden", "0.3cm", "0.3cm", "0x808080", + "0cm", "0cm", "0cm", "0cm", "0x000000", + "false", "none", "Thorndale", "24pt", + "normal", "none", "none", "normal", + "100%", "start", "solid", "0x00b8ff", + "false" ); + + m_graphicStyles.append( graphicStyle ); +} + +StyleFactory::~StyleFactory() +{ +} + +void StyleFactory::addOfficeStyles( QDomDocument & doc, QDomElement & styles ) +{ + StrokeDashStyle * sd; + for ( sd = m_strokeDashStyles.first(); sd ; sd = m_strokeDashStyles.next() ) + sd->toXML( doc, styles ); + + GradientStyle * g; + for ( g = m_gradientStyles.first(); g ; g = m_gradientStyles.next() ) + g->toXML( doc, styles ); + + MarkerStyle * m; + for ( m = m_markerStyles.first(); m ; m = m_markerStyles.next() ) + m->toXML( doc, styles ); + + HatchStyle * h; + for ( h = m_hatchStyles.first(); h ; h = m_hatchStyles.next() ) + h->toXML( doc, styles ); + + GraphicStyle * gr; + gr = m_graphicStyles.first(); // skip the "standard" style + gr->toXML( doc, styles ); +} + +void StyleFactory::addOfficeMaster( QDomDocument & doc, QDomElement & master ) +{ + PageMasterStyle * p; + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + QDomElement masterPage = doc.createElement( "style:master-page" ); + masterPage.setAttribute( "style:name", p->style() ); + masterPage.setAttribute( "style:page-master-name", p->name() ); + masterPage.setAttribute( "draw:style-name", "dp1" ); + master.appendChild( masterPage ); + } +} + +void StyleFactory::addOfficeAutomatic( QDomDocument & doc, QDomElement & automatic ) +{ + PageMasterStyle * p; + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + p->toXML( doc, automatic ); + } +} + +void StyleFactory::addAutomaticStyles( QDomDocument & doc, QDomElement & autoStyles ) +{ + ListStyle * l; + for ( l = m_listStyles.first(); l ; l = m_listStyles.next() ) + l->toXML( doc, autoStyles ); + + PageStyle * p; + for ( p = m_pageStyles.first(); p ; p = m_pageStyles.next() ) + p->toXML( doc, autoStyles ); + + TextStyle * t; + for ( t = m_textStyles.first(); t ; t = m_textStyles.next() ) + t->toXML( doc, autoStyles ); + + GraphicStyle * g; + g = m_graphicStyles.first(); // skip the "standard" style + for ( g = m_graphicStyles.next(); g ; g = m_graphicStyles.next() ) + g->toXML( doc, autoStyles ); + + ParagraphStyle * pg; + for ( pg = m_paragraphStyles.first(); pg ; pg = m_paragraphStyles.next() ) + pg->toXML( doc, autoStyles ); +} + +QString StyleFactory::createStrokeDashStyle( int style ) +{ + StrokeDashStyle * newStrokeDashStyle, * sd; + newStrokeDashStyle = new StrokeDashStyle( style ); + for ( sd = m_strokeDashStyles.first(); sd ; sd = m_strokeDashStyles.next() ) + { + if ( sd->name() == newStrokeDashStyle->name() ) + { + delete newStrokeDashStyle; + return sd->name(); + } + } + + m_strokeDashStyles.append( newStrokeDashStyle ); + return newStrokeDashStyle->name(); +} + +QString StyleFactory::createGradientStyle( QDomElement & gradient ) +{ + GradientStyle * newGradientStyle, * g; + newGradientStyle = new GradientStyle( gradient, m_gradientStyles.count() + 1 ); + for ( g = m_gradientStyles.first(); g ; g = m_gradientStyles.next() ) + { + if ( g->name() == newGradientStyle->name() ) + { + delete newGradientStyle; + return g->name(); + } + } + + m_gradientStyles.append( newGradientStyle ); + return newGradientStyle->name(); +} + +QString StyleFactory::createMarkerStyle( int style ) +{ + MarkerStyle * newMarkerStyle, * m; + newMarkerStyle = new MarkerStyle( style ); + for ( m = m_markerStyles.first(); m ; m = m_markerStyles.next() ) + { + if ( m->name() == newMarkerStyle->name() ) + { + delete newMarkerStyle; + return m->name(); + } + } + + m_markerStyles.append( newMarkerStyle ); + return newMarkerStyle->name(); +} + +QString StyleFactory::createHatchStyle( int style, QString & color ) +{ + HatchStyle * newHatchStyle, * h; + newHatchStyle = new HatchStyle( style, color ); + for ( h = m_hatchStyles.first(); h ; h = m_hatchStyles.next() ) + { + if ( h->name() == newHatchStyle->name() ) + { + delete newHatchStyle; + return h->name(); + } + } + + m_hatchStyles.append( newHatchStyle ); + return newHatchStyle->name(); +} + +QString StyleFactory::createListStyle( QDomElement & e ) +{ + ListStyle * newListStyle, * l; + newListStyle = new ListStyle( e, m_listStyles.count() + 1 ); + for ( l = m_listStyles.first(); l ; l = m_listStyles.next() ) + { + if ( *l == *newListStyle ) + { + delete newListStyle; + return l->name(); + } + } + + m_listStyles.append( newListStyle ); + return newListStyle->name(); +} + +QString StyleFactory::createPageStyle( QDomElement & e ) +{ + PageStyle * newPageStyle, * p; + newPageStyle = new PageStyle( this, e, m_pageStyles.count() + 1 ); + for ( p = m_pageStyles.first(); p ; p = m_pageStyles.next() ) + { + if ( *p == *newPageStyle ) + { + delete newPageStyle; + return p->name(); + } + } + + m_pageStyles.append( newPageStyle ); + return newPageStyle->name(); +} + +QString StyleFactory::createTextStyle( QDomElement & e ) +{ + TextStyle * newTextStyle, * t; + newTextStyle = new TextStyle( e, m_textStyles.count() + 1 ); + for ( t = m_textStyles.first(); t ; t = m_textStyles.next() ) + { + if ( *t == *newTextStyle ) + { + delete newTextStyle; + return t->name(); + } + } + + m_textStyles.append( newTextStyle ); + return newTextStyle->name(); +} + +QString StyleFactory::createGraphicStyle( QDomElement & e ) +{ + GraphicStyle * newGraphicStyle, * g; + newGraphicStyle = new GraphicStyle( this, e, m_graphicStyles.count() ); + for ( g = m_graphicStyles.first(); g ; g = m_graphicStyles.next() ) + { + if ( *g == *newGraphicStyle ) + { + delete newGraphicStyle; + return g->name(); + } + } + + m_graphicStyles.append( newGraphicStyle ); + return newGraphicStyle->name(); +} + +QString StyleFactory::createParagraphStyle( QDomElement & e ) +{ + ParagraphStyle * newParagraphStyle, * p; + newParagraphStyle = new ParagraphStyle( e, m_paragraphStyles.count() + 1 ); + for ( p = m_paragraphStyles.first(); p ; p = m_paragraphStyles.next() ) + { + if ( *p == *newParagraphStyle ) + { + delete newParagraphStyle; + return p->name(); + } + } + + m_paragraphStyles.append( newParagraphStyle ); + return newParagraphStyle->name(); +} + +QString StyleFactory::createPageMasterStyle( QDomElement & e ) +{ + PageMasterStyle * newPMStyle, * p; + newPMStyle = new PageMasterStyle( e, m_pageMasterStyles.count() ); + for ( p = m_pageMasterStyles.first(); p ; p = m_pageMasterStyles.next() ) + { + if ( *p == *newPMStyle ) + { + delete newPMStyle; + return p->style(); + } + } + + m_pageMasterStyles.append( newPMStyle ); + return newPMStyle->style(); +} + +QString StyleFactory::toCM( const QString & point ) +{ + double pt = point.toFloat(); + double cm = KoUnit::toCM( pt ); + return QString( "%1cm" ).arg ( cm ); +} + +StrokeDashStyle::StrokeDashStyle( int style ) +{ + switch ( style ) + { + case 2: + m_name = "Fine Dashed"; + m_style = "rect"; + m_dots1 = "1"; + m_dots1_length = "0.508cm"; + m_dots2 = "1"; + m_dots2_length = "0.508cm"; + m_distance = "0.508cm"; + break; + case 3: + m_name = "Fine Dotted"; + m_style = "rect"; + m_dots1 = "1"; + m_distance = "0.257cm"; + break; + case 4: + m_name = "Ultrafine 1 Dot 1 Dash"; + m_style = "rect"; + m_dots1 = "1"; + m_dots1_length = "0.051cm"; + m_dots2 = "1"; + m_dots2_length = "0.254cm"; + m_distance = "0.127cm"; + break; + case 5: + m_name = "2 Dots 1 Dash"; + m_style = "rect"; + m_dots1 = "2"; + m_dots2 = "1"; + m_dots2_length = "0.203cm"; + m_distance = "0.203cm"; + break; + } +} + +void StrokeDashStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement strokeDash = doc.createElement( "draw:stroke-dash" ); + strokeDash.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + strokeDash.setAttribute( "draw:style", m_style ); + if ( !m_dots1.isNull() ) + strokeDash.setAttribute( "draw:dots1", m_dots1 ); + if ( !m_dots1_length.isNull() ) + strokeDash.setAttribute( "draw:dots1-length", m_dots1_length ); + if ( !m_dots2.isNull() ) + strokeDash.setAttribute( "draw:dots2", m_dots2 ); + if ( !m_dots2_length.isNull() ) + strokeDash.setAttribute( "draw:dots2-length", m_dots2_length ); + if ( !m_distance.isNull() ) + strokeDash.setAttribute( "draw:distance", m_distance ); + + e.appendChild( strokeDash ); +} + +GradientStyle::GradientStyle( QDomElement & gradient, int index ) +{ + m_name = QString( "Gradient %1" ).arg( index ); + m_start_intensity = "100%"; + m_end_intensity = "100%"; + m_border = "0%"; + + int type = 1; + if ( gradient.nodeName() == "PAGE" ) + { + // gradient from page background + QDomElement backColor1 = gradient.namedItem( "BACKCOLOR1" ).toElement(); + QDomElement backColor2 = gradient.namedItem( "BACKCOLOR2" ).toElement(); + QDomElement bcType = gradient.namedItem( "BCTYPE" ).toElement(); + QDomElement bGradient = gradient.namedItem( "BGRADIENT" ).toElement(); + + if ( !backColor1.isNull() ) + m_start_color = backColor1.attribute( "color" ); + if ( !backColor2.isNull() ) + m_end_color = backColor2.attribute( "color" ); + if ( !bcType.isNull() ) + type = bcType.attribute( "value" ).toInt(); + if ( !bGradient.isNull() ) + { + if ( bGradient.attribute( "unbalanced" ) == "0" ) + { + m_cx = "50%"; + m_cy = "50%"; + } + else + { + int cx = bGradient.attribute( "xfactor" ).toInt(); + int cy = bGradient.attribute( "yfactor" ).toInt(); + m_cx = QString( "%1%" ).arg( cx / 4 + 50 ); + m_cy = QString( "%1%" ).arg( cy / 4 + 50 ); + } + } + + } + else + { + // gradient from object + if ( gradient.hasAttribute( "color1" ) ) + m_start_color = gradient.attribute( "color1" ); + if ( gradient.hasAttribute( "color2" ) ) + m_end_color = gradient.attribute( "color2" ); + if ( gradient.hasAttribute( "type" ) ) + type = gradient.attribute( "type" ).toInt(); + if ( gradient.hasAttribute( "unbalanced" ) ) + { + if ( gradient.attribute( "unbalanced" ) == "0" ) + { + m_cx = "50%"; + m_cy = "50%"; + } + else + { + int cx = gradient.attribute( "xfactor" ).toInt(); + int cy = gradient.attribute( "yfactor" ).toInt(); + m_cx = QString( "%1%" ).arg( cx / 4 + 50 ); + m_cy = QString( "%1%" ).arg( cy / 4 + 50 ); + } + } + + } + + switch ( type ) + { + case 1: + m_style = "linear"; + m_angle = "0"; + break; + case 2: + m_style = "linear"; + m_angle = "900"; + break; + case 3: + m_style = "linear"; + m_angle = "450"; + break; + case 4: + m_style = "linear"; + m_angle = "135"; + break; + case 5: + m_style = "radial"; + m_angle = "0"; + break; + case 6: + m_style = "square"; + m_angle = "0"; + break; + case 7: + m_style = "axial"; + m_angle = "0"; + break; + } +} + +void GradientStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement gradient = doc.createElement( "draw:gradient" ); + gradient.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + gradient.setAttribute( "draw:style", m_style ); + if ( !m_start_color.isNull() ) + gradient.setAttribute( "draw:start-color", m_start_color ); + if ( !m_end_color.isNull() ) + gradient.setAttribute( "draw:end-color", m_end_color ); + if ( !m_start_intensity.isNull() ) + gradient.setAttribute( "draw:start-intensity", m_start_intensity ); + if ( !m_end_intensity.isNull() ) + gradient.setAttribute( "draw:end-intensity", m_end_intensity ); + if ( !m_angle.isNull() ) + gradient.setAttribute( "draw:angle", m_angle ); + if ( !m_border.isNull() ) + gradient.setAttribute( "draw:border", m_border ); + if ( !m_cx.isNull() ) + gradient.setAttribute( "draw:cx", m_cx ); + if ( !m_cy.isNull() ) + gradient.setAttribute( "draw:cy", m_cy ); + + e.appendChild( gradient ); +} + +MarkerStyle::MarkerStyle( int style ) +{ + // Markers are not working because OOImpress depends on the sequence + // of the attributes in the draw:marker tag. svg:ViewBox has to be in + // front of svg:d in order to work. + + switch ( style ) + { + case 1: + m_name = "Arrow"; + m_viewBox = "0 0 20 30"; + m_d = "m10 0-10 30h20z"; + break; + case 2: + m_name = "Square"; + m_viewBox = "0 0 10 10"; + m_d = "m0 0h10v10h-10z"; + break; + case 3: + m_name = "Circle"; + m_viewBox = "0 0 1131 1131"; + m_d = "m462 1118-102-29-102-51-93-72-72-93-51-102-29-102-13-105 13-102 29-106 51-102 72-89 93-72 102-50 102-34 106-9 101 9 106 34 98 50 93 72 72 89 51 102 29 106 13 102-13 105-29 102-51 102-72 93-93 72-98 51-106 29-101 13z"; + break; + case 4: + m_name = "Line Arrow"; + m_viewBox = "0 0 1122 2243"; + m_d = "m0 2108v17 17l12 42 30 34 38 21 43 4 29-8 30-21 25-26 13-34 343-1532 339 1520 13 42 29 34 39 21 42 4 42-12 34-30 21-42v-39-12l-4 4-440-1998-9-42-25-39-38-25-43-8-42 8-38 25-26 39-8 42z"; + break; + case 5: + m_name = "Dimension Lines"; + m_viewBox = "0 0 836 110"; + m_d = "m0 0h278 278 280v36 36 38h-278-278-280v-36-36z"; + break; + case 6: + case 7: + m_name = "Double Arrow"; + m_viewBox = "0 0 1131 1918"; + m_d = "m737 1131h394l-564-1131-567 1131h398l-398 787h1131z"; + break; + } +} + +void MarkerStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement marker = doc.createElement( "draw:marker" ); + marker.setAttribute( "draw:name", m_name ); + if ( !m_viewBox.isNull() ) + marker.setAttribute( "svg:viewBox", m_viewBox ); + if ( !m_d.isNull() ) + marker.setAttribute( "svg:d", m_d ); + + e.appendChild( marker ); +} + +HatchStyle::HatchStyle( int style, QString & color ) +{ + m_color = color; + + switch ( style ) + { + case 9: + m_name = m_color + " 0 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "0"; + break; + case 10: + m_name = m_color + " 90 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "900"; + break; + case 11: + m_name = m_color + " Crossed 0 Degrees"; + m_style = "double"; + m_distance = "0.076cm"; + m_rotation = "900"; + break; + case 12: + m_name = m_color + " 45 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "450"; + break; + case 13: + m_name = m_color + " -45 Degrees"; + m_style = "single"; + m_distance = "0.102cm"; + m_rotation = "3150"; + break; + case 14: + m_name = m_color + " Crossed 45 Degrees"; + m_style = "double"; + m_distance = "0.076cm"; + m_rotation = "450"; + break; + } +} + +void HatchStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement hatch = doc.createElement( "draw:hatch" ); + hatch.setAttribute( "draw:name", m_name ); + if ( !m_style.isNull() ) + hatch.setAttribute( "draw:style", m_style ); + if ( !m_color.isNull() ) + hatch.setAttribute( "draw:color", m_color ); + if ( !m_distance.isNull() ) + hatch.setAttribute( "draw:distance", m_distance ); + if ( !m_rotation.isNull() ) + hatch.setAttribute( "draw:rotation", m_rotation ); + + e.appendChild( hatch ); +} + +FillImageStyle::FillImageStyle( QString & name ) +{ + +} + +void FillImageStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + +} + +PageMasterStyle::PageMasterStyle( QDomElement & e, const uint index ) +{ + QDomNode borders = e.namedItem( "PAPERBORDERS" ); + QDomElement b = borders.toElement(); + + m_name = QString( "PM%1" ).arg( index ); + m_style = QString( "Default%1" ).arg( index ); + m_margin_top = StyleFactory::toCM( b.attribute( "ptTop" ) ); + m_margin_bottom = StyleFactory::toCM( b.attribute( "ptBottom" ) ); + m_margin_left = StyleFactory::toCM( b.attribute( "ptLeft" ) ); + m_margin_right = StyleFactory::toCM( b.attribute( "ptRight" ) ); + m_page_width = StyleFactory::toCM( e.attribute( "ptWidth" ) ); + m_page_height = StyleFactory::toCM( e.attribute( "ptHeight" ) ); + m_orientation = "landscape"; +} + +void PageMasterStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:page-master" ); + style.setAttribute( "style:name", "PM0" ); + + QDomElement properties = doc.createElement( "style:properties" ); + properties.setAttribute( "fo:margin-top", m_margin_top ); + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + properties.setAttribute( "fo:margin-left", m_margin_left ); + properties.setAttribute( "fo:margin-right", m_margin_right ); + properties.setAttribute( "fo:page-width", m_page_width ); + properties.setAttribute( "fo:page-height", m_page_height ); + properties.setAttribute( "fo:print-orientation", m_orientation ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool PageMasterStyle::operator==( const PageMasterStyle & pageMasterStyle ) const +{ + return ( m_margin_top == pageMasterStyle.m_margin_top && + m_margin_bottom == pageMasterStyle.m_margin_bottom && + m_margin_left == pageMasterStyle.m_margin_left && + m_margin_right == pageMasterStyle.m_margin_right && + m_page_width == pageMasterStyle.m_page_width && + m_page_height == pageMasterStyle.m_page_height && + m_orientation == pageMasterStyle.m_orientation ); +} + +PageStyle::PageStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ) +{ + QDomElement backMaster = e.namedItem( "BACKMASTER" ).toElement(); + if( !backMaster.isNull()) + { + int tmp=0; + if(backMaster.hasAttribute("displayBackground")) + tmp = backMaster.attribute("displayBackground").toInt(); + m_bg_visible = (tmp==1) ? "true" : "false"; + tmp = 0; + if(backMaster.hasAttribute("displayMasterPageObject")) + tmp = backMaster.attribute("displayMasterPageObject").toInt(); + m_bg_objects_visible = (tmp==1) ? "true" : "false"; + } + else + { + m_bg_visible = "true"; + m_bg_objects_visible = "true"; + } + + m_name = QString( "dp%1" ).arg( index ); + + // check if this is an empty page tag + if ( !e.hasChildNodes() ) + return; + + QDomElement backType = e.namedItem( "BACKTYPE" ).toElement(); + if ( backType.isNull() || backType.attribute( "value" ) == "0" ) + { + // color + QDomElement bcType = e.namedItem( "BCTYPE" ).toElement(); + if ( bcType.isNull() || bcType.attribute( "value" ) == "0" ) + { + // plain + QDomElement backColor = e.namedItem( "BACKCOLOR1" ).toElement(); + m_fill = "solid"; + m_fill_color = backColor.attribute( "color" ); + } + else + { + // gradient + m_fill = "gradient"; + m_fill_gradient_name = styleFactory->createGradientStyle( e ); + } + } + else + { + // picture + } + + QDomElement pageDuration = e.namedItem( "PGTIMER" ).toElement(); + if ( !pageDuration.isNull() ) + { + + QTime time; + time = time.addSecs( pageDuration.attribute("timer").toInt() ); + QString hours( QString::number( time.hour() ).rightJustify( 2, '0' ) ); + QString ms( QString::number( time.minute() ).rightJustify( 2, '0' ) ); + QString sec( QString::number( time.second() ).rightJustify( 2, '0' ) ); + + + //ISO8601 chapter 5.5.3.2 + //QDate doesn't encode it as this format. + m_page_duration = QString( "PT%1H%2M%3S" ).arg( hours ).arg( ms ).arg( sec ); + } + + QDomElement pageEffect = e.namedItem( "PGEFFECT" ).toElement(); + if ( !pageEffect.isNull() ) + { + int tmp=0; + if(pageEffect.hasAttribute("value")) + tmp=pageEffect.attribute("value").toInt(); + kdDebug(30518)<<" tmp :"<= 2 && style <= 5 ) + { + m_stroke = "dash"; + m_stroke_dash = styleFactory->createStrokeDashStyle( style ); + } + else + m_stroke = "none"; + } + + if ( !brush.isNull() ) + { + QDomElement b = brush.toElement(); + m_fill_color = b.attribute( "color" ); + + int style = b.attribute( "style" ).toInt(); + if ( style == 1 ) + m_fill = "solid"; + else if ( style >= 9 && style <= 14 ) + { + m_fill = "hatch"; + m_fill_hatch_name = styleFactory->createHatchStyle( style, m_fill_color ); + } + else if ( style >= 2 && style <= 8 ) + { + if ( style == 2 ) + m_transparency = "94%"; + else if ( style == 3 ) + m_transparency = "88%"; + else if ( style == 4 ) + m_transparency = "63%"; + else if ( style == 5 ) + m_transparency = "50%"; + else if ( style == 6 ) + m_transparency = "37%"; + else if ( style == 7 ) + m_transparency = "12%"; + else if ( style == 8 ) + m_transparency = "6%"; + } + } + else if ( !gradient.isNull() ) + { + QDomElement g = gradient.toElement(); + m_fill = "gradient"; + m_fill_gradient_name = styleFactory->createGradientStyle( g ); + } + else + m_fill = "none"; + + if ( !linebegin.isNull() ) + { + QDomElement lb = linebegin.toElement(); + m_marker_start_width = "0.25cm"; + + int style = lb.attribute( "value" ).toInt(); + m_marker_start = styleFactory->createMarkerStyle( style ); + } + + if ( !lineend.isNull() ) + { + QDomElement le = lineend.toElement(); + m_marker_end_width = "0.25cm"; + + int style = le.attribute( "value" ).toInt(); + m_marker_end = styleFactory->createMarkerStyle( style ); + } + + if ( !shadow.isNull() ) + { + QDomElement s = shadow.toElement(); + m_shadow = "visible"; + m_shadow_color = s.attribute( "color" ); + + int direction = s.attribute( "direction" ).toInt(); + QString distance = StyleFactory::toCM( s.attribute( "distance" ) ); + switch ( direction ) + { + case 1: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = "-" + distance; + break; + case 2: + m_shadow_offset_x = "0cm"; + m_shadow_offset_y = "-" + distance; + break; + case 3: + m_shadow_offset_x = distance; + m_shadow_offset_y = "-" + distance; + break; + case 4: + m_shadow_offset_x = distance; + m_shadow_offset_y = "0cm"; + break; + case 5: + m_shadow_offset_x = distance; + m_shadow_offset_y = distance; + break; + case 6: + m_shadow_offset_x = "0cm"; + m_shadow_offset_y = distance; + break; + case 7: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = distance; + break; + case 8: + m_shadow_offset_x = "-" + distance; + m_shadow_offset_y = "0cm"; + break; + } + } +} + +GraphicStyle::GraphicStyle( const char * name, + const char * stroke, const char * stroke_color, + const char * stroke_width, const char * shadow, + const char * shadow_offset_x, const char * shadow_offset_y, + const char * shadow_color, const char * margin_left, + const char * margin_right, const char * margin_top, + const char * margin_bottom, const char * color, + const char * text_outline, const char * text_crossing_out, + const char * font_family, const char * font_size, + const char * font_style, const char * text_shadow, + const char * text_underline, const char * font_weight, + const char * line_height, const char * text_align, + const char * fill, const char * fill_color, + const char * enable_numbering ) + : m_name( name ) + , m_stroke( stroke ) + , m_stroke_color( stroke_color ) + , m_stroke_width( stroke_width ) + , m_shadow( shadow ) + , m_shadow_offset_x( shadow_offset_x ) + , m_shadow_offset_y( shadow_offset_y ) + , m_shadow_color( shadow_color ) + , m_margin_left( margin_left ) + , m_margin_right( margin_right ) + , m_margin_top( margin_top ) + , m_margin_bottom( margin_bottom ) + , m_color( color ) + , m_text_outline( text_outline ) + , m_text_crossing_out( text_crossing_out ) + , m_font_family( font_family ) + , m_font_size( font_size ) + , m_font_style( font_style ) + , m_text_shadow( text_shadow ) + , m_text_underline( text_underline ) + , m_font_weight( font_weight ) + , m_line_height( line_height ) + , m_text_align( text_align ) + , m_fill( fill ) + , m_fill_color( fill_color ) + , m_enable_numbering( enable_numbering ) +{ +} + + +void GraphicStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "graphics" ); + if ( m_name != "standard" ) + style.setAttribute( "style:parent-style-name", "standard" ); + + QDomElement properties = doc.createElement( "style:properties" ); + if ( !m_stroke.isNull() ) + properties.setAttribute( "draw:stroke", m_stroke ); + if ( !m_stroke_dash.isNull() ) + properties.setAttribute( "draw:stroke-dash", m_stroke_dash ); + if ( !m_stroke_color.isNull() ) + properties.setAttribute( "svg:stroke-color", m_stroke_color ); + if ( !m_stroke_width.isNull() ) + properties.setAttribute( "svg:stroke-width", m_stroke_width ); + if ( !m_shadow.isNull() ) + properties.setAttribute( "draw:shadow", m_shadow ); + if ( !m_shadow_offset_x.isNull() ) + properties.setAttribute( "draw:shadow-offset-x", m_shadow_offset_x ); + if ( !m_shadow_offset_y.isNull() ) + properties.setAttribute( "draw:shadow-offset-y", m_shadow_offset_y ); + if ( !m_shadow_color.isNull() ) + properties.setAttribute( "draw:shadow-color", m_shadow_color ); + if ( !m_margin_left.isNull() ) + properties.setAttribute( "fo:margin-left", m_margin_left ); + if ( !m_margin_right.isNull() ) + properties.setAttribute( "fo:margin-right", m_margin_right ); + if ( !m_margin_top.isNull() ) + properties.setAttribute( "fo:margin-top", m_margin_top ); + if ( !m_margin_bottom.isNull() ) + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + if ( !m_color.isNull() ) + properties.setAttribute( "fo:color", m_color ); + if ( !m_text_outline.isNull() ) + properties.setAttribute( "style:text-outline", m_text_outline ); + if ( !m_text_crossing_out.isNull() ) + properties.setAttribute( "style:text-crossing-out", m_text_crossing_out ); + if ( !m_font_family.isNull() ) + properties.setAttribute( "fo:font-family", m_font_family ); + if ( !m_font_size.isNull() ) + properties.setAttribute( "fo:font-size", m_font_size ); + if ( !m_font_style.isNull() ) + properties.setAttribute( "fo:font-style", m_font_style ); + if ( !m_text_shadow.isNull() ) + properties.setAttribute( "fo:text-shadow", m_text_shadow ); + if ( !m_text_underline.isNull() ) + properties.setAttribute( "style:text-underline", m_text_underline ); + if ( !m_font_weight.isNull() ) + properties.setAttribute( "fo:font-weight", m_font_weight ); + if ( !m_line_height.isNull() ) + properties.setAttribute( "fo:line-height", m_line_height ); + if ( !m_text_align.isNull() ) + properties.setAttribute( "fo:text-align", m_text_align ); + if ( !m_fill.isNull() ) + properties.setAttribute( "draw:fill", m_fill ); + if ( !m_fill_color.isNull() ) + properties.setAttribute( "draw:fill-color", m_fill_color ); + if ( !m_fill_hatch_name.isNull() ) + properties.setAttribute( "draw:fill-hatch-name", m_fill_hatch_name ); + if ( !m_enable_numbering.isNull() ) + properties.setAttribute( "text:enable-numbering", m_enable_numbering ); + if ( !m_marker_start.isNull() ) + properties.setAttribute( "draw:marker-start", m_marker_start ); + if ( !m_marker_start_width.isNull() ) + properties.setAttribute( "draw:marker-start-width", m_marker_start_width ); + if ( !m_marker_end.isNull() ) + properties.setAttribute( "draw:marker-end", m_marker_end ); + if ( !m_marker_end_width.isNull() ) + properties.setAttribute( "draw:marker-end-width", m_marker_end_width ); + if ( !m_fill_gradient_name.isNull() ) + properties.setAttribute( "draw:fill-gradient-name", m_fill_gradient_name ); + if ( !m_transparency.isNull() ) + properties.setAttribute( "draw:transparency", m_transparency ); + if ( !m_textAlignment.isNull() ) + properties.setAttribute( "draw:textarea-vertical-align", m_textAlignment ); + if ( !m_textMarginLeft.isNull() ) + properties.setAttribute( "fo:padding-left", m_textMarginLeft ); + if ( !m_textMarginBottom.isNull() ) + properties.setAttribute( "fo:padding-bottom", m_textMarginBottom ); + if ( !m_textMarginTop.isNull() ) + properties.setAttribute( "fo:padding-top", m_textMarginTop ); + if ( !m_textMarginRight.isNull() ) + properties.setAttribute( "fo:padding-right", m_textMarginRight ); + + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool GraphicStyle::operator==( const GraphicStyle & graphicStyle ) const +{ + return ( m_stroke == graphicStyle.m_stroke && + m_stroke_dash == graphicStyle.m_stroke_dash && + m_stroke_color == graphicStyle.m_stroke_color && + m_stroke_width == graphicStyle.m_stroke_width && + m_shadow == graphicStyle.m_shadow && + m_shadow_offset_x == graphicStyle.m_shadow_offset_x && + m_shadow_offset_y == graphicStyle.m_shadow_offset_y && + m_shadow_color == graphicStyle.m_shadow_color && + m_margin_left == graphicStyle.m_margin_left && + m_margin_right == graphicStyle.m_margin_right && + m_margin_top == graphicStyle.m_margin_top && + m_margin_bottom == graphicStyle.m_margin_bottom && + m_color == graphicStyle.m_color && + m_text_outline == graphicStyle.m_text_outline && + m_text_crossing_out == graphicStyle.m_text_crossing_out && + m_font_family == graphicStyle.m_font_family && + m_font_size == graphicStyle.m_font_size && + m_font_style == graphicStyle.m_font_style && + m_text_shadow == graphicStyle.m_text_shadow && + m_text_underline == graphicStyle.m_text_underline && + m_font_weight == graphicStyle.m_font_weight && + m_line_height == graphicStyle.m_line_height && + m_text_align == graphicStyle.m_text_align && + m_fill == graphicStyle.m_fill && + m_fill_color == graphicStyle.m_fill_color && + m_fill_hatch_name == graphicStyle.m_fill_hatch_name && + m_enable_numbering == graphicStyle.m_enable_numbering && + m_marker_start == graphicStyle.m_marker_start && + m_marker_start_width == graphicStyle.m_marker_start_width && + m_marker_end == graphicStyle.m_marker_end && + m_marker_end_width == graphicStyle.m_marker_end_width && + m_fill_gradient_name == graphicStyle.m_fill_gradient_name && + m_transparency == graphicStyle.m_transparency && + m_textAlignment == graphicStyle.m_textAlignment && + m_textMarginLeft == graphicStyle.m_textMarginLeft && + m_textMarginBottom == graphicStyle.m_textMarginBottom && + m_textMarginTop == graphicStyle.m_textMarginTop && + m_textMarginRight == graphicStyle.m_textMarginRight); +} + +ParagraphStyle::ParagraphStyle( QDomElement & e, const uint index ) +{ + // some defaults that may be overwritten + m_margin_left = "0cm"; + m_margin_right = "0cm"; + m_text_indent = "0cm"; + + QDomNode shadow = e.namedItem( "SHADOW" ); + QDomNode indents = e.namedItem( "INDENTS" ); + QDomNode offsets = e.namedItem( "OFFSETS" ); + QDomNode leftBorder = e.namedItem( "LEFTBORDER" ); + QDomNode rightBorder = e.namedItem( "RIGHTBORDER" ); + QDomNode topBorder = e.namedItem( "TOPBORDER" ); + QDomNode bottomBorder = e.namedItem( "BOTTOMBORDER" ); + QDomNode lineSpacing = e.namedItem( "LINESPACING" ); + QDomNode counter = e.namedItem( "COUNTER" ); + + m_name = QString( "P%1" ).arg( index ); + if ( e.hasAttribute( "align" ) ) + { + int align = e.attribute( "align" ).toInt(); + switch ( align ) + { + case 0: // left + m_text_align = "start"; + break; + case 2: // right + m_text_align = "end"; + break; + case 4: // center + m_text_align = "center"; + break; + case 8: // justify + m_text_align = "justify"; + break; + } + } + + if ( !shadow.isNull() ) + { + QDomElement s = shadow.toElement(); + QString distance = QString( "%1pt" ).arg( s.attribute( "distance" ) ); + m_text_shadow = distance + " " + distance; + } + + if ( !indents.isNull() ) + { + QDomElement i = indents.toElement(); + m_margin_left = StyleFactory::toCM( i.attribute( "left" ) ); + m_margin_right = StyleFactory::toCM( i.attribute( "right" ) ); + m_text_indent = StyleFactory::toCM( i.attribute( "first" ) ); + } + + if ( !offsets.isNull() ) + { + QDomElement o = offsets.toElement(); + m_margin_top = StyleFactory::toCM( o.attribute( "before" ) ); + m_margin_bottom = StyleFactory::toCM( o.attribute( "after" ) ); + } + + if ( !leftBorder.isNull() ) + m_border_left = parseBorder( leftBorder.toElement() ); + if ( !rightBorder.isNull() ) + m_border_right = parseBorder( rightBorder.toElement() ); + if ( !topBorder.isNull() ) + m_border_top = parseBorder( topBorder.toElement() ); + if ( !bottomBorder.isNull() ) + m_border_bottom = parseBorder( bottomBorder.toElement() ); + + if ( !lineSpacing.isNull() ) + { + QDomElement l = lineSpacing.toElement(); + QString type = l.attribute( "type" ); + + if ( type == "single" ) + m_line_height = "100%"; + else if ( type == "oneandhalf" ) + m_line_height = "150%"; + else if ( type == "double" ) + m_line_height = "200%"; + else if ( type == "multiple" ) + m_line_height = QString( "%1%" ).arg( l.attribute( "spacingvalue" ).toInt() * 100 ); + else if ( type == "custom" ) + m_line_spacing = StyleFactory::toCM( l.attribute( "spacingvalue" ) ); + else if ( type == "atleast" ) + m_line_height_at_least = StyleFactory::toCM( l.attribute( "spacingvalue" ) ); + } + + if ( !counter.isNull() ) + m_enable_numbering = "true"; +} + +void ParagraphStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "style:style" ); + style.setAttribute( "style:name", m_name ); + style.setAttribute( "style:family", "paragraph" ); + + QDomElement properties = doc.createElement( "style:properties" ); + if ( !m_margin_left.isNull() ) + properties.setAttribute( "fo:margin-left", m_margin_left ); + if ( !m_margin_right.isNull() ) + properties.setAttribute( "fo:margin-right", m_margin_right ); + if ( !m_text_indent.isNull() ) + properties.setAttribute( "fo:text-indent", m_text_indent ); + if ( !m_text_align.isNull() ) + properties.setAttribute( "fo:text-align", m_text_align ); + if ( !m_enable_numbering.isNull() ) + properties.setAttribute( "text:enable-numbering", m_enable_numbering ); + if ( !m_text_shadow.isNull() ) + properties.setAttribute( "fo:text-shadow", m_text_shadow ); + if ( !m_margin_top.isNull() ) + properties.setAttribute( "fo:margin-top", m_margin_top ); + if ( !m_margin_bottom.isNull() ) + properties.setAttribute( "fo:margin-bottom", m_margin_bottom ); + if ( !m_border_left.isNull() ) + properties.setAttribute( "fo:border-left", m_border_left ); + if ( !m_border_right.isNull() ) + properties.setAttribute( "fo:border-right", m_border_right ); + if ( !m_border_top.isNull() ) + properties.setAttribute( "fo:border-top", m_border_top ); + if ( !m_border_bottom.isNull() ) + properties.setAttribute( "fo:border-bottom", m_border_bottom ); + if ( !m_line_height.isNull() ) + properties.setAttribute( "fo:line-height", m_line_height ); + if ( !m_line_height_at_least.isNull() ) + properties.setAttribute( "style:line-height-at-least", m_line_height_at_least ); + if ( !m_line_spacing.isNull() ) + properties.setAttribute( "style:line-spacing", m_line_spacing ); + + style.appendChild( properties ); + e.appendChild( style ); +} + +bool ParagraphStyle::operator==( const ParagraphStyle & paragraphStyle ) const +{ + return ( m_margin_left == paragraphStyle.m_margin_left && + m_margin_right == paragraphStyle.m_margin_right && + m_text_indent == paragraphStyle.m_text_indent && + m_text_align == paragraphStyle.m_text_align && + m_enable_numbering == paragraphStyle.m_enable_numbering && + m_text_shadow == paragraphStyle.m_text_shadow && + m_margin_top == paragraphStyle.m_margin_top && + m_margin_bottom == paragraphStyle.m_margin_bottom && + m_border_left == paragraphStyle.m_border_left && + m_border_right == paragraphStyle.m_border_right && + m_border_top == paragraphStyle.m_border_top && + m_border_bottom == paragraphStyle.m_border_bottom && + m_line_height == paragraphStyle.m_line_height && + m_line_height_at_least == paragraphStyle.m_line_height_at_least && + m_line_spacing == paragraphStyle.m_line_spacing ); +} + +QString ParagraphStyle::parseBorder( QDomElement e ) +{ + QString style; + int _style = e.attribute( "style" ).toInt(); + if ( _style == 5 ) + style = "double"; + else + style = "solid"; + + QString width = StyleFactory::toCM( e.attribute( "width" ) ); + + QColor color( e.attribute( "red" ).toInt(), + e.attribute( "green" ).toInt(), + e.attribute( "blue" ).toInt() ); + + return QString( "%1 %2 %3" ).arg( width ).arg( style ).arg( color.name() ); +} + +ListStyle::ListStyle( QDomElement & e, const uint index ) +{ + // setting some default values + m_min_label_width = 0.6; + m_color = "#000000"; + m_font_size = "100%"; + + m_name = QString( "L%1" ).arg( index ); + + if ( e.hasAttribute( "type" ) ) + { + int type = e.attribute( "type" ).toInt(); + switch ( type ) + { + case 1: // arabic numbers + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "1"; + break; + case 2: // lower alphabetical + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "a"; + break; + case 3: // upper alphabetical + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "A"; + break; + case 4: // lower roman + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "i"; + break; + case 5: // upper roman + m_listLevelStyle = LLS_NUMBER; + m_num_suffix = "."; + m_num_format = "I"; + break; + case 6: // custom + m_listLevelStyle = LLS_BULLET; + if ( e.hasAttribute( "text" ) ) + m_bullet_char = e.attribute( "text" ); + break; + case 8: // circle bullet + m_listLevelStyle = LLS_BULLET; + break; + case 9: // square bullet + m_listLevelStyle = LLS_BULLET; + break; + case 10: // disc bullet + m_listLevelStyle = LLS_BULLET; + break; + case 11: // box bullet + m_listLevelStyle = LLS_BULLET; + break; + } + } + + if ( e.hasAttribute( "bulletfont" ) ) + m_font_family = e.attribute( "bulletfont" ); +} + +void ListStyle::toXML( QDomDocument & doc, QDomElement & e ) const +{ + QDomElement style = doc.createElement( "text:list-style" ); + style.setAttribute( "style:name", m_name ); + + for ( int level = 1; level <= 10; level++ ) + { + QDomElement listLevelStyle; + if ( m_listLevelStyle == LLS_NUMBER ) + { + listLevelStyle = doc.createElement( "text:list-level-style-number" ); + listLevelStyle.setAttribute( "text:level", level ); + if ( !m_num_suffix.isNull() ) + listLevelStyle.setAttribute( "style:num-suffix", m_num_suffix ); + if ( !m_num_format.isNull() ) + listLevelStyle.setAttribute( "style:num-format", m_num_format ); + } + else + { + listLevelStyle = doc.createElement( "text:list-level-style-bullet" ); + listLevelStyle.setAttribute( "text:level", level ); + if ( !m_bullet_char.isNull() ) + listLevelStyle.setAttribute( "text:bullet-char", m_bullet_char ); + } + + QDomElement properties = doc.createElement( "style:properties" ); + if ( level > 1 ) + { + properties.setAttribute( "text:min-label-width", + QString( "%1cm" ).arg( m_min_label_width ) ); + properties.setAttribute( "text:space-before", + QString( "%1cm" ).arg( m_min_label_width * ( level - 1 ) ) ); + } + + if ( !m_color.isNull() ) + properties.setAttribute( "fo:color", m_color ); + if ( !m_font_size.isNull() ) + properties.setAttribute( "fo:font-size", m_font_size ); + if ( !m_font_family.isNull() ) + properties.setAttribute( "fo:font-family", m_font_family ); + + listLevelStyle.appendChild( properties ); + style.appendChild( listLevelStyle ); + } + e.appendChild( style ); +} + +bool ListStyle::operator==( const ListStyle & listStyle ) const +{ + return ( m_listLevelStyle == listStyle.m_listLevelStyle && + m_num_suffix == listStyle.m_num_suffix && + m_num_format == listStyle.m_num_format && + m_bullet_char == listStyle.m_bullet_char && + m_min_label_width == listStyle.m_min_label_width && + m_color == listStyle.m_color && + m_font_size == listStyle.m_font_size && + m_font_family == listStyle.m_font_family ); +} diff --git a/filters/kpresenter/ooimpress/stylefactory.h b/filters/kpresenter/ooimpress/stylefactory.h new file mode 100644 index 000000000..9de6a5488 --- /dev/null +++ b/filters/kpresenter/ooimpress/stylefactory.h @@ -0,0 +1,282 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Percy Leonhardt + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + + +#ifndef STYLEFACTORY_H +#define STYLEFACTORY_H + +#include +#include + +#include + +class StyleFactory; + +class StrokeDashStyle +{ +public: + StrokeDashStyle( int style ); + ~StrokeDashStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + StrokeDashStyle() {}; + + QString m_name, m_style, m_dots1, m_dots2, m_dots1_length, m_dots2_length, + m_distance; +}; + +class GradientStyle +{ +public: + GradientStyle( QDomElement & gradient, int index ); + ~GradientStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + GradientStyle() {}; + + QString m_name, m_style, m_cx, m_cy, m_start_color, m_end_color, + m_start_intensity, m_end_intensity, m_angle, m_border; +}; + +class MarkerStyle +{ +public: + MarkerStyle( int style ); + ~MarkerStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + MarkerStyle() {}; + + QString m_name, m_viewBox, m_d; +}; + +class HatchStyle +{ +public: + HatchStyle( int style, QString & color ); + ~HatchStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + QString name() const { return m_name; }; + +private: + HatchStyle() {}; + + QString m_name, m_style, m_color, m_distance, m_rotation; +}; + +class FillImageStyle +{ +public: + FillImageStyle( QString & name ); + ~FillImageStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + +private: + FillImageStyle() {}; + + QString m_name, m_href, m_type, m_show, m_actuate; +}; + +class PageMasterStyle +{ +public: + PageMasterStyle( QDomElement & e, const uint index ); + ~PageMasterStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const PageMasterStyle & pageMasterStyle ) const; + QString name() const { return m_name; }; + QString style() const { return m_style; }; + +private: + PageMasterStyle() {}; + + QString m_name, m_page_width, m_page_height, m_orientation, m_style; + QString m_margin_top, m_margin_bottom, m_margin_left, m_margin_right; +}; + +class PageStyle +{ +public: + PageStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ); + ~PageStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const PageStyle & pageStyle ) const; + QString name() const { return m_name; }; + +private: + PageStyle() {}; + + QString m_name, m_bg_visible, m_bg_objects_visible, m_fill, m_fill_color, + m_fill_image_name, m_fill_image_width, m_fill_image_height, + m_fill_image_ref_point, m_fill_gradient_name, m_repeat, m_page_effect, + m_page_duration; +}; + +class TextStyle +{ +public: + TextStyle( QDomElement & e, const uint index ); + ~TextStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const TextStyle & textStyle ) const; + QString name() const { return m_name; }; + +private: + TextStyle() {}; + + QString m_name, m_font_size, m_font_family, m_font_family_generic, + m_color, m_font_pitch, m_font_style, m_font_weight, m_text_shadow, + m_text_underline, m_text_underline_color, m_text_crossing_out; +}; + +class GraphicStyle +{ +public: + GraphicStyle( StyleFactory * styleFactory, QDomElement & e, const uint index ); + GraphicStyle( const char * name, + const char * stroke, const char * stroke_color, + const char * stroke_width, const char * shadow, + const char * shadow_offset_x, const char * shadow_offset_y, + const char * shadow_color, const char * margin_left, + const char * margin_right, const char * margin_top, + const char * margin_bottom, const char * color, + const char * text_outline, const char * text_crossing_out, + const char * font_family, const char * font_size, + const char * font_style, const char * text_shadow, + const char * text_underline, const char * font_weight, + const char * line_height, const char * text_align, + const char * fill, const char * fill_color, + const char * enable_numbering ); + ~GraphicStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const GraphicStyle & graphicStyle ) const; + QString name() const { return m_name; }; + +private: + GraphicStyle() {}; + + QString m_name, m_stroke, m_stroke_color, m_stroke_width, m_shadow, + m_shadow_offset_x, m_shadow_offset_y, m_shadow_color, m_margin_left, + m_margin_right, m_margin_top, m_margin_bottom, m_color, m_text_outline, + m_text_crossing_out, m_font_family, m_font_size, m_font_style, + m_text_shadow, m_text_underline, m_font_weight, m_line_height, + m_text_align, m_fill, m_fill_color, m_enable_numbering, m_stroke_dash, + m_fill_hatch_name, m_marker_start, m_marker_start_width, + m_marker_end, m_marker_end_width, m_fill_gradient_name, m_transparency, m_textAlignment, + m_textMarginLeft, m_textMarginBottom, m_textMarginTop, m_textMarginRight; +}; + +class ParagraphStyle +{ +public: + ParagraphStyle( QDomElement & e, const uint index ); + ~ParagraphStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const ParagraphStyle & paragraphStyle ) const; + QString name() const { return m_name; }; + +private: + ParagraphStyle() {}; + QString parseBorder( QDomElement e ); + + QString m_name, m_margin_left, m_margin_right, m_text_indent, m_text_align, + m_enable_numbering, m_text_shadow, m_margin_top, m_margin_bottom, + m_border_left, m_border_right, m_border_top, m_border_bottom, + m_line_height, m_line_height_at_least, m_line_spacing; +}; + +class ListStyle +{ +public: + ListStyle( QDomElement & e, const uint index ); + ~ListStyle() {}; + + void toXML( QDomDocument & doc, QDomElement & e ) const; + bool operator==( const ListStyle & listStyle ) const; + QString name() const { return m_name; }; + +private: + ListStyle() {}; + + typedef enum { + LLS_NUMBER, + LLS_BULLET + } list_level_style_t; + + float m_min_label_width; + list_level_style_t m_listLevelStyle; + QString m_name, m_num_suffix, m_num_format, m_bullet_char, m_color, + m_font_size, m_font_family; +}; + +class StyleFactory +{ +public: + StyleFactory(); + ~StyleFactory(); + + void addOfficeStyles( QDomDocument & doc, QDomElement & styles ); + void addOfficeMaster( QDomDocument & doc, QDomElement & master ); + void addOfficeAutomatic( QDomDocument & doc, QDomElement & automatic ); + void addAutomaticStyles( QDomDocument & doc, QDomElement & autoStyles ); + + QString createStrokeDashStyle( int style ); + QString createGradientStyle( QDomElement & gradient ); + QString createMarkerStyle( int style ); + QString createHatchStyle( int style, QString & color ); + QString createListStyle( QDomElement & e ); + QString createPageStyle( QDomElement & e ); + QString createTextStyle( QDomElement & e ); + QString createGraphicStyle( QDomElement & e ); + QString createParagraphStyle( QDomElement & e ); + QString createPageMasterStyle( QDomElement & e ); + + static QString toCM( const QString & point ); + +private: + QPtrList m_strokeDashStyles; + QPtrList m_gradientStyles; + QPtrList m_hatchStyles; + QPtrList m_markerStyles; + QPtrList m_fillImageStyles; + QPtrList m_listStyles; + QPtrList m_pageStyles; + QPtrList m_textStyles; + QPtrList m_graphicStyles; + QPtrList m_paragraphStyles; + QPtrList m_pageMasterStyles; +}; + +#endif diff --git a/filters/kpresenter/png/Makefile.am b/filters/kpresenter/png/Makefile.am new file mode 100644 index 000000000..0568bfcfe --- /dev/null +++ b/filters/kpresenter/png/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresenterpngexport.la + +libkpresenterpngexport_la_SOURCES = pngexport.cpp +libkpresenterpngexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresenterpngexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + pngexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_png_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/png/kpresenter_png_export.desktop b/filters/kpresenter/png/kpresenter_png_export.desktop new file mode 100644 index 000000000..d6ec865f4 --- /dev/null +++ b/filters/kpresenter/png/kpresenter_png_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KPresenter PNG Export Filter +Name[bg]=Филтър за експортиране от Kpresenter в PNG +Name[br]=Sil ezporzh PNG evit KPresenter +Name[ca]=Filtre d'exportació PNG per a KPresenter +Name[cy]=Hidlen Allforio PNG KPresenter +Name[da]=KPresenter PNG-eksportfilter +Name[de]=KPresenter PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του KPresenter +Name[eo]=KPresenter PNG-eksportfiltrilo +Name[es]=Filtro de exportación a PNG para KPresenter +Name[et]=KPresenteri PNG ekspordifilter +Name[fa]=پالایۀ صادرات KPresenter PNG +Name[fi]=KPresenter PNG -vientisuodin +Name[fr]=Filtre d'exportation PNG de KPresenter +Name[fy]=PMG-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála PNG KPresenter +Name[gl]=Filtro de Exportación de PNG para KPresenter +Name[he]=KPresenter PNG מסנן יצוא +Name[hr]=KPresenter PNG filtar izvoza +Name[hu]=KPresenter PNG exportszűrő +Name[is]=KPresenter PNG útflutningssía +Name[it]=Filtro di esportazione PNG per KPresenter +Name[ja]=KPresenter PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ KPresenter +Name[lt]=KPresenter PNG eksportavimo filtras +Name[lv]=KPresenter PNG eksporta filtrs +Name[nb]=PNG-eksportfilter for KPresenter +Name[nds]=PNG-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता पीएनजी निर्यात फिल्टर +Name[nl]=KPresenter PNG Exportfilter +Name[pl]=Filtr eksportu do formatu PNG dla KPresenter +Name[pt]=Filtro de Exportação de PNG para o KPresenter +Name[pt_BR]=Filtro de Exportação de PNG para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в PNG +Name[se]=KPresenter PNG-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter PNG +Name[sl]=Izvozni filter PNG za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у PNG +Name[sr@Latn]=KPresenter-ov filter za izvoz u PNG +Name[sv]=Kpresenter PNG-exportfilter +Name[uk]=Фільтр експорту PNG для KPresenter +Name[uz]=KPresenter PNG eksport filteri +Name[uz@cyrillic]=KPresenter PNG экспорт филтери +Name[zh_CN]=KPresenter PNG 导出过滤器 +Name[zh_TW]=KPresenter PNG 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/png +X-KDE-Weight=1 +X-KDE-Library=libkpresenterpngexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/png/pngexport.cpp b/filters/kpresenter/png/pngexport.cpp new file mode 100644 index 000000000..571e78645 --- /dev/null +++ b/filters/kpresenter/png/pngexport.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "pngexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory PngExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresenterpngexport, PngExportFactory( "pngexport" ) ) + +PngExport::PngExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +PngExport::~PngExport() +{ +} + +bool PngExport::extraImageAttribute() +{ + bool ret = false; + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + ret = true; + kdDebug() << "PNG Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; + return ret; +} + +const char * PngExport::exportFormat() +{ + return "image/png"; +} + +bool PngExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "PNG" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "PNG Export Error" ) ); + } + return ret; +} + + +#include "pngexport.moc" + diff --git a/filters/kpresenter/png/pngexport.h b/filters/kpresenter/png/pngexport.h new file mode 100644 index 000000000..8856dbd87 --- /dev/null +++ b/filters/kpresenter/png/pngexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __PNGEXPORT_H__ +#define __PNGEXPORT_H__ + +#include "imageexport.h" + +class PngExport : public ImageExport +{ + Q_OBJECT + +public: + PngExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~PngExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __PNGEXPORT_H__ + diff --git a/filters/kpresenter/powerpoint/Makefile.am b/filters/kpresenter/powerpoint/Makefile.am new file mode 100644 index 000000000..cd80ba13d --- /dev/null +++ b/filters/kpresenter/powerpoint/Makefile.am @@ -0,0 +1,2 @@ +SUBDIRS = libppt import + diff --git a/filters/kpresenter/powerpoint/import/Makefile.am b/filters/kpresenter/powerpoint/import/Makefile.am new file mode 100644 index 000000000..91f27887b --- /dev/null +++ b/filters/kpresenter/powerpoint/import/Makefile.am @@ -0,0 +1,14 @@ +INCLUDES = -I$(srcdir) -I$(srcdir)/../libppt $(KOFFICE_INCLUDES) $(all_includes) + +kde_module_LTLIBRARIES = libpowerpointimport.la + +libpowerpointimport_la_SOURCES = powerpointimport.cc +libpowerpointimport_la_LIBADD = $(KOFFICE_LIBS) ../libppt/libppt.la +libpowerpointimport_la_LDFLAGS = -module $(KDE_PLUGIN) +noinst_HEADERS = powerpointimport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_powerpoint_import.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/powerpoint/import/kpresenter_powerpoint_import.desktop b/filters/kpresenter/powerpoint/import/kpresenter_powerpoint_import.desktop new file mode 100644 index 000000000..99def0089 --- /dev/null +++ b/filters/kpresenter/powerpoint/import/kpresenter_powerpoint_import.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=Microsoft PowerPoint Import Filter for KPresenter +Name[bg]=Филтър за импортиране от Microsoft PowerPoint в KPresenter +Name[br]=Sil enporzh Microsoft PowerPoint evit KPresenter +Name[ca]=Filtre d'importació Microsoft PowerPoint per a KPresenter +Name[cy]=Hidlen Fewnforio Microsoft PowerPoint i KPresenter +Name[da]=Microsoft Powerpoint import-filter for KPresenter +Name[de]=KPresenter Microsoft PowerPoint-Importfilter +Name[el]=Φίλτρο εισαγωγής Microsoft PowerPoint για το KPresenter +Name[es]=Filtro de importación de Microsoft PowerPoint para KPresenter +Name[et]=KPresenteri Microsoft PowerPoint'i impordifilter +Name[fa]=پالایۀ واردات Microsoft PowerPoint برای KPresenter +Name[fi]=Microsoft PowerPoint -tuontisuodin KPresenterille +Name[fr]=Filtre d'importation Microsoft PowerPoint pour KPresenter +Name[fy]=Microsoft PowerPoint-Ymportfilter foar KPresenter +Name[ga]=Scagaire Iompórtála Microsoft PowerPoint le haghaidh KSpread +Name[gl]=Filtro de Importación de Microsoft PowerPoint para KPresenter +Name[he]=Microsoft PowerPoint מסנן יבוא ל-KPresenter +Name[hr]=Microsoft PowerPoint filtar uvoza za KPresenter +Name[hu]=Microsoft PowerPoint importszűrő a KPresenterhez +Name[is]=Microsoft PowerPoint innflutningssía fyrir KPresenter +Name[it]=Filtro di importazione Microsoft PowerPoint per KPresenter +Name[ja]=KPresenter Microsoft PowerPoint インポートフィルタ +Name[km]=តម្រង​នាំចូល Microsoft PowerPoint សម្រាប់ KPresenter +Name[lt]=Microsoft PowerPoint importavimo filtras skirtas KPresenter +Name[lv]=Microsoft PowerPoint importa filtrs priekš KPresenter +Name[nb]=Microsoft PowerPoint-importfilter for KPresenter +Name[nds]="Microsoft PowerPoint"-Importfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ताका लागि माइक्रोसफ्ट पावरपोइन्ट आयात फिल्टर +Name[nl]= Microsoft Powerpoint importfilter voor KPresenter +Name[pl]=Filtr importu formatu Microsoft PowerPoint dla KPresenter +Name[pt]=Filtro de Importação do Microsoft PowerPoint para o KPresenter +Name[pt_BR]=Filtro de Importação do Microsoft PowerPoint para o KPresenter +Name[ru]=Фильтр импорта презентаций Microsoft PowerPoint в KPresenter +Name[se]=KPresenter Microsoft PowerPoint-sisafievrridansilli +Name[sk]=Filter pre import z Microsoft Power Point-u pre KPresenter +Name[sl]=Uvozni filter Microsoft PowerPoint za KPresenter +Name[sr]=KPresenter-ов филтер за увоз из Microsoft-овог PowerPoint-а +Name[sr@Latn]=KPresenter-ov filter za uvoz iz Microsoft-ovog PowerPoint-a +Name[sv]=Microsoft PowerPoint-importfilter för Kpresenter +Name[uk]=Фільтр імпорту Microsoft PowerPoint для KPresenter +Name[uz]=KPresenter MS PowerPoint import filteri +Name[uz@cyrillic]=KPresenter MS PowerPoint импорт филтери +Name[zh_CN]=KPresenter 的 Microsoft PowerPoint 导入过滤器 +Name[zh_TW]=KPresenter 的 Microsoft PowerPoint 匯入過濾程式 +X-KDE-Export=application/vnd.oasis.opendocument.presentation +X-KDE-Import=application/mspowerpoint +X-KDE-Weight=1 +X-KDE-Library=libpowerpointimport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/powerpoint/import/powerpointimport.cc b/filters/kpresenter/powerpoint/import/powerpointimport.cc new file mode 100644 index 000000000..761e4f0d2 --- /dev/null +++ b/filters/kpresenter/powerpoint/import/powerpointimport.cc @@ -0,0 +1,1592 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +#include "libppt.h" +#include +#include + +using namespace Libppt; + +typedef KGenericFactory PowerPointImportFactory; +K_EXPORT_COMPONENT_FACTORY( libpowerpointimport, + PowerPointImportFactory( "kofficefilters" ) ) + +namespace Libppt { + +inline QConstString string( const Libppt::UString& str ) +{ + return QConstString( reinterpret_cast( str.data() ), str.length() ); +} + +} + +class PowerPointImport::Private +{ +public: + QString inputFile; + QString outputFile; + + Presentation *presentation; +}; + + +PowerPointImport::PowerPointImport ( QObject*, const char*, const QStringList& ) + : KoFilter() +{ + d = new Private; +} + +PowerPointImport::~PowerPointImport() +{ + delete d; +} + +KoFilter::ConversionStatus PowerPointImport::convert( const QCString& from, const QCString& to ) +{ + if ( from != "application/mspowerpoint" ) + return KoFilter::NotImplemented; + + if ( to != "application/vnd.oasis.opendocument.presentation" ) + return KoFilter::NotImplemented; + + d->inputFile = m_chain->inputFile(); + d->outputFile = m_chain->outputFile(); + + // open inputFile + d->presentation = new Presentation; + if( !d->presentation->load( d->inputFile.local8Bit() ) ) + { + delete d->presentation; + d->presentation = 0; + return KoFilter::StupidError; + } + + // create output store + KoStore* storeout; + storeout = KoStore::createStore( d->outputFile, KoStore::Write, + "application/vnd.oasis.opendocument.presentation", KoStore::Zip ); + + if ( !storeout ) + { + kdWarning() << "Couldn't open the requested file." << endl; + return KoFilter::FileNotFound; + } + + // store document content + if ( !storeout->open( "content.xml" ) ) + { + kdWarning() << "Couldn't open the file 'content.xml'." << endl; + return KoFilter::CreationError; + } + storeout->write( createContent() ); + storeout->close(); + + // store document styles + if ( !storeout->open( "styles.xml" ) ) + { + kdWarning() << "Couldn't open the file 'styles.xml'." << endl; + return KoFilter::CreationError; + } + storeout->write( createStyles() ); + storeout->close(); + + // store document manifest + storeout->enterDirectory( "META-INF" ); + if ( !storeout->open( "manifest.xml" ) ) + { + kdWarning() << "Couldn't open the file 'META-INF/manifest.xml'." << endl; + return KoFilter::CreationError; + } + storeout->write( createManifest() ); + storeout->close(); + + + // we are done! + delete d->presentation; + delete storeout; + d->inputFile = QString::null; + d->outputFile = QString::null; + d->presentation = 0; + + return KoFilter::OK; +} + +QByteArray PowerPointImport::createStyles() +{ + KoXmlWriter* stylesWriter; + QByteArray stylesData; + QBuffer stylesBuffer( stylesData ); + + QString pageWidth = QString("%1pt").arg( d->presentation->masterSlide()->pageWidth() ); + QString pageHeight = QString("%1pt").arg( d->presentation->masterSlide()->pageHeight() ); + + stylesBuffer.open( IO_WriteOnly ); + stylesWriter = new KoXmlWriter( &stylesBuffer ); + + stylesWriter->startDocument( "office:document-styles" ); + stylesWriter->startElement( "office:document-styles" ); + stylesWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" ); + stylesWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" ); + stylesWriter->addAttribute( "xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" ); + stylesWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" ); + stylesWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" ); + stylesWriter->addAttribute( "xmlns:fo", "urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" ); + stylesWriter->addAttribute( "office:version","1.0" ); + + // office:styles + stylesWriter->startElement( "office:styles" ); + stylesWriter->endElement(); + + // office:automatic-styles + stylesWriter->startElement( "office:automatic-styles" ); + stylesWriter->startElement( "style:page-layout" ); + stylesWriter->addAttribute( "style:name","pm1" ); + stylesWriter->addAttribute( "style:page-usage","all" ); + stylesWriter->startElement( "style:page-layout-properties" ); + stylesWriter->addAttribute( "fo:margin-bottom","0pt" ); + stylesWriter->addAttribute( "fo:margin-left","0pt" ); + stylesWriter->addAttribute( "fo:margin-right","0pt" ); + stylesWriter->addAttribute( "fo:margin-top","0pt" ); + stylesWriter->addAttribute( "fo:page-height", pageHeight ); + stylesWriter->addAttribute( "fo:page-width", pageWidth ); + stylesWriter->addAttribute( "style:print-orientation","landscape" ); + stylesWriter->endElement(); // style:page-layout-properties + stylesWriter->endElement(); // style:page-layout + + stylesWriter->startElement( "style:style" ); + stylesWriter->addAttribute( "style:name","dp1" ); + stylesWriter->addAttribute( "style:family","drawing-page" ); + stylesWriter->startElement( "style:drawing-page-properties" ); + stylesWriter->addAttribute( "draw:background-size","border" ); + stylesWriter->addAttribute( "draw:fill","solid" ); + stylesWriter->addAttribute( "draw:fill-color","#ffffff" ); + stylesWriter->endElement(); // style:drawing-page-properties + stylesWriter->endElement(); // style:style + + stylesWriter->startElement( "style:style" ); + stylesWriter->addAttribute( "style:name","P1" ); + stylesWriter->addAttribute( "style:family","paragraph" ); + stylesWriter->startElement( "style:paragraph-properties" ); + stylesWriter->addAttribute( "fo:margin-left","0cm" ); + stylesWriter->addAttribute( "fo:margin-right","0cm" ); + stylesWriter->addAttribute( "fo:text-indent","0cm" ); + stylesWriter->endElement(); // style:paragraph-properties + stylesWriter->startElement( "style:text-properties" ); + stylesWriter->addAttribute( "fo:font-size","14pt" ); + stylesWriter->addAttribute( "style:font-size-asian","14pt" ); + stylesWriter->addAttribute( "style:font-size-complex","14pt" ); + stylesWriter->endElement(); // style:text-properties + stylesWriter->endElement(); // style:style + + stylesWriter->startElement( "text:list-style" ); + stylesWriter->addAttribute( "style:name","L2" ); + stylesWriter->startElement( "text:list-level-style-bullet" ); + stylesWriter->addAttribute( "text:level","1" ); + stylesWriter->addAttribute( "text:bullet-char","●" ); + stylesWriter->startElement( "style:text-properties" ); + stylesWriter->addAttribute( "fo:font-family","StarSymbol" ); + stylesWriter->addAttribute( "font-pitch","variable" ); + stylesWriter->addAttribute( "fo:color","#000000" ); + stylesWriter->addAttribute( "fo:font-size","45%" ); + stylesWriter->endElement(); // style:text-properties + stylesWriter->endElement(); // text:list-level-style-bullet + stylesWriter->endElement(); // text:list-style + + stylesWriter->endElement(); // office:automatic-styles + + // office:master-stylesborder + stylesWriter->startElement( "office:master-styles" ); + stylesWriter->startElement( "style:master-page" ); + stylesWriter->addAttribute( "style:name", "Standard" ); + stylesWriter->addAttribute( "style:page-layout-name", "pm1" ); + stylesWriter->addAttribute( "draw:style-name", "dp1" ); + stylesWriter->endElement(); + stylesWriter->endElement(); + + stylesWriter->endElement(); // office:document-styles + stylesWriter->endDocument(); + delete stylesWriter; + + // for troubleshooting only !! + QString dbg; + for( unsigned i=0; istartDocument( "office:document-content" ); + contentWriter->startElement( "office:document-content" ); + contentWriter->addAttribute( "xmlns:office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" ); + contentWriter->addAttribute( "xmlns:style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" ); + contentWriter->addAttribute( "xmlns:text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" ); + contentWriter->addAttribute( "xmlns:draw", "urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" ); + contentWriter->addAttribute( "xmlns:presentation", "urn:oasis:names:tc:opendocument:xmlns:presentation:1.0" ); + contentWriter->addAttribute( "xmlns:svg","urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" ); + contentWriter->addAttribute( "office:version","1.0" ); + + // office:automatic-styles + + drawingObjectCounter = 0; + contentWriter->startElement( "office:automatic-styles" ); + for( unsigned c=0; c < d->presentation->slideCount(); c++ ) + { + Slide* slide = d->presentation->slide( c ); + processSlideForStyle( c, slide, contentWriter ); + } + contentWriter->endElement(); + + + + // office:body + + contentWriter->startElement( "office:body" ); + contentWriter->startElement( "office:presentation" ); + + drawingObjectCounter = 0; + for( unsigned c=0; c < d->presentation->slideCount(); c++ ) + { + Slide* slide = d->presentation->slide( c ); + processSlideForBody( c, slide, contentWriter ); + } + + contentWriter->endElement(); // office:presentation + contentWriter->endElement(); // office:body + + contentWriter->endElement(); // office:document-content + contentWriter->endDocument(); + delete contentWriter; + + // for troubleshooting only !! + QString dbg; + for( unsigned i=0; istartDocument( "manifest:manifest" ); + manifestWriter->startElement( "manifest:manifest" ); + manifestWriter->addAttribute( "xmlns:manifest", + "urn:oasis:names:tc:openoffice:xmlns:manifest:1.0" ); + + manifestWriter->addManifestEntry( "/", "application/vnd.oasis.opendocument.presentation" ); + manifestWriter->addManifestEntry( "styles.xml", "text/xml" ); + manifestWriter->addManifestEntry( "content.xml", "text/xml" ); + + manifestWriter->endElement(); + manifestWriter->endDocument(); + delete manifestWriter; + + // for troubleshooting only !! + QString dbg; + for( unsigned i=0; iwidth() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:ellipse" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->endElement(); // draw:ellipse +} + +void PowerPointImport::processRectangle (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject ) return; + if( !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:rect" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + if ( drawObject->hasProperty ( "libppt:rotation" ) ) + { + + double rotAngle = drawObject->getDoubleProperty("libppt:rotation" ); + double xMid = ( drawObject->left() + 0.5*drawObject->width() ); + double yMid = ( drawObject->top() + 0.5*drawObject->height() ); + double xVec = drawObject->left()- xMid; + double yVec = yMid - drawObject->top(); + + double xNew = xVec*cos(rotAngle) - yVec*sin(rotAngle); + double yNew = xVec*sin(rotAngle) + yVec*cos(rotAngle); + QString rot = QString("rotate (%1) translate (%2mm %3mm)").arg(rotAngle).arg(xNew+xMid).arg(yMid-yNew); + xmlWriter->addAttribute( "draw:transform", rot ); + } + else + { + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + } + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->endElement(); // draw:rect +} + +void PowerPointImport::processRoundRectangle (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + + + if ( drawObject->hasProperty ( "libppt:rotation" ) ) + { + double rotAngle = drawObject->getDoubleProperty("libppt:rotation" ); + + + + if ( rotAngle > 0.785399 ) // > 45 deg + { xmlWriter->addAttribute( "svg:width", heightStr ); + xmlWriter->addAttribute( "svg:height", widthStr ); + double xMid = ( drawObject->left() - 0.5*drawObject->height() ); + double yMid = ( drawObject->top() + 0.5*drawObject->width() ); + double xVec = drawObject->left()- xMid; + double yVec = drawObject->top()- yMid; + + double xNew = xVec*cos(rotAngle) - yVec*sin(rotAngle); + double yNew = xVec*sin(rotAngle) + yVec*cos(rotAngle); + QString rot = QString("rotate (%1) translate (%2mm %3mm)").arg(rotAngle).arg(xNew+xMid).arg(yMid+yNew); + xmlWriter->addAttribute( "draw:transform", rot ); + } + else + { xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + double xMid = ( drawObject->left() + 0.5*drawObject->width() ); + double yMid = ( drawObject->top() + 0.5*drawObject->height() ); + double xVec = drawObject->left()- xMid; + double yVec = yMid - drawObject->top(); + + double xNew = xVec*cos(rotAngle) - yVec*sin(rotAngle); + double yNew = xVec*sin(rotAngle) + yVec*cos(rotAngle); + QString rot = QString("rotate (%1) translate (%2mm %3mm)").arg(rotAngle).arg(xNew+xMid).arg(yMid-yNew); + xmlWriter->addAttribute( "draw:transform", rot ); + } + + + } + else + { xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + } + // xmlWriter->addAttribute( "svg:x", xStr ); + // xmlWriter->addAttribute( "svg:y", yStr ); + + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "round-rectangle"); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 /3" ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "right-?f0 " ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "bottom-?f0 " ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "left+?f0 " ); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "top+?f0 " ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); // draw:equation + xmlWriter->endElement(); // draw:enhanced-geometry + xmlWriter->endElement(); // draw:custom-shape +} + +void PowerPointImport::processDiamond (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 10 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "diamond"); + xmlWriter->endElement(); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->endElement(); +} + +void PowerPointImport::processTriangle (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + /* draw IsocelesTriangle or RightTriangle */ + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 2.5 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 10 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 7.5 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + + xmlWriter->startElement( "draw:enhanced-geometry" ); + + if (drawObject->hasProperty("draw:mirror-vertical")) + { + xmlWriter->addAttribute("draw:mirror-vertical","true"); + } + if ( drawObject->hasProperty("draw:mirror-horizontal")) + { + xmlWriter->addAttribute("draw:mirror-horizontal","true"); + } + if ( drawObject->hasProperty ( "libppt:rotation" ) ) + { // draw:transform="rotate (1.5707963267946) translate (6.985cm 14.181cm)" + + double rotAngle = drawObject->getDoubleProperty("libppt:rotation" ); + double xMid = ( drawObject->left() + 0.5*drawObject->width() ); + double yMid = ( drawObject->top() + 0.5*drawObject->height() ); + QString rot = QString("rotate (%1) translate (%2cm %3cm)").arg(rotAngle).arg(xMid).arg(yMid); + xmlWriter->addAttribute( "draw:transform", rot ); + } + if (drawObject->shape() == DrawObject::RightTriangle) + { + xmlWriter->addAttribute( "draw:type", "right-triangle"); + } + else if (drawObject->shape() == DrawObject::IsoscelesTriangle) + { + xmlWriter->addAttribute( "draw:type", "isosceles-triangle"); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 /2" ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f1 +10800" ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 *2/3" ); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f3 +7200" ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f0 " ); + xmlWriter->addAttribute( "draw:name", "f5" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f5 /2" ); + xmlWriter->addAttribute( "draw:name", "f6" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f6 " ); + xmlWriter->addAttribute( "draw:name", "f7" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 21600); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute( "draw:handle-position","$0 top"); + xmlWriter->endElement(); + } + + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processTrapezoid (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 2.5 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + if ( drawObject->hasProperty("draw:mirror-vertical") ) + { + xmlWriter->addAttribute("draw:mirror-vertical","true"); + } + if ( drawObject->hasProperty("draw:mirror-horizontal")) + { + xmlWriter->addAttribute("draw:mirror-horizontal","true"); + } + xmlWriter->addAttribute( "draw:type", "trapezoid" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-$0 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0" ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 *10/18" ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f2 +1750"); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f3" ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 /2" ); + xmlWriter->addAttribute( "draw:name", "f5" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f5" ); + xmlWriter->addAttribute( "draw:name", "f6" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 10800); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$0 bottom"); + xmlWriter->endElement(); + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processParallelogram (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 6.25 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 4.5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 8.75 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 3.75 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 1.25 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + if (drawObject->hasProperty("draw:mirror-vertical")) + { + xmlWriter->addAttribute("draw:mirror-vertical","true"); + } + if ( drawObject->hasProperty("draw:mirror-horizontal")) + { + xmlWriter->addAttribute("draw:mirror-horizontal","true"); + } + xmlWriter->addAttribute( "draw:type", "parallelogram" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-$0" ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 *10/24" ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f2 +1750"); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f3" ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f0 /2" ); + xmlWriter->addAttribute( "draw:name", "f5" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "10800+?f5" ); + xmlWriter->addAttribute( "draw:name", "f6" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f0-10800 " ); + xmlWriter->addAttribute( "draw:name", "f7" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "if(?f7,?f12,0" ); + xmlWriter->addAttribute( "draw:name", "f8" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "10800-?f5" ); + xmlWriter->addAttribute( "draw:name", "f9" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "if(?f7, ?f12, 21600"); + xmlWriter->addAttribute( "draw:name", "f10" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f5" ); + xmlWriter->addAttribute( "draw:name", "f11" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600*10800/?f0" ); + xmlWriter->addAttribute( "draw:name", "f12" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f12" ); + xmlWriter->addAttribute( "draw:name", "f13" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 21600); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$0 top"); + xmlWriter->endElement(); + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processHexagon (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 10 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "hexagon" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-$0" ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 *100/234" ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "?f2 +1700"); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "21600-?f3" ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 10800); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$0 top"); + xmlWriter->endElement(); + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processOctagon (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 4.782 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 10 ); + xmlWriter->addAttribute( "svg:y", 4.782 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "octagon" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "left+$0 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "top+$0 " ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "right-$0 " ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "bottom-$0 "); + xmlWriter->addAttribute( "draw:name", "f3" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0 /2" ); + xmlWriter->addAttribute( "draw:name", "f4" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "left+?f4 " ); + xmlWriter->addAttribute( "draw:name", "f5" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "top+?f4 " ); + xmlWriter->addAttribute( "draw:name", "f6" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "right-?f4 " ); + xmlWriter->addAttribute( "draw:name", "f7" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "bottom-?f4 "); + xmlWriter->addAttribute( "draw:name", "f8" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 10800); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$0 top"); + xmlWriter->endElement(); + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processArrow (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:enhanced-geometry" ); + + if (drawObject->shape() == DrawObject::RightArrow) + xmlWriter->addAttribute( "draw:type", "right-arrow" ); + else if (drawObject->shape() == DrawObject::LeftArrow) + xmlWriter->addAttribute( "draw:type", "left-arrow" ); + else if (drawObject->shape() == DrawObject::UpArrow) + xmlWriter->addAttribute( "draw:type", "up-arrow" ); + else if (drawObject->shape() == DrawObject::DownArrow) + xmlWriter->addAttribute( "draw:type", "down-arrow" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","$1"); + xmlWriter->addAttribute( "draw:name","f0"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","$0"); + xmlWriter->addAttribute( "draw:name","f1"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","21600-$1"); + xmlWriter->addAttribute( "draw:name","f2"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","21600-?f1"); + xmlWriter->addAttribute( "draw:name","f3"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","?f3 *?f0 /10800"); + xmlWriter->addAttribute( "draw:name","f4"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","?f1 +?f4 " ); + xmlWriter->addAttribute( "draw:name","f5"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","?f1 *?f0 /10800"); + xmlWriter->addAttribute( "draw:name","f6"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula","?f1 -?f6 "); + xmlWriter->addAttribute( "draw:name","f7"); + xmlWriter->endElement(); // draw:equation + xmlWriter->startElement( "draw:handle" ); + if ( drawObject->shape() == DrawObject::RightArrow | drawObject->shape() == DrawObject::LeftArrow ) + { + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 21600); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$0 $1"); + xmlWriter->addAttribute("draw:handle-range-y-maximum",10800); + xmlWriter->addAttribute("draw:handle-range-y-minimum",0); + } + else if ( drawObject->shape() == DrawObject::UpArrow | drawObject->shape() == DrawObject::DownArrow ) + { + xmlWriter->addAttribute( "draw:handle-range-x-maximum", 10800); + xmlWriter->addAttribute( "draw:handle-range-x-minimum", 0); + xmlWriter->addAttribute("draw:handle-position","$1 $0"); + xmlWriter->addAttribute("draw:handle-range-y-maximum",21600); + xmlWriter->addAttribute("draw:handle-range-y-minimum",0); + } + xmlWriter->endElement(); // draw:handle + xmlWriter->endElement(); // draw:enhanced-geometry + xmlWriter->endElement(); // draw:custom-shape +} + +void PowerPointImport::processLine (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter) return; + + QString x1Str = QString("%1mm").arg( drawObject->left() ); + QString y1Str = QString("%1mm").arg( drawObject->top() ); + QString x2Str = QString("%1mm").arg( drawObject->left() + drawObject->width() ); + QString y2Str = QString("%1mm").arg( drawObject->top() + drawObject->height() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + if ( drawObject->hasProperty("draw:mirror-vertical") ) + { QString temp = y1Str; + y1Str = y2Str; + y2Str = temp; + } + if ( drawObject->hasProperty("draw:mirror-horizontal") ) + { QString temp = x1Str; + x1Str = x2Str; + x2Str = temp; + } + + xmlWriter->startElement( "draw:line" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:y1", y1Str ); + xmlWriter->addAttribute( "svg:y2", y2Str ); + xmlWriter->addAttribute( "svg:x1", x1Str ); + xmlWriter->addAttribute( "svg:x2", x2Str ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + + xmlWriter->endElement(); +} + +void PowerPointImport::processSmiley (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject ||!xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 0 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 1.461 ); + xmlWriter->addAttribute( "svg:y", 1.461 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 0 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 1.461 ); + xmlWriter->addAttribute( "svg:y", 8.536 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 10 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 8.536 ); + xmlWriter->addAttribute( "svg:y", 1.461 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "smiley" ); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "$0-15510 " ); + xmlWriter->addAttribute( "draw:name", "f0" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "17520-?f0" ); + xmlWriter->addAttribute( "draw:name", "f1" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:equation" ); + xmlWriter->addAttribute( "draw:formula", "15510+?f0" ); + xmlWriter->addAttribute( "draw:name", "f2" ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:handle" ); + xmlWriter->addAttribute( "draw:position", 10800); + xmlWriter->addAttribute( "draw:handle-range-y-maximum", 17520); + xmlWriter->addAttribute( "draw:handle-range-y-minimum", 15510); + xmlWriter->addAttribute("draw:handle-position","$0 top"); + xmlWriter->endElement(); + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processHeart (DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:custom-shape" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 1 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 1.43 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 5 ); + xmlWriter->addAttribute( "svg:y", 10 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:glue-point" ); + xmlWriter->addAttribute( "svg:x", 8.553 ); + xmlWriter->addAttribute( "svg:y", 5 ); + xmlWriter->endElement(); + xmlWriter->startElement( "draw:enhanced-geometry" ); + xmlWriter->addAttribute( "draw:type", "heart" ); + + xmlWriter->endElement(); // enhanced-geometry + xmlWriter->endElement(); // custom-shape +} + +void PowerPointImport::processFreeLine (DrawObject* drawObject, KoXmlWriter* xmlWriter) +{ + if( !drawObject ||!xmlWriter ) return; + + QString widthStr = QString("%1mm").arg( drawObject->width() ); + QString heightStr = QString("%1mm").arg( drawObject->height() ); + QString xStr = QString("%1mm").arg( drawObject->left() ); + QString yStr = QString("%1mm").arg( drawObject->top() ); + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "draw:path" ); + xmlWriter->addAttribute( "draw:style-name", styleName ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->endElement(); // path +} + +void PowerPointImport::processDrawingObjectForBody( DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + + if( !drawObject || !xmlWriter ) return; + + drawingObjectCounter++; + + + if (drawObject->shape() == DrawObject::Ellipse) + { + processEllipse (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Rectangle) + { + processRectangle (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::RoundRectangle) + { + processRoundRectangle (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Diamond) + { + processDiamond (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::IsoscelesTriangle | + drawObject->shape() == DrawObject::RightTriangle) + { + processTriangle (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Trapezoid) + { + processTrapezoid (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Parallelogram) + { + processParallelogram( drawObject, xmlWriter); + } + else if (drawObject->shape() == DrawObject::Hexagon) + { + processHexagon ( drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Octagon) + { + processOctagon ( drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::RightArrow | + drawObject->shape() == DrawObject::LeftArrow | + drawObject->shape() == DrawObject::UpArrow | + drawObject->shape() == DrawObject::DownArrow ) + { + processArrow ( drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Line) + { + processLine ( drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Smiley) + { + processSmiley (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::Heart) + { + processHeart (drawObject, xmlWriter ); + } + else if (drawObject->shape() == DrawObject::FreeLine) + { + processFreeLine (drawObject, xmlWriter ); + } +} + +void PowerPointImport::processGroupObjectForBody( GroupObject* groupObject, KoXmlWriter* xmlWriter ) +{ + if( !groupObject || !xmlWriter ) return; + if( !groupObject->objectCount() ) return; + + xmlWriter->startElement( "draw:g" ); + + for( unsigned i = 0; i < groupObject->objectCount(); i++ ) + { + Object* object = groupObject->object( i ); + if( object ) + processObjectForBody( object, xmlWriter ); + } + + xmlWriter->endElement(); // draw:g +} + +void PowerPointImport::processTextObjectForBody( TextObject* textObject, KoXmlWriter* xmlWriter ) +{ + if( !textObject || !xmlWriter ) return; + + QString classStr = "subtitle"; + if( textObject->type() == TextObject::Title ) + classStr = "title"; +// QString pStr = string( textObject->text() ).string(); + QString pStr; + + QString widthStr = QString("%1mm").arg( textObject->width() ); + QString heightStr = QString("%1mm").arg( textObject->height() ); + QString xStr = QString("%1mm").arg( textObject->left() ); + QString yStr = QString("%1mm").arg( textObject->top() ); + + xmlWriter->startElement( "draw:frame" ); + xmlWriter->addAttribute( "presentation:style-name", "pr1" ); + xmlWriter->addAttribute( "draw:layer", "layout" ); + xmlWriter->addAttribute( "svg:width", widthStr ); + xmlWriter->addAttribute( "svg:height", heightStr ); + xmlWriter->addAttribute( "svg:x", xStr ); + xmlWriter->addAttribute( "svg:y", yStr ); + xmlWriter->addAttribute( "presentation:class", classStr ); + xmlWriter->startElement( "draw:text-box" ); + + // count error if i begins with 0 + for (unsigned i=0; ilistSize(); i++) + { + pStr = Libppt::string(textObject->text(i)).string(); + if (textObject->bulletFlag(i) == 1 ) + { + xmlWriter->startElement( "text:list" ); + xmlWriter->addAttribute( "text:style-name","L2"); + xmlWriter->startElement( "text:list-item" ); + xmlWriter->startElement( "text:p" ); + xmlWriter->addAttribute( "text:style-name", "P1" ); + xmlWriter->addTextSpan( pStr ); + xmlWriter->endElement(); // text:p + xmlWriter->endElement(); // text:list-item + xmlWriter->endElement(); // text:list + } + else + { + xmlWriter->startElement( "text:p" ); + xmlWriter->addAttribute( "text:style-name", "P1" ); + xmlWriter->addTextSpan( pStr ); + xmlWriter->endElement(); // text:p + } + } + + xmlWriter->endElement(); // draw:text-box + xmlWriter->endElement(); // draw:frame + + +} + +void PowerPointImport::processObjectForBody( Object* object, KoXmlWriter* xmlWriter ) +{ + if( !object || !xmlWriter) return; + + if( object->isText() ) + processTextObjectForBody( static_cast(object), xmlWriter ); + else if( object->isGroup() ) + processGroupObjectForBody( static_cast(object), xmlWriter ); + else if( object->isDrawing() ) + processDrawingObjectForBody( static_cast(object), xmlWriter ); +} + +void PowerPointImport::processSlideForBody( unsigned slideNo, Slide* slide, KoXmlWriter* xmlWriter ) +{ + if( !slide || !xmlWriter ) return; + + QString nameStr = Libppt::string( slide->title() ).string(); + if( nameStr.isEmpty() ) + nameStr = QString("page%1").arg(slideNo+1); + + QString styleNameStr = QString("dp%1").arg(slideNo+1); + + xmlWriter->startElement( "draw:page" ); + xmlWriter->addAttribute( "draw:master-page-name", "Default" ); + xmlWriter->addAttribute( "draw:name", nameStr ); + xmlWriter->addAttribute( "draw:style-name", styleNameStr ); + xmlWriter->addAttribute( "presentation:presentation-page-layout-name", "AL1T0"); + + GroupObject* root = slide->rootObject(); + if( root ) + for( unsigned i = 0; i < root->objectCount(); i++ ) + { + Object* object = root->object( i ); + if( object ) + processObjectForBody( object, xmlWriter ); + } + + xmlWriter->endElement(); // draw:page +} + +void PowerPointImport::processSlideForStyle( unsigned , Slide* slide, KoXmlWriter* xmlWriter ) +{ + if( !slide || !xmlWriter ) return; + + GroupObject* root = slide->rootObject(); + if( root ) + for( unsigned i = 0; i < root->objectCount(); i++ ) + { + Object* object = root->object( i ); + if( object ) + processObjectForStyle( object, xmlWriter ); + } +} + +void PowerPointImport::processObjectForStyle( Object* object, KoXmlWriter* xmlWriter ) +{ + if( !object || !xmlWriter ) return; + + if( object->isText() ) + processTextObjectForStyle( static_cast(object), xmlWriter ); + else if( object->isGroup() ) + processGroupObjectForStyle( static_cast(object), xmlWriter ); + else if( object->isDrawing() ) + processDrawingObjectForStyle( static_cast(object), xmlWriter ); +} + +void PowerPointImport::processTextObjectForStyle( TextObject* textObject, KoXmlWriter* xmlWriter ) +{ + if( !textObject || !xmlWriter ) return; +} + +void PowerPointImport::processGroupObjectForStyle( GroupObject* groupObject, KoXmlWriter* xmlWriter ) +{ + if( !groupObject ||!xmlWriter ) return; +} + +QString hexname( const Color &c ) +{ + QColor qc( c.red, c.green, c.blue ); + return qc.name(); +} + +void PowerPointImport::processDrawingObjectForStyle( DrawObject* drawObject, KoXmlWriter* xmlWriter ) +{ + if( !drawObject || !xmlWriter) return; + + drawingObjectCounter++; + QString styleName = QString("gr%1").arg( drawingObjectCounter ); + + xmlWriter->startElement( "style:style" ); + xmlWriter->addAttribute( "style:name", styleName ); + xmlWriter->addAttribute( "style:family", "graphic" ); + xmlWriter->addAttribute( "style:parent-style-name", "standard" ); + + xmlWriter->startElement( "style:graphic-properties" ); +/* + if (drawObject->hasProperty("draw:stroke") ) + { + xmlWriter->addAttribute( "draw:stroke", "dash" ); + std::string s = drawObject->getStrProperty("draw:stroke-dash"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:stroke-dash", ss ); + } else xmlWriter->addAttribute( "draw:stroke", "dash" ); +*/ + if (drawObject->hasProperty( "libppt:invisibleLine" )) + { + if (drawObject->getBoolProperty("libppt:invisibleLine") == true) + xmlWriter->addAttribute( "draw:stroke", "none" ); + } + else if( drawObject->hasProperty( "draw:stroke" ) ) + { if (drawObject->getStrProperty( "draw:stroke" ) == "dash") + { + xmlWriter->addAttribute( "draw:stroke", "dash" ); + std::string s = drawObject->getStrProperty("draw:stroke-dash"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:stroke-dash", ss ); + qDebug("=============stroke dash==================="); +// qDebug("test %g\n",angka); + } + else if (drawObject->getStrProperty( "draw:stroke" ) == "solid") + xmlWriter->addAttribute( "draw:stroke", "solid" ); + } + + + if( drawObject->hasProperty( "svg:stroke-width" ) ) + { + double strokeWidth = drawObject->getDoubleProperty("svg:stroke-width" ); + xmlWriter->addAttribute( "svg:stroke-width",QString("%1mm").arg( strokeWidth ) ); + } + + if( drawObject->hasProperty( "svg:stroke-color" ) ) + { + Color strokeColor = drawObject->getColorProperty("svg:stroke-color" ); + xmlWriter->addAttribute( "svg:stroke-color", hexname( strokeColor ) ); + } + + if( drawObject->hasProperty( "draw:marker-start" ) ) + { + std::string s = drawObject->getStrProperty("draw:marker-start"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:marker-start", ss ); + } + if( drawObject->hasProperty( "draw:marker-end" ) ) + { + std::string s = drawObject->getStrProperty("draw:marker-end"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:marker-end", ss); + } +/* if( drawObject->hasProperty( "draw:marker-start-length" ) ) + { + std::string s = drawObject->getStrProperty("draw:marker-start-length"); + QString ss( s.c_str() ); + xmlWriter->addAttribute("draw:marker-start-length", ss ); + } + if( drawObject->hasProperty( "draw:marker-end-length" ) ) + { + std::string s = drawObject->getStrProperty("draw:marker-end-length"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:marker-end-length", ss); + } */ + + if( drawObject->hasProperty( "draw:marker-start-width" ) ) + { + double strokeWidth = drawObject->getDoubleProperty("svg:stroke-width" ); + double arrowWidth = (drawObject->getDoubleProperty("draw:marker-start-width") * strokeWidth); + xmlWriter->addAttribute( "draw:marker-start-width",QString("%1cm").arg( arrowWidth ) ); + } + + if( drawObject->hasProperty( "draw:marker-end-width" ) ) + { + double strokeWidth = drawObject->getDoubleProperty("svg:stroke-width" ); + double arrowWidth = (drawObject->getDoubleProperty("draw:marker-end-width") * strokeWidth); + xmlWriter->addAttribute( "draw:marker-end-width",QString("%1cm").arg( arrowWidth ) ); + } + + + + if( drawObject->hasProperty( "draw:fill" ) ) + { + std::string s = drawObject->getStrProperty("draw:fill"); + QString ss( s.c_str() ); + xmlWriter->addAttribute( "draw:fill", ss); + } + + + + if( drawObject->hasProperty( "draw:fill-color" ) ) + { + Color fillColor = drawObject->getColorProperty("draw:fill-color" ); + xmlWriter->addAttribute( "draw:fill-color", hexname( fillColor ) ); + + } else xmlWriter->addAttribute( "draw:fill-color", "#99ccff" ); + +#if 0 + if( drawObject->hasProperty( "draw:shadow-color" ) ) + { + xmlWriter->addAttribute( "draw:shadow", "visible" ); + Color shadowColor = drawObject->getColorProperty("draw:shadow-color" ); + xmlWriter->addAttribute( "draw:shadow-color", hexname( shadowColor ) ); + } + else xmlWriter->addAttribute( "draw:shadow", "hidden" ); +#endif + + if( drawObject->hasProperty( "draw:shadow-opacity" ) ) + { + double opacity = drawObject->getDoubleProperty("draw:shadow-opacity") ; + xmlWriter->addAttribute( "draw:shadow-opacity",QString("%1%").arg( opacity ) ); + } + + if( drawObject->hasProperty( "draw:shadow-offset-x" ) ) + { + double offset = drawObject->getDoubleProperty("draw:shadow-offset-x") ; + xmlWriter->addAttribute( "draw:shadow-offset-x",QString("%1cm").arg( offset ) ); + } + + if( drawObject->hasProperty( "draw:shadow-offset-y" ) ) + { + double offset = drawObject->getDoubleProperty("draw:shadow-offset-y"); + xmlWriter->addAttribute( "draw:shadow-offset-y",QString("%1cm").arg( offset ) ); + } + + + xmlWriter->endElement(); + + xmlWriter->endElement(); +} + diff --git a/filters/kpresenter/powerpoint/import/powerpointimport.h b/filters/kpresenter/powerpoint/import/powerpointimport.h new file mode 100644 index 000000000..6c6774ab4 --- /dev/null +++ b/filters/kpresenter/powerpoint/import/powerpointimport.h @@ -0,0 +1,83 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef POWERPOINTIMPORT_H +#define POWERPOINTIMPORT_H + +#include +#include + +#include + +#include "libppt.h" + +using namespace Libppt; + +class KoXmlWriter; + +class PowerPointImport : public KoFilter +{ +Q_OBJECT + +public: + PowerPointImport ( QObject *parent, const char* name, const QStringList& ); + virtual ~PowerPointImport(); + virtual KoFilter::ConversionStatus convert( const QCString& from, + const QCString& to ); + +private: + class Private; + Private* d; + + QByteArray createManifest(); + QByteArray createStyles(); + QByteArray createContent(); + + int drawingObjectCounter; + + void processSlideForBody( unsigned slideNo, Slide* slide, KoXmlWriter* xmlWriter ); + void processObjectForBody( Object* object, KoXmlWriter* xmlWriter ); + void processGroupObjectForBody( GroupObject* groupObject, KoXmlWriter* xmlWriter ); + void processDrawingObjectForBody( DrawObject* drawObject, KoXmlWriter* xmlWriter ); + void processTextObjectForBody( TextObject* textObject, KoXmlWriter* xmlWriter ); + + + void processSlideForStyle( unsigned slideNo, Slide* slide, KoXmlWriter* xmlWriter ); + void processObjectForStyle( Object* object, KoXmlWriter* xmlWriter ); + void processGroupObjectForStyle( GroupObject* groupObject, KoXmlWriter* xmlWriter ); + void processDrawingObjectForStyle( DrawObject* drawObject, KoXmlWriter* xmlWriter ); + void processTextObjectForStyle( TextObject* textObject, KoXmlWriter* xmlWriter ); + + void processEllipse(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processRectangle(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processRoundRectangle(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processDiamond(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processTriangle(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processTrapezoid(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processParallelogram(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processHexagon(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processOctagon(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processArrow(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processLine(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processSmiley(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processHeart(DrawObject* drawObject, KoXmlWriter* xmlWriter); + void processFreeLine(DrawObject* drawObject, KoXmlWriter* xmlWriter); +}; + +#endif // POWERPOINTIMPORT_H diff --git a/filters/kpresenter/powerpoint/libppt/Makefile.am b/filters/kpresenter/powerpoint/libppt/Makefile.am new file mode 100644 index 000000000..f4f7c98a8 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/Makefile.am @@ -0,0 +1,5 @@ +INCLUDES= -I$(srcdir) -I$(srcdir)/.. $(all_includes) + +noinst_LTLIBRARIES = libppt.la +libppt_la_SOURCES = slide.cpp objects.cpp presentation.cpp pole.cpp powerpoint.cpp ustring.cpp + diff --git a/filters/kpresenter/powerpoint/libppt/libppt.h b/filters/kpresenter/powerpoint/libppt/libppt.h new file mode 100644 index 000000000..1eee666f8 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/libppt.h @@ -0,0 +1,31 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#ifndef LIBPPT_H +#define LIBPPT_H + +#include "presentation.h" +#include "slide.h" +#include "objects.h" + +#include "ustring.h" +#include "powerpoint.h" + + +#endif /* LIBPPT_H */ diff --git a/filters/kpresenter/powerpoint/libppt/objects.cpp b/filters/kpresenter/powerpoint/libppt/objects.cpp new file mode 100644 index 000000000..29870cbdc --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/objects.cpp @@ -0,0 +1,426 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#include "objects.h" +#include "ustring.h" + +#include +#include +#include +#include + +using namespace Libppt; + +class PropertyValue +{ +public: + enum { InvalidType, IntType, DoubleType, StringType, BoolType, ColorType } type; + bool b; + int i; + double d; + std::string s; + Color c; + + PropertyValue() + { + type = InvalidType; + b = false; + i = 0; + d = 0.0; + + + } +}; + +class Object::Private +{ +public: + int id; + double top; + double left; + double width; + double height; + bool background; + std::map properties; +}; + +Object::Object() +{ + d = new Private; + d->id = -1; + d->top = 0.0; + d->left = 0.0; + d->width = 10.0; + d->height = 3.0; + d->background = false; +} + +Object::~Object() +{ + delete d; +} + +int Object::id() const +{ + return d->id; +} + +void Object::setId( int id ) +{ + d->id = id; +} + +double Object::top() const +{ + return d->top; +} + +double Object::left() const +{ + return d->left; +} + +double Object::width() const +{ + return d->width; +} + +double Object::height() const +{ + return d->height; +} + +void Object::setTop( double top ) +{ + d->top = top; +} + +void Object::setLeft( double left ) +{ + d->left = left; +} + +void Object::setWidth( double width ) +{ + d->width = width; +} + +void Object::setHeight( double height) +{ + d->height = height; +} + +bool Object::isBackground() const +{ + return d->background; +} + +void Object::setBackground( bool bg ) +{ + d->background = bg; +} + +bool Object::hasProperty( std::string name ) +{ + std::map::const_iterator i; + i = d->properties.find( name ); + if( i == d->properties.end() ) + return false; + else + return true; +} + +void Object::setProperty( std::string name, std::string value ) +{ + PropertyValue pv; + pv.type = PropertyValue::StringType; + pv.s = value; + d->properties[ name ] = pv; +} + +void Object::setProperty( std::string name, int value ) + { + PropertyValue pv; + pv.type = PropertyValue::IntType; + pv.i = value; + d->properties[ name ] = pv; +} + +void Object::setProperty( std::string name, double value ) +{ + PropertyValue pv; + pv.type = PropertyValue::DoubleType; + pv.d = value; + d->properties[ name ] = pv; +} + +void Object::setProperty( std::string name, bool value ) +{ + PropertyValue pv; + pv.type = PropertyValue::BoolType; + pv.b = value; + d->properties[ name ] = pv; +} + +void Object::setProperty( std::string name, Color value ) +{ + PropertyValue pv; + pv.type = PropertyValue::ColorType; + pv.c = value; + d->properties[ name ] = pv; +} + +int Object::getIntProperty( std::string name ) +{ + PropertyValue pv; + pv = d->properties[ name ]; + if( pv.type == PropertyValue::IntType ) + return pv.i; + else + return 0; +} + +double Object::getDoubleProperty( std::string name ) +{ + PropertyValue pv; + pv = d->properties[ name ]; + if( pv.type == PropertyValue::DoubleType ) + return pv.d; + else + return 0; +} + +bool Object::getBoolProperty( std::string name ) +{ + PropertyValue pv; + pv = d->properties[ name ]; + if( pv.type == PropertyValue::BoolType ) + return pv.b; + else + return false; + +} + +std::string Object::getStrProperty( std::string name ) +{ + PropertyValue pv; + pv = d->properties[ name ]; + if( pv.type == PropertyValue::StringType ) + return pv.s; + else + return "NoString"; +} + +Color Object::getColorProperty(std::string name) +{ + PropertyValue pv; + pv = d->properties[ name ]; + if( pv.type == PropertyValue::ColorType ) + return pv.c; + else + return Color(153,204,255); // #99ccff + +} + +class TextObject::Private +{ +public: + unsigned type; + std::vector text; + unsigned listSize; + std::vector bulletFlag; +}; + +TextObject::TextObject(): Object() +{ + d = new Private; +} + +TextObject::~TextObject() +{ + delete d; +} + +unsigned TextObject::type() const +{ + return d->type; +} + +unsigned TextObject::listSize() const +{ + return d->text.size(); +} + +const char* TextObject::typeAsString() const +{ + switch( d->type ) + { + case Title : return "Title"; + case Body : return "Body"; + case Notes : return "Notes"; + case NotUsed : return "NotUsed"; + case Other : return "Other"; + case CenterBody : return "CenterBody"; + case CenterTitle : return "CenterTitle"; + case HalfBody : return "HalfBody"; + case QuarterBody : return "QuarterBody"; + default: break; + } + + return "Unknown"; +} + +bool TextObject::bulletFlag( unsigned index ) const +{ + return d->bulletFlag[index]; +} + +void TextObject::setBulletFlag( bool flag ) +{ + d->bulletFlag.push_back( flag ); +} + + +void TextObject::setType( unsigned type ) +{ + d->type = type; +} + +UString TextObject::text( unsigned index) const +{ + return d->text[index]; +} + +void TextObject::setText( const UString& text ) +{ + d->text.push_back( text ); +} + +void TextObject::convertFrom( Object* object ) +{ + setId( object->id() ); + setLeft( object->left() ); + setTop( object->top() ); + setWidth( object->width() ); + setHeight( object->height() ); + + if( object->isText() ) + { + TextObject* textObj = static_cast( object ); + setType( textObj->type() ); + // jgn lupa diganti : setText( textObj->text() ); + } +} + +class GroupObject::Private +{ +public: + std::vector objects; +}; + +GroupObject::GroupObject() +{ + d = new Private; +} + +GroupObject::~GroupObject() +{ + for( unsigned i=0; iobjects.size(); i++ ) + delete d->objects[i]; + delete d; +} + +unsigned GroupObject::objectCount() const +{ + return d->objects.size(); +} + +Object* GroupObject::object( unsigned i ) +{ + return d->objects[i]; +} + +void GroupObject::addObject( Object* object ) +{ + d->objects.push_back( object ); +} + +void GroupObject::takeObject( Object* object ) +{ + std::vector result; + for( unsigned i=0; iobjects.size(); i++ ) + { + Object* obj = d->objects[i]; + if( obj != object ) + result.push_back( obj ); + } + + d->objects.clear(); + for( unsigned j=0; jobjects.push_back( result[j] ); +} + +class DrawObject::Private +{ +public: + unsigned shape; + bool isVerFlip; + bool isHorFlip; +}; + +DrawObject::DrawObject() +{ + d = new Private; + d->shape = None; +} + +DrawObject::~DrawObject() +{ + delete d; +} + +unsigned DrawObject::shape() const +{ + return d->shape; +} + +void DrawObject::setShape( unsigned s ) +{ + d->shape = s; +} + +bool DrawObject::isVerFlip() const +{ + return d->isVerFlip; +} + +void DrawObject::setVerFlip( bool isVerFlip ) +{ + d->isVerFlip = isVerFlip; +} + +bool DrawObject::isHorFlip() const +{ + return d->isHorFlip; +} + +void DrawObject::setHorFlip( bool isHorFlip ) +{ + d->isHorFlip = isHorFlip; +} diff --git a/filters/kpresenter/powerpoint/libppt/objects.h b/filters/kpresenter/powerpoint/libppt/objects.h new file mode 100644 index 000000000..823e2a759 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/objects.h @@ -0,0 +1,206 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#ifndef LIBPPT_OBJECTS +#define LIBPPT_OBJECTS + +#include "ustring.h" +#include + + +namespace Libppt +{ + +class Color +{ +public: + unsigned red, green, blue; + Color(){ red = green = blue = 0; } + Color( unsigned r, unsigned g, unsigned b ) + { red = r; green = g; blue = b; } + Color( const Color& c ) + { red = c.red; green = c.green; blue = c.blue; } + Color& operator=( const Color& c ) + { red = c.red; green = c.green; blue = c.blue; return *this; } +}; + +class Object +{ +public: + Object(); + virtual ~Object(); + + int id() const; + void setId( int id ); + + virtual bool isText() const { return false; } + virtual bool isPicture() const { return false; } + virtual bool isGroup() const { return false; } + virtual bool isDrawing() const { return false; } + + // all is in mm + + double top() const; + double left() const; + double width() const; + double height() const; + void setTop( double top ); + void setLeft( double left ); + void setWidth( double width ); + void setHeight( double height ); + + bool isBackground() const; + void setBackground( bool bg ); + + + bool hasProperty( std::string name ); + + void setProperty( std::string name, int value ); + void setProperty( std::string name, double value ); + void setProperty( std::string name, std::string value ); + void setProperty( std::string name, bool value ); + void setProperty( std::string name, Color value ); + void setProperty( std::string name, const char* value ) + { setProperty( name, std::string(value) ); } + + int getIntProperty( std::string name ); + double getDoubleProperty( std::string name ); + bool getBoolProperty( std::string name ); + std::string getStrProperty( std::string name ); + Color getColorProperty(std::string name); + +private: + // no copy or assign + Object( const Object& ); + Object& operator=( const Object& ); + + class Private; + Private* d; +}; + +class TextObject: public Object +{ +public: + + enum { + Title = 0, + Body = 1, + Notes = 2, + NotUsed = 3, + Other = 4, // text in a shape + CenterBody = 5, // subtitle in title slide + CenterTitle = 6, // title in title slide + HalfBody = 7, // body in two-column slide + QuarterBody = 8 // body in four-body slide + }; + + TextObject(); + virtual ~TextObject(); + virtual bool isText() const { return true; } + unsigned type() const; + void setType( unsigned type ); + const char* typeAsString() const; + UString text(unsigned index) const; + void setText( const UString& text ); + unsigned listSize() const; + bool bulletFlag(unsigned index) const; + void setBulletFlag( bool flag ) ; + void convertFrom( Object* object ); + +private: + // no copy or assign + TextObject( const TextObject& ); + TextObject& operator=( const TextObject& ); + + class Private; + Private* d; +}; + +class GroupObject: public Object +{ +public: + GroupObject(); + virtual ~GroupObject(); + virtual bool isGroup() const { return true; } + unsigned objectCount() const; + Object* object( unsigned index ); + void addObject( Object* object ); + void takeObject( Object* object ); + +private: + // no copy or assign + GroupObject( const GroupObject& ); + GroupObject& operator=( const GroupObject& ); + + class Private; + Private* d; + +}; + +class DrawObject: public Object +{ +public: + + enum { + None = 0, + Rectangle, + RoundRectangle, + Circle, + Ellipse, + Diamond, + RightArrow, + LeftArrow, + UpArrow, + DownArrow, + IsoscelesTriangle, + RightTriangle, + Parallelogram, + Trapezoid, + Hexagon, + Octagon, + Line, + Smiley, + Heart, + FreeLine + }; + + DrawObject(); + virtual ~DrawObject(); + virtual bool isDrawing() const { return true; } + + unsigned shape() const; + void setShape( unsigned s ); + + bool isVerFlip() const; + void setVerFlip( bool vFlip ); + bool isHorFlip() const; + void setHorFlip( bool hFlip ); + +private: + // no copy or assign + DrawObject( const DrawObject& ); + DrawObject& operator=( const DrawObject& ); + + class Private; + Private* d; +}; + +} + +#endif /* LIBPPT_OBJECTS */ diff --git a/filters/kpresenter/powerpoint/libppt/pole.cpp b/filters/kpresenter/powerpoint/libppt/pole.cpp new file mode 100644 index 000000000..2a78b79fc --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/pole.cpp @@ -0,0 +1,1317 @@ +/* POLE - Portable C++ library to access OLE Storage + Copyright (C) 2002-2005 Ariya Hidayat + + 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 authors 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. +*/ + +#include +#include +#include +#include +#include + +#include "pole.h" + +// enable to activate debugging output +// #define POLE_DEBUG + +namespace POLE +{ + +class Header +{ + public: + unsigned char id[8]; // signature, or magic identifier + unsigned b_shift; // bbat->blockSize = 1 << b_shift + unsigned s_shift; // sbat->blockSize = 1 << s_shift + unsigned num_bat; // blocks allocated for big bat + unsigned dirent_start; // starting block for directory info + unsigned threshold; // switch from small to big file (usually 4K) + unsigned sbat_start; // starting block index to store small bat + unsigned num_sbat; // blocks allocated for small bat + unsigned mbat_start; // starting block to store meta bat + unsigned num_mbat; // blocks allocated for meta bat + unsigned long bb_blocks[109]; + + Header(); + bool valid(); + void load( const unsigned char* buffer ); + void save( unsigned char* buffer ); + void debug(); +}; + +class AllocTable +{ + public: + static const unsigned Eof; + static const unsigned Avail; + static const unsigned Bat; + static const unsigned MetaBat; + unsigned blockSize; + AllocTable(); + void clear(); + unsigned long count(); + void resize( unsigned long newsize ); + void preserve( unsigned long n ); + void set( unsigned long index, unsigned long val ); + unsigned unused(); + void setChain( std::vector ); + std::vector follow( unsigned long start ); + unsigned long operator[](unsigned long index ); + void load( const unsigned char* buffer, unsigned len ); + void save( unsigned char* buffer ); + unsigned size(); + void debug(); + private: + std::vector data; + AllocTable( const AllocTable& ); + AllocTable& operator=( const AllocTable& ); +}; + +class DirEntry +{ + public: + bool valid; // false if invalid (should be skipped) + std::string name; // the name, not in unicode anymore + bool dir; // true if directory + unsigned long size; // size (not valid if directory) + unsigned long start; // starting block + unsigned prev; // previous sibling + unsigned next; // next sibling + unsigned child; // first child +}; + +class DirTree +{ + public: + static const unsigned End; + DirTree(); + void clear(); + unsigned entryCount(); + DirEntry* entry( unsigned index ); + DirEntry* entry( const std::string& name, bool create=false ); + int indexOf( DirEntry* e ); + int parent( unsigned index ); + std::string fullName( unsigned index ); + std::vector children( unsigned index ); + void load( unsigned char* buffer, unsigned len ); + void save( unsigned char* buffer ); + unsigned size(); + void debug(); + private: + std::vector entries; + DirTree( const DirTree& ); + DirTree& operator=( const DirTree& ); +}; + +class StorageIO +{ + public: + Storage* storage; // owner + std::string filename; // filename + std::fstream file; // associated with above name + int result; // result of operation + bool opened; // true if file is opened + unsigned long filesize; // size of the file + + Header* header; // storage header + DirTree* dirtree; // directory tree + AllocTable* bbat; // allocation table for big blocks + AllocTable* sbat; // allocation table for small blocks + + std::vector sb_blocks; // blocks for "small" files + + std::list streams; + + StorageIO( Storage* storage, const char* filename ); + ~StorageIO(); + + bool open(); + void close(); + void flush(); + void load(); + void create(); + + unsigned long loadBigBlocks( std::vector blocks, unsigned char* buffer, unsigned long maxlen ); + + unsigned long loadBigBlock( unsigned long block, unsigned char* buffer, unsigned long maxlen ); + + unsigned long loadSmallBlocks( std::vector blocks, unsigned char* buffer, unsigned long maxlen ); + + unsigned long loadSmallBlock( unsigned long block, unsigned char* buffer, unsigned long maxlen ); + + StreamIO* streamIO( const std::string& name ); + + private: + // no copy or assign + StorageIO( const StorageIO& ); + StorageIO& operator=( const StorageIO& ); + +}; + +class StreamIO +{ + public: + StorageIO* io; + DirEntry* entry; + std::string fullName; + bool eof; + bool fail; + + StreamIO( StorageIO* io, DirEntry* entry ); + ~StreamIO(); + unsigned long size(); + void seek( unsigned long pos ); + unsigned long tell(); + int getch(); + unsigned long read( unsigned char* data, unsigned long maxlen ); + unsigned long read( unsigned long pos, unsigned char* data, unsigned long maxlen ); + + + private: + std::vector blocks; + + // no copy or assign + StreamIO( const StreamIO& ); + StreamIO& operator=( const StreamIO& ); + + // pointer for read + unsigned long m_pos; + + // simple cache system to speed-up getch() + unsigned char* cache_data; + unsigned long cache_size; + unsigned long cache_pos; + void updateCache(); +}; + +} // namespace POLE + +using namespace POLE; + +static inline unsigned long readU16( const unsigned char* ptr ) +{ + return ptr[0]+(ptr[1]<<8); +} + +static inline unsigned long readU32( const unsigned char* ptr ) +{ + return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24); +} + +static inline void writeU16( unsigned char* ptr, unsigned long data ) +{ + ptr[0] = (unsigned char)(data & 0xff); + ptr[1] = (unsigned char)((data >> 8) & 0xff); +} + +static inline void writeU32( unsigned char* ptr, unsigned long data ) +{ + ptr[0] = (unsigned char)(data & 0xff); + ptr[1] = (unsigned char)((data >> 8) & 0xff); + ptr[2] = (unsigned char)((data >> 16) & 0xff); + ptr[3] = (unsigned char)((data >> 24) & 0xff); +} + +static const unsigned char pole_magic[] = + { 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1 }; + +// =========== Header ========== + +Header::Header() +{ + b_shift = 9; + s_shift = 6; + num_bat = 0; + dirent_start = 0; + threshold = 4096; + sbat_start = 0; + num_sbat = 0; + mbat_start = 0; + num_mbat = 0; + + for( unsigned i = 0; i < 8; i++ ) + id[i] = pole_magic[i]; + for( unsigned i=0; i<109; i++ ) + bb_blocks[i] = AllocTable::Avail; +} + +bool Header::valid() +{ + if( threshold != 4096 ) return false; + if( num_bat == 0 ) return false; + if( (num_bat > 109) && (num_bat > (num_mbat * 127) + 109)) return false; + if( (num_bat < 109) && (num_mbat != 0) ) return false; + if( s_shift > b_shift ) return false; + if( b_shift <= 6 ) return false; + if( b_shift >=31 ) return false; + + return true; +} + +void Header::load( const unsigned char* buffer ) +{ + b_shift = readU16( buffer + 0x1e ); + s_shift = readU16( buffer + 0x20 ); + num_bat = readU32( buffer + 0x2c ); + dirent_start = readU32( buffer + 0x30 ); + threshold = readU32( buffer + 0x38 ); + sbat_start = readU32( buffer + 0x3c ); + num_sbat = readU32( buffer + 0x40 ); + mbat_start = readU32( buffer + 0x44 ); + num_mbat = readU32( buffer + 0x48 ); + + for( unsigned i = 0; i < 8; i++ ) + id[i] = buffer[i]; + for( unsigned i=0; i<109; i++ ) + bb_blocks[i] = readU32( buffer + 0x4C+i*4 ); +} + +void Header::save( unsigned char* buffer ) +{ + memset( buffer, 0, 0x4c ); + memcpy( buffer, pole_magic, 8 ); // ole signature + writeU32( buffer + 8, 0 ); // unknown + writeU32( buffer + 12, 0 ); // unknown + writeU32( buffer + 16, 0 ); // unknown + writeU16( buffer + 24, 0x003e ); // revision ? + writeU16( buffer + 26, 3 ); // version ? + writeU16( buffer + 28, 0xfffe ); // unknown + writeU16( buffer + 0x1e, b_shift ); + writeU16( buffer + 0x20, s_shift ); + writeU32( buffer + 0x2c, num_bat ); + writeU32( buffer + 0x30, dirent_start ); + writeU32( buffer + 0x38, threshold ); + writeU32( buffer + 0x3c, sbat_start ); + writeU32( buffer + 0x40, num_sbat ); + writeU32( buffer + 0x44, mbat_start ); + writeU32( buffer + 0x48, num_mbat ); + + for( unsigned i=0; i<109; i++ ) + writeU32( buffer + 0x4C+i*4, bb_blocks[i] ); +} + +void Header::debug() +{ + std::cout << std::endl; + std::cout << "b_shift " << b_shift << std::endl; + std::cout << "s_shift " << s_shift << std::endl; + std::cout << "num_bat " << num_bat << std::endl; + std::cout << "dirent_start " << dirent_start << std::endl; + std::cout << "threshold " << threshold << std::endl; + std::cout << "sbat_start " << sbat_start << std::endl; + std::cout << "num_sbat " << num_sbat << std::endl; + std::cout << "mbat_start " << mbat_start << std::endl; + std::cout << "num_mbat " << num_mbat << std::endl; + + unsigned s = (num_bat<=109) ? num_bat : 109; + std::cout << "bat blocks: "; + for( unsigned i = 0; i < s; i++ ) + std::cout << bb_blocks[i] << " "; + std::cout << std::endl; +} + +// =========== AllocTable ========== + +const unsigned AllocTable::Avail = 0xffffffff; +const unsigned AllocTable::Eof = 0xfffffffe; +const unsigned AllocTable::Bat = 0xfffffffd; +const unsigned AllocTable::MetaBat = 0xfffffffc; + +AllocTable::AllocTable() +{ + blockSize = 4096; + // initial size + resize( 128 ); +} + +unsigned long AllocTable::count() +{ + return data.size(); +} + +void AllocTable::resize( unsigned long newsize ) +{ + unsigned oldsize = data.size(); + data.resize( newsize ); + if( newsize > oldsize ) + for( unsigned i = oldsize; i pre; + for( unsigned i=0; i < n; i++ ) + pre.push_back( unused() ); +} + +unsigned long AllocTable::operator[]( unsigned long index ) +{ + unsigned long result; + result = data[index]; + return result; +} + +void AllocTable::set( unsigned long index, unsigned long value ) +{ + if( index >= count() ) resize( index + 1); + data[ index ] = value; +} + +void AllocTable::setChain( std::vector chain ) +{ + if( chain.size() ) + { + for( unsigned i=0; i AllocTable::follow( unsigned long start ) +{ + std::vector chain; + + if( start >= count() ) return chain; + + unsigned long p = start; + while( p < count() ) + { + if( p == (unsigned long)Eof ) break; + if( p == (unsigned long)Bat ) break; + if( p == (unsigned long)MetaBat ) break; + if( p >= count() ) break; + chain.push_back( p ); + if( data[p] >= count() ) break; + p = data[ p ]; + } + + return chain; +} + +unsigned AllocTable::unused() +{ + // find first available block + for( unsigned i = 0; i < data.size(); i++ ) + if( data[i] == Avail ) + return i; + + // completely full, so enlarge the table + unsigned block = data.size(); + resize( data.size()+10 ); + return block; +} + +void AllocTable::load( const unsigned char* buffer, unsigned len ) +{ + resize( len / 4 ); + for( unsigned i = 0; i < count(); i++ ) + set( i, readU32( buffer + i*4 ) ); +} + +// return space required to save this dirtree +unsigned AllocTable::size() +{ + return count() * 4; +} + +void AllocTable::save( unsigned char* buffer ) +{ + for( unsigned i = 0; i < count(); i++ ) + writeU32( buffer + i*4, data[i] ); +} + +void AllocTable::debug() +{ + std::cout << "block size " << data.size() << std::endl; + for( unsigned i=0; i< data.size(); i++ ) + { + if( data[i] == Avail ) continue; + std::cout << i << ": "; + if( data[i] == Eof ) std::cout << "[eof]"; + else if( data[i] == Bat ) std::cout << "[bat]"; + else if( data[i] == MetaBat ) std::cout << "[metabat]"; + else std::cout << data[i]; + std::cout << std::endl; + } +} + +// =========== DirTree ========== + +const unsigned DirTree::End = 0xffffffff; + +DirTree::DirTree() +{ + clear(); +} + +void DirTree::clear() +{ + // leave only root entry + entries.resize( 1 ); + entries[0].valid = true; + entries[0].name = "Root Entry"; + entries[0].dir = true; + entries[0].size = 0; + entries[0].start = End; + entries[0].prev = End; + entries[0].next = End; + entries[0].child = End; +} + +unsigned DirTree::entryCount() +{ + return entries.size(); +} + +DirEntry* DirTree::entry( unsigned index ) +{ + if( index >= entryCount() ) return (DirEntry*) 0; + return &entries[ index ]; +} + +int DirTree::indexOf( DirEntry* e ) +{ + for( unsigned i = 0; i < entryCount(); i++ ) + if( entry( i ) == e ) return i; + + return -1; +} + +int DirTree::parent( unsigned index ) +{ + // brute-force, basically we iterate for each entries, find its children + // and check if one of the children is 'index' + for( unsigned j=0; j chi = children( j ); + for( unsigned i=0; iname; + result.insert( 0, "/" ); + int p = parent( index ); + DirEntry * _entry = 0; + while( p > 0 ) + { + _entry = entry( p ); + if (_entry->dir && _entry->valid) + { + result.insert( 0, _entry->name); + result.insert( 0, "/" ); + } + --p; + index = p; + if( index <= 0 ) break; + } + return result; +} + +// given a fullname (e.g "/ObjectPool/_1020961869"), find the entry +// if not found and create is false, return 0 +// if create is true, a new entry is returned +DirEntry* DirTree::entry( const std::string& name, bool create ) +{ + if( !name.length() ) return (DirEntry*)0; + + // quick check for "/" (that's root) + if( name == "/" ) return entry( 0 ); + + // split the names, e.g "/ObjectPool/_1020961869" will become: + // "ObjectPool" and "_1020961869" + std::list names; + std::string::size_type start = 0, end = 0; + if( name[0] == '/' ) start++; + while( start < name.length() ) + { + end = name.find_first_of( '/', start ); + if( end == std::string::npos ) end = name.length(); + names.push_back( name.substr( start, end-start ) ); + start = end+1; + } + + // start from root + int index = 0 ; + + // trace one by one + std::list::iterator it; + + for( it = names.begin(); it != names.end(); ++it ) + { + // find among the children of index + std::vector chi = children( index ); + unsigned child = 0; + for( unsigned i = 0; i < chi.size(); i++ ) + { + DirEntry* ce = entry( chi[i] ); + if( ce ) + if( ce->valid && ( ce->name.length()>1 ) ) + if( ce->name == *it ) + child = chi[i]; + } + + // traverse to the child + if( child > 0 ) index = child; + else + { + // not found among children + if( !create ) return (DirEntry*)0; + + // create a new entry + unsigned parent = index; + entries.push_back( DirEntry() ); + index = entryCount()-1; + DirEntry* e = entry( index ); + e->valid = true; + e->name = *it; + e->dir = false; + e->size = 0; + e->start = 0; + e->child = End; + e->prev = End; + e->next = entry(parent)->child; + entry(parent)->child = index; + } + } + + return entry( index ); +} + +// helper function: recursively find siblings of index +void dirtree_find_siblings( DirTree* dirtree, std::vector& result, + unsigned index ) +{ + DirEntry* e = dirtree->entry( index ); + if( !e ) return; + if( !e->valid ) return; + + // prevent infinite loop + for( unsigned i = 0; i < result.size(); i++ ) + if( result[i] == index ) return; + + // add myself + result.push_back( index ); + + // visit previous sibling, don't go infinitely + unsigned prev = e->prev; + if( ( prev > 0 ) && ( prev < dirtree->entryCount() ) ) + { + for( unsigned i = 0; i < result.size(); i++ ) + if( result[i] == prev ) prev = 0; + if( prev ) dirtree_find_siblings( dirtree, result, prev ); + } + + // visit next sibling, don't go infinitely + unsigned next = e->next; + if( ( next > 0 ) && ( next < dirtree->entryCount() ) ) + { + for( unsigned i = 0; i < result.size(); i++ ) + if( result[i] == next ) next = 0; + if( next ) dirtree_find_siblings( dirtree, result, next ); + } +} + +std::vector DirTree::children( unsigned index ) +{ + std::vector result; + + DirEntry* e = entry( index ); + if( e ) if( e->valid && e->child < entryCount() ) + dirtree_find_siblings( this, result, e->child ); + + return result; +} + +void DirTree::load( unsigned char* buffer, unsigned size ) +{ + entries.clear(); + + for( unsigned i = 0; i < size/128; i++ ) + { + unsigned p = i * 128; + + // would be < 32 if first char in the name isn't printable + unsigned prefix = 32; + + // parse name of this entry, which stored as Unicode 16-bit + std::string name; + int name_len = readU16( buffer + 0x40+p ); + if( name_len > 64 ) name_len = 64; + for( int j=0; ( buffer[j+p]) && (jchild ); + buffer[ 0x42 ] = 5; + buffer[ 0x43 ] = 1; + + for( unsigned i = 1; i < entryCount(); i++ ) + { + DirEntry* e = entry( i ); + if( !e ) continue; + if( e->dir ) + { + e->start = 0xffffffff; + e->size = 0; + } + + // max length for name is 32 chars + std::string name = e->name; + if( name.length() > 32 ) + name.erase( 32, name.length() ); + + // write name as Unicode 16-bit + for( unsigned j = 0; j < name.length(); j++ ) + buffer[ i*128 + j*2 ] = name[j]; + + writeU16( buffer + i*128 + 0x40, name.length()*2 + 2 ); + writeU32( buffer + i*128 + 0x74, e->start ); + writeU32( buffer + i*128 + 0x78, e->size ); + writeU32( buffer + i*128 + 0x44, e->prev ); + writeU32( buffer + i*128 + 0x48, e->next ); + writeU32( buffer + i*128 + 0x4c, e->child ); + buffer[ i*128 + 0x42 ] = e->dir ? 1 : 2; + buffer[ i*128 + 0x43 ] = 1; // always black + } +} + +void DirTree::debug() +{ + for( unsigned i = 0; i < entryCount(); i++ ) + { + DirEntry* e = entry( i ); + if( !e ) continue; + std::cout << i << ": "; + if( !e->valid ) std::cout << "INVALID "; + std::cout << e->name << " "; + if( e->dir ) std::cout << "(Dir) "; + else std::cout << "(File) "; + std::cout << e->size << " "; + std::cout << "s:" << e->start << " "; + std::cout << "("; + if( e->child == End ) std::cout << "-"; else std::cout << e->child; + std::cout << " "; + if( e->prev == End ) std::cout << "-"; else std::cout << e->prev; + std::cout << ":"; + if( e->next == End ) std::cout << "-"; else std::cout << e->next; + std::cout << ")"; + std::cout << std::endl; + } +} + +// =========== StorageIO ========== + +StorageIO::StorageIO( Storage* st, const char* fname ) +{ + storage = st; + filename = fname; + result = Storage::Ok; + opened = false; + + header = new Header(); + dirtree = new DirTree(); + bbat = new AllocTable(); + sbat = new AllocTable(); + + filesize = 0; + bbat->blockSize = 1 << header->b_shift; + sbat->blockSize = 1 << header->s_shift; +} + +StorageIO::~StorageIO() +{ + if( opened ) close(); + delete sbat; + delete bbat; + delete dirtree; + delete header; +} + +bool StorageIO::open() +{ + // already opened ? close first + if( opened ) close(); + + load(); + + return result == Storage::Ok; +} + +void StorageIO::load() +{ + unsigned char* buffer = 0; + unsigned long buflen = 0; + std::vector blocks; + + // open the file, check for error + result = Storage::OpenFailed; + file.open( filename.c_str(), std::ios::binary | std::ios::in ); + if( !file.good() ) return; + + // find size of input file + file.seekg( 0, std::ios::end ); + filesize = file.tellg(); + + // load header + buffer = new unsigned char[512]; + file.seekg( 0 ); + file.read( (char*)buffer, 512 ); + header->load( buffer ); + delete[] buffer; + + // check OLE magic id + result = Storage::NotOLE; + for( unsigned i=0; i<8; i++ ) + if( header->id[i] != pole_magic[i] ) + return; + + // sanity checks + result = Storage::BadOLE; + if( !header->valid() ) return; + if( header->threshold != 4096 ) return; + + // important block size + bbat->blockSize = 1 << header->b_shift; + sbat->blockSize = 1 << header->s_shift; + + // find blocks allocated to store big bat + // the first 109 blocks are in header, the rest in meta bat + blocks.clear(); + blocks.resize( header->num_bat ); + for( unsigned i = 0; i < 109; i++ ) + if( i >= header->num_bat ) break; + else blocks[i] = header->bb_blocks[i]; + if( (header->num_bat > 109) && (header->num_mbat > 0) ) + { + unsigned char* buffer2 = new unsigned char[ bbat->blockSize ]; + unsigned k = 109; + unsigned mblock = header->mbat_start; + for( unsigned r = 0; r < header->num_mbat; r++ ) + { + loadBigBlock( mblock, buffer2, bbat->blockSize ); + for( unsigned s=0; s < bbat->blockSize-4; s+=4 ) + { + if( k >= header->num_bat ) break; + else blocks[k++] = readU32( buffer2 + s ); + } + mblock = readU32( buffer2 + bbat->blockSize-4 ); + } + delete[] buffer2; + } + + // load big bat + buflen = blocks.size()*bbat->blockSize; + if( buflen > 0 ) + { + buffer = new unsigned char[ buflen ]; + loadBigBlocks( blocks, buffer, buflen ); + bbat->load( buffer, buflen ); + delete[] buffer; + } + + // load small bat + blocks.clear(); + blocks = bbat->follow( header->sbat_start ); + buflen = blocks.size()*bbat->blockSize; + if( buflen > 0 ) + { + buffer = new unsigned char[ buflen ]; + loadBigBlocks( blocks, buffer, buflen ); + sbat->load( buffer, buflen ); + delete[] buffer; + } + + // load directory tree + blocks.clear(); + blocks = bbat->follow( header->dirent_start ); + buflen = blocks.size()*bbat->blockSize; + buffer = new unsigned char[ buflen ]; + loadBigBlocks( blocks, buffer, buflen ); + dirtree->load( buffer, buflen ); + unsigned sb_start = readU32( buffer + 0x74 ); + delete[] buffer; + + // fetch block chain as data for small-files + sb_blocks = bbat->follow( sb_start ); // small files + + // for troubleshooting, just enable this block +#if 0 + header->debug(); + sbat->debug(); + bbat->debug(); + dirtree->debug(); +#endif + + // so far so good + result = Storage::Ok; + opened = true; +} + +void StorageIO::create() +{ + // std::cout << "Creating " << filename << std::endl; + + file.open( filename.c_str(), std::ios::out|std::ios::binary ); + if( !file.good() ) + { + std::cerr << "Can't create " << filename << std::endl; + result = Storage::OpenFailed; + return; + } + + // so far so good + opened = true; + result = Storage::Ok; +} + +void StorageIO::flush() +{ + /* Note on Microsoft implementation: + - directory entries are stored in the last block(s) + - BATs are as second to the last + - Meta BATs are third to the last + */ +} + +void StorageIO::close() +{ + if( !opened ) return; + + file.close(); + opened = false; + + std::list::iterator it; + for( it = streams.begin(); it != streams.end(); ++it ) + delete *it; +} + +StreamIO* StorageIO::streamIO( const std::string& name ) +{ + // sanity check + if( !name.length() ) return (StreamIO*)0; + + // search in the entries + DirEntry* entry = dirtree->entry( name ); + //if( entry) std::cout << "FOUND\n"; + if( !entry ) return (StreamIO*)0; + //if( !entry->dir ) std::cout << " NOT DIR\n"; + if( entry->dir ) return (StreamIO*)0; + + StreamIO* result = new StreamIO( this, entry ); + result->fullName = name; + + return result; +} + +unsigned long StorageIO::loadBigBlocks( std::vector blocks, + unsigned char* data, unsigned long maxlen ) +{ + // sentinel + if( !data ) return 0; + if( !file.good() ) return 0; + if( blocks.size() < 1 ) return 0; + if( maxlen == 0 ) return 0; + + // read block one by one, seems fast enough + unsigned long bytes = 0; + for( unsigned long i=0; (i < blocks.size() ) & ( bytesblockSize * ( block+1 ); + unsigned long p = (bbat->blockSize < maxlen-bytes) ? bbat->blockSize : maxlen-bytes; + if( pos + p > filesize ) p = filesize - pos; + file.seekg( pos ); + file.read( (char*)data + bytes, p ); + bytes += p; + } + + return bytes; +} + +unsigned long StorageIO::loadBigBlock( unsigned long block, + unsigned char* data, unsigned long maxlen ) +{ + // sentinel + if( !data ) return 0; + if( !file.good() ) return 0; + + // wraps call for loadBigBlocks + std::vector blocks; + blocks.resize( 1 ); + blocks[ 0 ] = block; + + return loadBigBlocks( blocks, data, maxlen ); +} + +// return number of bytes which has been read +unsigned long StorageIO::loadSmallBlocks( std::vector blocks, + unsigned char* data, unsigned long maxlen ) +{ + // sentinel + if( !data ) return 0; + if( !file.good() ) return 0; + if( blocks.size() < 1 ) return 0; + if( maxlen == 0 ) return 0; + + // our own local buffer + unsigned char* buf = new unsigned char[ bbat->blockSize ]; + + // read small block one by one + unsigned long bytes = 0; + for( unsigned long i=0; ( iblockSize; + unsigned long bbindex = pos / bbat->blockSize; + if( bbindex >= sb_blocks.size() ) break; + + loadBigBlock( sb_blocks[ bbindex ], buf, bbat->blockSize ); + + // copy the data + unsigned offset = pos % bbat->blockSize; + unsigned long p = (maxlen-bytes < bbat->blockSize-offset ) ? maxlen-bytes : bbat->blockSize-offset; + p = (sbat->blockSize

    blockSize : p; + memcpy( data + bytes, buf + offset, p ); + bytes += p; + } + + delete[] buf; + + return bytes; +} + +unsigned long StorageIO::loadSmallBlock( unsigned long block, + unsigned char* data, unsigned long maxlen ) +{ + // sentinel + if( !data ) return 0; + if( !file.good() ) return 0; + + // wraps call for loadSmallBlocks + std::vector blocks; + blocks.resize( 1 ); + blocks.assign( 1, block ); + + return loadSmallBlocks( blocks, data, maxlen ); +} + +// =========== StreamIO ========== + +StreamIO::StreamIO( StorageIO* s, DirEntry* e) +{ + io = s; + entry = e; + eof = false; + fail = false; + + m_pos = 0; + + if( entry->size >= io->header->threshold ) + blocks = io->bbat->follow( entry->start ); + else + blocks = io->sbat->follow( entry->start ); + + // prepare cache + cache_pos = 0; + cache_size = 4096; // optimal ? + cache_data = new unsigned char[cache_size]; + updateCache(); +} + +// FIXME tell parent we're gone +StreamIO::~StreamIO() +{ + delete[] cache_data; +} + +void StreamIO::seek( unsigned long pos ) +{ + m_pos = pos; +} + +unsigned long StreamIO::tell() +{ + return m_pos; +} + +int StreamIO::getch() +{ + // past end-of-file ? + if( m_pos > entry->size ) return -1; + + // need to update cache ? + if( !cache_size || ( m_pos < cache_pos ) || + ( m_pos >= cache_pos + cache_size ) ) + updateCache(); + + // something bad if we don't get good cache + if( !cache_size ) return -1; + + int data = cache_data[m_pos - cache_pos]; + m_pos++; + + return data; +} + +unsigned long StreamIO::read( unsigned long pos, unsigned char* data, unsigned long maxlen ) +{ + // sanity checks + if( !data ) return 0; + if( maxlen == 0 ) return 0; + + unsigned long totalbytes = 0; + + if ( entry->size < io->header->threshold ) + { + // small file + unsigned long index = pos / io->sbat->blockSize; + + if( index >= blocks.size() ) return 0; + + unsigned char* buf = new unsigned char[ io->sbat->blockSize ]; + unsigned long offset = pos % io->sbat->blockSize; + while( totalbytes < maxlen ) + { + if( index >= blocks.size() ) break; + io->loadSmallBlock( blocks[index], buf, io->bbat->blockSize ); + unsigned long count = io->sbat->blockSize - offset; + if( count > maxlen-totalbytes ) count = maxlen-totalbytes; + memcpy( data+totalbytes, buf + offset, count ); + totalbytes += count; + offset = 0; + index++; + } + delete[] buf; + + } + else + { + // big file + unsigned long index = pos / io->bbat->blockSize; + + if( index >= blocks.size() ) return 0; + + unsigned char* buf = new unsigned char[ io->bbat->blockSize ]; + unsigned long offset = pos % io->bbat->blockSize; + while( totalbytes < maxlen ) + { + if( index >= blocks.size() ) break; + io->loadBigBlock( blocks[index], buf, io->bbat->blockSize ); + unsigned long count = io->bbat->blockSize - offset; + if( count > maxlen-totalbytes ) count = maxlen-totalbytes; + memcpy( data+totalbytes, buf + offset, count ); + totalbytes += count; + index++; + offset = 0; + } + delete [] buf; + + } + + return totalbytes; +} + +unsigned long StreamIO::read( unsigned char* data, unsigned long maxlen ) +{ + unsigned long bytes = read( tell(), data, maxlen ); + m_pos += bytes; + return bytes; +} + +void StreamIO::updateCache() +{ + // sanity check + if( !cache_data ) return; + + cache_pos = m_pos - ( m_pos % cache_size ); + unsigned long bytes = cache_size; + if( cache_pos + bytes > entry->size ) bytes = entry->size - cache_pos; + cache_size = read( cache_pos, cache_data, bytes ); +} + + +// =========== Storage ========== + +Storage::Storage( const char* filename ) +{ + io = new StorageIO( this, filename ); +} + +Storage::~Storage() +{ + delete io; +} + +int Storage::result() +{ + return io->result; +} + +bool Storage::open() +{ + return io->open(); +} + +void Storage::close() +{ + io->close(); +} + +std::list Storage::entries( const std::string& path ) +{ + std::list result; + DirTree* dt = io->dirtree; + DirEntry* e = dt->entry( path, false ); + if( e && e->dir ) + { + unsigned parent = dt->indexOf( e ); + std::vector children = dt->children( parent ); + for( unsigned i = 0; i < children.size(); i++ ) + result.push_back( dt->entry( children[i] )->name ); + } + + return result; +} + +bool Storage::isDirectory( const std::string& name ) +{ + DirEntry* e = io->dirtree->entry( name, false ); + return e ? e->dir : false; +} + +// =========== Stream ========== + +Stream::Stream( Storage* storage, const std::string& name ) +{ + io = storage->io->streamIO( name ); +} + +// FIXME tell parent we're gone +Stream::~Stream() +{ + delete io; +} + +std::string Stream::fullName() +{ + return io ? io->fullName : std::string(); +} + +unsigned long Stream::tell() +{ + return io ? io->tell() : 0; +} + +void Stream::seek( unsigned long newpos ) +{ + if( io ) io->seek( newpos ); +} + +unsigned long Stream::size() +{ + return io ? io->entry->size : 0; +} + +int Stream::getch() +{ + return io ? io->getch() : 0; +} + +unsigned long Stream::read( unsigned char* data, unsigned long maxlen ) +{ + return io ? io->read( data, maxlen ) : 0; +} + +bool Stream::eof() +{ + return io ? io->eof : false; +} + +bool Stream::fail() +{ + return io ? io->fail : true; +} diff --git a/filters/kpresenter/powerpoint/libppt/pole.h b/filters/kpresenter/powerpoint/libppt/pole.h new file mode 100644 index 000000000..61256b8f0 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/pole.h @@ -0,0 +1,177 @@ +/* POLE - Portable C++ library to access OLE Storage + Copyright (C) 2002-2005 Ariya Hidayat + + 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 authors 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. +*/ + +#ifndef POLE_H +#define POLE_H + +#include +#include + +namespace POLE +{ + +class StorageIO; +class Stream; +class StreamIO; + +class Storage +{ + friend class Stream; + friend class StreamOut; + +public: + + // for Storage::result() + enum { Ok, OpenFailed, NotOLE, BadOLE, UnknownError }; + + /** + * Constructs a storage with name filename. + **/ + Storage( const char* filename ); + + /** + * Destroys the storage. + **/ + ~Storage(); + + /** + * Opens the storage. Returns true if no error occurs. + **/ + bool open(); + + /** + * Closes the storage. + **/ + void close(); + + /** + * Returns the error code of last operation. + **/ + int result(); + + /** + * Finds all stream and directories in given path. + **/ + std::list entries( const std::string& path = "/" ); + + /** + * Returns true if specified entry name is a directory. + */ + bool isDirectory( const std::string& name ); + + /** + * Finds and returns a stream with the specified name. + * If reuse is true, this function returns the already created stream + * (if any). Otherwise it will create the stream. + * + * When errors occur, this function returns NULL. + * + * You do not need to delete the created stream, it will be handled + * automatically. + **/ + Stream* stream( const std::string& name, bool reuse = true ); + //Stream* stream( const std::string& name, int mode = Stream::ReadOnly, bool reuse = true ); + +private: + StorageIO* io; + + // no copy or assign + Storage( const Storage& ); + Storage& operator=( const Storage& ); + +}; + +class Stream +{ + friend class Storage; + friend class StorageIO; + +public: + + /** + * Creates a new stream. + */ + // name must be absolute, e.g "/Workbook" + Stream( Storage* storage, const std::string& name ); + + /** + * Destroys the stream. + */ + ~Stream(); + + /** + * Returns the full stream name. + */ + std::string fullName(); + + /** + * Returns the stream size. + **/ + unsigned long size(); + + /** + * Returns the current read/write position. + **/ + unsigned long tell(); + + /** + * Sets the read/write position. + **/ + void seek( unsigned long pos ); + + /** + * Reads a byte. + **/ + int getch(); + + /** + * Reads a block of data. + **/ + unsigned long read( unsigned char* data, unsigned long maxlen ); + + /** + * Returns true if the read/write position is past the file. + **/ + bool eof(); + + /** + * Returns true whenever error occurs. + **/ + bool fail(); + +private: + StreamIO* io; + + // no copy or assign + Stream( const Stream& ); + Stream& operator=( const Stream& ); +}; + +} + +#endif // POLE_H diff --git a/filters/kpresenter/powerpoint/libppt/powerpoint.cpp b/filters/kpresenter/powerpoint/libppt/powerpoint.cpp new file mode 100644 index 000000000..af035c697 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/powerpoint.cpp @@ -0,0 +1,6201 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#include "powerpoint.h" +#include "presentation.h" +#include "slide.h" +#include "pole.h" +#include "objects.h" + +#include +#include + +#include +#include + +#include +#include + +// Use anonymous namespace to cover following functions +namespace{ + +static inline unsigned long readU16( const void* p ) +{ + const unsigned char* ptr = (const unsigned char*) p; + return ptr[0]+(ptr[1]<<8); +} + +static inline signed long readS16( const void* p ) +{ + const unsigned char* ptr = (const unsigned char*) p; + return ptr[0]+(ptr[1]<<8); +} + +static inline unsigned long readU32( const void* p ) +{ + const unsigned char* ptr = (const unsigned char*) p; + return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24); +} + +static inline signed long readS32( const void* p ) +{ + const unsigned char* ptr = (const unsigned char*) p; + return ptr[0]+(ptr[1]<<8)+(ptr[2]<<16)+(ptr[3]<<24); +} + +} + +namespace Libppt +{ +std::ostream& operator<<( std::ostream& s, UString ustring ) +{ + char* str = ustring.ascii(); + s << str; + return s; +} + +} + + +using namespace Libppt; + + +// ========== base record ========== + +const unsigned int Record::id = 0; // invalid of-course + +Record::Record() +{ + stream_position = 0; + record_instance = 0; + record_parent = 0; +} + +Record::~Record() +{ +} + +Record* Record::create( unsigned type ) +{ + Record* record = 0; + + if( type == BookmarkCollectionContainer::id ) + record = new BookmarkCollectionContainer(); + + else if( type == DocumentContainer::id ) + record = new DocumentContainer(); + + else if( type == EnvironmentContainer::id ) + record = new EnvironmentContainer(); + + else if( type == ExObjListContainer::id ) + record = new ExObjListContainer(); + + else if( type == ExOleObjStgContainer::id ) + record = new ExOleObjStgContainer(); + + else if( type == ExHyperlinkContainer::id ) + record = new ExHyperlinkContainer(); + + else if( type == ExEmbedContainer::id ) + record = new ExEmbedContainer(); + + else if( type == ExLinkContainer::id ) + record = new ExLinkContainer(); + + else if( type == FontCollectionContainer::id ) + record = new FontCollectionContainer(); + + else if( type == HandoutContainer::id ) + record = new HandoutContainer(); + + else if( type == HeadersFootersContainer::id ) + record = new HeadersFootersContainer(); + + else if( type == ListContainer::id ) + record = new ListContainer(); + + else if( type == SlideContainer::id ) + record = new SlideContainer(); + + else if( type == SlideBaseContainer::id ) + record = new SlideBaseContainer(); + + else if( type == MainMasterContainer::id ) + record = new MainMasterContainer(); + + else if( type == NotesContainer::id ) + record = new NotesContainer(); + + else if( type == RunArrayContainer::id ) + record = new RunArrayContainer(); + + else if( type == SlideListWithTextContainer::id ) + record = new SlideListWithTextContainer(); + + else if( type == SlideViewInfoContainer::id ) + record = new SlideViewInfoContainer(); + + else if( type == SorterViewInfoContainer::id ) + record = new SorterViewInfoContainer(); + + else if( type == SrKinsokuContainer::id ) + record = new SrKinsokuContainer(); + + else if( type == SummaryContainer::id ) + record = new SummaryContainer(); + + else if( type == OutlineViewInfoContainer::id ) + record = new OutlineViewInfoContainer(); + + else if( type == ProgStringTagContainer ::id ) + record = new ProgStringTagContainer (); + + else if( type == PPDrawingGroupContainer ::id ) + record = new PPDrawingGroupContainer (); + + else if( type == PPDrawingContainer ::id ) + record = new PPDrawingContainer (); + + else if( type == ProgBinaryTagContainer ::id ) + record = new ProgBinaryTagContainer (); + + else if( type == ProgTagsContainer ::id ) + record = new ProgTagsContainer (); + + else if( type == VBAInfoContainer::id ) + record = new VBAInfoContainer(); + + else if( type == ViewInfoContainer::id ) + record = new ViewInfoContainer(); + + + else if( type == msofbtDgContainer::id ) + record = new msofbtDgContainer(); + + else if( type == msofbtSpgrContainer::id ) + record = new msofbtSpgrContainer(); + + else if( type == msofbtSpContainer::id ) + record = new msofbtSpContainer(); + + else if( type == msofbtDggContainer::id ) + record = new msofbtDggContainer(); + + else if( type == msofbtBstoreContainer::id ) + record = new msofbtBstoreContainer(); + + else if( type == msofbtSolverContainer::id ) + record = new msofbtSolverContainer(); + + + else if( type == BookmarkEntityAtom::id ) + record = new BookmarkEntityAtom(); + + else if( type == CStringAtom::id ) + record = new CStringAtom(); + + else if( type == ColorSchemeAtom::id ) + record = new ColorSchemeAtom(); + + else if( type == CurrentUserAtom::id ) + record = new CurrentUserAtom(); + + else if( type == DocumentAtom::id ) + record = new DocumentAtom(); + + else if( type == EndDocumentAtom::id ) + record = new EndDocumentAtom(); + + else if( type == ExEmbedAtom::id ) + record = new ExEmbedAtom(); + + else if( type == ExHyperlinkAtom::id ) + record = new ExHyperlinkAtom(); + + else if( type == ExLinkAtom::id ) + record = new ExLinkAtom(); + + else if( type == ExObjListAtom::id ) + record = new ExObjListAtom(); + + else if( type == ExOleObjAtom::id ) + record = new ExOleObjAtom(); + + else if( type == FontEntityAtom::id ) + record = new FontEntityAtom(); + + else if( type == GuideAtom::id ) + record = new GuideAtom(); + + else if( type == HeadersFootersAtom ::id ) + record = new HeadersFootersAtom (); + + else if( type == NotesAtom::id ) + record = new NotesAtom(); + + else if( type == PersistIncrementalBlockAtom::id ) + record = new PersistIncrementalBlockAtom(); + + else if( type == Record1043::id ) + record = new Record1043 (); + + else if( type == Record1044::id ) + record = new Record1044 (); + + else if( type == SrKinsokuAtom::id ) + record = new SrKinsokuAtom(); + + else if( type == SlideAtom::id ) + record = new SlideAtom(); + + else if( type == SlidePersistAtom::id ) + record = new SlidePersistAtom(); + + else if( type == StyleTextPropAtom::id ) + record = new StyleTextPropAtom(); + + else if( type == SlideViewInfoAtom::id ) + record = new SlideViewInfoAtom(); + + else if( type == SSDocInfoAtom ::id ) + record = new SSDocInfoAtom(); + + else if( type == SSlideLayoutAtom ::id ) + record = new SSlideLayoutAtom(); + + else if( type == SSSlideInfoAtom ::id ) + record = new SSSlideInfoAtom(); + + else if( type == TextHeaderAtom ::id ) + record = new TextHeaderAtom(); + + else if( type == TextBookmarkAtom ::id ) + record = new TextBookmarkAtom(); + + else if( type == TextBytesAtom::id ) + record = new TextBytesAtom (); + + else if( type == TextCharsAtom::id ) + record = new TextCharsAtom (); + + else if( type == TextSpecInfoAtom ::id ) + record = new TextSpecInfoAtom(); + + else if( type == TxCFStyleAtom ::id ) + record = new TxCFStyleAtom(); + + else if( type == TxMasterStyleAtom ::id ) + record = new TxMasterStyleAtom(); + + else if( type == TxPFStyleAtom ::id ) + record = new TxPFStyleAtom(); + + else if( type == TxSIStyleAtom ::id ) + record = new TxSIStyleAtom(); + + else if( type == UserEditAtom::id ) + record = new UserEditAtom(); + + else if( type == ViewInfoAtom::id ) + record = new ViewInfoAtom(); + + else if( type == msofbtDgAtom::id ) + record = new msofbtDgAtom() ; + + else if( type == msofbtSpgrAtom::id ) + record = new msofbtSpgrAtom() ; + + else if( type == msofbtSpAtom::id ) + record = new msofbtSpAtom() ; + + else if( type == msofbtOPTAtom::id ) + record = new msofbtOPTAtom() ; + + else if( type == msofbtChildAnchorAtom::id ) + record = new msofbtChildAnchorAtom() ; + + else if( type == msofbtClientAnchorAtom::id ) + record = new msofbtClientAnchorAtom() ; + + else if( type == msofbtClientDataAtom::id ) + record = new msofbtClientDataAtom() ; + + else if( type == msofbtClientTextboxAtom::id ) + record = new msofbtClientTextboxAtom() ; + + else if( type == msofbtDggAtom::id ) + record = new msofbtDggAtom() ; + + else if( type == msofbtColorMRUAtom::id ) + record = new msofbtColorMRUAtom() ; + + else if( type == msofbtSplitMenuColorsAtom::id ) + record = new msofbtSplitMenuColorsAtom() ; + + else if( type == msofbtBSEAtom::id ) + record = new msofbtBSEAtom() ; + + else if( type == msofbtCLSIDAtom::id ) + record = new msofbtCLSIDAtom() ; + + else if( type == msofbtRegroupItemsAtom::id ) + record = new msofbtRegroupItemsAtom() ; + + else if( type == msofbtColorSchemeAtom::id ) + record = new msofbtColorSchemeAtom() ; + + else if( type == msofbtClientTextboxAtom::id ) + record = new msofbtClientTextboxAtom() ; + + else if( type == msofbtAnchorAtom::id ) + record = new msofbtAnchorAtom() ; + + else if( type == msofbtOleObjectAtom::id ) + record = new msofbtOleObjectAtom() ; + + else if( type == msofbtDeletedPsplAtom::id ) + record = new msofbtDeletedPsplAtom() ; + + else if( type == msofbtConnectorRuleAtom::id ) + record = new msofbtConnectorRuleAtom() ; + + else if( type == msofbtAlignRuleAtom::id ) + record = new msofbtAlignRuleAtom() ; + + else if( type == msofbtArcRuleAtom::id ) + record = new msofbtArcRuleAtom() ; + + else if( type == msofbtClientRuleAtom::id ) + record = new msofbtClientRuleAtom() ; + + else if( type == msofbtCalloutRuleAtom::id ) + record = new msofbtCalloutRuleAtom() ; + + else if( type == msofbtSelectionAtom::id ) + record = new msofbtSelectionAtom() ; + +return record; +} + +void Record::setParent( Record* parent ) +{ + record_parent = parent; +} + +const Record* Record::parent() const +{ + return record_parent; +} + +void Record::setPosition( unsigned pos ) +{ + stream_position = pos; +} + +unsigned Record::position() const +{ + return stream_position; +} + +void Record::setInstance( unsigned instance ) +{ + record_instance = instance; +} + +unsigned Record::instance() const +{ + return record_instance; +} + +void Record::setData( unsigned, const unsigned char* ) +{ +} + +void Record::setData( unsigned, const unsigned char*, unsigned ) +{ +} + +void Record::dump( std::ostream& ) const +{ + // nothing to dump +} + +// ========== Container ========== + +Container::Container() +{ +} + +// ========== BookmarkCollectionContainer ========== + +const unsigned int BookmarkCollectionContainer::id = 2019; + +BookmarkCollectionContainer::BookmarkCollectionContainer() +{ +} + +// ========== msofbtDggContainer ========== + +const unsigned int msofbtDggContainer::id = 61440; /* F000 */ + +msofbtDggContainer::msofbtDggContainer() +{ +} + +// ========== msofbtBstoreContainer ========== + +const unsigned int msofbtBstoreContainer::id = 61441; /* F001 */ + +msofbtBstoreContainer::msofbtBstoreContainer() +{ +} + +// ========== msofbtDgContainer ========== + +const unsigned int msofbtDgContainer::id = 61442; /* F002 */ + +msofbtDgContainer::msofbtDgContainer() +{ +} + +// ========== msofbtSpgrContainer ========== + +const unsigned int msofbtSpgrContainer::id = 61443; /* F003*/ + +msofbtSpgrContainer::msofbtSpgrContainer() +{ +} + +// ========== msofbtSpContainer ========== + +const unsigned int msofbtSpContainer::id = 61444; /* F004 */ + +msofbtSpContainer::msofbtSpContainer() +{ +} + +// ========== msofbtSolverContainer ========== + +const unsigned int msofbtSolverContainer::id = 61445; /* F005 */ + +msofbtSolverContainer::msofbtSolverContainer() +{ +} + + +// ========== DocumentContainer ========== + +const unsigned int DocumentContainer::id = 1000; + +DocumentContainer::DocumentContainer() +{ +} + +// ========== NotesContainer ========== + +const unsigned int NotesContainer::id = 1008; + +NotesContainer::NotesContainer() +{ +} + +// ========== ExOleObjStgContainer ========== + +const unsigned int ExOleObjStgContainer::id = 4113; + +ExOleObjStgContainer::ExOleObjStgContainer() +{ +} + +// ========== FontCollectionContainer ========== + +const unsigned int FontCollectionContainer::id = 2005; + +FontCollectionContainer::FontCollectionContainer() +{ +} + + +// ========== ExObjListContainer ========== + +const unsigned int ExObjListContainer::id = 1033; + +ExObjListContainer::ExObjListContainer() +{ +} + +// ========== SlideContainer ========== + +const unsigned int SlideContainer::id = 1006; + +SlideContainer::SlideContainer() +{ +} + +// ========== SlideBaseContainer ========== + +const unsigned int SlideBaseContainer::id = 1004; + +SlideBaseContainer::SlideBaseContainer() +{ +} + +// ========== SlideListWithTextContainer ========== + +const unsigned int SlideListWithTextContainer::id = 4080; + +SlideListWithTextContainer::SlideListWithTextContainer() +{ +} + +// ========== SlideViewInfoContainer ========== + +const unsigned int SlideViewInfoContainer::id = 1018; + +SlideViewInfoContainer::SlideViewInfoContainer() +{ +} + +// ========== OutlineViewInfoContainer ========== + +const unsigned int OutlineViewInfoContainer::id = 1031; + +OutlineViewInfoContainer::OutlineViewInfoContainer() +{ +} + +// ========== SorterViewInfoContainer ========== + +const unsigned int SorterViewInfoContainer::id = 1032; + +SorterViewInfoContainer::SorterViewInfoContainer() +{ +} + +// ========== HandoutContainer ========== + +const unsigned int HandoutContainer::id = 4041; + +HandoutContainer::HandoutContainer() +{ +} + +// ========== ListContainer ========== + +const unsigned int ListContainer::id = 2000; + +ListContainer::ListContainer() +{ +} + +// ========== ExEmbedContainer ========== + +const unsigned int ExEmbedContainer::id = 4044; + +ExEmbedContainer::ExEmbedContainer() +{ +} + +// ========== ExLinkContainer ========== + +const unsigned int ExLinkContainer::id = 4046; + +ExLinkContainer::ExLinkContainer() +{ +} + +// ========== ExHyperlinkContainer ========== + +const unsigned int ExHyperlinkContainer::id = 4055; + +ExHyperlinkContainer::ExHyperlinkContainer() +{ +} + +// ========== MainMasterContainer ========== + +const unsigned int MainMasterContainer::id = 1016; + +MainMasterContainer::MainMasterContainer() +{ +} + +// ========== EnvironmentContainer ========== + +const unsigned int EnvironmentContainer::id = 1010; + +EnvironmentContainer::EnvironmentContainer() +{ +} + +// ========== HeadersFootersContainer ========== + +const unsigned int HeadersFootersContainer::id = 4057; + +HeadersFootersContainer::HeadersFootersContainer() +{ +} + +// ========== RunArrayContainer ========== + +const unsigned int RunArrayContainer::id = 2028; + +RunArrayContainer::RunArrayContainer() +{ +} + +// ========== SrKinsokuContainer ========== + +const unsigned int SrKinsokuContainer::id = 4040; + +SrKinsokuContainer::SrKinsokuContainer() +{ +} + +// ========== ProgTagsContainer ========== + +const unsigned int ProgTagsContainer::id = 5000; + +ProgTagsContainer::ProgTagsContainer() +{ +} + +// ========== ProgBinaryTagContainer ========== + +const unsigned int ProgBinaryTagContainer::id = 5002; + +ProgBinaryTagContainer::ProgBinaryTagContainer() +{ +} + +// ========== ProgStringTagContainer ========== + +const unsigned int ProgStringTagContainer::id = 5001; + +ProgStringTagContainer::ProgStringTagContainer() +{ +} + +// ========== PPDrawingGroupContainer ========== + +const unsigned int PPDrawingGroupContainer::id = 1035; + +PPDrawingGroupContainer::PPDrawingGroupContainer() +{ +} + +// ========== PPDrawingContainer ========== + +const unsigned int PPDrawingContainer::id = 1036; + +PPDrawingContainer::PPDrawingContainer() +{ +} + +// ========== SummaryContainer ========== + +const unsigned int SummaryContainer::id = 1026; + +SummaryContainer::SummaryContainer() +{ +} + +// ========== VBAInfoContainer ========== + +const unsigned int VBAInfoContainer::id = 1023; + +VBAInfoContainer::VBAInfoContainer() +{ +} + +// ========== ViewInfoContainer ========== + +const unsigned int ViewInfoContainer::id = 1020; + +ViewInfoContainer::ViewInfoContainer() +{ +} + +// ========== CStringAtom ========== + +const unsigned int CStringAtom::id = 4026; + +class CStringAtom::Private +{ +public: + UString ustring; +}; + + +CStringAtom::CStringAtom() +{ + d = new Private; +} + +CStringAtom::~CStringAtom() +{ + delete d; +} + +UString CStringAtom::ustring() const +{ + return d->ustring; +} + +void CStringAtom::setUString( const UString& ustr ) +{ + d->ustring = ustr; +} + +void CStringAtom::setData( unsigned size, const unsigned char* data ) +{ + UString str; + for( unsigned k=0; k<(size/2); k++ ) + { + unsigned uchar = readU16( data + k*2 ); + if (uchar == 0x0d) + { + uchar = 0x0b; +// std::cout << "found 0x0d in CStringAtom " << std::endl; + } + str.append( UString(uchar) ); + } + setUString( str ); +} + +void CStringAtom::dump( std::ostream& out ) const +{ + out << "CStringAtom" << std::endl; + out << "String : [" << ustring() << "]" << std::endl; +} + +// ========== DocumentAtom ========== + +const unsigned int DocumentAtom::id = 1001; + +class DocumentAtom::Private +{ +public: + int slideWidth; + int slideHeight; + int notesWidth; + int notesHeight; + int zoomNumer; + int zoomDenom; + int notesMasterPersist; + int handoutMasterPersist; + int firstSlideNum; + int slideSizeType; + int saveWithFonts; + int omitTitlePlace; + int rightToLeft; + int showComments; +}; + +DocumentAtom::DocumentAtom() +{ + d = new Private; + d->slideWidth = 5760; // 10 inches + d->slideHeight = 4320; // 7.5 inches + d->notesWidth = 4320; + d->notesHeight = 5760; + d->zoomNumer = 1; + d->zoomDenom = 2; + d->notesMasterPersist = 0; + d->handoutMasterPersist = 0; + d->firstSlideNum = 0; + d->slideSizeType = 0; + d->saveWithFonts = 0; + d->omitTitlePlace = 0; + d->rightToLeft = 0 ; + d->showComments = 0; +} + +DocumentAtom::~DocumentAtom() +{ + delete d; +} + +int DocumentAtom::slideWidth() const +{ + return d->slideWidth; +} + +void DocumentAtom::setSlideWidth( int w ) +{ + d->slideWidth = w; +} + +int DocumentAtom::slideHeight() const +{ + return d->slideHeight; +} + +void DocumentAtom::setSlideHeight( int h ) +{ + d->slideHeight = h; +} + +int DocumentAtom::notesWidth() const +{ + return d->notesWidth; +} + +void DocumentAtom::setNotesWidth( int nw ) +{ + d->notesWidth = nw; +} + +int DocumentAtom::notesHeight() const +{ + return d->notesHeight; +} + +void DocumentAtom::setNotesHeight( int nh ) +{ + d->notesHeight = nh; +} + +int DocumentAtom::zoomNumer () const +{ + return d->zoomNumer; +} + +void DocumentAtom::setZoomNumer( int numer ) +{ + d->zoomNumer = numer; +} + +int DocumentAtom::zoomDenom() const +{ + return d->zoomDenom; +} + +void DocumentAtom::setZoomDenom( int denom ) +{ + d->zoomDenom = denom; +} + +int DocumentAtom::notesMasterPersist() const +{ + return d->notesMasterPersist; +} + +void DocumentAtom::setNotesMasterPersist( int notesMasterPersist ) +{ + d->notesMasterPersist = notesMasterPersist; +} + +int DocumentAtom::handoutMasterPersist() const +{ + return d->handoutMasterPersist; +} + +void DocumentAtom::setHandoutMasterPersist(int handoutMasterPersist) +{ + d->handoutMasterPersist = handoutMasterPersist; +} + +int DocumentAtom::firstSlideNum() const +{ + return d->firstSlideNum; +} + +void DocumentAtom::setFirstSlideNum( int firstSlideNum ) +{ + d->firstSlideNum = firstSlideNum; +} + +int DocumentAtom::slideSizeType() const +{ + return d->slideSizeType; +} + +void DocumentAtom::setSlideSizeType( int slideSizeType ) +{ + d->slideSizeType = slideSizeType; +} + +int DocumentAtom::saveWithFonts() const +{ + return d->saveWithFonts; +} + +void DocumentAtom::setSaveWithFonts( int saveWithFonts ) +{ + d->saveWithFonts = saveWithFonts; +} + +int DocumentAtom::omitTitlePlace() const +{ + return d->omitTitlePlace; +} + +void DocumentAtom::setOmitTitlePlace( int omitTitlePlace ) +{ + d->omitTitlePlace = omitTitlePlace; +} + +int DocumentAtom::rightToLeft() const +{ + return d->rightToLeft; +} + +void DocumentAtom::setRightToLeft( int rightToLeft ) +{ + d->rightToLeft = rightToLeft; +} + +int DocumentAtom::showComments() const +{ + return d->showComments; +} + +void DocumentAtom::setShowComments( int showComments) +{ + d->showComments = showComments; +} + +void DocumentAtom::setData( unsigned , const unsigned char* data ) +{ + setSlideWidth( readU32( data+0 ) ); + setSlideHeight( readU32( data+4 ) ); + setNotesWidth( readU32( data+8 ) ); + setNotesHeight( readU32( data+12 ) ); + setZoomNumer( readS32( data+16 ) ); + setZoomDenom( readS32( data+20) ); + setNotesMasterPersist( readU32( data+24 ) ); + setHandoutMasterPersist ( readU32( data+28 ) ); + setFirstSlideNum( readU16( data+32 ) ); + setSlideSizeType( readS16( data+34 ) ); + setSaveWithFonts(data[36]); + setOmitTitlePlace(data[37]); + setRightToLeft(data[38]); + setShowComments(data[39]); +} + +void DocumentAtom::dump( std::ostream& out ) const +{ + out << "DocumentAtom" << std::endl; + out << "slide width " << slideWidth() << std::endl; + out << "slide height " << slideHeight() << std::endl; + out << "notes width " << notesWidth() << std::endl; + out << "notes height " << notesHeight() << std::endl; + out << "zoom numer " << zoomNumer() << std::endl; + out << "zoom denum " << zoomDenom() << std::endl; + out << "notesMasterPersist " << notesMasterPersist() << std::endl; + out << "handoutMasterPersist " << handoutMasterPersist() << std::endl; + out << "firstSlideNum " << firstSlideNum() << std::endl; + out << "slideSizeType " << slideSizeType() << std::endl; + out << "saveWithFonts " << saveWithFonts() << std::endl; + out << "omitTitlePlace " << omitTitlePlace() << std::endl; + out << "rightToLeft " << rightToLeft() << std::endl; + out << "showComments " << showComments() << std::endl; +} + +// ========== EndDocumentAtom ========== + +const unsigned int EndDocumentAtom::id = 1002; + +EndDocumentAtom::EndDocumentAtom() +{ +} + +void EndDocumentAtom::dump( std::ostream& out ) const +{ + out << "EndDocumentAtom" << std::endl; +} + + +// ========== FontEntityAtom ========== + +const unsigned int FontEntityAtom::id = 4023; + +class FontEntityAtom::Private +{ +public: + UString ustring; + int charset; + int clipPrecision; + int quality; + int pitchAndFamily; + +}; + +FontEntityAtom::FontEntityAtom() +{ + d = new Private; + d->charset = 0; + d->clipPrecision = 0; + d->quality = 0; + d->pitchAndFamily = 0; +} + +FontEntityAtom::~FontEntityAtom() +{ + delete d; +} + +UString FontEntityAtom::ustring() const +{ + return d->ustring; +} + +void FontEntityAtom::setUString( const UString& ustring ) +{ + d->ustring = ustring; +} + +int FontEntityAtom::charset() const +{ + return d->charset; +} + +void FontEntityAtom::setCharset( int charset ) +{ + d->charset = charset; +} + +int FontEntityAtom::clipPrecision() const +{ + return d->clipPrecision; +} + +void FontEntityAtom::setClipPrecision( int clipPrecision) +{ + d->clipPrecision = clipPrecision ; +} + +int FontEntityAtom::quality() const +{ + return d->quality; +} + +void FontEntityAtom::setQuality( int quality ) +{ + d->quality = quality; +} + +int FontEntityAtom::pitchAndFamily() const +{ + return d->pitchAndFamily; +} + +void FontEntityAtom::setPitchAndFamily( int pitchAndFamily ) +{ + d->pitchAndFamily = pitchAndFamily; +} + +void FontEntityAtom::setData( unsigned , const unsigned char* data ) +{ + + UString str; + for( unsigned k=0; k<32; k++ ) + { + unsigned uchar = readU16( data + k*2 ); + str.append( UString(uchar) ); + } + setUString( str ); + setCharset( data[64] ); + setClipPrecision( data[65] ); + setQuality( data[66] ); + setPitchAndFamily( data[67] ); +} + +void FontEntityAtom::dump( std::ostream& out ) const +{ + out << "FontEntityAtom" << std::endl; + out << "String : [" << ustring() << "]" << std::endl; + out << "Charset " << charset() << std::endl; + out << "ClipPrecision " << clipPrecision() << std::endl; + out << "Quality " << quality() << std::endl; + out << "PitchAndFamily " << pitchAndFamily() << std::endl; +} + +// ========== TextCharsAtom ========== + +const unsigned int TextCharsAtom::id = 4000; + + +class TextCharsAtom::Private +{ +public: + std::vector index; + std::vector ustring; +}; + +TextCharsAtom::TextCharsAtom() +{ + d = new Private; +} + +TextCharsAtom::~TextCharsAtom() +{ + delete d; +} + +unsigned TextCharsAtom::listSize() const +{ + return d->ustring.size(); +} + +UString TextCharsAtom::strValue( unsigned index ) const +{ + return d->ustring[index]; +} + +void TextCharsAtom::setText( UString ustring ) +{ + d->ustring.push_back( ustring ); +} + +void TextCharsAtom::setData( unsigned size, const unsigned char* data ) +{ + UString tempStr; + int index = 0; + + for( unsigned k=0; k<((0.5*size) + 1); k++ ) + { + unsigned uchar = readU16( data + k*2 ); + if ( (uchar == 0x0b) | (uchar == 0x0d) | (k == 0.5*size) ) + { + setText(tempStr); + index++; + tempStr = ""; + } + else + tempStr.append( UString(uchar) ); + + if ( ( uchar & 0xff00 ) == 0xf000 ) + { // handle later + std::cout << "got a symbol at " << k << "th character" << std::endl; + } + + } +} + +void TextCharsAtom::dump( std::ostream& out ) const +{ + out << "TextCharsAtom" << std::endl; + out << "listSize " << listSize() << std::endl; + + for (uint i=0; itype = 0; + d->pos = 0; +} + +GuideAtom::~GuideAtom () +{ + delete d; +} + +int GuideAtom::type() const +{ + return d->type; +} + +void GuideAtom::setType(int type) +{ + d->type= type; +} + +int GuideAtom::pos() const +{ + return d->pos; +} + +void GuideAtom::setPos(int pos) +{ + d->pos= pos; +} + +void GuideAtom::setData( unsigned , const unsigned char* data ) +{ + setType( readS32( data + 0 ) ); + setPos( readS32( data + 4 ) ); +} + +void GuideAtom::dump( std::ostream& out ) const +{ + out << "GuideAtom" << std::endl; + out << "type " << type() << std::endl; + out << "pos " << pos() << std::endl; +} + + +// ========== SSlideLayoutAtom ========== + +const unsigned int SSlideLayoutAtom::id = 1015; + +class SSlideLayoutAtom ::Private +{ +public: + int geom; + int placeholderId; +}; + +SSlideLayoutAtom::SSlideLayoutAtom () +{ + d = new Private; + d->geom = 0; + d->placeholderId = 0; +} + +SSlideLayoutAtom::~SSlideLayoutAtom () +{ + delete d; +} + +int SSlideLayoutAtom::geom() const +{ + return d->geom; +} + +void SSlideLayoutAtom::setGeom(int geom) +{ + d->geom= geom; +} + +int SSlideLayoutAtom::placeholderId() const +{ + return d->placeholderId; +} + +void SSlideLayoutAtom::setPlaceholderId(int placeholderId) +{ + d->placeholderId= placeholderId; +} + +void SSlideLayoutAtom ::setData( unsigned , const unsigned char* data ) +{ + setGeom( readS32( data + 0 ) ); + setPlaceholderId( data [4] ); +} + +void SSlideLayoutAtom ::dump( std::ostream& out ) const +{ + out << "SSlideLayoutAtom" << std::endl; + out << "geom " << geom() << std::endl; + out << "placeholderId " << placeholderId() << std::endl; +} + +// ========== ExLinkAtom ========== + +const unsigned int ExLinkAtom::id = 4049; + +class ExLinkAtom ::Private +{ +public: + int exObjId; + int flags; + int unavailable; +}; + +ExLinkAtom::ExLinkAtom () +{ + d = new Private; + d->exObjId = 0; + d->flags = 0; + d->unavailable = 0; +} + +ExLinkAtom::~ExLinkAtom () +{ + delete d; +} + +int ExLinkAtom::exObjId() const +{ + return d->exObjId; +} + +void ExLinkAtom::setExObjId(int exObjId) +{ + d->exObjId= exObjId; +} + +int ExLinkAtom::flags() const +{ + return d->flags; +} + +void ExLinkAtom::setFlags(int flags) +{ + d->flags= flags; +} + +int ExLinkAtom::unavailable() const +{ + return d->unavailable; +} + +void ExLinkAtom::setUnavailable(int unavailable) +{ + d->unavailable= unavailable; +} + +void ExLinkAtom ::setData( unsigned , const unsigned char* data ) +{ + setExObjId( readU32( data + 0 ) ); + setFlags( readU16( data + 4 ) ); + setUnavailable( data [6] ); + +} + +void ExLinkAtom ::dump( std::ostream& out ) const +{ + out << "ExLinkAtom" << std::endl; + out << "exObjId " << exObjId() << std::endl; + out << "flags " << flags() << std::endl; + out << "unavailable " << unavailable() << std::endl; +} + +// ========== NotesAtom ========== + +const unsigned int NotesAtom::id = 1009; + +class NotesAtom ::Private +{ +public: + int slideId; + int flags; +}; + +NotesAtom::NotesAtom () +{ + d = new Private; + d->slideId = 0; + d->flags = 0; +} + +NotesAtom::~NotesAtom () +{ + delete d; +} + +int NotesAtom::slideId() const +{ + return d->slideId; +} + +void NotesAtom::setSlideId(int slideId) +{ + d->slideId= slideId; +} + +int NotesAtom::flags() const +{ + return d->flags; +} + +void NotesAtom::setFlags(int flags) +{ + d->flags= flags; +} + +void NotesAtom ::setData( unsigned , const unsigned char* data ) +{ + setSlideId( readS32( data + 0 ) ); + setFlags( readU16( data + 4 ) ); +} + +void NotesAtom ::dump( std::ostream& out ) const +{ + out << "NotesAtom" << std::endl; + out << "slideId " << slideId() << std::endl; + out << "flags " << flags() << std::endl; +} + + +// ========== ExObjListAtom ========== + +const unsigned int ExObjListAtom::id = 1034; + +class ExObjListAtom ::Private +{ +public: + int objectIdSeed; +}; + +ExObjListAtom::ExObjListAtom () +{ + d = new Private; + d->objectIdSeed = 0; +} + +ExObjListAtom::~ExObjListAtom () +{ + delete d; +} + +int ExObjListAtom::objectIdSeed() const +{ + return d->objectIdSeed; +} + +void ExObjListAtom::setObjectIdSeed(int objectIdSeed) +{ + d->objectIdSeed= objectIdSeed; +} + +void ExObjListAtom ::setData( unsigned , const unsigned char* data ) +{ // check later for valid value + setObjectIdSeed( readU32( data + 0 ) ); +} + +void ExObjListAtom ::dump( std::ostream& out ) const +{ + out << "ExObjListAtom" << std::endl; + out << "objectIdSeed " << objectIdSeed() << std::endl; +} + + +// ========== ExEmbedAtom ========== + +const unsigned int ExEmbedAtom::id = 4045; + +class ExEmbedAtom ::Private +{ +public: + int followColorScheme; + int cantLockServerB; + int noSizeToServerB; + int isTable; +}; + +ExEmbedAtom::ExEmbedAtom () +{ + d = new Private; + d->followColorScheme = 0; + d->cantLockServerB = 0; + d->noSizeToServerB = 0; + d->isTable = 0; +} + +ExEmbedAtom::~ExEmbedAtom () +{ + delete d; +} + +int ExEmbedAtom::followColorScheme() const +{ + return d->followColorScheme; +} + +void ExEmbedAtom::setFollowColorScheme(int followColorScheme) +{ + d->followColorScheme= followColorScheme; +} + +int ExEmbedAtom::cantLockServerB() const +{ + return d->cantLockServerB; +} + +void ExEmbedAtom::setCantLockServerB(int cantLockServerB) +{ + d->cantLockServerB= cantLockServerB; +} + +int ExEmbedAtom::noSizeToServerB() const +{ + return d->noSizeToServerB; +} + +void ExEmbedAtom::setNoSizeToServerB(int noSizeToServerB) +{ + d->noSizeToServerB= noSizeToServerB; +} + +int ExEmbedAtom::isTable() const +{ + return d->isTable; +} + +void ExEmbedAtom::setIsTable(int isTable) +{ + d->isTable= isTable; +} + +void ExEmbedAtom ::setData( unsigned , const unsigned char* data ) +{ + setFollowColorScheme( readS32( data + 0 ) ); + setCantLockServerB( data [4] ); + setNoSizeToServerB( data[5] ); + setIsTable( data[6] ); +} + +void ExEmbedAtom ::dump( std::ostream& out ) const +{ + out << "ExEmbedAtom" << std::endl; + out << "followColorScheme " << followColorScheme() << std::endl; + out << "cantLockServerB " << cantLockServerB() << std::endl; + out << "noSizeToServerB " << noSizeToServerB() << std::endl; + out << "isTable " << isTable() << std::endl; +} + +// ========== ExOleObjAtom ========== + +const unsigned int ExOleObjAtom::id = 4035; + +class ExOleObjAtom ::Private +{ +public: + int drawAspect; + int type; + int objID; + int subType; + int objStgDataRef; + int isBlank; +}; + +ExOleObjAtom::ExOleObjAtom () +{ + d = new Private; + d->drawAspect = 0; + d->type = 0; + d->objID = 0; + d->subType = 0; + d->objStgDataRef = 0; + d->isBlank = 0; +} + +ExOleObjAtom::~ExOleObjAtom () +{ + delete d; +} + +int ExOleObjAtom::drawAspect() const +{ + return d->drawAspect; +} + +void ExOleObjAtom::setDrawAspect(int drawAspect) +{ + d->drawAspect= drawAspect; +} + +int ExOleObjAtom::type() const +{ + return d->type; +} + +void ExOleObjAtom::setType(int type) +{ + d->type= type; +} + +int ExOleObjAtom::objID() const +{ + return d->objID; +} + +void ExOleObjAtom::setObjID(int objID) +{ + d->objID= objID; +} + +int ExOleObjAtom::subType() const +{ + return d->subType; +} + +void ExOleObjAtom::setSubType(int subType) +{ + d->subType= subType; +} + +int ExOleObjAtom::objStgDataRef() const +{ + return d->objStgDataRef; +} + +void ExOleObjAtom::setObjStgDataRef(int objStgDataRef) +{ + d->objStgDataRef= objStgDataRef; +} + +int ExOleObjAtom::isBlank() const +{ + return d->isBlank; +} + +void ExOleObjAtom::setIsBlank(int isBlank) +{ + d->isBlank= isBlank; +} + +void ExOleObjAtom ::setData( unsigned , const unsigned char* data ) +{ + setDrawAspect( readU32( data + 0 ) ); + setType( readS32( data + 4 ) ); + setObjID( readS32( data + 8 ) ); + setSubType( readS32( data + 12 ) ); + setObjStgDataRef( readS32( data + 16 ) ); + setIsBlank( data[20] ); +} + +void ExOleObjAtom ::dump( std::ostream& out ) const +{ + out << "ExOleObjAtom" << std::endl; + out << "drawAspect " << drawAspect() << std::endl; + out << "type " << type() << std::endl; + out << "objID " << objID() << std::endl; + out << "subType " << subType() << std::endl; + out << "objID " << objID() << std::endl; + out << "objStgDataRef " << objStgDataRef() << std::endl; + out << "isBlank " << isBlank() << std::endl; +} + +// ========== ExHyperlinkAtom ========== + +const unsigned int ExHyperlinkAtom::id = 4051; + +class ExHyperlinkAtom ::Private +{ +public: + int objID; +}; + +ExHyperlinkAtom ::ExHyperlinkAtom () +{ + d = new Private; + d->objID = 0; +} + +ExHyperlinkAtom ::~ExHyperlinkAtom () +{ + delete d; +} + +int ExHyperlinkAtom ::objID() const +{ + return d->objID; +} + +void ExHyperlinkAtom ::setObjID(int objID) +{ + d->objID = objID; +} + +void ExHyperlinkAtom::setData( unsigned , const unsigned char* data ) +{ + setObjID( readU32( data + 0 ) ); +} + +void ExHyperlinkAtom ::dump( std::ostream& out ) const +{ + out << "ExHyperlinkAtom" << std::endl; + out << "objID " << objID() << std::endl; +} + + +// ========== PersistIncrementalBlockAtom ========== + +const unsigned int PersistIncrementalBlockAtom::id = 6002; + +class PersistIncrementalBlockAtom::Private +{ +public: + std::vector references; + std::vector offsets; +}; + +PersistIncrementalBlockAtom::PersistIncrementalBlockAtom() +{ + d = new Private; +} + +PersistIncrementalBlockAtom::~PersistIncrementalBlockAtom() +{ + delete d; +} + +unsigned PersistIncrementalBlockAtom::entryCount() const +{ + return d->references.size(); +} + +unsigned long PersistIncrementalBlockAtom::reference( unsigned index ) const +{ + unsigned long r = 0; + if( index < d->references.size() ) + r = d->references[index]; + return r; +} + +unsigned long PersistIncrementalBlockAtom::offset( unsigned index ) const +{ + unsigned long ofs = 0; + if( index < d->offsets.size() ) + ofs = d->offsets[index]; + return ofs; +} + +void PersistIncrementalBlockAtom ::setData( unsigned size, const unsigned char* data ) +{ + d->references.clear(); + d->offsets.clear(); + + unsigned ofs = 0; + while( ofs < size ) + { + long k = readU32( data+ ofs ); + unsigned count = k>>20; + unsigned start = k&0xfffff; + ofs += 4; + for( unsigned c=0; c < count; c++, ofs+=4 ) + { + if( ofs >= size ) break; + long of = readU32( data + ofs ); + d->references.push_back( start+c ); + d->offsets.push_back( of ); + } + } +} + +void PersistIncrementalBlockAtom ::dump( std::ostream& out ) const +{ + out << "PersistIncrementalBlockAtom" << std::endl; + for( unsigned i = 0; i < entryCount(); i++ ) + out << " Ref #" << reference(i) << " at offset " << offset(i) << std::endl; +} + + +// ========== HeadersFootersAtom ========== + +const unsigned int HeadersFootersAtom::id = 4058; + +class HeadersFootersAtom ::Private +{ +public: + int formatId; + int flags; +}; + +HeadersFootersAtom::HeadersFootersAtom () +{ + d = new Private; + d->formatId = 0; + d->flags = 0; +} + +HeadersFootersAtom::~HeadersFootersAtom () +{ + delete d; +} + +int HeadersFootersAtom::formatId() const +{ + return d->formatId; +} + +void HeadersFootersAtom::setFormatId(int formatId) +{ + d->formatId= formatId; +} + +int HeadersFootersAtom::flags() const +{ + return d->flags; +} + +void HeadersFootersAtom::setFlags(int flags) +{ + d->flags= flags; +} + +void HeadersFootersAtom::setData( unsigned , const unsigned char* data ) +{ + setFormatId( readS16( data + 0 ) ); + setFlags( readU16( data + 2 ) ); +} + +void HeadersFootersAtom::dump( std::ostream& out ) const +{ + out << "HeadersFootersAtom" << std::endl; + out << "formatId " << formatId() << std::endl; + out << "flags " << flags() << std::endl; +} + + +// ========== ColorSchemeAtom ========== + +const unsigned int ColorSchemeAtom::id = 2032; + +class ColorSchemeAtom ::Private +{ +public: + int background; + int textAndLines; + int shadows; + int titleText; + int fills; + int accent; + int accentAndHyperlink; + int accentAndFollowedHyperlink; + +}; + +ColorSchemeAtom::ColorSchemeAtom () +{ + d = new Private; + d->background = 0 ; + d->textAndLines = 0; + d->shadows = 0 ; + d->titleText = 0 ; + d->fills = 0; + d->accent = 0; + d->accentAndHyperlink = 0; + d->accentAndFollowedHyperlink = 0; +} + + +ColorSchemeAtom::~ColorSchemeAtom () +{ + delete d; +} + +int ColorSchemeAtom::background() const +{ + return d->background; +} + +void ColorSchemeAtom::setBackground( int background ) +{ + d->background = background; +} + +int ColorSchemeAtom::textAndLines() const +{ + return d->textAndLines; +} + +void ColorSchemeAtom::setTextAndLines( int textAndLines ) +{ + d->textAndLines = textAndLines; +} + +int ColorSchemeAtom::shadows() const +{ + return d->shadows; +} + +void ColorSchemeAtom::setShadows( int shadows ) +{ + d->shadows = shadows; +} + +int ColorSchemeAtom::titleText() const +{ + return d->titleText; +} + +void ColorSchemeAtom::setTitleText( int titleText ) +{ + d->titleText = titleText; +} + +int ColorSchemeAtom::fills() const +{ + return d->fills; +} + +void ColorSchemeAtom::setFills( int fills ) +{ + d->fills = fills; +} + +int ColorSchemeAtom::accent() const +{ + return d->accent; +} + +void ColorSchemeAtom::setAccent( int accent ) +{ + d->accent = accent; +} + +int ColorSchemeAtom::accentAndHyperlink() const +{ + return d->accentAndHyperlink; +} + +void ColorSchemeAtom::setAccentAndHyperlink ( int accentAndHyperlink ) +{ + d->accentAndHyperlink = accentAndHyperlink; +} + +int ColorSchemeAtom::accentAndFollowedHyperlink() const +{ + return d->accentAndFollowedHyperlink; +} + +void ColorSchemeAtom::setAccentAndFollowedHyperlink( int accentAndFollowedHyperlink ) +{ + d->accentAndFollowedHyperlink = accentAndFollowedHyperlink; +} + +void ColorSchemeAtom ::setData( unsigned , const unsigned char* data ) +{ + setBackground( readS32( data + 0 ) ); + setTextAndLines( readU32( data + 4 ) ); + setShadows( readU32( data + 8 ) ); + setTitleText( readU32( data + 12 ) ); + setFills( readU32( data + 16 ) ); + setAccent( readU32( data + 20 ) ); + setAccentAndHyperlink( readU32( data + 24 ) ); + setAccentAndFollowedHyperlink( readU32( data + 28 ) ); + +} + +void ColorSchemeAtom ::dump( std::ostream& out ) const +{ + out << "ColorSchemeAtom" << std::endl; + out << "background " << background() << std::endl; + out << " R " << ( (background() >> 0 ) & 0xff ) ; + out << " G " << ( (background() >> 8 ) & 0xff ) ; + out << " B " << ( (background() >> 16 ) & 0xff ) ; + out << " I " << ( (background() >> 24 ) & 0xff ) << std::endl; + out << "text and Lines " << textAndLines() << std::endl; + out << " R " << ( ( textAndLines() >> 0 ) & 0xff ) ; + out << " G " << ( ( textAndLines() >> 8 ) & 0xff ) ; + out << " B " << ( ( textAndLines() >> 16 ) & 0xff ) ; + out << " I " << ( ( textAndLines() >> 24 ) & 0xff ) << std::endl; + out << "shadows " << shadows() << std::endl; + out << " R " << ( ( shadows() >> 0 ) & 0xff ) ; + out << " G " << ( ( shadows() >> 8 ) & 0xff ) ; + out << " B " << ( ( shadows() >> 16 ) & 0xff ) ; + out << " I " << ( ( shadows() >> 24 ) & 0xff ) << std::endl; + out << "titleText " << titleText() << std::endl; + out << " R " << ( ( titleText() >> 0 ) & 0xff ) ; + out << " G " << ( ( titleText() >> 8 ) & 0xff ) ; + out << " B " << ( ( titleText() >> 16 ) & 0xff ) ; + out << " I " << ( ( titleText() >> 24 ) & 0xff ) << std::endl; + out << "fills " << fills() << std::endl; + out << " R " << ( ( fills() >> 0 ) & 0xff ) ; + out << " G " << ( ( fills() >> 8 ) & 0xff ) ; + out << " B " << ( ( fills() >> 16 ) & 0xff ) ; + out << " I " << ( ( fills() >> 24 ) & 0xff ) << std::endl; + out << "accent " << accent() << std::endl; + out << " R " << ( ( accent() >> 0 ) & 0xff ) ; + out << " G " << ( ( accent() >> 8 ) & 0xff ) ; + out << " B " << ( ( accent() >> 16 ) & 0xff ) ; + out << " I " << ( ( accent() >> 24 ) & 0xff ) << std::endl; + out << "accentAndHyperlink " << accentAndHyperlink() << std::endl; + out << " R " << ( ( accentAndHyperlink() >> 0 ) & 0xff ) ; + out << " G " << ( ( accentAndHyperlink() >> 8 ) & 0xff ) ; + out << " B " << ( ( accentAndHyperlink() >> 16 ) & 0xff ) ; + out << " I " << ( ( accentAndHyperlink() >> 24 ) & 0xff ) << std::endl; + out << "accentAndFollowedHyperlink " << accentAndFollowedHyperlink() << std::endl; + out << " R " << ( ( accentAndFollowedHyperlink() >> 0 ) & 0xff ) ; + out << " G " << ( ( accentAndFollowedHyperlink() >> 8 ) & 0xff ) ; + out << " B " << ( ( accentAndFollowedHyperlink() >> 16 ) & 0xff ) ; + out << " I " << ( ( accentAndFollowedHyperlink() >> 24 ) & 0xff ) << std::endl; +} + + +// ========== CurrentUserAtom ========== + +const unsigned int CurrentUserAtom::id = 4086; + +class CurrentUserAtom ::Private +{ +public: + int size; + int magic; + int offsetToCurrentEdit; + int lenUserName; + int docFileVersion; + int majorVersion; + int minorVersion; +}; + +CurrentUserAtom::CurrentUserAtom () +{ + d = new Private; + d->size = 0 ; + d->magic = 0 ; + d->offsetToCurrentEdit = 0; + d->lenUserName = 0 ; + d->docFileVersion = 0 ; + d->majorVersion = 0; + d->minorVersion = 0; +} + +CurrentUserAtom::~CurrentUserAtom () +{ + delete d; +} + +int CurrentUserAtom::size() const +{ + return d->size; +} + +void CurrentUserAtom::setSize( int size ) +{ + d->size = size; +} + +int CurrentUserAtom::magic() const +{ + return d->magic; +} + +void CurrentUserAtom::setMagic( int magic ) +{ + d->magic = magic; +} + +int CurrentUserAtom::offsetToCurrentEdit() const +{ + return d->offsetToCurrentEdit; +} + +void CurrentUserAtom::setOffsetToCurrentEdit( int offsetToCurrentEdit ) +{ + d->offsetToCurrentEdit = offsetToCurrentEdit; +} + +int CurrentUserAtom::lenUserName() const +{ + return d->lenUserName; +} + +void CurrentUserAtom::setLenUserName( int lenUserName ) +{ + d->lenUserName = lenUserName; +} + +int CurrentUserAtom::docFileVersion() const +{ + return d->docFileVersion; +} + +void CurrentUserAtom::setDocFileVersion( int docFileVersion ) +{ + d->docFileVersion = docFileVersion; +} + +int CurrentUserAtom::majorVersion() const +{ + return d->majorVersion; +} + +void CurrentUserAtom::setMajorVersion( int majorVersion ) +{ + d->majorVersion = majorVersion; +} + +int CurrentUserAtom::minorVersion() const +{ + return d->minorVersion; +} + +void CurrentUserAtom::setMinorVersion( int minorVersion ) +{ + d->minorVersion = minorVersion; +} + +void CurrentUserAtom ::setData( unsigned , const unsigned char* data ) +{ + setSize( readU32( data + 0 ) ); + setMagic( readU32( data + 4 ) ); + setOffsetToCurrentEdit( readU32( data + 8 ) ); + setLenUserName( readU16( data + 12 ) ); + setDocFileVersion( readU32( data + 14 ) ); + setMajorVersion( data[18] ); + setMinorVersion( data[19] ); +} + +void CurrentUserAtom ::dump( std::ostream& out ) const +{ + out << " CurrentUserAtom" << std::endl; + out << " size " << size() << std::endl; + out << " magic " << magic() << std::endl; + out << " offsetToCurrentEdit " << offsetToCurrentEdit() << std::endl; + out << " lenUserName " << lenUserName() << std::endl; + out << " docFileVersion " << docFileVersion() << std::endl; + out << " majorVersion " << majorVersion() << std::endl; + out << " minorVersion " << minorVersion() << std::endl; +} + + +// ========== UserEditAtom ========== + +const unsigned int UserEditAtom::id = 4085; + +class UserEditAtom::Private +{ +public: + int lastSlideId; + int majorVersion; + int minorVersion; + unsigned long offsetLastEdit; + unsigned long offsetPersistDir; + unsigned long documentRef; +}; + +UserEditAtom::UserEditAtom() +{ + d = new Private; + d->lastSlideId = 0; + d->majorVersion = 0; + d->minorVersion = 0; +} + +UserEditAtom::~UserEditAtom() +{ + delete d; +} + +int UserEditAtom::lastSlideId() const +{ + return d->lastSlideId; +} + +void UserEditAtom::setLastSlideId( int id ) +{ + d->lastSlideId = id; +} + +int UserEditAtom::majorVersion() const +{ + return d->majorVersion; +} + +void UserEditAtom::setMajorVersion( int majorVersion ) +{ + d->majorVersion = majorVersion; +} + +int UserEditAtom::minorVersion() const +{ + return d->minorVersion; +} + +void UserEditAtom::setMinorVersion( int minorVersion ) +{ + d->minorVersion = minorVersion; +} + +unsigned long UserEditAtom::offsetLastEdit() const +{ + return d->offsetLastEdit; +} + +void UserEditAtom::setOffsetLastEdit( unsigned long ofs ) +{ + d->offsetLastEdit = ofs; +} + +unsigned long UserEditAtom::offsetPersistDir() const +{ + return d->offsetPersistDir; +} + +void UserEditAtom::setOffsetPersistDir( unsigned long ofs ) const +{ + d->offsetPersistDir = ofs; +} + +unsigned long UserEditAtom::documentRef() const +{ + return d->documentRef; +} + +void UserEditAtom::setDocumentRef( unsigned long ref ) const +{ + d->documentRef = ref; +} + +void UserEditAtom::setData( unsigned , const unsigned char* data ) +{ + setLastSlideId( readU32( data + 0 ) ); + setMinorVersion( readU16( data + 4 ) ); + setMajorVersion( readU16( data + 6 ) ); + setOffsetLastEdit( readU32( data + 8 ) ); + setOffsetPersistDir( readU32( data + 12 ) ); + setDocumentRef( readU32( data + 16 ) ); +} + +void UserEditAtom::dump( std::ostream& out ) const +{ + out << " UserEditAtom" << std::endl; + out << " LastSlideID " << lastSlideId() << std::endl; + out << " MajorVersion " << majorVersion() << std::endl; + out << " MinorVersion " << minorVersion() << std::endl; + out << " Offset Last Edit " << offsetLastEdit() << std::endl; + out << " Offset Persist Dir " << offsetPersistDir() << std::endl; + out << " Document Ref " << documentRef() << std::endl; +} + +// ========== TextBookmarkAtom ========== + +const unsigned int TextBookmarkAtom::id = 4007; + +class TextBookmarkAtom::Private +{ +public: + int begin; + int end; + int bookmarkID; +}; + +TextBookmarkAtom::TextBookmarkAtom() +{ + d = new Private; + d->begin = 0; + d->end = 0; + d->bookmarkID = 0; +} + +TextBookmarkAtom::~TextBookmarkAtom() +{ + delete d; +} + +int TextBookmarkAtom::begin() const +{ + return d->begin; +} + +void TextBookmarkAtom::setBegin( int begin ) +{ + d->begin = begin; +} + +int TextBookmarkAtom::end() const +{ + return d->end; +} + +void TextBookmarkAtom::setEnd( int end ) +{ + d->end = end; +} + +int TextBookmarkAtom::bookmarkID() const +{ + return d->bookmarkID; +} + +void TextBookmarkAtom::setBookmarkID( int bookmarkID ) +{ + d->bookmarkID = bookmarkID; +} + +void TextBookmarkAtom::setData( unsigned , const unsigned char* data ) +{ + setBegin( readU32( data + 0 ) ); + setEnd( readU32( data + 4 ) ); + setBookmarkID( readU32( data + 8 ) ); +} + +void TextBookmarkAtom::dump( std::ostream& out ) const +{ + out << "TextBookmarkAtom" << std::endl; + out << "begin " << begin() << std::endl; + out << "end " << end() << std::endl; + out << "bookmarkID " << bookmarkID() << std::endl; +} + +// ========== BookmarkEntityAtom ========== + +const unsigned int BookmarkEntityAtom::id = 4048; + +class BookmarkEntityAtom::Private +{ +public: + int bookmarkID; + int bookmarkName; +}; + +BookmarkEntityAtom::BookmarkEntityAtom() +{ + d = new Private; + d->bookmarkID = 0; + d->bookmarkName = 0; +} + +BookmarkEntityAtom::~BookmarkEntityAtom() +{ + delete d; +} + +int BookmarkEntityAtom::bookmarkID() const +{ + return d->bookmarkID; +} + +void BookmarkEntityAtom::setBookmarkID( int bookmarkID ) +{ + d->bookmarkID = bookmarkID; +} + +int BookmarkEntityAtom::bookmarkName() const +{ + return d->bookmarkName; +} + +void BookmarkEntityAtom::setBookmarkName( int bookmarkName ) +{ + d->bookmarkName = bookmarkName; +} + +void BookmarkEntityAtom::setData( unsigned , const unsigned char* data ) +{ + setBookmarkID( readU32( data + 0 ) ); + setBookmarkName( readU16( data + 4 ) ); +} + +void BookmarkEntityAtom::dump( std::ostream& out ) const +{ + out << "BookmarkEntityAtom" << std::endl; + out << "bookmarkID " << bookmarkID() << std::endl; + out << "bookmarkName " << bookmarkName() << std::endl; +} + +// ========== SSDocInfoAtom ========== + +const unsigned int SSDocInfoAtom::id = 1025; + +class SSDocInfoAtom::Private +{ +public: + int penColorRed; + int penColorGreen; + int penColorBlue; + int penColorIndex; + int restartTime; + int startSlide; + int endSlide; + int namedShow; + int flags; +}; + +SSDocInfoAtom::SSDocInfoAtom() +{ + d = new Private; + d->penColorRed = 0; + d->penColorGreen = 0; + d->penColorBlue = 0; + d->penColorIndex = 0; + d->restartTime = 0; + d->startSlide = 0; + d->endSlide = 0; + d->namedShow = 0; + d->flags = 0; +} + +SSDocInfoAtom::~SSDocInfoAtom() +{ + delete d; +} + +int SSDocInfoAtom::penColorRed() const +{ + return d->penColorRed; +} + +void SSDocInfoAtom::setPenColorRed( int penColorRed ) +{ + d->penColorRed = penColorRed; +} + +int SSDocInfoAtom::penColorGreen() const +{ + return d->penColorGreen; +} + +void SSDocInfoAtom::setPenColorGreen( int penColorGreen ) +{ + d->penColorGreen = penColorGreen; +} + +int SSDocInfoAtom::penColorBlue() const +{ + return d->penColorBlue; +} + +void SSDocInfoAtom::setPenColorBlue( int penColorBlue ) +{ + d->penColorBlue = penColorBlue; +} + +int SSDocInfoAtom::penColorIndex() const +{ + return d->penColorIndex; +} + +void SSDocInfoAtom::setPenColorIndex( int penColorIndex ) +{ + d->penColorIndex = penColorIndex; +} + +int SSDocInfoAtom::restartTime() const +{ + return d->restartTime; +} + +void SSDocInfoAtom::setRestartTime( int restartTime ) +{ + d->restartTime = restartTime; +} + +int SSDocInfoAtom::startSlide() const +{ + return d->startSlide; +} + +void SSDocInfoAtom::setStartSlide( int startSlide ) +{ + d->startSlide = startSlide; +} + +int SSDocInfoAtom::endSlide() const +{ + return d->endSlide; +} + +void SSDocInfoAtom::setEndSlide( int endSlide ) +{ + d->endSlide = endSlide; +} + +int SSDocInfoAtom::namedShow() const +{ + return d->namedShow; +} + +void SSDocInfoAtom::setNamedShow( int namedShow ) +{ + d->namedShow = namedShow; +} + +int SSDocInfoAtom::flags() const +{ + return d->flags; +} + +void SSDocInfoAtom::setFlags( int flags ) +{ + d->flags = flags; +} + +void SSDocInfoAtom::setData( unsigned , const unsigned char* data ) +{ + setPenColorRed( data[0] ); + setPenColorGreen( data[1] ); + setPenColorBlue( data[2]); + setPenColorIndex( data[3] ); + setRestartTime( readS32( data + 4 ) ); + setStartSlide( readS16( data + 8 ) ); + setEndSlide( readS16( data + 10 ) ); + setNamedShow( readU16( data + 12 ) ); // 2 bytes repeat 32x + setFlags( readU16( data + 76 ) ); // offset correct ? +} + +void SSDocInfoAtom::dump( std::ostream& out ) const +{ + out << "UserEditAtom" << std::endl; + out << "penColorRed " << penColorRed() << std::endl; + out << "penColorGreen " << penColorGreen() << std::endl; + out << "penColorBlue " << penColorBlue() << std::endl; + out << "penColorIndex " << penColorIndex() << std::endl; + out << "restartTime " << restartTime() << std::endl; + out << "startSlide " << startSlide() << std::endl; + out << "endSlide " << endSlide() << std::endl; + out << "namedShow " << namedShow() << std::endl; + out << "Flags " << flags() << std::endl; +} + +// ========== SrKinsokuAtom ========== + +const unsigned int SrKinsokuAtom::id = 4050; + +SrKinsokuAtom::SrKinsokuAtom() +{ +} + +SrKinsokuAtom::~SrKinsokuAtom() +{ +} + +void SrKinsokuAtom::dump( std::ostream& out ) const +{ + out << "SrKinsokuAtom - not yet implemented" << std::endl; +} + +// ========== TxMasterStyleAtom ========== + +const unsigned int TxMasterStyleAtom::id = 4003; + +TxMasterStyleAtom::TxMasterStyleAtom() +{ +} + +TxMasterStyleAtom::~TxMasterStyleAtom() +{ +} + +void TxMasterStyleAtom::dump( std::ostream& out ) const +{ + out << "TxMasterStyleAtom - not yet implemented" << std::endl; +} + +// ========== SlideViewInfoAtom ========== + +const unsigned int SlideViewInfoAtom::id = 1022; + +class SlideViewInfoAtom ::Private +{ +public: + int showGuides; + int snapToGrid; + int snapToShape; +}; + +SlideViewInfoAtom::SlideViewInfoAtom () +{ + d = new Private; + d->showGuides = 0; + d->snapToGrid = 0; + d->snapToShape = 0; +} + +SlideViewInfoAtom::~SlideViewInfoAtom () +{ + delete d; +} + +int SlideViewInfoAtom::showGuides() const +{ + return d->showGuides; +} + +void SlideViewInfoAtom::setShowGuides(int showGuides) +{ + d->showGuides= showGuides; +} + +int SlideViewInfoAtom::snapToGrid() const +{ + return d->snapToGrid; +} + +void SlideViewInfoAtom::setSnapToGrid(int snapToGrid) +{ + d->snapToGrid= snapToGrid; +} + +int SlideViewInfoAtom::snapToShape() const +{ + return d->snapToShape; +} + +void SlideViewInfoAtom::setSnapToShape(int snapToShape) +{ + d->snapToGrid= snapToShape; +} + +void SlideViewInfoAtom ::setData( unsigned , const unsigned char* data ) +{ + setShowGuides(data[0]); + setSnapToGrid(data[1]); + setSnapToShape(data[2]); +} + +void SlideViewInfoAtom ::dump( std::ostream& out ) const +{ + out << "SlideViewInfoAtom" << std::endl; + out << "showGuides " << showGuides() << std::endl; + out << "snapToGrid " << snapToGrid() << std::endl; + out << "snapToShape " << snapToShape() << std::endl; +} + +// ========== ViewInfoAtom ========== + +const unsigned int ViewInfoAtom::id = 1021; + +class ViewInfoAtom ::Private +{ +public: + int curScaleXNum; + int curScaleXDen; + int curScaleYNum; + int curScaleYDen; + int prevScaleXNum; + int prevScaleXDen; + int prevScaleYNum; + int prevScaleYDen; + int viewSizeX; + int viewSizeY; + int originX; + int originY; + int varScale; + int draftMode; + int padding; +}; + +ViewInfoAtom::ViewInfoAtom () +{ + d = new Private; + d->curScaleXNum = 0; + d->curScaleXDen = 0; + d->curScaleYNum = 0; + d->curScaleYDen = 0; + d->prevScaleXNum = 0; + d->prevScaleXDen = 0; + d->prevScaleYNum = 0; + d->prevScaleYDen = 0; + d->viewSizeX = 0; + d->viewSizeY = 0; + d->originX = 0; + d->originY = 0; + d->varScale = 0; + d->draftMode = 0; + d->padding = 0; +} + +ViewInfoAtom::~ViewInfoAtom () +{ + delete d; +} + +int ViewInfoAtom::varScale() const +{ + return d->varScale; +} + +void ViewInfoAtom::setVarScale(int varScale) +{ + d->varScale= varScale; +} + +int ViewInfoAtom::draftMode() const +{ + return d->draftMode; +} + +void ViewInfoAtom::setDraftMode(int draftMode) +{ + d->draftMode= draftMode; +} + +int ViewInfoAtom::padding() const +{ + return d->padding; +} + +void ViewInfoAtom::setPadding(int padding) +{ + d->padding= padding; +} + +int ViewInfoAtom::viewSizeX() const +{ + return d->viewSizeX; +} + +void ViewInfoAtom::setViewSizeX(int viewSizeX) +{ + d->viewSizeX= viewSizeX; +} + +int ViewInfoAtom::viewSizeY() const +{ + return d->viewSizeY; +} + +void ViewInfoAtom::setViewSizeY(int viewSizeY) +{ + d->viewSizeY= viewSizeY; +} + +int ViewInfoAtom::originX() const +{ + return d->originX; +} + +void ViewInfoAtom::setOriginX(int originX) +{ + d->originX= originX; +} + +int ViewInfoAtom::originY() const +{ + return d->originY; +} + +void ViewInfoAtom::setOriginY (int originY) +{ + d->originY= originY; +} + +int ViewInfoAtom::prevScaleXNum() const +{ + return d->prevScaleXNum; +} + +void ViewInfoAtom::setPrevScaleXNum(int prevScaleXNum) +{ + d->prevScaleXNum= prevScaleXNum; +} + +int ViewInfoAtom::prevScaleXDen() const +{ + return d->prevScaleXDen; +} + +void ViewInfoAtom::setPrevScaleXDen(int prevScaleXDen) +{ + d->prevScaleXDen= prevScaleXDen; +} + +int ViewInfoAtom::prevScaleYNum() const +{ + return d->prevScaleYNum; +} + +void ViewInfoAtom::setPrevScaleYNum(int prevScaleYNum) +{ + d->prevScaleYNum= prevScaleYNum; +} + +int ViewInfoAtom::prevScaleYDen() const +{ + return d->prevScaleYDen; +} + +void ViewInfoAtom::setPrevScaleYDen(int prevScaleYDen) +{ + d->prevScaleYDen= prevScaleYDen; +} + +int ViewInfoAtom::curScaleXNum() const +{ + return d->curScaleXNum; +} + +void ViewInfoAtom::setCurScaleXNum(int curScaleXNum) +{ + d->curScaleXNum= curScaleXNum; +} + +int ViewInfoAtom::curScaleXDen() const +{ + return d->curScaleXDen; +} + +void ViewInfoAtom::setCurScaleXDen(int curScaleXDen) +{ + d->curScaleXDen= curScaleXDen; +} + +int ViewInfoAtom::curScaleYNum() const +{ + return d->curScaleYNum; +} + +void ViewInfoAtom::setCurScaleYNum(int curScaleYNum) +{ + d->curScaleYNum= curScaleYNum; +} + +int ViewInfoAtom::curScaleYDen() const +{ + return d->curScaleYDen; +} + +void ViewInfoAtom::setCurScaleYDen(int curScaleYDen) +{ + d->curScaleYDen= curScaleYDen; +} + +void ViewInfoAtom ::setData( unsigned , const unsigned char* data ) +{ + setCurScaleXNum(readS32( data + 0)); + setCurScaleXDen(readS32( data + 4 )); + setCurScaleYNum(readS32( data + 8)); + setCurScaleYDen(readS32( data + 12 )); + setPrevScaleXNum(readS32( data + 16 )); + setPrevScaleXDen(readS32( data + 20 )); + setPrevScaleYNum(readS32( data + 24 )); + setPrevScaleYDen(readS32( data + 28 )); + setViewSizeX(readS32( data + 32 )); + setViewSizeY(readS32( data + 36 )); + setOriginX(readS32( data + 40 )); + setOriginY(readS32( data + 44)); + setVarScale(data[48]); + setDraftMode(data[49]); + setPadding(readU16( data + 50 )); +} + +void ViewInfoAtom ::dump( std::ostream& out ) const +{ + out << "ViewInfoAtom" << std::endl; + out << "curScaleXNum " << curScaleXNum() << std::endl; + out << "curScaleXDen " << curScaleXDen() << std::endl; + out << "curScaleYNum " << curScaleYNum() << std::endl; + out << "curScaleYDen " << curScaleYDen() << std::endl; + out << "prevScaleXNum " << prevScaleXNum() << std::endl; + out << "prevScaleXDen " << prevScaleXNum() << std::endl; + out << "prevScaleYNum " << prevScaleYNum() << std::endl; + out << "prevScaleYDen " << prevScaleYNum() << std::endl; + out << "viewSizeX " << viewSizeX() << std::endl; + out << "viewSizeY " << viewSizeY() << std::endl; + out << "originX " << originX() << std::endl; + out << "originY " << originY() << std::endl; + out << "varScale " << varScale() << std::endl; + out << "draftMode " << draftMode() << std::endl; + out << "padding " << padding() << std::endl; +} + +// ========== StyleTextPropAtom ========== + +const unsigned int StyleTextPropAtom ::id = 4001; + +class StyleTextPropAtom::Private +{ +public: + unsigned stringLength; + struct PropAtomData + { + PropAtomData() + : charCount(0) + , depth(0) + , bulletOn(0) + , bulletHardFont(0) + , bulletHardColor(0) + , bulletChar(0) + , bulletFont(0) + , bulletHeight(0) + , bulletColor(0) + , align(0) + , lineFeed(0) + , upperDist(0) + , lowerDist(0) + , asianLB1(0) + , asianLB2(0) + , asianLB3(0) + , biDi(0) + {} + + int charCount; + int depth; + unsigned bulletOn; + unsigned bulletHardFont; + unsigned bulletHardColor; + unsigned bulletChar; + unsigned bulletFont; + unsigned bulletHeight; + unsigned bulletColor; + unsigned align; + unsigned lineFeed; + int upperDist; + int lowerDist; + int asianLB1; + int asianLB2; + int asianLB3; + unsigned biDi; + }; + std::vector atomData; + + int charMask; + int charCount2; + int charFlags; +}; + +StyleTextPropAtom::StyleTextPropAtom() +{ + d = new Private; + d->charMask = 0; + d->charCount2 = 0; + d->charFlags = 0; +} + +StyleTextPropAtom::~StyleTextPropAtom() +{ + delete d; +} + +unsigned StyleTextPropAtom::listSize() const +{ + return d->atomData.size(); +} + +int StyleTextPropAtom::charCount( unsigned index ) const +{ + return d->atomData[index].charCount; +} + +int StyleTextPropAtom::depth( unsigned index ) const +{ + return d->atomData[index].depth; +} + +int StyleTextPropAtom::bulletOn( unsigned index ) const +{ + return d->atomData[index].bulletOn; +} + +int StyleTextPropAtom::bulletHardFont( unsigned index ) const +{ + return d->atomData[index].bulletHardFont; +} + +int StyleTextPropAtom::bulletHardColor( unsigned index ) const +{ + return d->atomData[index].bulletHardColor; +} + +int StyleTextPropAtom::bulletChar( unsigned index ) const +{ + return d->atomData[index].bulletChar; +} + +int StyleTextPropAtom::bulletFont( unsigned index ) const +{ + return d->atomData[index].bulletFont; +} + +int StyleTextPropAtom::bulletHeight( unsigned index ) const +{ + return d->atomData[index].bulletHeight; +} + +int StyleTextPropAtom::bulletColor( unsigned index ) const +{ + return d->atomData[index].bulletColor; +} + +int StyleTextPropAtom::lineFeed( unsigned index ) const +{ + return d->atomData[index].lineFeed; +} + +int StyleTextPropAtom::upperDist( unsigned index ) const +{ + return d->atomData[index].upperDist; +} + +int StyleTextPropAtom::lowerDist( unsigned index ) const +{ + return d->atomData[index].lowerDist; +} + +int StyleTextPropAtom::align( unsigned index ) const +{ + return d->atomData[index].align; +} + +int StyleTextPropAtom::asianLB1( unsigned index ) const +{ + return d->atomData[index].asianLB1; +} + +int StyleTextPropAtom::asianLB2( unsigned index ) const +{ + return d->atomData[index].asianLB2; +} + +int StyleTextPropAtom::asianLB3( unsigned index ) const +{ + return d->atomData[index].asianLB3; +} + +int StyleTextPropAtom::biDi( unsigned index ) const +{ + return d->atomData[index].biDi; +} + +int StyleTextPropAtom::charMask() const +{ + return d->charMask; +} + +void StyleTextPropAtom::setCharMask( int charMask ) +{ + d->charMask = charMask; +} + +int StyleTextPropAtom::charFlags() const +{ + return d->charFlags; +} + +void StyleTextPropAtom::setCharFlags( int charFlags ) +{ + d->charFlags = charFlags; +} + +void StyleTextPropAtom::setData( unsigned /*size*/, const unsigned char* data, unsigned lastSize ) +{ + unsigned charRead = 0; + unsigned charCount = 0; + unsigned stringLength = unsigned( (0.5*lastSize) + 1 ); + + bool isTextPropAtom = true; + unsigned k=0; + + while ( charRead < stringLength ) + { + if ( isTextPropAtom == true ) + { + Private::PropAtomData atomData; + charCount = readU32(data+k) - 1; + k += 4; + atomData.charCount = charCount; + atomData.depth = readU16(data+k); + k += 2; + unsigned mask = readU32(data+6); + k += 4; + + if ( mask & 0xF ) + { + int bulletFlag = readU16(data+k); + k += 2; + atomData.bulletOn = ( bulletFlag & 1 ) ? 1 : 0; + atomData.bulletHardFont = ( bulletFlag & 2 ) ? 1 : 0; + atomData.bulletHardColor = ( bulletFlag & 4 ) ? 1 : 0; + } + + if ( mask & 0x0080 ) + { + atomData.bulletChar = readU16(data+k); + k += 2; + } + + if ( mask & 0x0010 ) + { + atomData.bulletFont = readU16(data+k); + k += 2; + } + + if ( mask & 0x0040 ) + { + atomData.bulletHeight = readU16(data+k); + k += 2; + } + + if ( mask & 0x0020 ) + { + atomData.bulletColor = readU32(data+k); + k += 4; + } + + if ( mask & 0x0F00 ) + { + if ( mask & 0x800 ) + { + unsigned dummy = readU16(data+k); + atomData.align = ( dummy & 3 ); + k += 2; + } + if ( mask & 0x400 ) + { + /*unsigned dummy =*/ readU16(data+k); + k += 2; + } + if ( mask & 0x200 ) + { + /*unsigned dummy =*/ readU16(data+k); + k += 2; + } + if ( mask & 0x100 ) + { + /*unsigned dummy =*/ readU16(data+k); + k += 2; + } + } + + if ( mask & 0x1000 ) + { + atomData.lineFeed = readU16(data+k); + k += 2; + } + + if ( mask & 0x2000 ) + { + atomData.upperDist = readU16(data+k); + k += 2; + } + + if ( mask & 0x4000 ) + { + atomData.lowerDist = readU16(data+k); + k += 2; + } + + if ( mask & 0x8000 ) + { + /*unsigned dummy =*/ readU16(data+k); + k += 2; + } + + if ( mask & 0x10000 ) + { + /*unsigned dummy =*/ readU16(data+k); + k += 2; + } + + if ( mask & 0xe0000 ) + { + unsigned dummy = readU16(data+k); + if ( mask & 0x20000 ) + atomData.asianLB1 = dummy & 1; + if ( mask & 0x40000 ) + atomData.asianLB2 = (dummy >> 1) & 1; + if ( mask & 0x80000 ) + atomData.asianLB3 = (dummy >> 2) & 1; + + k += 2; + } + + if ( mask & 0x200000 ) + { + atomData.biDi = readU16(data+k); + k += 2; + } + d->atomData.push_back( atomData ); + } + else + { + std::cout << "isTextPropAtom == false " << std::endl; + charCount = stringLength; + Private::PropAtomData atomData; + atomData.charCount = charCount; + d->atomData.push_back( atomData ); + } + + if ( ( charCount > stringLength ) || ( stringLength - ( charRead + charCount ) < 0 ) ) + { + isTextPropAtom = false; + charCount = stringLength - charRead; + Private::PropAtomData atomData; + atomData.charCount = charCount; + d->atomData.push_back( atomData ); + } + + charRead += charCount + 1; + + // std::cout << "k = " << k << std::endl; + } + + + /* charRead = 0; + while ( charRead < stringLength ) + { + std::cout << "in second while-loop " << std::endl; + if ( (isTextPropAtom == false) && (k < size) ) + { + unsigned charCount = readU16(data+k) ; + setCharCount (charCount); + k += 2; + unsigned dummy = readU16(data+k); + k += 2;else setAlign( dummy & 3 ); + int charToRead = size - (charRead + charCount); + // std::cout << "charToRead = " << charToRead << std::endl; + if (charToRead < 0) + { + charCount = size - charRead; + if ( charToRead < -1 ) + { + isTextPropAtom = false; + } + } + unsigned charMask = readU16(data+k) ; + k += 2; + setCharMask ( charMask ); + if ( charMask ) + { + setCharFlags( readU16(data+k) ); + k += 2; + } + // std::cout << "k = " << k << std::endl; + + static unsigned charAttrTable[16] = + { 16, 21, 22, 23, 17, 18, 19, 20, 24, 25, 26, 27, 28, 29, 30, 31 }; + + for ( int i = 0; i < 16; i++ ) + { + int j = charAttrTable[ i ]; + if ( charMask & ( 1 << j ) ) + { + switch ( j ) + { + case 23: //PPT_CharAttr_Symbol + { else setAlign( dummy & 3 ); + unsigned setSymbolFont= (readU16(data+k)); + std::cout << "setSymbolFont = " << setSymbolFont << std::endl; + //setSymbolFont(readU16(data+k)); + } break; + case 16: //PPT_CharAttr_Font + { + unsigned setFont= (readU16(data+k)); + std::cout << "setFont = " << setFont << std::endl; + //setFont(readU16(data+k)); + } break; + case 21: //PPT_CharAttr_AsianOrComplexFont + { + unsigned setAsianOrComplexFont= (readU16(data+k)); + std::cout << "setAsianOrComplexFont = " << setAsianOrComplexFont << std::endl; + //setAsianOrComplexFont(readU16(data+k)); + } break; + case 22: // PPT_CharAttr_Unknown2 + { unsigned setUnknown= (readU16(data+k)); + std::cout << "setUnknown = " << setUnknown << std::endl; + //setUnknown(readU16(data+k)); + } break; + case 17: //PPT_CharAttr_Fontvoid Record::setData( unsigned, const unsigned char* ) + { unsigned setFonttPropAtomHeight= (readU16(data+k)); + std::cout << "setFontHeight = " << setFontHeight << std::endl; + //setFontHeight(readU16(data+k)); + } break; + case 18: //PPT_CharAttr_FontColor + { unsigned setFontColor= (readU32(data+k)); + std::cout << "setFontColor = " << setFontColor << std::endl; + //setFontColor(readU32(data+k)); + k +=2; + } break; + case 19://PPT_CharAttr_Escapement + { unsigned setEscapement= (readU16(data+k)); + std::cout << "setEscapement = " << setEscapement << std::endl; + //setEscapement(readU32(data+k)); + } break; + default: + { unsigned dummy = readU16(data+k); + std::cout << "default " << dummy << std::endl; + } + } + k +=2; + } + } +powerpoint.cpp:3370: warning: convert + std::cout << "k = " << k << std::endl; + } + else + { + charRead = stringLength; + } + } */ + +} + + +void StyleTextPropAtom::dump( std::ostream& out ) const +{ + out << "StyleTextPropAtom" << std::endl; + out << "listSize " << listSize() << std::endl << std::endl; + for ( unsigned i = 0; i < listSize(); i++) + { + out << "charCount " << charCount(i) << std::endl; + out << "depth " << depth(i) << std::endl; + out << "isBulletOn " << bulletOn(i) << std::endl; + out << "isbulletHardFont " << bulletHardFont(i) << std::endl; + out << "isbulletHardColor " << bulletHardColor(i) << std::endl; + out << "bulletChar " << bulletChar(i) << std::endl; + out << "bulletFont " << bulletFont(i) << std::endl; + out << "bulletHeight " << bulletHeight(i) << std::endl; + out << "bulletColor " << std::endl; + out << " R " << ((bulletColor(i) >>0) & 0xff) << std::endl; + out << " G " << ((bulletColor(i) >>8) & 0xff) << std::endl; + out << " B " << ((bulletColor(i) >>16) & 0xff) << std::endl; + out << " I " << ((bulletColor(i) >>24) & 0xff) << std::endl; + out << "align " << align(i) << std::endl; + out << "lineFeed " << lineFeed(i) << std::endl; + out << "upperDist " << upperDist(i) << std::endl; + out << "lowerDist " << lowerDist(i) << std::endl; + out << "biDi " << biDi(i) << std::endl; + + out << std::endl; + } +// out << "charMask " << charMask() << std::endl; +// out << "charFlags " << charFlags() << std::endl; + +} + + + +// ========== TxCFStyleAtom ========== + +const unsigned int TxCFStyleAtom ::id = 4004; + + +class TxCFStyleAtom ::Private +{ +public: + int flags1; + int flags2; + int flags3; + int n1; + int fontHeight; + int fontColor; +}; + +TxCFStyleAtom ::TxCFStyleAtom () +{ + d = new Private; + d->flags1 = 0; + d->flags2 = 0; + d->flags3 = 0; + d->n1 = 0; + d->fontHeight = 0; + d->fontColor = 0; +} + +TxCFStyleAtom ::~TxCFStyleAtom () +{ + delete d; +} + +int TxCFStyleAtom::flags1() const +{ + return d->flags1; +} + +void TxCFStyleAtom::setFlags1( int flags1 ) +{ + d->flags1 = flags1; +} + +int TxCFStyleAtom::flags2() const +{ + return d->flags2; +} + +void TxCFStyleAtom::setFlags2( int flags2 ) +{ + d->flags2 = flags2; +} + +int TxCFStyleAtom::flags3() const +{ + return d->flags3; +} + +void TxCFStyleAtom::setFlags3( int flags3 ) +{ + d->flags3 = flags3; +} + +int TxCFStyleAtom::n1() const +{ + return d->n1; +} + +void TxCFStyleAtom::setN1( int n1 ) +{ + d->n1 = n1; +} + +int TxCFStyleAtom::fontHeight() const +{ + return d->fontHeight; +} + +void TxCFStyleAtom::setFontHeight( int fontHeight ) +{ + d->fontHeight = fontHeight; +} + +int TxCFStyleAtom::fontColor() const +{ + return d->fontColor; +} + +void TxCFStyleAtom::setFontColor( int fontColor ) +{ + d->fontColor = fontColor; +} + +void TxCFStyleAtom::setData( unsigned , const unsigned char* data ) +{ + setFlags1(readU16( data + 0)); + setFlags2(readU16( data + 2)); + setFlags3(readU16( data + 4)); + setN1(readU32( data + 6)); + setFontHeight(readU16( data + 10)); + setFontColor(readU32( data + 12)); +} + +void TxCFStyleAtom ::dump( std::ostream& out ) const +{ + out << "TxCFStyleAtom " << std::endl; + out << "flags1 " << flags1() << std::endl; + out << "flags2 " << flags2() << std::endl; + out << "flags3 " << flags3() << std::endl; + out << "n1 " << n1() << std::endl; + out << "font height " << fontHeight() << std::endl; + out << "font color " << fontColor() << std::endl; +} + +// ========== TxPFStyleAtom ========== + +const unsigned int TxPFStyleAtom::id = 4005; + +TxPFStyleAtom::TxPFStyleAtom() +{ +} + +TxPFStyleAtom::~TxPFStyleAtom() +{ +} + +void TxPFStyleAtom::dump( std::ostream& out ) const +{ + out << "TxPFStyleAtom - need special parse code" << std::endl; +} + +// ========== TxSIStyleAtom ========== + +const unsigned int TxSIStyleAtom ::id = 4009; + +TxSIStyleAtom ::TxSIStyleAtom () +{ +} + +TxSIStyleAtom ::~TxSIStyleAtom () +{ +} + +void TxSIStyleAtom ::dump( std::ostream& out ) const +{ + out << "TxSIStyleAtom - need special parse code" << std::endl; +} + +// ========== Record1043 ========== + +const unsigned int Record1043::id = 1043; + +Record1043::Record1043() +{ +} + +void Record1043::dump( std::ostream& out ) const +{ + out << "Record1043 - not known" << std::endl; +} + +// ========== Record1044 ========== + +const unsigned int Record1044::id = 1044; + +Record1044::Record1044() +{ +} + +void Record1044::dump( std::ostream& out ) const +{ + out << "Record1044 - not known" << std::endl; +} + +// ========== SlideAtom ========== + +const unsigned int SlideAtom::id = 1007; + +class SlideAtom::Private +{ +public: + int layoutGeom; + int layoutPlaceholderId1; + int layoutPlaceholderId2; + int layoutPlaceholderId3; + int layoutPlaceholderId4; + int layoutPlaceholderId5; + int layoutPlaceholderId6; + int layoutPlaceholderId7; + int layoutPlaceholderId8; + int masterId; + int notesId; + int flags; +}; + +SlideAtom::SlideAtom() +{ + d = new Private; + d->layoutGeom = 0; + d->layoutPlaceholderId1 = 0; + d->layoutPlaceholderId2 = 0; + d->layoutPlaceholderId3 = 0; + d->layoutPlaceholderId4 = 0; + d->layoutPlaceholderId5 = 0; + d->layoutPlaceholderId6 = 0; + d->layoutPlaceholderId7 = 0; + d->layoutPlaceholderId8 = 0; + d->masterId = 0; + d->notesId = 0; + d->flags = 0; +} + +SlideAtom::~SlideAtom() +{ + delete d; +} + +int SlideAtom::layoutGeom() const +{ + return d->layoutGeom; +} + +void SlideAtom::setLayoutGeom(int layoutGeom ) +{ + d->layoutGeom = layoutGeom; +} + + +int SlideAtom::layoutPlaceholderId() const +{ + return d->layoutPlaceholderId1; + return d->layoutPlaceholderId2; + return d->layoutPlaceholderId3; + return d->layoutPlaceholderId4; + return d->layoutPlaceholderId5; + return d->layoutPlaceholderId6; + return d->layoutPlaceholderId7; + return d->layoutPlaceholderId8; +} + +void SlideAtom::setLayoutPlaceholderId(int layoutPlaceholderId1, int layoutPlaceholderId2,int layoutPlaceholderId3,int layoutPlaceholderId4,int layoutPlaceholderId5,int layoutPlaceholderId6,int layoutPlaceholderId7,int layoutPlaceholderId8) +{ + d->layoutPlaceholderId1 = layoutPlaceholderId1; + d->layoutPlaceholderId2 = layoutPlaceholderId2; + d->layoutPlaceholderId3 = layoutPlaceholderId3; + d->layoutPlaceholderId4 = layoutPlaceholderId4; + d->layoutPlaceholderId5 = layoutPlaceholderId5; + d->layoutPlaceholderId6 = layoutPlaceholderId6; + d->layoutPlaceholderId7 = layoutPlaceholderId7; + d->layoutPlaceholderId8 = layoutPlaceholderId8; +} + +int SlideAtom::masterId() const +{ + return d->masterId; +} + +void SlideAtom::setMasterId(int masterId ) +{ + d->masterId = masterId; +} + +int SlideAtom::notesId() const +{ + return d->notesId; +} + +void SlideAtom::setNotesId(int notesId) +{ + d->notesId = notesId; +} + +int SlideAtom::flags() const +{ + return d->flags; +} + +void SlideAtom::setFlags( int flags) +{ + d->flags = flags; +} + +void SlideAtom::setData( unsigned , const unsigned char* data ) +{ + setLayoutGeom(readS32( data + 0 ) ); + setLayoutPlaceholderId (data[4], data[5], data[6], data[7], data[8], data[9], data[10],data[11]); + setMasterId( readS32( data + 12 ) ); + setNotesId( readS32( data + 16 ) ); + setFlags( readU16( data + 20 ) ); +} + +void SlideAtom::dump( std::ostream& out ) const +{ + out << "SlideAtom" << std::endl; + out << "layoutGeom " << layoutGeom() << std::endl; + // out << "layoutPlaceholderId " << layoutPlaceholderId() <layoutPlaceholderId1 <layoutPlaceholderId2 <layoutPlaceholderId3 <layoutPlaceholderId4 <layoutPlaceholderId5 <layoutPlaceholderId6 <layoutPlaceholderId7 <layoutPlaceholderId8 <transType = 0; + d->speed = 0; + d->direction = 0; + d->slideTime = 0; + d->buildFlags = 0; + d->soundRef = 0; +} + +SSSlideInfoAtom ::~SSSlideInfoAtom () +{ + delete d; +} + +int SSSlideInfoAtom ::transType() const +{ + return d->transType; +} + +void SSSlideInfoAtom ::settransType(int transType) +{ + d->transType = transType; +} + +int SSSlideInfoAtom ::speed() const +{ + return d->transType; +} + +void SSSlideInfoAtom ::setspeed(int speed) +{ + d->speed = speed; +} + +int SSSlideInfoAtom ::direction() const +{ + return d->transType; +} + +void SSSlideInfoAtom ::setdirection(int direction) +{ + d->direction = direction; +} + +int SSSlideInfoAtom ::slideTime() const +{ + return d->slideTime; +} + +void SSSlideInfoAtom ::setslideTime(int slideTime) +{ + d->slideTime = slideTime; +} + +int SSSlideInfoAtom ::buildFlags() const +{ + return d->buildFlags; +} + +void SSSlideInfoAtom ::setbuildFlags(int buildFlags) +{ + d->buildFlags = buildFlags; +} + +int SSSlideInfoAtom ::soundRef() const +{ + return d->soundRef; +} + +void SSSlideInfoAtom ::setsoundRef(int soundRef) +{ + d->soundRef = soundRef; +} + +void SSSlideInfoAtom ::setData( unsigned , const unsigned char* data ) +{ + settransType( readU32( data + 0 ) ); + setspeed(readS32( data + 4 )); + setdirection(readS32( data + 8 )); + setslideTime(readS32( data + 12 )); + setbuildFlags(readS32( data + 16 )); + setsoundRef(readS32( data + 20 )); +} + +void SSSlideInfoAtom ::dump( std::ostream& out ) const +{ + out << "SSSlideInfoAtom" << std::endl; + out << "transType " << transType() << std::endl; + out << "speed " << speed() << std::endl; + out << "direction " << direction() << std::endl; + out << "slideTime " << slideTime() << std::endl; + out << "buildFlags " << buildFlags() << std::endl; + out << "soundRef " << soundRef() << std::endl; +} + +// ========== TextHeaderAtom ========== + +const unsigned int TextHeaderAtom::id = 3999; + +class TextHeaderAtom ::Private +{ +public: + int textType; +}; + +TextHeaderAtom ::TextHeaderAtom () +{ + d = new Private; + d->textType = 0; +} + +TextHeaderAtom ::~TextHeaderAtom () +{ + delete d; +} + +int TextHeaderAtom ::textType() const +{ + return d->textType; +} + +void TextHeaderAtom ::setTextType( int type ) +{ + d->textType = type; +} + +void TextHeaderAtom ::setData( unsigned size, const unsigned char* data ) +{ + if( size < 4 ) return; + setTextType( readU32( data + 0 ) ); +} + +void TextHeaderAtom ::dump( std::ostream& out ) const +{ + out << "TextHeaderAtom" << std::endl; + out << " textType " << textType() << std::endl; +} + +// ========== TextBytesAtom ========== + +const unsigned int TextBytesAtom::id = 4008; + +class TextBytesAtom::Private +{ +public: + std::vector index; + std::vector ustring; + unsigned stringLength; +}; + +TextBytesAtom::TextBytesAtom() +{ + d = new Private; +} + +TextBytesAtom::~TextBytesAtom() +{ + delete d; +} + +unsigned TextBytesAtom::listSize() const +{ + return d->ustring.size(); +} + +unsigned TextBytesAtom::stringLength() const +{ + return d->stringLength; +} + +void TextBytesAtom::setStringLength( unsigned stringLength ) +{ + d->stringLength = stringLength; +} + +UString TextBytesAtom::strValue( unsigned index ) const +{ + return d->ustring[index]; +} + +void TextBytesAtom::setText( UString ustring ) +{ + d->ustring.push_back( ustring ); +} + +void TextBytesAtom::setData( unsigned size, const unsigned char* data ) +{ + UString tempStr; + int index = 0; + unsigned length = 0; + for( unsigned k=0; k<(size + 1); k++ ) + { + unsigned uchar = data[k]; + if ( (uchar == 0x0b) | (uchar == 0x0d) | (k == size) ) + { + setText(tempStr); + index++; + tempStr = ""; + } + else + tempStr.append( UString(uchar) ); + + if ( ( uchar & 0xff00 ) == 0xf000 ) + { // handle later + std::cout << "got a symbol at " << k << "th character" << std::endl; + } + length++; + } + + setStringLength(length); +} + +void TextBytesAtom::dump( std::ostream& out ) const +{ + out << "TextBytesAtom" << std::endl; + out << "stringLength " << stringLength() << std::endl; + out << "listSize " << listSize() << std::endl; + for (uint i=0; icharCount = 0; + d->flags = 0; +} + +TextSpecInfoAtom::~TextSpecInfoAtom () +{ + delete d; +} + +int TextSpecInfoAtom::charCount() const +{ + return d->charCount; +} + +void TextSpecInfoAtom::setCharCount(int charCount) +{ + d->charCount = charCount; +} + +int TextSpecInfoAtom::flags() const +{ + return d->flags; +} + +void TextSpecInfoAtom::setFlags(int flags) +{ + d->flags = flags; +} + +void TextSpecInfoAtom::setData( unsigned , const unsigned char* data ) +{ + setCharCount( readU32( data + 0 ) ); + setFlags( readU32( data + 4 ) ); + +} + +void TextSpecInfoAtom::dump( std::ostream& out ) const +{ + out << "TextSpecInfoAtom" << std::endl; + out << "charCount " << charCount() << std::endl; + out << "flags " << flags() << std::endl; +} + +// ========== SlidePersistAtom ========== + +const unsigned int SlidePersistAtom::id = 1011; + +class SlidePersistAtom::Private +{ +public: + int psrReference; + int flags; + int numberTexts; + int slideId; + int reserved; +}; + +SlidePersistAtom::SlidePersistAtom () +{ + d = new Private; + d->psrReference = 0; + d->flags = 0; + d->numberTexts=0; + d->slideId=0; + d->reserved=0; + } + +SlidePersistAtom::~SlidePersistAtom () +{ + delete d; +} + +int SlidePersistAtom::psrReference() const +{ + return d->psrReference; +} + +void SlidePersistAtom::setPsrReference( int psrReference ) +{ + d->psrReference = psrReference; +} + +int SlidePersistAtom::flags() const +{ + return d->flags; +} + +void SlidePersistAtom::setFlags( int flags ) +{ + d->flags = flags; +} + +int SlidePersistAtom::numberTexts() const +{ + return d->numberTexts; +} + +void SlidePersistAtom::setNumberTexts( int numberTexts ) +{ + d->numberTexts = numberTexts; +} + +int SlidePersistAtom::slideId() const +{ + return d->slideId; +} + +void SlidePersistAtom::setSlideId( int slideId ) +{ + d->slideId = slideId; +} + +int SlidePersistAtom::reserved() const +{ + return d->reserved; +} + +void SlidePersistAtom::setReserved( int reserved ) +{ + d->reserved = reserved; +} + +void SlidePersistAtom::setData( unsigned size, const unsigned char* data ) +{ + if( size < 20 ) return; + + setPsrReference( readU32( data + 0 ) ); + setFlags( readU32( data + 4 ) ); + setNumberTexts( readS32( data + 8 ) ); + setSlideId( readS32( data + 12 ) ); + setReserved(readU32( data + 16) ); +} + +void SlidePersistAtom ::dump( std::ostream& out ) const +{ + out << "SlidePersistAtom" << std::endl; + out << "psrReference " << psrReference() << std::endl; + out << "flags " << flags() << std::endl; + out << "numberTexts " << numberTexts() << std::endl; + out << "slideId " << slideId() << std::endl; + out << "reserved " << reserved() << " always 0."<shapeId = 0; + d->persistentFlag = 0; + d->background = false; + d->hFlip = false; + d->vFlip = false; +} + +msofbtSpAtom ::~msofbtSpAtom () +{ + delete d; +} + +unsigned long msofbtSpAtom::shapeId() const +{ + return d->shapeId; +} + +void msofbtSpAtom::setShapeId( unsigned long id ) +{ + d->shapeId = id; +} + +const char* msofbtSpAtom::shapeTypeAsString() const +{ + switch( instance() ) + { + case 0: return "msosptMin"; + case 1: return "msosptRectangle"; + case 2: return "msosptRoundRectangle"; + case 3: return "msosptEllipse"; + case 4: return "msosptDiamond"; + case 5: return "msosptIsoscelesTriangle"; + case 6: return "msosptRightTriangle"; + case 7: return "msosptParallelogram"; + case 8: return "msosptTrapezoid"; + case 9: return "msosptHexagon"; + case 10: return "msosptOctagon"; + case 11: return "msosptPlus"; + case 12: return "msosptStar"; + case 13: return "msosptArrow"; + case 14: return "msosptThickArrow"; + case 15: return "msosptHomePlate"; + case 16: return "msosptCube"; + case 17: return "msosptBalloon"; + case 18: return "msosptSeal"; + case 19: return "msosptArc"; + case 20: return "msosptLine"; + case 21: return "msosptPlaque"; + case 22: return "msosptCan ="; + case 23: return "msosptDonut"; + case 24: return "msosptTextSimple"; + case 25: return "msosptTextOctagon"; + case 26: return "msosptTextHexagon"; + case 27: return "msosptTextCurve"; + case 28: return "msosptTextOnRing"; + case 29: return "msosptTextRing"; + case 30: return "msosptTextOnCurve"; + case 31: return "msosptTextOnRing"; + case 32: return "msosptStraightConnector1"; + case 75: return "msosptPictureFrame"; + case 74: return "msosptHeart"; + case 96: return "msosptSmileyFace"; + case 202: return "msosptTextBox"; + default: break; + }; + return "Unknown"; +} + +unsigned long msofbtSpAtom::persistentFlag() const +{ + return d->persistentFlag; +} + +void msofbtSpAtom::setPersistentFlag( unsigned long persistentFlag ) +{ + d->persistentFlag = persistentFlag; +} + +bool msofbtSpAtom::isBackground() const +{ + return d->background; +} + +void msofbtSpAtom::setBackground( bool bg ) +{ + d->background = bg; +} + +bool msofbtSpAtom::isVerFlip() const +{ + return d->vFlip; +} + +void msofbtSpAtom::setVerFlip( bool vFlip ) +{ + d->vFlip = vFlip; +} + +bool msofbtSpAtom::isHorFlip() const +{ + return d->hFlip; +} + +void msofbtSpAtom::setHorFlip( bool hFlip ) +{ + d->hFlip = hFlip; +} + +void msofbtSpAtom::setData( unsigned size, const unsigned char* data ) +{ + if( size < 8 ) return; + + setShapeId( readU32( data + 0 ) ); + setPersistentFlag( readU32( data + 4 ) ); + + unsigned flag = readU16( data + 4 ); + setBackground( flag & 0x800 ); + setVerFlip( flag & 0x80 ); + setHorFlip( flag & 0x40 ); +} + +void msofbtSpAtom ::dump( std::ostream& out ) const +{ + out << "msofbtSpAtom " << std::endl; +} + +// ========== msofbtOPTAtom ========== + +const unsigned int msofbtOPTAtom::id = 61451; /* F00B */ + +class msofbtOPTAtom::Private +{ +public: + std::vector ids; + std::vector values; +}; + +msofbtOPTAtom ::msofbtOPTAtom () +{ + d = new Private; +} + +msofbtOPTAtom ::~msofbtOPTAtom () +{ + delete d; +} + +unsigned msofbtOPTAtom ::propertyCount() const +{ + return d->ids.size(); +} + +unsigned msofbtOPTAtom ::propertyId( unsigned index ) const +{ + return d->ids[index]; +} + +unsigned long msofbtOPTAtom ::propertyValue( unsigned index ) const +{ + return d->values[index]; +} + +void msofbtOPTAtom::setProperty( unsigned id, unsigned long val ) +{ + d->ids.push_back( id ); + d->values.push_back( val ); +} + +void msofbtOPTAtom::setData( unsigned size, const unsigned char* data ) +{ + unsigned i = 0; + unsigned comp_len = 0; + + d->ids.clear(); + d->values.clear(); + + while( i < size ) + { + unsigned x = readU16( data+i ); + unsigned int id = x & 0x3fff; + bool comp = x & 0x8000; + unsigned long val = readU32( data + i + 2 ); + if( comp ) + comp_len += val; + i += 6; + setProperty( id, val ); + } +} + +void msofbtOPTAtom ::dump( std::ostream& out ) const +{ + out << "msofbtOPTAtom " << std::endl; +} + + +// ========== msofbtChildAnchorAtom ========== + +const unsigned int msofbtChildAnchorAtom::id = 61455; /* F00F */ + +msofbtChildAnchorAtom ::msofbtChildAnchorAtom () +{ +} + +msofbtChildAnchorAtom ::~msofbtChildAnchorAtom () +{ +} + +void msofbtChildAnchorAtom ::dump( std::ostream& out ) const +{ + out << "msofbtChildAnchorAtom " << std::endl; +} + +// ========== msofbtClientAnchorAtom ========== + +const unsigned int msofbtClientAnchorAtom::id = 61456; /* F010 */ + +class msofbtClientAnchorAtom::Private +{ +public: + int left; + int top; + int right; + int bottom; +}; + +msofbtClientAnchorAtom::msofbtClientAnchorAtom () +{ + d = new Private; + d->left = 0; + d->top = 0; + d->right=0; + d->bottom=0; + } + +msofbtClientAnchorAtom ::~msofbtClientAnchorAtom () +{ + delete d; +} + +int msofbtClientAnchorAtom ::left() const +{ + return d->left; +} + +void msofbtClientAnchorAtom ::setLeft( int left ) +{ + d->left = left; +} + +int msofbtClientAnchorAtom ::top() const +{ + return d->top; +} + +void msofbtClientAnchorAtom ::setTop( int top ) +{ + d->top = top; +} + +int msofbtClientAnchorAtom ::right() const +{ + return d->right; +} + +void msofbtClientAnchorAtom ::setRight( int right ) +{ + d->right = right; +} + +int msofbtClientAnchorAtom ::bottom() const +{ + return d->bottom; +} + +void msofbtClientAnchorAtom ::setBottom( int bottom ) +{ + d->bottom = bottom; +} + +void msofbtClientAnchorAtom ::setData( unsigned , const unsigned char* data ) +{ + setTop( readU16( data + 0 ) ); + setLeft( readU16( data + 2 ) ); + setRight( readU16( data + 4 ) ); + setBottom( readU16( data + 6 ) ); +} + +void msofbtClientAnchorAtom ::dump( std::ostream& out ) const +{ + out << "msofbtClientAnchorAtom " << std::endl; + out << "left " << left() << std::endl; + out << "top " << top() << std::endl; + out << "right " << right() << std::endl; + out << "bottom " << bottom() << std::endl; + +} + +// ========== msofbtClientDataAtom ========== + +const unsigned int msofbtClientDataAtom::id = 61457; /* F011 */ + +class msofbtClientDataAtom::Private +{ +public: + unsigned placementId; + unsigned placeholderId; +}; + +msofbtClientDataAtom::msofbtClientDataAtom () +{ + d = new Private; + d->placementId = 0; + d->placeholderId = 0; +} + +msofbtClientDataAtom::~msofbtClientDataAtom () +{ + delete d; +} + +unsigned msofbtClientDataAtom::placementId() const +{ + return d->placementId; +} + +void msofbtClientDataAtom::setPlacementId( unsigned id ) +{ + d->placementId = id; +} + +unsigned msofbtClientDataAtom::placeholderId() const +{ + return d->placeholderId; +} + +void msofbtClientDataAtom::setPlaceholderId( unsigned id ) +{ + d->placeholderId = id; +} + +const char* msofbtClientDataAtom::placeholderIdAsString() const +{ + switch( d->placeholderId ) + { + case 0: return "None"; + case 1: return "Master title"; + case 2: return "Master body"; + case 3: return "Master centered title"; + case 4: return "Master notes slide image"; + case 5: return "Master notes body image"; + case 6: return "Master date"; + case 7: return "Master slide number"; + case 8: return "Master footer"; + case 9: return "Master header"; + case 10: return "Master subtitle"; + case 11: return "Generic text object"; + case 12: return "Title"; + case 13: return "Body"; + case 14: return "Notes body"; + case 15: return "Centered title"; + case 16: return "Subtitle"; + case 17: return "Vertical text title"; + case 18: return "Vertical text body"; + case 19: return "Notes slide image"; + case 20: return "Object"; + case 21: return "Graph"; + case 22: return "Table"; + case 23: return "Clip Art"; + case 24: return "Organization Chart"; + case 25: return "Media Clip"; + default: break; + }; + + return "Unknown"; +} + + +// 00 00 c3 0b ===> OEPlaceholderAtom +// 08 00 00 00 +// 00 00 00 00 ===> Placement ID +// 0f ====> Placeholder ID +// 00 =====> Size of placeholder +// 9e 00 + +void msofbtClientDataAtom::setData( unsigned size, const unsigned char* data ) +{ + if( size < 12 ) return; + setPlacementId( readU16( data+8 ) ); + setPlaceholderId( data[12]-1 ); +} + +void msofbtClientDataAtom ::dump( std::ostream& out ) const +{ + out << "msofbtClientDataAtom " << std::endl; +} + +// ========== msofbtDggAtom ========== + +const unsigned int msofbtDggAtom::id = 61446; /* F011 */ + +msofbtDggAtom ::msofbtDggAtom () +{ +} + +msofbtDggAtom ::~msofbtDggAtom () +{ +} + +void msofbtDggAtom ::dump( std::ostream& out ) const +{ + out << "msofbtDggAtom " << std::endl; +} + +// ========== msofbtClientTextboxAtom ========== + +const unsigned int msofbtClientTextboxAtom::id = 61453; /* F00D */ + +class msofbtClientTextboxAtom::Private +{ +public: + UString ustring; +}; + +msofbtClientTextboxAtom::msofbtClientTextboxAtom() +{ + d = new Private; +} + +msofbtClientTextboxAtom::~msofbtClientTextboxAtom() +{ + delete d; +} + +UString msofbtClientTextboxAtom::ustring() const +{ + return d->ustring; +} + +void msofbtClientTextboxAtom::setUString( const UString& ustr ) +{ + d->ustring = ustr; +} + +void msofbtClientTextboxAtom::setData( unsigned size, const unsigned char* data ) +{ + UString str; + for( unsigned k=0; kfillColor = 0; + d->lineColor = 0; + d->shadowColor = 0; + d->threeDColor = 0; +} + +msofbtSplitMenuColorsAtom ::~msofbtSplitMenuColorsAtom () +{ + delete d; +} + +unsigned msofbtSplitMenuColorsAtom::fillColor() const +{ + return d->fillColor; +} + +void msofbtSplitMenuColorsAtom::setFillColor( unsigned fillColor ) +{ + d->fillColor = fillColor; +} + +unsigned msofbtSplitMenuColorsAtom::lineColor() const +{ + return d->lineColor; +} + +void msofbtSplitMenuColorsAtom::setLineColor( unsigned lineColor ) +{ + d->lineColor = lineColor; +} + +unsigned msofbtSplitMenuColorsAtom::shadowColor() const +{ + return d->shadowColor; +} + +void msofbtSplitMenuColorsAtom::setShadowColor( unsigned shadowColor ) +{ + d->shadowColor = shadowColor; +} + +unsigned msofbtSplitMenuColorsAtom::threeDColor() const +{ + return d->threeDColor; +} + +void msofbtSplitMenuColorsAtom::setThreeDColor( unsigned threeDColor ) +{ + d->threeDColor = threeDColor; +} + +void msofbtSplitMenuColorsAtom::setData( unsigned , const unsigned char* data ) +{ + setFillColor( readU32( data+0 ) ); + setLineColor( readU32( data+4 ) ); + setShadowColor( readU32( data+8 ) ); + setThreeDColor( readU32( data+12 ) ); +} + +void msofbtSplitMenuColorsAtom ::dump( std::ostream& out ) const +{ + out << "msofbtSplitMenuColorsAtom " << std::endl; + out << "fillColor" << fillColor() << std::endl; + out << "lineColor" << lineColor() << std::endl; + out << "shadowColor" << shadowColor() << std::endl; + out << "threeDColor" << threeDColor() << std::endl; +} + +// ========== msofbtBSEAtom ========== + +const unsigned int msofbtBSEAtom::id = 61447; /* F007 */ + +msofbtBSEAtom ::msofbtBSEAtom () +{ +} + +msofbtBSEAtom ::~msofbtBSEAtom () +{ +} + +void msofbtBSEAtom ::dump( std::ostream& out ) const +{ + out << "msofbtBSEAtom " << std::endl; +} + +// ========== msofbtCLSIDAtom ========== + +const unsigned int msofbtCLSIDAtom::id = 61462; /* F016 */ + +msofbtCLSIDAtom ::msofbtCLSIDAtom () +{ +} + +msofbtCLSIDAtom ::~msofbtCLSIDAtom () +{ +} + +void msofbtCLSIDAtom ::dump( std::ostream& out ) const +{ + out << "msofbtCLSIDAtom " << std::endl; +} + +// ========== msofbtRegroupItemsAtom ========== + +const unsigned int msofbtRegroupItemsAtom::id = 61720; /* F118 */ + +msofbtRegroupItemsAtom ::msofbtRegroupItemsAtom () +{ +} + +msofbtRegroupItemsAtom ::~msofbtRegroupItemsAtom () +{ +} + +void msofbtRegroupItemsAtom ::dump( std::ostream& out ) const +{ + out << "msofbtRegroupItemsAtom " << std::endl; +} + +// ========== msofbtColorSchemeAtom ========== + +const unsigned int msofbtColorSchemeAtom::id = 61728; /* F120 */ + +msofbtColorSchemeAtom ::msofbtColorSchemeAtom () +{ +} + +msofbtColorSchemeAtom ::~msofbtColorSchemeAtom () +{ +} + +void msofbtColorSchemeAtom ::dump( std::ostream& out ) const +{ + out << "msofbtColorSchemeAtom " << std::endl; +} + +// ========== msofbtConnectorRuleAtom ========== + +const unsigned int msofbtConnectorRuleAtom::id = 61458; /* F012 */ + +msofbtConnectorRuleAtom ::msofbtConnectorRuleAtom () +{ +} + +msofbtConnectorRuleAtom ::~msofbtConnectorRuleAtom () +{ +} + +void msofbtConnectorRuleAtom ::dump( std::ostream& out ) const +{ + out << "msofbtConnectorRuleAtom " << std::endl; +} + +// ========== msofbtAlignRuleAtom ========== + +const unsigned int msofbtAlignRuleAtom::id = 61459; /* F013 */ + +class msofbtAlignRuleAtom ::Private +{ +public: + int ruid; + int align; + int cProxies; +}; + + +msofbtAlignRuleAtom ::msofbtAlignRuleAtom () +{ d = new Private; + d->ruid = 0; + d->align = 0; + d->cProxies = 0; +} + +msofbtAlignRuleAtom ::~msofbtAlignRuleAtom () +{ + delete d; +} + +int msofbtAlignRuleAtom::ruid() const +{ + return d->ruid; +} + +void msofbtAlignRuleAtom::setRuid( int ruid ) +{ + d->ruid = ruid; +} + +int msofbtAlignRuleAtom::align() const +{ + return d->align; +} + +void msofbtAlignRuleAtom::setAlign( int ruid ) +{ + d->ruid = ruid; +} + +int msofbtAlignRuleAtom::cProxies() const +{ + return d->cProxies; +} + +void msofbtAlignRuleAtom::setCProxies( int cProxies ) +{ + d->cProxies = cProxies; +} + +void msofbtAlignRuleAtom::setData( unsigned , const unsigned char* data ) +{ + setRuid( readU32( data+0 ) ); + setAlign( readU32( data+4 ) ); + setCProxies( readU32( data+8 ) ); +} + +void msofbtAlignRuleAtom ::dump( std::ostream& out ) const +{ + out << "msofbtAlignRuleAtom " << std::endl; + out << "ruid" << ruid() << std::endl; + out << "align " << align() << std::endl; + out << "cProxies " << cProxies() << std::endl; +} + + +// ========== msofbtArcRuleAtom ========== + +const unsigned int msofbtArcRuleAtom::id = 61460; /* F014 */ + +msofbtArcRuleAtom ::msofbtArcRuleAtom () +{ +} + +msofbtArcRuleAtom ::~msofbtArcRuleAtom () +{ +} + +void msofbtArcRuleAtom ::dump( std::ostream& out ) const +{ + out << "msofbtArcRuleAtom " << std::endl; +} + +// ========== msofbtClientRuleAtom ========== + +const unsigned int msofbtClientRuleAtom::id = 61461; /* F015 */ + +msofbtClientRuleAtom ::msofbtClientRuleAtom () +{ +} + +msofbtClientRuleAtom ::~msofbtClientRuleAtom () +{ +} + +void msofbtClientRuleAtom ::dump( std::ostream& out ) const +{ + out << "msofbtClientRuleAtom " << std::endl; +} + +// ========== msofbtCalloutRuleAtom ========== + +const unsigned int msofbtCalloutRuleAtom::id = 61463; /* F017 */ + +msofbtCalloutRuleAtom ::msofbtCalloutRuleAtom () +{ +} + +msofbtCalloutRuleAtom ::~msofbtCalloutRuleAtom () +{ +} + +void msofbtCalloutRuleAtom ::dump( std::ostream& out ) const +{ + out << "msofbtCalloutRuleAtom " << std::endl; +} + +// ========== msofbtSelectionAtom ========== + +const unsigned int msofbtSelectionAtom::id = 61465; /* F019 */ + +msofbtSelectionAtom ::msofbtSelectionAtom () +{ +} + +msofbtSelectionAtom ::~msofbtSelectionAtom () +{ +} + +void msofbtSelectionAtom ::dump( std::ostream& out ) const +{ + out << "msofbtSelectionAtom " << std::endl; +} + +// ========== PPTReader ========== + +class PPTReader::Private +{ +public: + Libppt::Presentation* presentation; // put result here + + POLE::Stream* userStream; // "/Current User" + POLE::Stream* docStream; // "/PowerPoint Document" + + std::vector persistenceList; + std::map slideMap; + Libppt::Slide* currentSlide; + unsigned currentTextType; + unsigned currentTextId; + + GroupObject* currentGroup; + Object* currentObject; + bool isShapeGroup; +}; + + +PPTReader::PPTReader() +{ + d = new Private; + d->presentation = 0; + + d->userStream = 0; + d->docStream = 0; + + d->persistenceList.clear(); + d->slideMap.clear(); + d->currentSlide = 0; + d->currentTextType = 0; + d->currentTextId = 0; + d->isShapeGroup = false; +} + +PPTReader::~PPTReader() +{ + delete d; +} + +bool PPTReader::load( Presentation* pr, const char* filename ) +{ + bool result = false; + + // initialization + d->presentation = pr; + d->docStream = 0; + d->userStream = 0; + d->persistenceList.clear(); + d->slideMap.clear(); + d->currentSlide = 0; + d->currentTextType = 0; + d->currentTextId = 0; + d->currentGroup = 0; + d->currentObject = 0; + d->isShapeGroup = false; + + POLE::Storage storage( filename ); + if( !storage.open() ) + { + std::cerr << "Cannot open " << filename << std::endl; + } + else + { + // file is MS Office document + // check whether it's PowerPoint presentation of not + std::cout << "Loading file " << filename << std::endl; + d->docStream = new POLE::Stream( &storage, "/PowerPoint Document" ); + d->userStream = new POLE::Stream( &storage, "/Current User" ); + + if( d->docStream->fail() || d->userStream->fail() ) + { + // not PowerPoint, we need to quit + storage.close(); + std::cerr << filename << " is not PowerPoint presentation" << std::endl; + delete d->docStream; + d->docStream = 0; + return false; + } + else + { + // so here is PowerPoint stuff + loadUserEdit(); + + d->presentation->clear(); + loadMaster(); + loadSlides(); + loadDocument(); + + result = true; + std::cout << std::endl << filename << " loaded. Done." << std::endl; + } + + // clean-up + storage.close(); + delete d->docStream; + delete d->userStream; + d->presentation = 0; + d->docStream = 0; + d->userStream = 0; + d->persistenceList.clear(); + d->slideMap.clear(); + d->currentSlide = 0; + d->currentTextType = 0; + d->currentTextId = 0; + d->currentGroup = 0; + d->currentObject = 0; + d->isShapeGroup = false; + } + + return result; +} + +void PPTReader::loadUserEdit() +{ + unsigned char buffer[128]; + unsigned long currentUserEditAtom = 0; + std::vector userEditList; + std::vector lastEditList; + std::vector persistDirList; + std::vector usefulPersistDirList; + std::map persistenceMap; + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Parsing Current User information" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + // read one record from "/Current User" stream + d->userStream->seek( 0 ); + unsigned bytes_read = d->userStream->read( buffer, 8 ); + if( bytes_read != 8 ) return; + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + + // sanity checks + if( ( size < 20 ) || ( size > sizeof(buffer) ) ) + { + std::cerr << "ERROR: CurrentUserAtom is not recognized" << std::endl; + return; + } + + // the first in "/Current User" must be CurrentUserAtom + if( type != CurrentUserAtom::id ) + { + std::cerr << "ERROR: First in /Current User is not CurrentUserAtom" << std::endl; + return; + } + else + { + d->userStream->read( buffer, size ); + CurrentUserAtom* atom = new CurrentUserAtom; + atom->setData( size, buffer ); + currentUserEditAtom = atom->offsetToCurrentEdit(); +#ifdef LIBPPT_DEBUG +#if 0 + d->userStream->read( buffer, atom->lenUserName()*2 ); + std::cout << "Found username: "; + for( unsigned b=0; blenUserName()*2; b+=2 ) + std::cout << (char)buffer[b]; + std::cout << std::endl; +#endif + atom->dump( std::cout ); +#endif + delete atom; + } + + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Scanning for all UserEdit atoms" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + d->docStream->seek( 0 ); + unsigned long stream_size = d->docStream->size(); + while( d->docStream->tell() < stream_size ) + { + // get record type and data size + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) break; + + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + + // we only care for UserEditAtom + if( type == UserEditAtom::id ) + if( size < sizeof(buffer) ) + { + d->docStream->read( buffer, size ); + UserEditAtom* atom = new UserEditAtom; + atom->setData( size, buffer ); + userEditList.push_back( pos ); + lastEditList.push_back( atom->offsetLastEdit() ); + persistDirList.push_back( atom->offsetPersistDir() ); +#ifdef LIBPPT_DEBUG + std::cout << "Found at pos " << pos << " size is " << size << std::endl; +#endif + atom->dump( std::cout ); + delete atom; + } + + d->docStream->seek( nextpos ); + } + +#ifdef LIBPPT_DEBUG + std::cout << "Found: " << userEditList.size() << " UserEdit atom(s) " << std::endl; +#endif + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Constructing UserEdit list" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + bool stop = true; + do + { + stop = true; + +#ifdef LIBPPT_DEBUG + std::cout << "Searching for UserEdit at offset " << currentUserEditAtom << std::endl; +#endif + // search current user edit + for( unsigned k=0; k < userEditList.size(); k++ ) + if( (userEditList[k] = currentUserEditAtom) ) + { + stop = false; + usefulPersistDirList.push_back( persistDirList[k] ); + currentUserEditAtom = lastEditList[k]; +#ifdef LIBPPT_DEBUG + std::cout << " found... "; + std::cout << " persistence at offset " << persistDirList[k]; + if( lastEditList[k] != 0 ) + std::cout << " previous is " << lastEditList[k]; + std::cout << std::endl; +#endif + break; + } + } + while( !stop && (currentUserEditAtom!=0) ); + + // sanity check + if( usefulPersistDirList.size() == 0 ) + { + std::cerr << "ERROR: No useful UserEdit information !" << std::endl; + return; + } + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Searching for persistence information" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + unsigned max = 0; + + for( unsigned j = 0; j < usefulPersistDirList.size(); j++ ) + { + unsigned long offset = usefulPersistDirList[j]; + + d->docStream->seek( 0 ); + while( d->docStream->tell() < stream_size ) + { + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) break; + + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + + // we only care for PersistIncrementalBlockAtom + if( pos == offset ) //TODO VERIFY IT + if( type == PersistIncrementalBlockAtom::id ) + { + unsigned char* buf = new unsigned char[ size ]; + d->docStream->read( buf, size ); + PersistIncrementalBlockAtom* atom = new PersistIncrementalBlockAtom; + atom->setData( size, buf ); + delete [] buf; + + +#ifdef LIBPPT_DEBUG + std::cout << "Found at pos " << pos << " size is " << size << std::endl; + atom->dump( std::cout ); +#endif + + for( unsigned m = 0; m < atom->entryCount(); m++ ) + { + unsigned long ref = atom->reference(m); + unsigned long ofs = atom->offset(m); + // if it is already there, ignore !! + if( !persistenceMap.count( ref ) ) + persistenceMap[ref] = ofs; + max = (ref > max) ? ref : max; + } + delete atom; + } + + d->docStream->seek( nextpos ); + } + } + + // convert to a good list + for( unsigned n = 0; n <= max; n++ ) + { + unsigned long ofs = -1; + if( persistenceMap.count( n ) ) + ofs = persistenceMap[n]; + d->persistenceList.push_back( ofs ); + } + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Final persistence list" << std::endl; + for( unsigned nn = 1; nn < d->persistenceList.size(); nn++ ) + std::cout << " #" << nn << ": " << d->persistenceList[nn] << std::endl; + std::cout << std::endl; +#endif + +} + +void PPTReader::loadMaster() +{ +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Loading master" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + d->docStream->seek( 0 ); + unsigned long stream_size = d->docStream->size(); + while( d->docStream->tell() < stream_size ) + { + unsigned char buffer[8]; + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) break; + + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + + // we only care for MainMasterContainer.... + if( type == MainMasterContainer::id ) + if( indexPersistence( pos ) ) + { +#ifdef LIBPPT_DEBUG + std::cout << "Found at pos " << pos << " size is " << size << std::endl; + std::cout << std::endl; +#endif + Slide* master = new Slide( d->presentation ); + d->presentation->setMasterSlide( master ); + d->currentSlide = master; + MainMasterContainer* container = new MainMasterContainer; + handleContainer( container, type, size ); + delete container; + } + + d->docStream->seek( nextpos ); + } + d->currentSlide = 0; +} + +void PPTReader::loadSlides() +{ +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Loading all slide containers" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + int totalSlides = 0; + + d->docStream->seek( 0 ); + unsigned long stream_size = d->docStream->size(); + while( d->docStream->tell() < stream_size ) + { + unsigned char buffer[8]; + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) break; + + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + + unsigned k = 0; + + // we only care for SlideContainer.... + if( type == SlideContainer::id ) + if( (k = indexPersistence( pos )) ) + { + // create a new slide, make it current + Slide* s = new Slide( d->presentation ); + d->slideMap[ k ] = s; + d->presentation->appendSlide( s ); + d->currentSlide = s; + d->currentTextId = 0; + d->currentTextType = TextObject::Body; + +#ifdef LIBPPT_DEBUG + std::cout << "SLIDE #" << totalSlides+1 << std::endl; + std::cout << "Found at pos " << pos << " size is " << size << std::endl; + std::cout << "Reference #" << k << std::endl; + std::cout << std::endl; +#endif + + // process all atoms inside + SlideContainer* container = new SlideContainer; + handleContainer( container, type, size ); + delete container; + + totalSlides++; + } + + d->docStream->seek( nextpos ); + } + + +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Total: " << totalSlides << " slides" << std::endl; +#endif +} + +void PPTReader::loadDocument() +{ +#ifdef LIBPPT_DEBUG + std::cout << std::endl; + std::cout << "Loading document content" << std::endl; + std::cout << "================================================" << std::endl; +#endif + + d->currentSlide = 0; + d->currentGroup = 0; + d->currentObject = 0; + d->isShapeGroup = false; + + d->docStream->seek( 0 ); + unsigned long stream_size = d->docStream->size(); + while( d->docStream->tell() < stream_size ) + { + unsigned char buffer[8]; + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) break; + + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + + // we only care for DocumentContainer.... + if( type == DocumentContainer::id ) + if( indexPersistence( pos ) ) + { +#ifdef LIBPPT_DEBUG + std::cout << "Found at pos " << pos << " size is " << size << std::endl; + std::cout << std::endl; +#endif + DocumentContainer* container = new DocumentContainer; + container->setPosition( pos ); + handleContainer( container, type, size ); + delete container; + } + + d->docStream->seek( nextpos ); + } + +} + +int PPTReader::indexPersistence( unsigned long ofs ) +{ + for( unsigned k=1; k < d->persistenceList.size(); k++ ) + if( (d->persistenceList[k] == ofs) ) + return k; + + return 0; +} + +void PPTReader::loadRecord( Record* parent ) +{ + // FIXME + unsigned char buffer[65536]; + + // get record type and data size + unsigned long pos = d->docStream->tell(); + unsigned bytes_read = d->docStream->read( buffer, 8 ); + if( bytes_read != 8 ) return; + + unsigned instance = readU16( buffer ) >> 4; + unsigned long type = readU16( buffer + 2 ); + unsigned long size = readU32( buffer + 4 ); + unsigned long nextpos = d->docStream->tell() + size; + unsigned lastSize; + // create the record using the factory + Record* record = Record::create( type ); + if( record ) + { + record->setParent( parent ); + record->setPosition( pos ); + record->setInstance( instance ); + + if( !record->isContainer() ) + { + d->docStream->read( buffer, size ); + // special treatment for StyleTextPropAtom + if ( type == StyleTextPropAtom::id ) + record->setData(size, buffer, lastSize); + else + record->setData( size, buffer ); + handleRecord( record, type ); + } + else + handleContainer( static_cast( record ), type, size ); + + delete record; + } + lastSize = size; + d->docStream->seek( nextpos ); +} + +void PPTReader::handleRecord( Record* record, int type ) +{ + if( !record ) return; + + switch( type ) + { + case DocumentAtom::id: + handleDocumentAtom( static_cast(record) ); break; + case SlidePersistAtom::id: + handleSlidePersistAtom( static_cast(record) ); break; + case TextHeaderAtom::id: + handleTextHeaderAtom( static_cast(record) ); break; + case TextCharsAtom::id: + handleTextCharsAtom( static_cast(record) ); break; + case TextBytesAtom::id: + handleTextBytesAtom( static_cast(record) ); break; + case StyleTextPropAtom::id: + handleStyleTextPropAtom( static_cast(record) ); break; + case ColorSchemeAtom::id: + handleColorSchemeAtom( static_cast(record) ); break; + + case msofbtSpgrAtom::id: + handleEscherGroupAtom( static_cast(record) ); break; + case msofbtSpAtom::id: + handleEscherSpAtom( static_cast(record) ); break; + case msofbtOPTAtom::id: + handleEscherPropertiesAtom( static_cast(record) ); break; + case msofbtClientDataAtom::id: + handleEscherClientDataAtom( static_cast(record) ); break; + case msofbtClientAnchorAtom::id: + handleEscherClientAnchorAtom( static_cast(record) ); break; + case msofbtClientTextboxAtom::id: + handleEscherTextBoxAtom( static_cast(record) ); break; + + default: break; + } +} + +void PPTReader::handleContainer( Container* container, int type, unsigned size ) +{ + if( !container || !container->isContainer() ) return; + + unsigned long nextpos = d->docStream->tell() + size - 6; + + switch( type ) + { + case msofbtDgContainer::id: + handleDrawingContainer( static_cast(container), size ); break; + case msofbtSpgrContainer::id: + handleEscherGroupContainer( static_cast(container), size ); break; + case msofbtSpContainer::id: + handleSPContainer( static_cast(container), size ); break; + default: + while( d->docStream->tell() < nextpos ) + loadRecord( container ); + } +} + +void PPTReader::handleDocumentAtom( DocumentAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + + double pageWidth = atom->slideWidth() * 0.125; // pt, in cm * 0.0440972 + double pageHeight = atom->slideHeight() * 0.125; // pt + + d->presentation->masterSlide()->setPageWidth( pageWidth ); + d->presentation->masterSlide()->setPageHeight ( pageHeight ); + +#ifdef LIBPPT_DEBUG + std::cout << std::endl<< "page width = " << pageWidth << std::endl; + std::cout << std::endl<< "page height = " << pageHeight << std::endl; +#endif +} + +void PPTReader::handleSlidePersistAtom( SlidePersistAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + + //int id = atom->slideId(); + unsigned ref = atom->psrReference(); + + d->currentSlide = d->slideMap[ ref ]; + d->currentTextId = 0; + d->currentTextType = TextObject::Body; + +#ifdef LIBPPT_DEBUG + std::cout << std::endl<< "Slide id = " << id << std::endl; +#endif +} + +void PPTReader::handleTextHeaderAtom( TextHeaderAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + + d->currentTextId++; + d->currentTextType = atom->textType(); +} + +void PPTReader::handleTextCharsAtom( TextCharsAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentTextId ) return; + + int placeId = d->currentTextId-1; + TextObject* text = d->currentSlide->textObject( placeId ); + if( !text ) + { + std::cerr << "No place for text object! " << placeId << std::endl; + return; + } + + text->setType( d->currentTextType ); + + for (uint i=0; ilistSize(); i++) + { + text->setText(atom->strValue(i)); + // qDebug("=====================text list ================"); + } + + if( (d->currentTextType == TextObject::Title) | (d->currentTextType == TextObject::CenterTitle) ) + for (unsigned i=0; ilistSize(); i++) + d->currentSlide->setTitle( atom->strValue(i) ); + + + +#ifdef LIBPPT_DEBUG + std::cout << " Text Object " << atom->ustring().ascii(); + std::cout << " placed at " << placeId << std::endl; +#endif + +} + +void PPTReader::handleTextBytesAtom( TextBytesAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentTextId ) return; + + int placeId = d->currentTextId-1; + TextObject* text = d->currentSlide->textObject( placeId ); + if( !text ) + { + std::cerr << "No place for text object! " << placeId << std::endl; + return; + } + + text->setType( d->currentTextType ); + + for (uint i=0; ilistSize(); i++) + { + text->setText(atom->strValue(i)); + // qDebug("=====================text list ================"); + } + + if( (d->currentTextType == TextObject::Title) | (d->currentTextType == TextObject::CenterTitle) ) + for (unsigned i=0; ilistSize(); i++) + d->currentSlide->setTitle( atom->strValue(i) ); + + + +#ifdef LIBPPT_DEBUG + std::cout << " Text Object " << atom->ustring().ascii(); + std::cout << " placed at " << placeId << std::endl; +#endif +} + +void PPTReader::handleStyleTextPropAtom ( StyleTextPropAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentTextId ) return; + + int placeId = d->currentTextId-1; + TextObject* text = d->currentSlide->textObject( placeId ); + + for (uint i=0; ilistSize(); i++) + { + if (atom->bulletOn(i) == 1) + text->setBulletFlag(true); + else /* if (atom->bulletOn(i) == 0) */ + text->setBulletFlag(false); + } + +} + +void PPTReader::handleColorSchemeAtom( ColorSchemeAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + +} + +std::string spaces( int x ) +{ + std::string str; + for( int i=0; itop() << std::endl; + std::cout << spaces(indent) << "Left: " << obj->left() << std::endl; + + if( obj->isGroup() ) + { + std::cout << spaces(indent) << "This is a group" << std::endl; + GroupObject* gr = static_cast(obj); + dumpGroup( gr, indent+2 ); + } +} + +void dumpGroup( GroupObject* obj, unsigned indent ) +{ + for( unsigned i=0; i objectCount(); i++ ) + { + std::cout << spaces(indent) << "Object #" << i+1 << std::endl; + Object* o = obj->object(i); + dumpObject( o, indent+2 ); + } +} + +void dumpSlide( Slide* slide ) +{ + std::cout << "Slide: " << slide->title().ascii() << std::endl; + GroupObject* root = slide->rootObject(); + dumpGroup( root, 0 ); + std::cout << std::endl; +} + + +void PPTReader::handleDrawingContainer( msofbtDgContainer* container, unsigned size ) +{ + if( !container ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + + d->currentGroup = new GroupObject(); + d->currentObject = 0; + d->isShapeGroup = false; + + unsigned long nextpos = d->docStream->tell() + size - 6; + while( d->docStream->tell() < nextpos ) + loadRecord( container ); + + for( unsigned i=0; icurrentGroup->objectCount(); i++ ) + { + Object* obj = d->currentGroup->object(i); + if( ( i == 0 ) && ( obj->isGroup() ) ) + { + d->currentGroup->takeObject( obj ); + d->currentSlide->setRootObject( (GroupObject*)obj ); + break; + } + } + + delete d->currentGroup; + d->currentGroup = 0; + d->currentObject = 0; + d->isShapeGroup = false; +} + +void PPTReader::handleEscherGroupContainer( msofbtSpgrContainer* container, unsigned size ) +{ + if( !container ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + + GroupObject* lastGroup = d->currentGroup; + + d->currentGroup = new GroupObject(); + d->currentObject = 0; + d->isShapeGroup = false; + + unsigned long nextpos = d->docStream->tell() + size - 6; + while( d->docStream->tell() < nextpos ) + loadRecord( container ); + + lastGroup->addObject( d->currentGroup ); // FIXME only if patriarch + d->currentGroup = lastGroup; + d->currentObject = 0; + d->isShapeGroup = false; +} + +void PPTReader::handleSPContainer( msofbtSpContainer* container, unsigned size ) +{ + if( !container ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + + d->isShapeGroup = false; + + unsigned long nextpos = d->docStream->tell() + size - 6; + while( d->docStream->tell() < nextpos ) + loadRecord( container ); + + if( d->currentObject ) + if( !d->isShapeGroup ) + d->currentGroup->addObject( d->currentObject ); + + d->currentObject = 0; + d->isShapeGroup = false; +} + +void PPTReader::handleEscherGroupAtom( msofbtSpgrAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + + // set rect bound of current group + + // this is shape for the group, no need to + d->isShapeGroup = true; +} + +void PPTReader::handleEscherSpAtom( msofbtSpAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + + DrawObject* drawObject = new DrawObject; + + drawObject->setBackground( atom->isBackground() ); + + unsigned sh = DrawObject::None; + switch( atom->instance() ) + { + case msofbtSpAtom::msosptRectangle: sh = DrawObject::Rectangle; break; + case msofbtSpAtom::msosptRoundRectangle: sh = DrawObject::RoundRectangle; break; + case msofbtSpAtom::msosptEllipse: sh = DrawObject::Ellipse; break; + case msofbtSpAtom::msosptDiamond: sh = DrawObject::Diamond; break; + case msofbtSpAtom::msosptIsoscelesTriangle: sh = DrawObject::IsoscelesTriangle; break; + case msofbtSpAtom::msosptRightTriangle: sh = DrawObject::RightTriangle; break; + case msofbtSpAtom::msosptParallelogram: sh = DrawObject::Parallelogram; break; + case msofbtSpAtom::msosptTrapezoid: sh = DrawObject::Trapezoid; break; + case msofbtSpAtom::msosptHexagon: sh = DrawObject::Hexagon; break; + case msofbtSpAtom::msosptOctagon: sh = DrawObject::Octagon; break; + + case msofbtSpAtom::msosptArrow: sh = DrawObject::LeftArrow; break; + case msofbtSpAtom::msosptDownArrow: sh = DrawObject::DownArrow; break; + case msofbtSpAtom::msosptUpArrow: sh = DrawObject::UpArrow; break; + case msofbtSpAtom::msosptLeftArrow: sh = DrawObject::LeftArrow; break; + + case msofbtSpAtom::msosptLine: sh = DrawObject::Line; break; + case msofbtSpAtom::msosptSmileyFace: sh = DrawObject::Smiley; break; + case msofbtSpAtom::msosptHeart: sh = DrawObject::Heart; break; + case msofbtSpAtom::msosptMin: sh = DrawObject::FreeLine; break; + + default: break; + } + + drawObject->setShape( sh ); +/* + if (atom->isVerFlip() == true) + d->currentObject->setProperty( "draw:mirror-vertical", "true"); + + if (atom->isHorFlip() == true) + d->currentObject->setProperty( "draw:mirror-horizontal", "true"); +*/ + d->currentObject = drawObject; + + if (atom->isVerFlip() == true) + d->currentObject->setProperty( "draw:mirror-vertical", "true"); + + if (atom->isHorFlip() == true) + d->currentObject->setProperty( "draw:mirror-horizontal", "true"); + + +} + +void PPTReader::handleEscherClientDataAtom( msofbtClientDataAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + if( !d->currentObject ) return; + + TextObject* textObject = 0; + if( !d->currentObject->isText() ) + { + textObject = new TextObject(); + textObject->convertFrom( d->currentObject ); + delete d->currentObject; + d->currentObject = textObject; + } + else + textObject = static_cast( d->currentObject ); + + switch( atom->placeholderId() ) + { + case msofbtClientDataAtom::MasterTitle: + case msofbtClientDataAtom::Title: + textObject->setType( TextObject::Title ); break; + + case msofbtClientDataAtom::MasterBody: + case msofbtClientDataAtom::MasterSubtitle: + case msofbtClientDataAtom::Body: + case msofbtClientDataAtom::Subtitle: + textObject->setType( TextObject::Body ); break; + + case msofbtClientDataAtom::MasterCenteredTitle: + case msofbtClientDataAtom::CenteredTitle: + textObject->setType( TextObject::CenterTitle ); break; + + default: + textObject->setType( TextObject::Other ); break; + break; + } + + textObject->setId( atom->placementId() ); +} + +void PPTReader::handleEscherClientAnchorAtom( msofbtClientAnchorAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + if( !d->currentObject ) return; + + d->currentObject->setLeft( atom->left()*25.4/576 ); + d->currentObject->setTop( atom->top()*25.4/576 ); + d->currentObject->setWidth( (atom->right()-atom->left())*25.4/576 ); + d->currentObject->setHeight( (atom->bottom()-atom->top())*25.4/576 ); +} + +void PPTReader::handleEscherTextBoxAtom( msofbtClientTextboxAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentGroup ) return; + if( !d->currentObject ) return; + + TextObject* textObject = 0; + if( !d->currentObject->isText() ) + { + textObject = new TextObject(); + textObject->convertFrom( d->currentObject ); + delete d->currentObject; + d->currentObject = textObject; + } + else + textObject = static_cast( d->currentObject ); + + textObject->setType( TextObject::Other ); + textObject->setText( atom->ustring() ); + textObject->setBulletFlag( false ); +} + +Color convertFromLong( unsigned long i ) +{ + unsigned r = (i & 0xff); + unsigned g = (i>>8) & 0xff; + unsigned b = (i>>16) & 0xff; + //unsigned index = (i>>24) & 0xff; + return Color( r, g, b ); +} + +void PPTReader::handleEscherPropertiesAtom( msofbtOPTAtom* atom ) +{ + if( !atom ) return; + if( !d->presentation ) return; + if( !d->currentSlide ) return; + if( !d->currentGroup ) return; + if( !d->currentObject ) return; + + for( unsigned c=0; cpropertyCount(); c++ ) + { + unsigned pid = atom->propertyId(c); + signed long pvalue = atom->propertyValue(c); + + switch( pid ) + { + case msofbtOPTAtom::FillColor: + d->currentObject->setProperty( "draw:fill-color", convertFromLong(pvalue) ); + break; + case msofbtOPTAtom::LineColor: + d->currentObject->setProperty( "svg:stroke-color", convertFromLong(pvalue) ); + break; + case msofbtOPTAtom::LineWidth: + d->currentObject->setProperty( "svg:stroke-width", pvalue*(25.4/(12700*72) )); + break; + case msofbtOPTAtom::Rotation: + { double deg = pvalue/65536.00 ; + if (deg > 180.00) deg = 360.00 - deg; // in range (-180,180) deg + d->currentObject->setProperty( "libppt:rotation", (deg*0.0174533) ) ;// rad + } break; + case msofbtOPTAtom::FillType: + switch( pvalue ) + { + case msofbtOPTAtom::FillSolid: + d->currentObject->setProperty( "draw:fill", "solid"); break; + case msofbtOPTAtom::FillPattern: + d->currentObject->setProperty( "draw:fill", "solid"); break; + default: + d->currentObject->setProperty( "draw:fill", "solid"); break; + } + break; + case msofbtOPTAtom::LineDashing: + switch( pvalue ) + { + case msofbtOPTAtom::LineSolid : + {d->currentObject->setProperty( "draw:stroke", "solid"); + //qDebug("=====================solid================"); + } break; + case msofbtOPTAtom::LineDashSys : + { + d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_2"); + //qDebug("===================== solid================"); + } break; + case msofbtOPTAtom::LineDotSys : + { + d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_3"); + //qDebug("===================== dash 2================"); + } break; + case msofbtOPTAtom::LineDashDotSys : + { + d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_2"); + //qDebug("===================== dash 3================"); + } break; + case msofbtOPTAtom::LineDashDotDotSys : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_2"); + //qDebug("===================== dash 4================"); + } break; + case msofbtOPTAtom::LineDotGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_2"); + //qDebug("===================== dash 5================"); + } break; + case msofbtOPTAtom::LineDashGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_4"); + //qDebug("===================== dash 6================"); + } break; + case msofbtOPTAtom::LineLongDashGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_6"); + //qDebug("=====================dash 7================"); + } break; + case msofbtOPTAtom::LineDashDotGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_5"); + //qDebug("=====================dash 8================"); + } break; + case msofbtOPTAtom::LineLongDashDotGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_7"); + //qDebug("=====================dash 9================"); + } break; + case msofbtOPTAtom::LineLongDashDotDotGEL : + { d->currentObject->setProperty( "draw:stroke", "dash"); + d->currentObject->setProperty( "draw:stroke-dash", "Dash_20_8"); + //qDebug("=====================dash 10================"); + } break; + default: + d->currentObject->setProperty( "draw:stroke", "solid"); break; + } break; + + case msofbtOPTAtom::FlagNoLineDrawDash: + { if (pvalue == 589824 ) + d->currentObject->setProperty( "libppt:invisibleLine", true ); + } break; + + case msofbtOPTAtom::LineStartArrowhead: + { + switch( pvalue ) + { + case msofbtOPTAtom::LineNoEnd : break; + case msofbtOPTAtom::LineArrowEnd : + d->currentObject->setProperty( "draw:marker-start", "msArrowEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowStealthEnd : + d->currentObject->setProperty( "draw:marker-start", "msArrowStealthEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowDiamondEnd : + d->currentObject->setProperty( "draw:marker-start", "msArrowDiamondEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowOvalEnd : + d->currentObject->setProperty( "draw:marker-start", "msArrowOvalEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowOpenEnd : + d->currentObject->setProperty( "draw:marker-start", "msArrowOpenEnd_20_5" ); break; + default : break; + } + } break; + + case msofbtOPTAtom::LineStartArrowWidth: + { + switch ( pvalue ) + { + case msofbtOPTAtom::LineNarrowArrow : + d->currentObject->setProperty( "draw:marker-start-width", 0.2 ); break; + case msofbtOPTAtom::LineMediumWidthArrow : + d->currentObject->setProperty( "draw:marker-start-width", 0.3 ); break; + case msofbtOPTAtom::LineWideArrow : + d->currentObject->setProperty( "draw:marker-start-width", 0.4 ); break; + default : break; + } + } break; + + case msofbtOPTAtom::LineEndArrowhead: + { + switch( pvalue ) + { + case msofbtOPTAtom::LineNoEnd : break; + case msofbtOPTAtom::LineArrowEnd : + d->currentObject->setProperty( "draw:marker-end", "msArrowEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowStealthEnd : + d->currentObject->setProperty( "draw:marker-end", "msArrowStealthEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowDiamondEnd : + d->currentObject->setProperty( "draw:marker-end", "msArrowDiamondEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowOvalEnd : + d->currentObject->setProperty( "draw:marker-end", "msArrowOvalEnd_20_5" ); break; + case msofbtOPTAtom::LineArrowOpenEnd : + d->currentObject->setProperty( "draw:marker-end", "msArrowOpenEnd_20_5" ); break; + default : break; + } + } break; + + +/* + case msofbtOPTAtom::LineStartArrowLength: + { + switch ( pvalue ) + { + case msofbtOPTAtom::LineShortArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.2cm" ); break; + case msofbtOPTAtom::LineMediumLenArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.4cm" ); break; + case msofbtOPTAtom::LineLongArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.6cm" ); break; + default : break; + } + } break; +*/ + case msofbtOPTAtom::LineEndArrowWidth: + { + switch ( pvalue ) + { + case msofbtOPTAtom::LineNarrowArrow : + d->currentObject->setProperty( "draw:marker-end-width", 0.2 ); break; + case msofbtOPTAtom::LineMediumWidthArrow : + d->currentObject->setProperty( "draw:marker-end-width", 0.3 ); break; + case msofbtOPTAtom::LineWideArrow : + d->currentObject->setProperty( "draw:marker-end-width", 0.4 ); break; + default : break; + } + } break; +/* + case msofbtOPTAtom::LineEndArrowLength: + { + switch ( pvalue ) + { + case msofbtOPTAtom::LineShortArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.2cm" ); break; + case msofbtOPTAtom::LineMediumLenArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.4cm" ); break; + case msofbtOPTAtom::LineLongArrow : + d->currentObject->setProperty( "draw:marker-end-length", "0.6cm" ); break; + default : break; + } + } break; +*/ + #if 0 + case msofbtOPTAtom::ShadowColor: + { + d->currentObject->setProperty( "draw:shadow-color", convertFromLong(pvalue) ); + } break; + case msofbtOPTAtom::ShadowOpacity: + { + d->currentObject->setProperty( "draw:shadow-opacity", 100.0-(pvalue/(65536.0)) ); + } break; + case msofbtOPTAtom::ShadowOffsetX: + { + d->currentObject->setProperty("draw:shadow-offset-x",(pvalue*2.54/(12700*72))); + } break; + case msofbtOPTAtom::ShadowOffsetY: + { + d->currentObject->setProperty("draw:shadow-offset-y",(pvalue*2.54/(12700*72))); + } break; +#endif + } // switch pid + + } // for + +} // handleEscherPropertiesAtom diff --git a/filters/kpresenter/powerpoint/libppt/powerpoint.h b/filters/kpresenter/powerpoint/libppt/powerpoint.h new file mode 100644 index 000000000..49950817d --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/powerpoint.h @@ -0,0 +1,2533 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#ifndef LIBPPT_POWERPOINT +#define LIBPPT_POWERPOINT + +#include +#include "ustring.h" + +namespace Libppt +{ + +// forward declaration +class Presentation; + +class Record +{ +public: + + /** + Static ID of the record. Subclasses should override this value + with the id of the record they handle. + */ + static const unsigned int id; + + virtual unsigned int rtti(){ + return this->id; + } + + /** + Creates a new generic record. + */ + Record(); + + /** + Destroys the record. + */ + virtual ~Record(); + + /** + * Record factory, create a new record of specified type. + */ + static Record* create( unsigned type ); + + /** + * Returns true if this is a Container. + */ + virtual bool isContainer() const { return false; } + + void setParent( Record* parent ); + + const Record* parent() const; + + /** + Sets the data for this record. + */ + virtual void setData( unsigned size, const unsigned char* data ); + virtual void setData( unsigned size, const unsigned char* data, unsigned lastSize ); + + /** + Sets the position of the record in the OLE stream. + */ + void setPosition( unsigned pos ); + + /** + Gets the position of this record in the OLE stream. + */ + unsigned position() const; + + void setInstance( unsigned inst ); + unsigned instance() const; + + /** + Returns the name of the record. For debugging only. + */ + virtual const char* name(){ return "Unknown"; } + + /** + Dumps record information to output stream. For debugging only. + */ + virtual void dump( std::ostream& out ) const; + +protected: + + // position of this record in the OLE stream + unsigned stream_position; + + unsigned record_instance; + + Record* record_parent; + +private: + // no copy or assign + Record( const Record& ); + Record& operator=( const Record& ); +}; + +// Container is a special record, it is for holding another records +class Container: public Record +{ +public: + Container(); + virtual bool isContainer() const { return true; } + const char* name(){ return "Container"; } + +private: + // no copy or assign + Container( const Container& ); + Container& operator=( const Container& ); +}; + + +class BookmarkCollectionContainer: public Container +{ +public: + static const unsigned int id; + BookmarkCollectionContainer(); + const char* name(){ return "BookmarkCollectionContainer"; } + +private: + // no copy or assign + BookmarkCollectionContainer( const BookmarkCollectionContainer& ); + BookmarkCollectionContainer& operator=( const BookmarkCollectionContainer& ); +}; + +class DocumentContainer: public Container +{ +public: + static const unsigned int id; + DocumentContainer(); + const char* name(){ return "DocumentContainer"; } + +private: + // no copy or assign + DocumentContainer( const DocumentContainer& ); + DocumentContainer& operator=( const DocumentContainer& ); +}; + +class EnvironmentContainer: public Container +{ +public: + static const unsigned int id; + EnvironmentContainer(); + const char* name(){ return "EnvironmentContainer"; } + +private: + // no copy or assign + EnvironmentContainer( const EnvironmentContainer& ); + EnvironmentContainer& operator=( const EnvironmentContainer& ); +}; + +class ExObjListContainer: public Container +{ +public: + static const unsigned int id; + ExObjListContainer(); + const char* name(){ return "ExObjListContainer"; } + +private: + // no copy or assign + ExObjListContainer( const ExObjListContainer& ); + ExObjListContainer& operator=( const ExObjListContainer& ); +}; + +class ExHyperlinkContainer : public Container +{ +public: + static const unsigned int id; + ExHyperlinkContainer (); + const char* name(){ return "ExHyperlinkContainer "; } + +private: + // no copy or assign + ExHyperlinkContainer ( const ExHyperlinkContainer & ); + ExHyperlinkContainer & operator=( const ExHyperlinkContainer & ); +}; + +class ExEmbedContainer : public Container +{ +public: + static const unsigned int id; + ExEmbedContainer (); + const char* name(){ return "ExEmbedContainer "; } + +private: + // no copy or assign + ExEmbedContainer ( const ExEmbedContainer & ); + ExEmbedContainer & operator=( const ExEmbedContainer & ); +}; + +class ExLinkContainer : public Container +{ +public: + static const unsigned int id; + ExLinkContainer (); + const char* name(){ return "ExLinkContainer "; } + +private: + // no copy or assign + ExLinkContainer ( const ExLinkContainer & ); + ExLinkContainer & operator=( const ExLinkContainer & ); +}; + +class RunArrayContainer: public Container +{ +public: + static const unsigned int id; + RunArrayContainer(); + + const char* name(){ return "RunArrayContainer"; } + +private: + // no copy or assign + RunArrayContainer( const RunArrayContainer& ); + RunArrayContainer& operator=( const RunArrayContainer& ); +}; + +class ExOleObjStgContainer: public Container +{ +public: + static const unsigned int id; + ExOleObjStgContainer(); + const char* name(){ return "ExOleObjStgContainer"; } + +private: + // no copy or assign + ExOleObjStgContainer( const ExOleObjStgContainer& ); + ExOleObjStgContainer& operator=( const ExOleObjStgContainer& ); +}; + +class FontCollectionContainer: public Container +{ +public: + static const unsigned int id; + FontCollectionContainer(); + const char* name(){ return "FontCollectionContainer"; } + +private: + // no copy or assign + FontCollectionContainer( const FontCollectionContainer& ); + FontCollectionContainer& operator=( const FontCollectionContainer& ); +}; + +class HandoutContainer: public Container +{ +public: + static const unsigned int id; + HandoutContainer(); + const char* name(){ return "HandoutContainer"; } + +private: + // no copy or assign + HandoutContainer( const HandoutContainer& ); + HandoutContainer& operator=( const HandoutContainer& ); +}; + +class HeadersFootersContainer: public Container +{ +public: + static const unsigned int id; + HeadersFootersContainer(); + const char* name(){ return "HeadersFootersContainer"; } + +private: + // no copy or assign + HeadersFootersContainer( const DocumentContainer& ); + HeadersFootersContainer& operator=( const DocumentContainer& ); +}; + +class ListContainer: public Container +{ +public: + static const unsigned int id; + ListContainer(); + const char* name(){ return "ListContainer"; } + +private: + // no copy or assign + ListContainer( const ListContainer& ); + ListContainer& operator=( const ListContainer& ); +}; + +class MainMasterContainer: public Container +{ +public: + static const unsigned int id; + MainMasterContainer(); + const char* name(){ return "MainMasterContainer"; } + +private: + // no copy or assign + MainMasterContainer( const MainMasterContainer& ); + MainMasterContainer& operator=( const MainMasterContainer& ); +}; + +class NotesContainer: public Container +{ +public: + static const unsigned int id; + NotesContainer(); + const char* name(){ return "NotesContainer"; } + +private: + // no copy or assign + NotesContainer( const NotesContainer& ); + NotesContainer& operator=( const NotesContainer& ); +}; + +class OutlineViewInfoContainer : public Container +{ +public: + static const unsigned int id; + OutlineViewInfoContainer (); + const char* name(){ return "OutlineViewInfoContainer "; } + +private: + // no copy or assign + OutlineViewInfoContainer ( const OutlineViewInfoContainer & ); + OutlineViewInfoContainer & operator=( const OutlineViewInfoContainer & ); +}; + +class PPDrawingContainer : public Container +{ +public: + static const unsigned int id; + PPDrawingContainer (); + const char* name(){ return "PPDrawingContainer "; } + +private: + // no copy or assign + PPDrawingContainer ( const PPDrawingContainer & ); + PPDrawingContainer & operator=( const PPDrawingContainer & ); +}; + +class PPDrawingGroupContainer : public Container +{ +public: + static const unsigned int id; + PPDrawingGroupContainer (); + const char* name(){ return "PPDrawingGroupContainer "; } + +private: + // no copy or assign + PPDrawingGroupContainer ( const PPDrawingGroupContainer & ); + PPDrawingGroupContainer & operator=( const PPDrawingGroupContainer & ); +}; + +class ProgBinaryTagContainer: public Container +{ +public: + static const unsigned int id; + ProgBinaryTagContainer(); + const char* name(){ return "ProgBinaryTagContainer"; } + +private: + // no copy or assign + ProgBinaryTagContainer( const ProgBinaryTagContainer& ); + ProgBinaryTagContainer& operator=( const ProgBinaryTagContainer& ); +}; + +class ProgStringTagContainer: public Container +{ +public: + static const unsigned int id; + ProgStringTagContainer(); + const char* name(){ return "ProgStringTagContainer"; } + +private: + // no copy or assign + ProgStringTagContainer( const ProgStringTagContainer& ); + ProgStringTagContainer& operator=( const ProgStringTagContainer& ); +}; + +class ProgTagsContainer : public Container +{ +public: + static const unsigned int id; + ProgTagsContainer (); + const char* name(){ return "ProgTagsContainer "; } + +private: + // no copy or assign + ProgTagsContainer ( const ProgTagsContainer & ); + ProgTagsContainer & operator=( const ProgTagsContainer & ); +}; + +class SlideContainer: public Container +{ +public: + static const unsigned int id; + SlideContainer(); + const char* name(){ return "SlideContainer"; } + +private: + // no copy or assign + SlideContainer( const SlideContainer& ); + SlideContainer& operator=( const SlideContainer& ); +}; + +class SlideBaseContainer: public Container +{ +public: + static const unsigned int id; + SlideBaseContainer(); + const char* name(){ return "SlideBaseContainer"; } + +private: + // no copy or assign + SlideBaseContainer( const SlideBaseContainer& ); + SlideBaseContainer& operator=( const SlideBaseContainer& ); +}; + +class SlideListWithTextContainer: public Container +{ +public: + static const unsigned int id; + SlideListWithTextContainer(); + const char* name(){ return "SlideListWithTextContainer"; } + +private: + // no copy or assign + SlideListWithTextContainer( const SlideListWithTextContainer& ); + SlideListWithTextContainer& operator=( const SlideListWithTextContainer& ); +}; + +class SlideViewInfoContainer: public Container +{ +public: + static const unsigned int id; + SlideViewInfoContainer(); + const char* name(){ return "SlideViewInfoContainer"; } + +private: + // no copy or assign + SlideViewInfoContainer( const SlideViewInfoContainer& ); + SlideViewInfoContainer& operator=( const SlideViewInfoContainer& ); +}; + +class SorterViewInfoContainer : public Container +{ +public: + static const unsigned int id; + SorterViewInfoContainer (); + const char* name(){ return "SorterViewInfoContainer "; } + +private: + // no copy or assign + SorterViewInfoContainer ( const SorterViewInfoContainer & ); + SorterViewInfoContainer & operator=( const SorterViewInfoContainer & ); +}; + +class SummaryContainer : public Container +{ +public: + static const unsigned int id; + SummaryContainer (); + const char* name(){ return "SummaryContainer "; } + +private: + // no copy or assign + SummaryContainer ( const SummaryContainer & ); + SummaryContainer & operator=( const SummaryContainer & ); +}; + +class SrKinsokuContainer: public Container +{ +public: + static const unsigned int id; + SrKinsokuContainer(); + const char* name(){ return "SrKinsokuContainer"; } + +private: + // no copy or assign + SrKinsokuContainer( const SrKinsokuContainer& ); + SrKinsokuContainer& operator=( const SrKinsokuContainer& ); +}; + +class VBAInfoContainer: public Container +{ +public: + static const unsigned int id; + VBAInfoContainer(); + const char* name(){ return "VBAInfoContainer"; } + +private: + // no copy or assign + VBAInfoContainer( const VBAInfoContainer& ); + VBAInfoContainer& operator=( const VBAInfoContainer& ); +}; + +class ViewInfoContainer: public Container +{ +public: + static const unsigned int id; + ViewInfoContainer(); + const char* name(){ return "ViewInfoContainer"; } + +private: + // no copy or assign + ViewInfoContainer( const ViewInfoContainer& ); + ViewInfoContainer& operator=( const ViewInfoContainer& ); +}; + +class msofbtDgContainer: public Container +{ +public: + static const unsigned int id; + msofbtDgContainer(); + const char* name(){ return "msofbtDgContainer"; } + +private: + // no copy or assign + msofbtDgContainer( const msofbtDgContainer& ); + msofbtDgContainer& operator=( const msofbtDgContainer& ); +}; + +class msofbtSpContainer: public Container +{ +public: + static const unsigned int id; + msofbtSpContainer(); + const char* name(){ return "msofbtSpContainer"; } + +private: + // no copy or assign + msofbtSpContainer( const msofbtSpContainer& ); + msofbtSpContainer& operator=( const msofbtSpContainer& ); +}; + +class msofbtSpgrContainer: public Container +{ +public: + static const unsigned int id; + msofbtSpgrContainer(); + const char* name(){ return "msofbtSpgrContainer"; } + +private: + // no copy or assign + msofbtSpgrContainer( const msofbtSpgrContainer& ); + msofbtSpgrContainer& operator=( const msofbtSpgrContainer& ); +}; + +class msofbtDggContainer: public Container +{ +public: + static const unsigned int id; + msofbtDggContainer(); + const char* name(){ return "msofbtDggContainer"; } + +private: + // no copy or assign + msofbtDggContainer( const msofbtDggContainer& ); + msofbtDggContainer& operator=( const msofbtDggContainer& ); +}; + +class msofbtBstoreContainer: public Container +{ +public: + static const unsigned int id; + msofbtBstoreContainer(); + const char* name(){ return "msofbtBstoreContainer"; } + +private: + // no copy or assign + msofbtBstoreContainer( const msofbtBstoreContainer& ); + msofbtBstoreContainer& operator=( const msofbtBstoreContainer& ); +}; + +class msofbtSolverContainer: public Container +{ +public: + static const unsigned int id; + msofbtSolverContainer(); + const char* name(){ return "msofbtSolverContainer"; } + +private: + // no copy or assign + msofbtSolverContainer( const msofbtSolverContainer& ); + msofbtSolverContainer& operator=( const msofbtSolverContainer& ); +}; + +class BookmarkEntityAtom : public Record +{ +public: + static const unsigned int id; + BookmarkEntityAtom (); + ~BookmarkEntityAtom (); + + int bookmarkID() const; + void setBookmarkID( int bookmarkID ); + int bookmarkName() const; + void setBookmarkName( int bookmarkName ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "BookmarkEntityAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + BookmarkEntityAtom ( const BookmarkEntityAtom & ); + BookmarkEntityAtom & operator=( const BookmarkEntityAtom & ); + + class Private; + Private *d; +}; + +class CStringAtom: public Record +{ +public: + static const unsigned int id; + CStringAtom(); + ~CStringAtom(); + + UString ustring() const; + void setUString( const UString& ustr ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "CStringAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + CStringAtom( const CStringAtom& ); + CStringAtom& operator=( const CStringAtom& ); + + class Private; + Private *d; +}; + +class ColorSchemeAtom : public Record +{ +public: + static const unsigned int id; + ColorSchemeAtom(); + ~ColorSchemeAtom(); + + int background() const; + void setBackground( int background ); + int textAndLines() const; + void setTextAndLines( int textAndLines ); + int shadows() const; + void setShadows( int shadows ); + int titleText() const; + void setTitleText( int titleText ); + int fills() const; + void setFills( int fills ); + int accent() const; + void setAccent( int accent ); + int accentAndHyperlink() const; + void setAccentAndHyperlink ( int accentAndHyperlink ); + int accentAndFollowedHyperlink() const; + void setAccentAndFollowedHyperlink( int accentAndFollowedHyperlink ); + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ColorSchemeAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ColorSchemeAtom ( const ColorSchemeAtom & ); + ColorSchemeAtom & operator=( const ColorSchemeAtom & ); + + class Private; + Private *d; +}; + +class CurrentUserAtom : public Record +{ +public: + static const unsigned int id; + CurrentUserAtom(); + ~CurrentUserAtom(); + + int size() const; + void setSize( int size ); + int magic() const; + void setMagic( int magic ); + int offsetToCurrentEdit() const; + void setOffsetToCurrentEdit( int offsetToCurrentEdit ); + int lenUserName() const; + void setLenUserName( int lenUserName ); + int docFileVersion() const; + void setDocFileVersion( int docFileVersion ); + int majorVersion() const; + void setMajorVersion( int majorVersion ); + int minorVersion() const; + void setMinorVersion ( int minorVersion ); + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ColorSchemeAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + CurrentUserAtom ( const CurrentUserAtom & ); + CurrentUserAtom & operator=( const CurrentUserAtom & ); + + class Private; + Private *d; +}; + +class DocumentAtom : public Record +{ +public: + static const unsigned int id; + DocumentAtom(); + ~DocumentAtom(); + + int slideWidth() const; + void setSlideWidth( int w ); + int slideHeight() const; + void setSlideHeight( int h ); + int notesWidth() const; + void setNotesWidth( int nw ); + int notesHeight() const; + void setNotesHeight( int nh ); + int zoomNumer() const; + void setZoomNumer( int numer ); + int zoomDenom() const; + void setZoomDenom( int denom ); + + int notesMasterPersist() const; + void setNotesMasterPersist( int notesMasterPersist ); + + int handoutMasterPersist() const; + void setHandoutMasterPersist(int handoutMasterPersist); + + int firstSlideNum() const; + void setFirstSlideNum( int firstSlideNum ); + + int slideSizeType() const; + void setSlideSizeType( int slideSizeType ); + + int saveWithFonts() const; + void setSaveWithFonts( int saveWithFonts ); + + int omitTitlePlace() const; + void setOmitTitlePlace( int omitTitlePlace ); + + int rightToLeft() const; + void setRightToLeft( int rightToLeft ); + + int showComments() const; + void setShowComments( int showComments); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "DocumentAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + DocumentAtom ( const DocumentAtom & ); + DocumentAtom & operator=( const DocumentAtom & ); + + class Private; + Private *d; +}; + +class EndDocumentAtom: public Record +{ +public: + static const unsigned int id; + EndDocumentAtom(); + const char* name(){ return "EndDocumentAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + EndDocumentAtom( const EndDocumentAtom& ); + EndDocumentAtom& operator=( const EndDocumentAtom& ); +}; + +class ExObjListAtom : public Record +{ +public: + static const unsigned int id; + ExObjListAtom(); + ~ExObjListAtom(); + + int objectIdSeed() const; + void setObjectIdSeed( int objectIdSeed ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ExObjListAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ExObjListAtom ( const ExObjListAtom & ); + ExObjListAtom & operator=( const ExObjListAtom & ); + + class Private; + Private *d; +}; + +class ExHyperlinkAtom : public Record +{ +public: + static const unsigned int id; + ExHyperlinkAtom (); + ~ExHyperlinkAtom (); + + int objID() const; + void setObjID (int objID); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ExHyperlinkAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ExHyperlinkAtom ( const ExHyperlinkAtom & ); + ExHyperlinkAtom & operator=( const ExHyperlinkAtom & ); + + class Private; + Private *d; +}; + +class ExLinkAtom : public Record +{ +public: + static const unsigned int id; + ExLinkAtom(); + ~ExLinkAtom(); + + int exObjId() const; + void setExObjId( int exObjId); + int flags() const; + void setFlags( int flags); + int unavailable() const; + void setUnavailable( int unavailable); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ExLinkAtom"; } + void dump( std::ostream& out ) const; +private: + // no copy or assign + ExLinkAtom ( const ExLinkAtom & ); + ExLinkAtom & operator=( const ExLinkAtom & ); + + class Private; + Private *d; +}; + +class ExOleObjAtom : public Record +{ +public: + static const unsigned int id; + ExOleObjAtom (); + ~ExOleObjAtom (); + + int drawAspect() const; + void setDrawAspect(int drawAspect); + int type() const; + void setType(int type); + int objID() const; + void setObjID(int objID); + int subType() const; + void setSubType(int subType); + int objStgDataRef() const; + void setObjStgDataRef(int objStgDataRef); + int isBlank() const; + void setIsBlank(int isBlank); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ExOleObjAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ExOleObjAtom ( const ExOleObjAtom & ); + ExOleObjAtom & operator=( const ExOleObjAtom & ); + + class Private; + Private *d; +}; + +class ExEmbedAtom : public Record +{ +public: + static const unsigned int id; + ExEmbedAtom (); + ~ExEmbedAtom (); + + int followColorScheme() const; + void setFollowColorScheme(int followColorScheme); + int cantLockServerB() const; + void setCantLockServerB(int cantLockServerB); + int noSizeToServerB() const; + void setNoSizeToServerB(int noSizeToServerB); + int isTable() const; + void setIsTable(int isTable); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ExEmbedAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ExEmbedAtom ( const ExEmbedAtom & ); + ExEmbedAtom & operator=( const ExEmbedAtom & ); + + class Private; + Private *d; +}; + +class FontEntityAtom : public Record +{ +public: + static const unsigned int id; + FontEntityAtom(); + ~FontEntityAtom(); + + UString ustring() const; + void setUString( const UString& ustr ); + int charset() const; + void setCharset( int charset ) ; + int clipPrecision() const; + void setClipPrecision( int clipPrecision); + int quality() const; + void setQuality( int quality ); + int pitchAndFamily() const; + void setPitchAndFamily( int pitchAndFamily ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "FontEntityAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + FontEntityAtom ( const FontEntityAtom & ); + FontEntityAtom & operator=( const FontEntityAtom & ); + + class Private; + Private *d; +}; + +class GuideAtom : public Record +{ +public: + static const unsigned int id; + GuideAtom (); + ~GuideAtom (); + + int type() const; + void setType(int type); + int pos() const; + void setPos(int pos); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "GuideAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + GuideAtom ( const GuideAtom & ); + GuideAtom & operator=( const GuideAtom & ); + + class Private; + Private *d; +}; + +class HeadersFootersAtom : public Record +{ +public: + static const unsigned int id; + HeadersFootersAtom (); + ~HeadersFootersAtom (); + + int formatId() const; + void setFormatId( int slideId ); + int flags() const; + void setFlags( int flags ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "HeadersFootersAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + HeadersFootersAtom ( const HeadersFootersAtom & ); + HeadersFootersAtom & operator=( const HeadersFootersAtom & ); + + class Private; + Private *d; +}; + +class NotesAtom : public Record +{ +public: + static const unsigned int id; + NotesAtom(); + ~NotesAtom(); + + int slideId() const; + void setSlideId( int slideId ); + int flags() const; + void setFlags( int flags ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "NotesAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + NotesAtom ( const NotesAtom & ); + NotesAtom & operator=( const NotesAtom & ); + + class Private; + Private *d; +}; + +class PersistIncrementalBlockAtom : public Record +{ +public: + static const unsigned int id; + PersistIncrementalBlockAtom(); + ~PersistIncrementalBlockAtom(); + + unsigned entryCount() const; + unsigned long reference( unsigned index ) const; + unsigned long offset( unsigned index ) const; + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "PersistIncrementalBlockAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + PersistIncrementalBlockAtom ( const PersistIncrementalBlockAtom & ); + PersistIncrementalBlockAtom & operator=( const PersistIncrementalBlockAtom & ); + + class Private; + Private *d; +}; + +class Record1043 : public Record +{ +public: + static const unsigned int id; + Record1043 (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "Record1043 "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + Record1043 ( const Record1043 & ); + Record1043 & operator=( const Record1043 & ); + + class Private; + Private *d; +}; + +class Record1044 : public Record +{ +public: + static const unsigned int id; + Record1044 (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "Record1044 "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + Record1044 ( const Record1044 & ); + Record1044 & operator=( const Record1044 & ); + + class Private; + Private *d; +}; + +class SSlideLayoutAtom : public Record +{ +public: + static const unsigned int id; + SSlideLayoutAtom (); + ~SSlideLayoutAtom (); + + int geom() const; + void setGeom( int geom); + int placeholderId() const; + void setPlaceholderId( int placeholderId); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SSlideLayoutAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SSlideLayoutAtom ( const SSlideLayoutAtom & ); + SSlideLayoutAtom & operator=( const SSlideLayoutAtom & ); + + class Private; + Private *d; +}; + +class SlideViewInfoAtom : public Record +{ +public: + static const unsigned int id; + SlideViewInfoAtom (); + ~SlideViewInfoAtom (); + + int showGuides() const; + void setShowGuides( int showGuides); + int snapToGrid() const; + void setSnapToGrid( int snapToGrid); + int snapToShape() const; + void setSnapToShape( int snapToShape); + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SlideViewInfoAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SlideViewInfoAtom ( const SlideViewInfoAtom & ); + SlideViewInfoAtom & operator=( const SlideViewInfoAtom & ); + + class Private; + Private *d; +}; + +class SlidePersistAtom : public Record +{ +public: + static const unsigned int id; + SlidePersistAtom (); + virtual ~SlidePersistAtom (); + + int psrReference() const; + void setPsrReference( int psrReference ); + int flags() const; + void setFlags( int flags ); + int numberTexts() const; + void setNumberTexts( int numberTexts ); + int slideId() const; + void setSlideId( int slideId ); + int reserved() const; + void setReserved(int reserved); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SlidePersistAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SlidePersistAtom ( const SlidePersistAtom & ); + SlidePersistAtom & operator=( const SlidePersistAtom & ); + + class Private; + Private *d; +}; + +class SSDocInfoAtom : public Record +{ +public: + static const unsigned int id; + SSDocInfoAtom (); + ~SSDocInfoAtom (); + + int penColorRed() const; + void setPenColorRed( int penColorRed ); + int penColorGreen() const; + void setPenColorGreen( int penColorGreen ); + int penColorBlue() const; + void setPenColorBlue( int penColorBlue ); + int penColorIndex() const; + void setPenColorIndex( int penColorIndex ); + int restartTime() const; + void setRestartTime( int restartTime ); + int startSlide() const; + void setStartSlide( int startSlide ); + int endSlide() const; + void setEndSlide( int endSlide ); + int namedShow() const; + void setNamedShow(int namedShow); + int flags() const; + void setFlags(int flags); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SSDocInfoAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SSDocInfoAtom ( const SSDocInfoAtom & ); + SSDocInfoAtom & operator=( const SSDocInfoAtom & ); + + class Private; + Private *d; +}; + +class StyleTextPropAtom : public Record +{ +public: + static const unsigned int id; + StyleTextPropAtom (); + ~StyleTextPropAtom (); + + // paragraph properties + int charCount( unsigned index ) const; + int depth( unsigned index ) const; + int bulletOn ( unsigned index ) const; + int bulletHardFont( unsigned index ) const; + int bulletHardColor( unsigned index ) const; + int bulletChar ( unsigned index ) const; + int bulletFont( unsigned index ) const; + int bulletHeight( unsigned index ) const; + int bulletColor( unsigned index ) const; + int align( unsigned index ) const; + int lineFeed( unsigned index ) const; + int upperDist( unsigned index ) const; + int lowerDist( unsigned index ) const; + int asianLB1( unsigned index ) const; + int asianLB2( unsigned index ) const; + int asianLB3( unsigned index ) const; + int biDi( unsigned index ) const; + +// character properties + int charMask() const; + int charFlags() const; + + unsigned listSize() const; + + void setData( unsigned size, const unsigned char* data, unsigned lastSize ); + const char* name(){ return "StyleTextPropAtom "; } + void dump( std::ostream& out ) const; +private: + // character properties + void setCharMask ( int charMask ); + void setCharFlags( int charFlags ); + + // no copy or assign + StyleTextPropAtom ( const StyleTextPropAtom & ); + StyleTextPropAtom & operator=( const StyleTextPropAtom & ); + + class Private; + Private *d; +}; + +class SlideAtom: public Record +{ +public: + static const unsigned int id; + SlideAtom(); + ~SlideAtom(); + + int layoutGeom() const; + void setLayoutGeom( int layoutGeom ); + // see OEPlaceHolderAtom + int layoutPlaceholderId() const; + // void setLayoutPlaceholderId(int layoutPlaceholderId); + void setLayoutPlaceholderId(int layoutPlaceholderId1, int layoutPlaceholderId2,int layoutPlaceholderId3,int layoutPlaceholderId4,int layoutPlaceholderId5,int layoutPlaceholderId6,int layoutPlaceholderId7,int layoutPlaceholderId8); + int masterId() const; + void setMasterId( int masterId ); + int notesId() const; + void setNotesId( int notesId ); + int flags() const; + void setFlags( int flags ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SlideAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SlideAtom( const SlideAtom& ); + SlideAtom& operator=( const SlideAtom& ); + + class Private; + Private *d; +}; + +class SSSlideInfoAtom: public Record +{ +public: + static const unsigned int id; + SSSlideInfoAtom(); + ~SSSlideInfoAtom(); + + int transType() const; + void settransType( int transType ); + int speed() const; + void setspeed(int speed); + int direction() const; + void setdirection( int direction ); + int slideTime() const; + void setslideTime( int slideTime ); + int buildFlags() const; + void setbuildFlags( int buildFlags ); + int soundRef() const; + void setsoundRef( int soundRef ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SSSlideInfoAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SSSlideInfoAtom( const SSSlideInfoAtom& ); + SSSlideInfoAtom& operator=( const SSSlideInfoAtom& ); + + class Private; + Private *d; +}; + +class SrKinsokuAtom : public Record +{ +public: + static const unsigned int id; + SrKinsokuAtom (); + ~SrKinsokuAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "SrKinsokuAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + SrKinsokuAtom ( const SrKinsokuAtom & ); + SrKinsokuAtom & operator=( const SrKinsokuAtom & ); + + class Private; + Private *d; +}; + +class TxMasterStyleAtom : public Record +{ +public: + static const unsigned int id; + TxMasterStyleAtom(); + ~TxMasterStyleAtom(); + + const char* name(){ return "TxMasterStyleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TxMasterStyleAtom ( const TxMasterStyleAtom & ); + TxMasterStyleAtom & operator=( const TxMasterStyleAtom & ); + + class Private; + Private *d; +}; + +class TxCFStyleAtom : public Record +{ +public: + static const unsigned int id; + TxCFStyleAtom (); + ~TxCFStyleAtom (); + + int flags1() const; + void setFlags1( int flags1 ); + int flags2() const; + void setFlags2( int flags2 ); + int flags3() const; + void setFlags3( int flags3 ); + int n1() const; + void setN1( int n1 ); + int fontHeight() const; + void setFontHeight( int fontHeight ); + int fontColor() const; + void setFontColor( int fontColor ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TxCFStyleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TxCFStyleAtom ( const TxCFStyleAtom & ); + TxCFStyleAtom & operator=( const TxCFStyleAtom & ); + + class Private; + Private *d; +}; + + +class TextCharsAtom : public Record +{ +public: + static const unsigned int id; + TextCharsAtom (); + ~TextCharsAtom (); + + unsigned listSize() const; + UString strValue( unsigned index ) const; + void setText( UString ustring ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TextCharsAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TextCharsAtom ( const TextCharsAtom & ); + TextCharsAtom & operator=( const TextCharsAtom & ); + + class Private; + Private *d; +}; + +class TxPFStyleAtom : public Record +{ +public: + static const unsigned int id; + TxPFStyleAtom (); + ~TxPFStyleAtom (); + + const char* name(){ return "TxPFStyleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TxPFStyleAtom ( const TxPFStyleAtom & ); + TxPFStyleAtom & operator=( const TxPFStyleAtom & ); + + class Private; + Private *d; +}; + +class TxSIStyleAtom : public Record +{ +public: + static const unsigned int id; + TxSIStyleAtom (); + ~TxSIStyleAtom (); + + const char* name(){ return "TxSIStyleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TxSIStyleAtom ( const TxSIStyleAtom & ); + TxSIStyleAtom & operator=( const TxSIStyleAtom & ); + + class Private; + Private *d; +}; + +class TextHeaderAtom : public Record +{ +public: + static const unsigned int id; + TextHeaderAtom (); + ~TextHeaderAtom (); + + int textType() const; + void setTextType( int type ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TextHeaderAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TextHeaderAtom ( const TextHeaderAtom & ); + TextHeaderAtom & operator=( const TextHeaderAtom & ); + + class Private; + Private *d; +}; + +class TextSpecInfoAtom : public Record +{ +public: + static const unsigned int id; + TextSpecInfoAtom (); + ~TextSpecInfoAtom (); + + int charCount() const; + void setCharCount( int txSpecInfo ); + int flags() const; + void setFlags( int flags ); + + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TextSpecInfoAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TextSpecInfoAtom ( const TextSpecInfoAtom & ); + TextSpecInfoAtom & operator=( const TextSpecInfoAtom & ); + + class Private; + Private *d; +}; + +class TextBookmarkAtom: public Record +{ +public: + static const unsigned int id; + TextBookmarkAtom(); + ~TextBookmarkAtom(); + + int begin() const; + void setBegin( int begin ); + int end() const; + void setEnd( int end ); + int bookmarkID() const; + void setBookmarkID( int bookmarkID ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TextBookmarkAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TextBookmarkAtom( const TextBookmarkAtom& ); + TextBookmarkAtom& operator=( const TextBookmarkAtom& ); + + class Private; + Private *d; +}; + +class TextBytesAtom : public Record +{ +public: + static const unsigned int id; + TextBytesAtom (); + ~TextBytesAtom (); + + unsigned listSize() const; + unsigned stringLength() const; + void setStringLength( unsigned stringLength ); + + UString strValue( unsigned index ) const; + void setText( UString ustring ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "TextBytesAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + TextBytesAtom ( const TextBytesAtom & ); + TextBytesAtom & operator=( const TextBytesAtom & ); + + class Private; + Private *d; +}; + +class UserEditAtom: public Record +{ +public: + static const unsigned int id; + UserEditAtom(); + ~UserEditAtom(); + + int lastSlideId() const; + void setLastSlideId( int id ); + int majorVersion() const; + void setMajorVersion( int majorVersion ); + int minorVersion() const; + void setMinorVersion( int minorVersion ); + + unsigned long offsetLastEdit() const; + void setOffsetLastEdit( unsigned long ofs ); + unsigned long offsetPersistDir() const; + void setOffsetPersistDir( unsigned long ofs ) const; + unsigned long documentRef() const; + void setDocumentRef( unsigned long ref ) const; + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "UserEditAtom"; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + UserEditAtom( const UserEditAtom& ); + UserEditAtom& operator=( const UserEditAtom& ); + + class Private; + Private *d; +}; + +class ViewInfoAtom : public Record +{ +public: + static const unsigned int id; + ViewInfoAtom (); + ~ViewInfoAtom (); + + int curScaleXNum() const; + void setCurScaleXNum( int curScaleXNum); + int curScaleXDen() const; + void setCurScaleXDen( int curScaleXDen); + int curScaleYNum() const; + void setCurScaleYNum( int curScaleYNum); + int curScaleYDen() const; + void setCurScaleYDen( int curScaleYDen); + int prevScaleXNum() const; + void setPrevScaleXNum( int prevScaleXNum); + int prevScaleXDen() const; + void setPrevScaleXDen( int prevScaleXDen); + int prevScaleYNum() const; + void setPrevScaleYNum( int prevScaleYNum); + int prevScaleYDen() const; + void setPrevScaleYDen( int prevScaleYDen); + int viewSizeX() const; + void setViewSizeX( int viewSizeX); + int viewSizeY() const; + void setViewSizeY( int viewSizeY); + int originX() const; + void setOriginX( int originX); + int originY() const; + void setOriginY( int originY); + int varScale() const; + void setVarScale( int varScale); + int draftMode() const; + void setDraftMode( int draftMode); + int padding() const; + void setPadding( int padding); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "ViewInfoAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + ViewInfoAtom ( const ViewInfoAtom & ); + ViewInfoAtom & operator=( const ViewInfoAtom & ); + + class Private; + Private *d; +}; + +class msofbtDgAtom : public Record +{ +public: + static const unsigned int id; + msofbtDgAtom (); + ~msofbtDgAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtDgAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtDgAtom ( const msofbtDgAtom & ); + msofbtDgAtom & operator=( const msofbtDgAtom & ); + + class Private; + Private *d; +}; + +class msofbtSpgrAtom : public Record +{ +public: + static const unsigned int id; + msofbtSpgrAtom (); + ~msofbtSpgrAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtSpgrAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtSpgrAtom ( const msofbtSpgrAtom & ); + msofbtSpgrAtom & operator=( const msofbtSpgrAtom & ); + + class Private; + Private *d; +}; + +class msofbtSpAtom : public Record +{ +public: + enum + { + msosptMin = 0, + msosptNotPrimitive = msosptMin, + msosptRectangle = 1, + msosptRoundRectangle = 2, + msosptEllipse = 3, + msosptDiamond = 4, + msosptIsoscelesTriangle = 5, + msosptRightTriangle = 6, + msosptParallelogram = 7, + msosptTrapezoid = 8, + msosptHexagon = 9, + msosptOctagon = 10, + msosptPlus = 11, + msosptStar = 12, + msosptArrow = 13, + msosptThickArrow = 14, + msosptHomePlate = 15, + msosptCube = 16, + msosptBalloon = 17, + msosptSeal = 18, + msosptArc = 19, + msosptLine = 20, + msosptPlaque = 21, + msosptCan = 22, + msosptDonut = 23, + msosptTextSimple = 24, + msosptTextOctagon = 25, + msosptTextHexagon = 26, + msosptTextCurve = 27, + msosptTextWave = 28, + msosptTextRing = 29, + msosptTextOnCurve = 30, + msosptTextOnRing = 31, + msosptStraightConnector1 = 32, + msosptBentConnector2 = 33, + msosptBentConnector3 = 34, + msosptBentConnector4 = 35, + msosptBentConnector5 = 36, + msosptCurvedConnector2 = 37, + msosptCurvedConnector3 = 38, + msosptCurvedConnector4 = 39, + msosptCurvedConnector5 = 40, + msosptCallout1 = 41, + msosptCallout2 = 42, + msosptCallout3 = 43, + msosptAccentCallout1 = 44, + msosptAccentCallout2 = 45, + msosptAccentCallout3 = 46, + msosptBorderCallout1 = 47, + msosptBorderCallout2 = 48, + msosptBorderCallout3 = 49, + msosptAccentBorderCallout1 = 50, + msosptAccentBorderCallout2 = 51, + msosptAccentBorderCallout3 = 52, + msosptRibbon = 53, + msosptRibbon2 = 54, + msosptChevron = 55, + msosptPentagon = 56, + msosptNoSmoking = 57, + msosptSeal8 = 58, + msosptSeal16 = 59, + msosptSeal32 = 60, + msosptWedgeRectCallout = 61, + msosptWedgeRRectCallout = 62, + msosptWedgeEllipseCallout = 63, + msosptWave = 64, + msosptFoldedCorner = 65, + msosptLeftArrow = 66, + msosptDownArrow = 67, + msosptUpArrow = 68, + msosptLeftRightArrow = 69, + msosptUpDownArrow = 70, + msosptIrregularSeal1 = 71, + msosptIrregularSeal2 = 72, + msosptLightningBolt = 73, + msosptHeart = 74, + msosptPictureFrame = 75, + msosptQuadArrow = 76, + msosptLeftArrowCallout = 77, + msosptRightArrowCallout = 78, + msosptUpArrowCallout = 79, + msosptDownArrowCallout = 80, + msosptLeftRightArrowCallout = 81, + msosptUpDownArrowCallout = 82, + msosptQuadArrowCallout = 83, + msosptBevel = 84, + msosptLeftBracket = 85, + msosptRightBracket = 86, + msosptLeftBrace = 87, + msosptRightBrace = 88, + msosptLeftUpArrow = 89, + msosptBentUpArrow = 90, + msosptBentArrow = 91, + msosptSeal24 = 92, + msosptStripedRightArrow = 93, + msosptNotchedRightArrow = 94, + msosptBlockArc = 95, + msosptSmileyFace = 96, + msosptVerticalScroll = 97, + msosptHorizontalScroll = 98, + msosptCircularArrow = 99, + msosptNotchedCircularArrow = 100, + msosptUturnArrow = 101, + msosptCurvedRightArrow = 102, + msosptCurvedLeftArrow = 103, + msosptCurvedUpArrow = 104, + msosptCurvedDownArrow = 105, + msosptCloudCallout = 106, + msosptEllipseRibbon = 107, + msosptEllipseRibbon2 = 108, + msosptFlowChartProcess = 109, + msosptFlowChartDecision = 110, + msosptFlowChartInputOutput = 111, + msosptFlowChartPredefinedProcess = 112, + msosptFlowChartInternalStorage = 113, + msosptFlowChartDocument = 114, + msosptFlowChartMultidocument = 115, + msosptFlowChartTerminator = 116, + msosptFlowChartPreparation = 117, + msosptFlowChartManualInput = 118, + msosptFlowChartManualOperation = 119, + msosptFlowChartConnector = 120, + msosptFlowChartPunchedCard = 121, + msosptFlowChartPunchedTape = 122, + msosptFlowChartSummingJunction = 123, + msosptFlowChartOr = 124, + msosptFlowChartCollate = 125, + msosptFlowChartSort = 126, + msosptFlowChartExtract = 127, + msosptFlowChartMerge = 128, + msosptFlowChartOfflineStorage = 129, + msosptFlowChartOnlineStorage = 130, + msosptFlowChartMagneticTape = 131, + msosptFlowChartMagneticDisk = 132, + msosptFlowChartMagneticDrum = 133, + msosptFlowChartDisplay = 134, + msosptFlowChartDelay = 135, + msosptTextPlainText = 136, + msosptTextStop = 137, + msosptTextTriangle = 138, + msosptTextTriangleInverted = 139, + msosptTextChevron = 140, + msosptTextChevronInverted = 141, + msosptTextRingInside = 142, + msosptTextRingOutside = 143, + msosptTextArchUpCurve = 144, + msosptTextArchDownCurve = 145, + msosptTextCircleCurve = 146, + msosptTextButtonCurve = 147, + msosptTextArchUpPour = 148, + msosptTextArchDownPour = 149, + msosptTextCirclePour = 150, + msosptTextButtonPour = 151, + msosptTextCurveUp = 152, + msosptTextCurveDown = 153, + msosptTextCascadeUp = 154, + msosptTextCascadeDown = 155, + msosptTextWave1 = 156, + msosptTextWave2 = 157, + msosptTextWave3 = 158, + msosptTextWave4 = 159, + msosptTextInflate = 160, + msosptTextDeflate = 161, + msosptTextInflateBottom = 162, + msosptTextDeflateBottom = 163, + msosptTextInflateTop = 164, + msosptTextDeflateTop = 165, + msosptTextDeflateInflate = 166, + msosptTextDeflateInflateDeflate = 167, + msosptTextFadeRight = 168, + msosptTextFadeLeft = 169, + msosptTextFadeUp = 170, + msosptTextFadeDown = 171, + msosptTextSlantUp = 172, + msosptTextSlantDown = 173, + msosptTextCanUp = 174, + msosptTextCanDown = 175, + msosptFlowChartAlternateProcess = 176, + msosptFlowChartOffpageConnector = 177, + msosptCallout90 = 178, + msosptAccentCallout90 = 179, + msosptBorderCallout90 = 180, + msosptAccentBorderCallout90 = 181, + msosptLeftRightUpArrow = 182, + msosptSun = 183, + msosptMoon = 184, + msosptBracketPair = 185, + msosptBracePair = 186, + msosptSeal4 = 187, + msosptDoubleWave = 188, + msosptActionButtonBlank = 189, + msosptActionButtonHome = 190, + msosptActionButtonHelp = 191, + msosptActionButtonInformation = 192, + msosptActionButtonForwardNext = 193, + msosptActionButtonBackPrevious = 194, + msosptActionButtonEnd = 195, + msosptActionButtonBeginning = 196, + msosptActionButtonReturn = 197, + msosptActionButtonDocument = 198, + msosptActionButtonSound = 199, + msosptActionButtonMovie = 200, + msosptHostControl = 201, + msosptTextBox = 202, + msosptMax, + msosptNil = 0x0FFF + } ; + + static const unsigned int id; + msofbtSpAtom (); + ~msofbtSpAtom (); + + unsigned long shapeId() const; + void setShapeId( unsigned long id ); + const char* shapeTypeAsString() const; + unsigned long persistentFlag() const; + void setPersistentFlag( unsigned long persistentFlag ); + + bool isBackground() const; + void setBackground( bool bg ); + bool isVerFlip() const; + void setVerFlip( bool vFlip ); + bool isHorFlip() const; + void setHorFlip( bool hFlip ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtSpAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtSpAtom ( const msofbtSpAtom & ); + msofbtSpAtom & operator=( const msofbtSpAtom & ); + + class Private; + Private *d; +}; + +class msofbtOPTAtom : public Record +{ +public: + enum { // PID + Rotation = 4, + FillType = 384, + FillColor = 385, + LineColor = 448, + LineOpacity = 449, + LineBackColor = 450, + LineType = 452, + LineWidth = 459, + LineDashing = 462, + LineStartArrowhead = 464, + LineEndArrowhead = 465, + LineStartArrowWidth = 466, + LineStartArrowLength = 467, + LineEndArrowWidth = 468, + LineEndArrowLength = 469, + FlagNoLineDrawDash = 511, + ShadowColor = 513, + ShadowOpacity = 516, + ShadowOffsetX = 517, + ShadowOffsetY = 518 + }; + + enum { + FillSolid, // Fill with a solid color + FillPattern, // Fill with a pattern (bitmap) + FillTexture, // A texture (pattern with its own color map) + FillPicture, // Center a picture in the shape + FillShade, // Shade from start to end points + FillShadeCenter, // Shade from bounding rectangle to end point + FillShadeShape, // Shade from shape outline to end point + FillShadeScale, // Similar to msofillShade, but the fillAngle + FillShadeTitle, // special type - shade to title --- for PP + FillBackground // Use the background fill color/pattern + }; // MSOFILLTYPE + + enum { + LineSolid, // Solid (continuous) pen 0 + LineDashSys, // PS_DASH system dash style 1 + LineDotSys, // PS_DOT system dash style 2 + LineDashDotSys, // PS_DASHDOT system dash style 3 + LineDashDotDotSys, // PS_DASHDOTDOT system dash style 4 + LineDotGEL, // square dot style 5 + LineDashGEL, // dash style 6 + LineLongDashGEL, // long dash style 7 + LineDashDotGEL, // dash short dash 8 + LineLongDashDotGEL, // long dash short dash 9 + LineLongDashDotDotGEL // long dash short dash short dash 10 + }; // MSOLINEDASHING + + + enum { + LineNoEnd, + LineArrowEnd, + LineArrowStealthEnd, + LineArrowDiamondEnd, + LineArrowOvalEnd, + LineArrowOpenEnd + }; // MSOLINEEND - line end effect + + + enum { + LineNarrowArrow, + LineMediumWidthArrow, + LineWideArrow + }; // MSOLINEENDWIDTH - size of arrowhead + + enum { + LineShortArrow, + LineMediumLenArrow, + LineLongArrow + }; // MSOLINEENDLENGTH - size of arrowhead + + static const unsigned int id; + msofbtOPTAtom (); + ~msofbtOPTAtom (); + + unsigned propertyCount() const; + unsigned propertyId( unsigned index ) const; + unsigned long propertyValue( unsigned index ) const; + void setProperty( unsigned id, unsigned long value ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtOPTAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtOPTAtom ( const msofbtOPTAtom & ); + msofbtOPTAtom & operator=( const msofbtOPTAtom & ); + + class Private; + Private *d; +}; + +class msofbtChildAnchorAtom : public Record +{ +public: + static const unsigned int id; + msofbtChildAnchorAtom (); + ~msofbtChildAnchorAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtChildAnchorAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtChildAnchorAtom ( const msofbtChildAnchorAtom & ); + msofbtChildAnchorAtom & operator=( const msofbtChildAnchorAtom & ); + + class Private; + Private *d; +}; + +class msofbtClientAnchorAtom : public Record +{ +public: + static const unsigned int id; + msofbtClientAnchorAtom (); + ~msofbtClientAnchorAtom (); + + int left() const; + void setLeft( int left ); + int top() const; + void setTop( int top ); + int right() const; + void setRight( int right ); + int bottom() const; + void setBottom( int bottom ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtClientAnchorAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtClientAnchorAtom ( const msofbtClientAnchorAtom & ); + msofbtClientAnchorAtom & operator=( const msofbtClientAnchorAtom & ); + + class Private; + Private *d; +}; + +class msofbtClientDataAtom : public Record +{ +public: + enum + { None = 0, + MasterTitle, + MasterBody, + MasterCenteredTitle, + MasterNotesSlideImage, + MasterNotesBodyImage, + MasterDate, + MasterSlideNumber, + MasterFooter, + MasterHeader, + MasterSubtitle, + Generic, + Title, + Body, + NotesBody, + CenteredTitle, + Subtitle, + VerticalTextTitle, + VerticalTextBody, + NotesSlideImage, + Object, + Graph, + Table, + ClipArt, + OrganizationChart, + MediaClip + }; + + static const unsigned int id; + msofbtClientDataAtom (); + ~msofbtClientDataAtom (); + + unsigned placementId() const; + void setPlacementId( unsigned id ); + unsigned placeholderId() const; + void setPlaceholderId( unsigned id ); + const char* placeholderIdAsString() const; + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtClientDataAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtClientDataAtom ( const msofbtClientDataAtom & ); + msofbtClientDataAtom & operator=( const msofbtClientDataAtom & ); + + class Private; + Private *d; +}; + +class msofbtClientTextboxAtom : public Record +{ +public: + static const unsigned int id; + msofbtClientTextboxAtom (); + ~msofbtClientTextboxAtom (); + + UString ustring() const; + void setUString( const UString& ustr ); + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtClientTextboxAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtClientTextboxAtom ( const msofbtClientTextboxAtom & ); + msofbtClientTextboxAtom & operator=( const msofbtClientTextboxAtom & ); + + class Private; + Private *d; +}; + +class msofbtOleObjectAtom : public Record +{ +public: + static const unsigned int id; + msofbtOleObjectAtom (); + ~msofbtOleObjectAtom (); + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtOleObjectAtom "; } + void dump( std::ostream& out ) const; +private: + // no copy or assign + msofbtOleObjectAtom ( const msofbtOleObjectAtom & ); + msofbtOleObjectAtom & operator=( const msofbtOleObjectAtom & ); + class Private; + Private *d; +}; + +class msofbtDeletedPsplAtom : public Record +{ +public: + static const unsigned int id; + msofbtDeletedPsplAtom (); + ~msofbtDeletedPsplAtom (); + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtDeletedPsplAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtDeletedPsplAtom ( const msofbtDeletedPsplAtom & ); + msofbtDeletedPsplAtom & operator=( const msofbtDeletedPsplAtom & ); + class Private; + Private *d; + +}; + +class msofbtDggAtom : public Record +{ +public: + static const unsigned int id; + msofbtDggAtom (); + ~msofbtDggAtom (); + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtDggAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtDggAtom ( const msofbtDggAtom & ); + msofbtDggAtom & operator=( const msofbtDggAtom & ); + + class Private; + Private *d; +}; + +class msofbtColorMRUAtom : public Record +{ +public: + static const unsigned int id; + msofbtColorMRUAtom (); + ~msofbtColorMRUAtom (); + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtColorMRUAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtColorMRUAtom ( const msofbtColorMRUAtom & ); + msofbtColorMRUAtom & operator=( const msofbtColorMRUAtom & ); + + class Private; + Private *d; +}; + +class msofbtSplitMenuColorsAtom : public Record +{ +public: + static const unsigned int id; + msofbtSplitMenuColorsAtom (); + ~msofbtSplitMenuColorsAtom (); + + unsigned fillColor() const; + void setFillColor( unsigned fillColor ); + unsigned lineColor() const; + void setLineColor( unsigned lineColor ); + unsigned shadowColor() const; + void setShadowColor( unsigned shadowColor ); + unsigned threeDColor() const; + void setThreeDColor( unsigned threeDColor ); + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtSplitMenuColorsAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtSplitMenuColorsAtom ( const msofbtSplitMenuColorsAtom & ); + msofbtSplitMenuColorsAtom & operator=( const msofbtSplitMenuColorsAtom & ); + + class Private; + Private *d; +}; + +class msofbtBSEAtom : public Record +{ +public: + static const unsigned int id; + msofbtBSEAtom (); + ~msofbtBSEAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtBSEAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtBSEAtom ( const msofbtBSEAtom & ); + msofbtBSEAtom & operator=( const msofbtBSEAtom & ); + + class Private; + Private *d; +}; + +class msofbtCLSIDAtom : public Record +{ +public: + static const unsigned int id; + msofbtCLSIDAtom (); + ~msofbtCLSIDAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtCLSIDAtom "; } + void dump( std::ostream& out ) const; + + +private: + // no copy or assign + msofbtCLSIDAtom ( const msofbtCLSIDAtom & ); + msofbtCLSIDAtom & operator=( const msofbtCLSIDAtom & ); + + class Private; + Private *d; +}; + +class msofbtRegroupItemsAtom : public Record +{ +public: + static const unsigned int id; + msofbtRegroupItemsAtom (); + ~msofbtRegroupItemsAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtRegroupItemsAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtRegroupItemsAtom ( const msofbtRegroupItemsAtom & ); + msofbtRegroupItemsAtom & operator=( const msofbtRegroupItemsAtom & ); + + class Private; + Private *d; +}; + +class msofbtColorSchemeAtom : public Record +{ +public: + static const unsigned int id; + msofbtColorSchemeAtom (); + ~msofbtColorSchemeAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtColorSchemeAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtColorSchemeAtom ( const msofbtColorSchemeAtom & ); + msofbtColorSchemeAtom & operator=( const msofbtColorSchemeAtom & ); + + class Private; + Private *d; +}; + +class msofbtAnchorAtom : public Record +{ +public: + static const unsigned int id; + msofbtAnchorAtom (); + ~msofbtAnchorAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtAnchorAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtAnchorAtom ( const msofbtAnchorAtom & ); + msofbtAnchorAtom & operator=( const msofbtAnchorAtom & ); + + class Private; + Private *d; +}; + +class msofbtConnectorRuleAtom : public Record +{ +public: + static const unsigned int id; + msofbtConnectorRuleAtom (); + ~msofbtConnectorRuleAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtConnectorRuleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtConnectorRuleAtom ( const msofbtConnectorRuleAtom & ); + msofbtConnectorRuleAtom & operator=( const msofbtConnectorRuleAtom & ); + + class Private; + Private *d; +}; + +class msofbtAlignRuleAtom : public Record +{ +public: + static const unsigned int id; + msofbtAlignRuleAtom (); + ~msofbtAlignRuleAtom (); + + int ruid() const; // rule ID + void setRuid( int ruid ); + int align() const; + void setAlign( int align );// alignment + int cProxies() const; + void setCProxies( int cProxies );// number of shapes governed by rule + + void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtAlignRuleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtAlignRuleAtom ( const msofbtAlignRuleAtom & ); + msofbtAlignRuleAtom & operator=( const msofbtAlignRuleAtom & ); + + class Private; + Private *d; +}; + +class msofbtArcRuleAtom : public Record +{ +public: + static const unsigned int id; + msofbtArcRuleAtom (); + ~msofbtArcRuleAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtArcRuleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtArcRuleAtom ( const msofbtArcRuleAtom & ); + msofbtArcRuleAtom & operator=( const msofbtArcRuleAtom & ); + + class Private; + Private *d; +}; + +class msofbtClientRuleAtom : public Record +{ +public: + static const unsigned int id; + msofbtClientRuleAtom (); + ~msofbtClientRuleAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtClientRuleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtClientRuleAtom ( const msofbtClientRuleAtom & ); + msofbtClientRuleAtom & operator=( const msofbtClientRuleAtom & ); + + class Private; + Private *d; +}; + +class msofbtCalloutRuleAtom : public Record +{ +public: + static const unsigned int id; + msofbtCalloutRuleAtom (); + ~msofbtCalloutRuleAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtCalloutRuleAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtCalloutRuleAtom ( const msofbtCalloutRuleAtom & ); + msofbtCalloutRuleAtom & operator=( const msofbtCalloutRuleAtom & ); + + class Private; + Private *d; +}; + +class msofbtSelectionAtom : public Record +{ +public: + static const unsigned int id; + msofbtSelectionAtom (); + ~msofbtSelectionAtom (); + + // void setData( unsigned size, const unsigned char* data ); + const char* name(){ return "msofbtSelectionAtom "; } + void dump( std::ostream& out ) const; + +private: + // no copy or assign + msofbtSelectionAtom ( const msofbtSelectionAtom & ); + msofbtSelectionAtom & operator=( const msofbtSelectionAtom & ); + + class Private; + Private *d; +}; + +class PPTReader +{ +public: + PPTReader(); + virtual ~PPTReader(); + bool load( Presentation* pr, const char* filename ); + +protected: + + void loadUserEdit(); + void loadMaster(); + void loadSlides(); + void loadDocument(); + int indexPersistence( unsigned long offset ); + + void loadRecord( Record* parent ); + void handleRecord( Record* record, int type ); + void handleContainer( Container* container, int type, unsigned size ); + + void handleDocumentAtom( DocumentAtom* r ); + void handleSlidePersistAtom( SlidePersistAtom* r ); + void handleTextHeaderAtom( TextHeaderAtom* r ); + void handleTextCharsAtom( TextCharsAtom* r ); + void handleTextBytesAtom( TextBytesAtom* r ); + void handleStyleTextPropAtom ( StyleTextPropAtom* r ); + void handleColorSchemeAtom( ColorSchemeAtom* r ); + + void handleDrawingContainer( msofbtDgContainer* r, unsigned size ); + void handleEscherGroupContainer( msofbtSpgrContainer* r, unsigned size ); + void handleSPContainer( msofbtSpContainer* r, unsigned size ); + void handleEscherGroupAtom( msofbtSpgrAtom* r ); + void handleEscherSpAtom( msofbtSpAtom* r ); + void handleEscherPropertiesAtom( msofbtOPTAtom* atom ); + void handleEscherClientDataAtom( msofbtClientDataAtom* r ); + void handleEscherClientAnchorAtom( msofbtClientAnchorAtom* r ); + void handleEscherTextBoxAtom( msofbtClientTextboxAtom* r); + +private: + // no copy or assign + PPTReader( const PPTReader& ); + PPTReader& operator=( const PPTReader& ); + + class Private; + Private* d; +}; + +} + +#endif /* LIBPPT_POWERPOINT */ diff --git a/filters/kpresenter/powerpoint/libppt/presentation.cpp b/filters/kpresenter/powerpoint/libppt/presentation.cpp new file mode 100644 index 000000000..6aaf7e2bc --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/presentation.cpp @@ -0,0 +1,91 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#include "presentation.h" +#include "slide.h" +#include "powerpoint.h" + +#include + +using namespace Libppt; + +class Presentation::Private +{ +public: + Slide* masterSlide; + std::vector slides; +}; + +Presentation::Presentation() +{ + d = new Private; + d->masterSlide = 0; +} + +Presentation::~Presentation() +{ + clear(); + delete d; +} + +void Presentation::clear() +{ + // FIXME use iterator + for( unsigned i=0; islides.clear(); + delete d->masterSlide; + d->masterSlide = 0; +} + +bool Presentation::load( const char* filename ) +{ + PPTReader* reader = new PPTReader; + bool result = reader->load( this, filename ); + delete reader; + return result; +} + +void Presentation::appendSlide( Slide* slide ) +{ + d->slides.push_back( slide ); +} + +unsigned Presentation::slideCount() const +{ + return d->slides.size(); +} + +Slide* Presentation::slide( unsigned index ) +{ + if( index >= slideCount() ) return (Slide*)0; + return d->slides[index]; +} + + +Slide* Presentation::masterSlide() +{ + return d->masterSlide; +} + +void Presentation::setMasterSlide( Slide* masterSlide ) +{ + delete d->masterSlide; + d->masterSlide = masterSlide; +} diff --git a/filters/kpresenter/powerpoint/libppt/presentation.h b/filters/kpresenter/powerpoint/libppt/presentation.h new file mode 100644 index 000000000..78d75823f --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/presentation.h @@ -0,0 +1,86 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#ifndef LIBPPT_PRESENTATION +#define LIBPPT_PRESENTATION + + +namespace Libppt +{ + +class Slide; + +class Presentation +{ +public: + + /* + * Constructs a new presentation. + */ + Presentation(); + + /* + * Destroys the presentation. + */ + ~Presentation(); + + /* + * Clears the presentation, i.e. makes it as if it is just constructed. + */ + void clear(); + + /* + * Loads the presentation file. Returns false if error occurred. + */ + bool load( const char* filename ); + + /* + * Appends a new slide. + */ + void appendSlide( Slide* slide ); + + /* + * Returns the number of slides in this presentation. A newly created + * presentation has no slide, i.e. slideCount() returns 0. + */ + unsigned slideCount() const; + + /* + * Returns a slide at given index. If index is invalid (e.g. larger + * than total number of slides), this function returns NULL. + */ + + Slide* slide( unsigned index ); + + Slide* masterSlide(); + void setMasterSlide( Slide* master ); + +private: + // no copy or assign + Presentation( const Presentation& ); + Presentation& operator=( const Presentation& ); + + class Private; + Private* d; +}; + + +} + +#endif /* LIBPPT_PRESENTATION */ diff --git a/filters/kpresenter/powerpoint/libppt/slide.cpp b/filters/kpresenter/powerpoint/libppt/slide.cpp new file mode 100644 index 000000000..e336dc304 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/slide.cpp @@ -0,0 +1,138 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#include "slide.h" +#include "presentation.h" +#include "ustring.h" +#include "objects.h" + +#include +#include + + +using namespace Libppt; + +class Slide::Private +{ +public: + Presentation* presentation; + UString title; + GroupObject* rootObject; + + double pageWidth; + double pageHeight; +}; + +Slide::Slide( Presentation* pr ) +{ + d = new Private; + d->presentation = pr; + d->rootObject = new GroupObject; + d->pageWidth = 0.0; + d->pageHeight = 0.0; +} + +Slide::~Slide() +{ + delete d->rootObject; + delete d; +} + +void Slide::clear() +{ + d->title = UString::null; + setRootObject( 0 ); + d->rootObject = new GroupObject; +} + +UString Slide::title() const +{ + return d->title; +} + +void Slide::setTitle( const UString& t ) +{ + UChar* s = new UChar[t.length()]; + int len = 0; + + // filter crazy characters + for( int i=0; ititle = UString( s, len ); + delete [] s; +} + +GroupObject *Slide::rootObject() +{ + return d->rootObject; +} + +void Slide::setRootObject( GroupObject* root ) +{ + delete d->rootObject; + d->rootObject = root; +} + +TextObject* recursiveSearch( GroupObject* group, unsigned placeId ) +{ + if( group ) + for( unsigned i=0; iobjectCount(); i++ ) + { + Object* object = group->object(i); + if( object->isText() ) + { + TextObject* textObject = static_cast(object); + if( textObject) + if( textObject->id() == (int)placeId ) + return textObject; + } + if( object->isGroup() ) + return recursiveSearch( static_cast(object), placeId ); + } + + return 0; +} + + +TextObject* Slide::textObject( unsigned placeId ) +{ + return recursiveSearch( d->rootObject, placeId ); +} + +double Slide::pageWidth() const +{ + return d->pageWidth; +} + +void Slide::setPageWidth( double pageWidth ) +{ + d->pageWidth = pageWidth; +} + +double Slide::pageHeight() const +{ + return d->pageHeight; +} + +void Slide::setPageHeight( double pageHeight ) +{ + d->pageHeight = pageHeight; +} diff --git a/filters/kpresenter/powerpoint/libppt/slide.h b/filters/kpresenter/powerpoint/libppt/slide.h new file mode 100644 index 000000000..d47ba841a --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/slide.h @@ -0,0 +1,61 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#ifndef LIBPPT_SLIDE +#define LIBPPT_SLIDE + +#include "ustring.h" + + +namespace Libppt +{ + +class Presentation; +class GroupObject; +class TextObject; + +class Slide +{ +public: + Slide( Presentation* presentation ); + ~Slide(); + void clear(); + UString title() const; + void setTitle( const UString& title ); + GroupObject* rootObject(); + void setRootObject( GroupObject *); + TextObject* textObject( unsigned placeId ); + + double pageWidth() const; + void setPageWidth( double pageWidth ) ; + double pageHeight() const; + void setPageHeight( double pageHeight ) ; + +private: + // no copy or assign + Slide( const Slide& ); + Slide& operator=( const Slide& ); + + class Private; + Private* d; +}; + +} + +#endif /* LIBPPT_SLIDE */ diff --git a/filters/kpresenter/powerpoint/libppt/testppt.cpp b/filters/kpresenter/powerpoint/libppt/testppt.cpp new file mode 100644 index 000000000..5ab9c4d53 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/testppt.cpp @@ -0,0 +1,42 @@ +/* libppt - library to read PowerPoint presentation + Copyright (C) 2005 Yolla Indria + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA +*/ + +#include "presentation.h" + +#include + +int main( int argc, char** argv ) +{ + if( argc < 2 ) + { + std::cout << "Usage:" << std::endl; + std::cout << " testppt filename" << std::endl; + return -1; + } + + char* filename = argv[1]; + + + Libppt::Presentation* p; + p = new Libppt::Presentation; + p->load( filename ); + delete p; + + return 0; +} diff --git a/filters/kpresenter/powerpoint/libppt/ustring.cpp b/filters/kpresenter/powerpoint/libppt/ustring.cpp new file mode 100644 index 000000000..b0a44e562 --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/ustring.cpp @@ -0,0 +1,675 @@ +// -*- c-basic-offset: 2 -*- +/* + * This file is part of the KDE libraries + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "ustring.h" + +#ifdef HAVE_CONFIG_H +#include +#endif + + +#define USTRING_SIMPLIFIED + +#ifdef USTRING_SIMPLIFIED +#include +#include +#include +#include +#include +#endif + + +#ifndef USTRING_SIMPLIFIED + +#include +#include +#include +#ifdef HAVE_STRING_H +#include +#endif +#ifdef HAVE_STRINGS_H +#include +#endif + +#ifdef HAVE_MATH_H +#include +#endif +#ifdef HAVE_FLOAT_H +#include +#endif +#ifdef HAVE_IEEEFP_H +#include +#endif + +#endif + +namespace Libppt { +#ifdef WORDS_BIGENDIAN + unsigned char NaN_Bytes[] = { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }; + unsigned char Inf_Bytes[] = { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }; +#elif defined(arm) + unsigned char NaN_Bytes[] = { 0, 0, 0xf8, 0x7f, 0, 0, 0, 0 }; + unsigned char Inf_Bytes[] = { 0, 0, 0xf0, 0x7f, 0, 0, 0, 0 }; +#else + unsigned char NaN_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }; + unsigned char Inf_Bytes[] = { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }; +#endif + + const double NaN = *( reinterpret_cast( NaN_Bytes ) ); + const double Inf = *( reinterpret_cast( Inf_Bytes ) ); +} + +using namespace Libppt; + +#ifdef USTRING_SIMPLIFIED +bool Libppt::isNaN(double) +{ + return false; +} +#else +bool Libppt::isNaN(double d) +{ +#ifdef HAVE_FUNC_ISNAN + return isnan(d); +#elif defined HAVE_FLOAT_H + return _isnan(d) != 0; +#else + return !(d == d); +#endif +} +#endif + +#ifdef USTRING_SIMPLIFIED +bool Libppt::isPosInf(double) +{ + return false; +} +#else +bool Libppt::isPosInf(double d) +{ +#if defined(HAVE_FUNC_ISINF) + return (isinf(d) == 1); +#elif HAVE_FUNC_FINITE + return finite(d) == 0 && d == d; // ### can we distinguish between + and - ? +#elif HAVE_FUNC__FINITE + return _finite(d) == 0 && d == d; // ### +#else + return false; +#endif +} +#endif + +#ifdef USTRING_SIMPLIFIED +bool Libppt::isNegInf(double) +{ + return false; +} +#else +bool Libppt::isNegInf(double d) +{ +#if defined(HAVE_FUNC_ISINF) + return (isinf(d) == -1); +#elif HAVE_FUNC_FINITE + return finite(d) == 0 && d == d; // ### +#elif HAVE_FUNC__FINITE + return _finite(d) == 0 && d == d; // ### +#else + return false; +#endif +} +#endif + +CString::CString(const char *c) +{ + data = new char[strlen(c)+1]; + strcpy(data, c); +} + +CString::CString(const CString &b) +{ + data = new char[b.length()+1]; + strcpy(data, b.c_str()); +} + +CString::~CString() +{ + delete [] data; +} + +CString &CString::append(const CString &t) +{ + char *n; + if (data) { + n = new char[strlen(data)+t.length()+1]; + strcpy(n, data); + } else { + n = new char[t.length()+1]; + n[0] = '\0'; + } + strcat(n, t.c_str()); + + delete [] data; + data = n; + + return *this; +} + +CString &CString::operator=(const char *c) +{ + if (data) + delete [] data; + data = new char[strlen(c)+1]; + strcpy(data, c); + + return *this; +} + +CString &CString::operator=(const CString &str) +{ + if (this == &str) + return *this; + + if (data) + delete [] data; + data = new char[str.length()+1]; + strcpy(data, str.c_str()); + + return *this; +} + +CString &CString::operator+=(const CString &str) +{ + return append(CString(str.c_str())); +} + +int CString::length() const +{ + return strlen(data); +} + +bool Libppt::operator==(const Libppt::CString& c1, const Libppt::CString& c2) +{ + return (strcmp(c1.c_str(), c2.c_str()) == 0); +} + +UChar UChar::null; +UString::Rep UString::Rep::null = { 0, 0, 1 }; +UString UString::null; +static char *statBuffer = 0L; + +UChar::UChar(const UCharReference &c) + : uc( c.unicode() ) +{ +} + +UChar UChar::toLower() const +{ + // ### properly support unicode tolower + if (uc >= 256 || islower(uc)) + return *this; + + return UChar(tolower(uc)); +} + +UChar UChar::toUpper() const +{ + if (uc >= 256 || isupper(uc)) + return *this; + + return UChar(toupper(uc)); +} + +UCharReference& UCharReference::operator=(UChar c) +{ + str->detach(); + if (offset < str->rep->len) + *(str->rep->dat + offset) = c; + /* TODO: lengthen string ? */ + return *this; +} + +UChar& UCharReference::ref() const +{ + if (offset < str->rep->len) + return *(str->rep->dat + offset); + else + return UChar::null; +} + +namespace { + // return an uninitialized UChar array of size s + static inline UChar* allocateChars(int s) + { + // work around default UChar constructor code + return reinterpret_cast(new short[s]); + } +} + +UString::Rep *UString::Rep::create(UChar *d, int l) +{ + Rep *r = new Rep; + r->dat = d; + r->len = l; + r->rc = 1; + + return r; +} + +UString::UString() +{ + null.rep = &Rep::null; + attach(&Rep::null); +} + +UString::UString(char c) +{ + UChar *d = allocateChars( 1 ); + d[0] = UChar(0, c); + rep = Rep::create(d, 1); +} + +UString::UString(UChar c) +{ + UChar *d = allocateChars( 1 ); + d[0] = c; + rep = Rep::create(d, 1); +} + +UString::UString(const char *c) +{ + attach(&Rep::null); + operator=(c); +} + +UString::UString(const UChar *c, int length) +{ + UChar *d = allocateChars( length ); + memcpy(d, c, length * sizeof(UChar)); + rep = Rep::create(d, length); +} + +UString::UString(UChar *c, int length, bool copy) +{ + UChar *d; + if (copy) { + d = allocateChars( length ); + memcpy(d, c, length * sizeof(UChar)); + } else + d = c; + rep = Rep::create(d, length); +} + +UString::UString(const UString &b) +{ + attach(b.rep); +} + +UString::~UString() +{ + release(); +} + +UString UString::from(int i) +{ + char buf[40]; + sprintf(buf, "%d", i); + + return UString(buf); +} + +UString UString::from(unsigned int u) +{ + char buf[40]; + sprintf(buf, "%u", u); + + return UString(buf); +} + +UString UString::from(double d) +{ + char buf[40]; + + if (d == -0) + strcpy(buf,"0"); + else if (isNaN(d)) + strcpy(buf,"NaN"); + else if (isPosInf(d)) + strcpy(buf,"Infinity"); + else if (isNegInf(d)) + strcpy(buf,"-Infinity"); + else + sprintf(buf, "%.16g", d); // does the right thing + + // ECMA 3rd ed. 9.8.1 9 e: "with no leading zeros" + int buflen = strlen(buf); + if (buflen >= 4 && buf[buflen-4] == 'e' && buf[buflen-2] == '0') { + buf[buflen-2] = buf[buflen-1]; + buf[buflen-1] = 0; + } + + return UString(buf); +} + +UString &UString::append(const UString &t) +{ + int l = length(); + UChar *n = allocateChars( l+t.length() ); + memcpy(n, data(), l * sizeof(UChar)); + memcpy(n+l, t.data(), t.length() * sizeof(UChar)); + release(); + rep = Rep::create(n, l + t.length()); + + return *this; +} + +CString UString::cstring() const +{ + return CString(ascii()); +} + +char *UString::ascii() const +{ + if (statBuffer) + delete [] statBuffer; + + statBuffer = new char[length()+1]; + for(int i = 0; i < length(); i++) + statBuffer[i] = data()[i].low(); + statBuffer[length()] = '\0'; + + return statBuffer; +} + +UString &UString::operator=(const char *c) +{ + release(); + int l = c ? strlen(c) : 0; + UChar *d = allocateChars( l ); + for (int i = 0; i < l; i++) + d[i].uc = static_cast( c[i] ); + rep = Rep::create(d, l); + + return *this; +} + +UString &UString::operator=(const UString &str) +{ + str.rep->ref(); + release(); + rep=str.rep; + + return *this; +} + +UString &UString::operator+=(const UString &s) +{ + return append(s); +} + +bool UString::is8Bit() const +{ + const UChar *u = data(); + for(int i = 0; i < length(); i++, u++) + if (u->uc > 0xFF) + return false; + + return true; +} + +UChar UString::operator[](int pos) const +{ + if (pos >= length()) + return UChar::null; + + return static_cast( data() )[pos]; +} + +UCharReference UString::operator[](int pos) +{ + /* TODO: boundary check */ + return UCharReference(this, pos); +} + +double UString::toDouble( bool tolerant ) const +{ + double d; + + if (!is8Bit()) + return NaN; + + CString str = cstring(); + const char *c = str.c_str(); + + // skip leading white space + while (isspace(*c)) + c++; + + // empty string ? + if (*c == '\0') + return tolerant ? NaN : 0.0; + + // hex number ? + if (*c == '0' && (*(c+1) == 'x' || *(c+1) == 'X')) { + c++; + d = 0.0; + while (*(++c)) { + if (*c >= '0' && *c <= '9') + d = d * 16.0 + *c - '0'; + else if ((*c >= 'A' && *c <= 'F') || (*c >= 'a' && *c <= 'f')) + d = d * 16.0 + (*c & 0xdf) - 'A' + 10.0; + else + break; + } + } else { + // regular number ? + char *end; + d = strtod(c, &end); + if ((d != 0.0 || end != c) && d != HUGE_VAL && d != -HUGE_VAL) { + c = end; + } else { + // infinity ? + d = 1.0; + if (*c == '+') + c++; + else if (*c == '-') { + d = -1.0; + c++; + } + if (strncmp(c, "Infinity", 8) != 0) + return NaN; + d = d * Inf; + c += 8; + } + } + + // allow trailing white space + while (isspace(*c)) + c++; + // don't allow anything after - unless tolerant=true + if ( !tolerant && *c != '\0') + d = NaN; + + return d; +} + +unsigned long UString::toULong(bool *ok) const +{ + double d = toDouble(); + bool b = true; + + if (isNaN(d) || d != static_cast(d)) { + b = false; + d = 0; + } + + if (ok) + *ok = b; + + return static_cast(d); +} + +int UString::find(const UString &f, int pos) const +{ + if (isNull()) + return -1; + long fsize = f.length() * sizeof(UChar); + if (pos < 0) + pos = 0; + const UChar *end = data() + length() - f.length(); + for (const UChar *c = data() + pos; c <= end; c++) + if (!memcmp(c, f.data(), fsize)) + return (c-data()); + + return -1; +} + +int UString::rfind(const UString &f, int pos) const +{ + if (isNull()) + return -1; + if (pos + f.length() >= length()) + pos = length() - f.length(); + long fsize = f.length() * sizeof(UChar); + for (const UChar *c = data() + pos; c >= data(); c--) { + if (!memcmp(c, f.data(), fsize)) + return (c-data()); + } + + return -1; +} + +UString UString::substr(int pos, int len) const +{ + if (isNull()) + return UString(); + if (pos < 0) + pos = 0; + else if (pos >= static_cast( length() )) + pos = length(); + if (len < 0) + len = length(); + if (pos + len >= static_cast( length() )) + len = length() - pos; + + UChar *tmp = allocateChars( len ); + memcpy(tmp, data()+pos, len * sizeof(UChar)); + UString result(tmp, len); + delete [] tmp; + + return result; +} + +void UString::attach(Rep *r) +{ + rep = r; + rep->ref(); +} + +void UString::detach() +{ + if (rep->rc > 1) { + int l = length(); + UChar *n = allocateChars( l ); + memcpy(n, data(), l * sizeof(UChar)); + release(); + rep = Rep::create(n, l); + } +} + +void UString::release() +{ + if (!rep->deref()) { + delete [] rep->dat; + delete rep; + } +} + +bool Libppt::operator==(const UString& s1, const UString& s2) +{ + if (s1.rep->len != s2.rep->len) + return false; + + return (memcmp(s1.rep->dat, s2.rep->dat, + s1.rep->len * sizeof(UChar)) == 0); +} + +bool Libppt::operator==(const UString& s1, const char *s2) +{ + if (s2 == 0L && s1.isNull()) + return true; + + if (s1.length() != static_cast( strlen(s2) )) + return false; + + const UChar *u = s1.data(); + while (*s2) { + if (u->uc != *s2 ) + return false; + s2++; + u++; + } + + return true; +} + +bool Libppt::operator<(const UString& s1, const UString& s2) +{ + const int l1 = s1.length(); + const int l2 = s2.length(); + const int lmin = l1 < l2 ? l1 : l2; + const UChar *c1 = s1.data(); + const UChar *c2 = s2.data(); + int l = 0; + while (l < lmin && *c1 == *c2) { + c1++; + c2++; + l++; + } + if (l < lmin) + return (c1->unicode() < c2->unicode()); + + return (l1 < l2); +} + +UString Libppt::operator+(const UString& s1, const UString& s2) +{ + UString tmp(s1); + tmp.append(s2); + + return tmp; +} + + +UConstString::UConstString( UChar* data, unsigned int length ) : UString( data, length, false ) +{ +} + +UConstString::~UConstString() +{ + if ( rep->rc > 1 ) { + int l = length(); + UChar* n = allocateChars( l ); + memcpy( n, data(), l * sizeof( UChar ) ); + rep->dat = n; + } + else + rep->dat = 0; +} diff --git a/filters/kpresenter/powerpoint/libppt/ustring.h b/filters/kpresenter/powerpoint/libppt/ustring.h new file mode 100644 index 000000000..dfadbc7df --- /dev/null +++ b/filters/kpresenter/powerpoint/libppt/ustring.h @@ -0,0 +1,395 @@ +// -*- c-basic-offset: 2 -*- +/* + * This file is part of the KDE libraries + * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef LIBPPT_USTRING_H_ +#define LIBPPT_USTRING_H_ + +namespace Libppt { + + /** + * @return True if d is not a number (platform support required). + */ + bool isNaN(double d); + + bool isPosInf(double d); + bool isNegInf(double d); + + class UCharReference; + class UString; + class UConstString; + + /** + * @short Unicode character. + * + * UChar represents a 16 bit Unicode character. It's internal data + * representation is compatible to XChar2b and QChar. It's therefore + * possible to exchange data with X and Qt with shallow copies. + */ + struct UChar { + /** + * Construct a character with value 0. + */ + UChar(); + /** + * Construct a character with the value denoted by the arguments. + * @param h higher byte + * @param l lower byte + */ + UChar(unsigned char h , unsigned char l); + /** + * Construct a character with the given value. + * @param u 16 bit Unicode value + */ + UChar(unsigned short u); + UChar(const UCharReference &c); + /** + * @return The higher byte of the character. + */ + unsigned char high() const { return uc >> 8; } + /** + * @return The lower byte of the character. + */ + unsigned char low() const { return uc & 0xFF; } + /** + * @return the 16 bit Unicode value of the character + */ + unsigned short unicode() const { return uc; } + public: + /** + * @return The character converted to lower case. + */ + UChar toLower() const; + /** + * @return The character converted to upper case. + */ + UChar toUpper() const; + /** + * A static instance of UChar(0). + */ + static UChar null; + private: + friend class UCharReference; + friend class UString; + friend bool operator==(const UChar &c1, const UChar &c2); + friend bool operator==(const UString& s1, const char *s2); + friend bool operator<(const UString& s1, const UString& s2); + + unsigned short uc; + }; + + inline UChar::UChar() : uc(0) { } + inline UChar::UChar(unsigned char h , unsigned char l) : uc(h << 8 | l) { } + inline UChar::UChar(unsigned short u) : uc(u) { } + + /** + * @short Dynamic reference to a string character. + * + * UCharReference is the dynamic counterpart of @ref UChar. It's used when + * characters retrieved via index from a @ref UString are used in an + * assignment expression (and therefore can't be treated as being const): + *

    +   * UString s("hello world");
    +   * s[0] = 'H';
    +   * 
    + * + * If that sounds confusing your best bet is to simply forget about the + * existance of this class and treat is as being identical to @ref UChar. + */ + class UCharReference { + friend class UString; + UCharReference(UString *s, unsigned int off) : str(s), offset(off) { } + public: + /** + * Set the referenced character to c. + */ + UCharReference& operator=(UChar c); + /** + * Same operator as above except the argument that it takes. + */ + UCharReference& operator=(char c) { return operator=(UChar(c)); } + /** + * @return Unicode value. + */ + unsigned short unicode() const { return ref().unicode(); } + /** + * @return Lower byte. + */ + unsigned char low() const { return ref().uc & 0xFF; } + /** + * @return Higher byte. + */ + unsigned char high() const { return ref().uc >> 8; } + /** + * @return Character converted to lower case. + */ + UChar toLower() const { return ref().toLower(); } + /** + * @return Character converted to upper case. + */ + UChar toUpper() const { return ref().toUpper(); } + private: + // not implemented, can only be constructed from UString + UCharReference(); + + UChar& ref() const; + UString *str; + int offset; + }; + + /** + * @short 8 bit char based string class + */ + class CString { + public: + CString() : data(0L) { } + explicit CString(const char *c); + CString(const CString &); + + ~CString(); + + CString &append(const CString &); + CString &operator=(const char *c); + CString &operator=(const CString &); + CString &operator+=(const CString &); + + int length() const; + const char *c_str() const { return data; } + private: + char *data; + }; + + /** + * @short Unicode string class + */ + class UString { + friend bool operator==(const UString&, const UString&); + friend class UCharReference; + friend class UConstString; + /** + * @internal + */ + struct Rep { + friend class UString; + friend bool operator==(const UString&, const UString&); + static Rep *create(UChar *d, int l); + inline UChar *data() const { return dat; } + inline int length() const { return len; } + + inline void ref() { rc++; } + inline int deref() { return --rc; } + + UChar *dat; + int len; + int rc; + static Rep null; + }; + + public: + /** + * Constructs a null string. + */ + UString(); + /** + * Constructs a string from the single character c. + */ + explicit UString(char c); + /** + * Constructs a string from the single character c. + */ + explicit UString(UChar c); + /** + * Constructs a string from a classical zero determined char string. + */ + explicit UString(const char *c); + /** + * Constructs a string from an array of Unicode characters of the specified + * length. + */ + UString(const UChar *c, int length); + /** + * If copy is false a shallow copy of the string will be created. That + * means that the data will NOT be copied and you'll have to guarantee that + * it doesn't get deleted during the lifetime of the UString object. + */ + UString(UChar *c, int length, bool copy); + /** + * Copy constructor. Makes a shallow copy only. + */ + UString(const UString &); + /** + * Destructor. If this handle was the only one holding a reference to the + * string the data will be freed. + */ + ~UString(); + + /** + * Constructs a string from an int. + */ + static UString from(int i); + /** + * Constructs a string from an unsigned int. + */ + static UString from(unsigned int u); + /** + * Constructs a string from a double. + */ + static UString from(double d); + + /** + * Append another string. + */ + UString &append(const UString &); + + /** + * @return The string converted to the 8-bit string type @ref CString(). + */ + CString cstring() const; + /** + * Convert the Unicode string to plain ASCII chars chopping of any higher + * bytes. This method should only be used for *debugging* purposes as it + * is neither Unicode safe nor free from side effects. In order not to + * waste any memory the char buffer is static and *shared* by all UString + * instances. + */ + char *ascii() const; + + /** + * Assignment operator. + */ + UString &operator=(const char *c); + /** + * Assignment operator. + */ + UString &operator=(const UString &); + /** + * Appends the specified string. + */ + UString &operator+=(const UString &s); + + /** + * @return A pointer to the internal Unicode data. + */ + const UChar* data() const { return rep->data(); } + /** + * @return True if null. + */ + bool isNull() const { return (rep == &Rep::null); } + /** + * @return True if null or zero length. + */ + bool isEmpty() const { return (!rep->len); } + /** + * Use this if you want to make sure that this string is a plain ASCII + * string. For example, if you don't want to lose any information when + * using @ref cstring() or @ref ascii(). + * + * @return True if the string doesn't contain any non-ASCII characters. + */ + bool is8Bit() const; + /** + * @return The length of the string. + */ + int length() const { return rep->length(); } + /** + * Const character at specified position. + */ + UChar operator[](int pos) const; + /** + * Writable reference to character at specified position. + */ + UCharReference operator[](int pos); + + /** + * Attempts an conversion to a number. Apart from floating point numbers, + * the algorithm will recognize hexadecimal representations (as + * indicated by a 0x or 0X prefix) and +/- Infinity. + * Returns NaN if the conversion failed. + * @param tolerant if true, toDouble can tolerate garbage after the number. + */ + double toDouble(bool tolerant=false) const; + /** + * Attempts an conversion to an unsigned long integer. ok will be set + * according to the success. + */ + unsigned long toULong(bool *ok = 0L) const; + /** + * @return Position of first occurence of f starting at position pos. + * -1 if the search was not successful. + */ + int find(const UString &f, int pos = 0) const; + /** + * @return Position of first occurence of f searching backwards from + * position pos. + * -1 if the search was not successful. + */ + int rfind(const UString &f, int pos) const; + /** + * @return The sub string starting at position pos and length len. + */ + UString substr(int pos = 0, int len = -1) const; + /** + * Static instance of a null string. + */ + static UString null; + + private: + void attach(Rep *r); + void detach(); + void release(); + Rep *rep; + }; + + inline bool operator==(const UChar &c1, const UChar &c2) { + return (c1.uc == c2.uc); + } + inline bool operator!=(const UChar &c1, const UChar &c2) { + return !(c1 == c2); + } + bool operator==(const UString& s1, const UString& s2); + inline bool operator!=(const UString& s1, const UString& s2) { + return !Libppt::operator==(s1, s2); + } + bool operator<(const UString& s1, const UString& s2); + bool operator==(const UString& s1, const char *s2); + inline bool operator!=(const UString& s1, const char *s2) { + return !Libppt::operator==(s1, s2); + } + inline bool operator==(const char *s1, const UString& s2) { + return operator==(s2, s1); + } + inline bool operator!=(const char *s1, const UString& s2) { + return !Libppt::operator==(s1, s2); + } + bool operator==(const CString& s1, const CString& s2); + UString operator+(const UString& s1, const UString& s2); + + + class UConstString : private UString { + public: + UConstString( UChar* data, unsigned int length ); + ~UConstString(); + + const UString& string() const { return *this; } + }; + +} + +#endif /* LIBPPT_USTRING_H_ */ diff --git a/filters/kpresenter/svg/Makefile.am b/filters/kpresenter/svg/Makefile.am new file mode 100644 index 000000000..4783e9f8d --- /dev/null +++ b/filters/kpresenter/svg/Makefile.am @@ -0,0 +1,21 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + $(all_includes) + +####### Files +kde_module_LTLIBRARIES = libkpresentersvgexport.la + +libkpresentersvgexport_la_SOURCES = svgexport.cc +libkpresentersvgexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresentersvgexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + svgexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_svg_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/svg/kpresenter_svg_export.desktop b/filters/kpresenter/svg/kpresenter_svg_export.desktop new file mode 100644 index 000000000..be387dc58 --- /dev/null +++ b/filters/kpresenter/svg/kpresenter_svg_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=KPresenter SVG Export Filter +Name[bg]=Филтър за експортиране от KPresenter в SVG +Name[br]=Sil ezporzh SVG evit KPresenter +Name[ca]=Filtre d'exportació SVG per a KPresenter +Name[cy]=Hidlen Allforio SVG KPresenter +Name[da]=KPresenter SVG-eksportfilter +Name[de]=KPresenter SVG-Exportfilter +Name[el]=Φίλτρο εξαγωγής SVG του KPresenter +Name[eo]=KPresenter PNG-eksportfiltrilo +Name[es]=Filtro de exportación a SVG para KPresenter +Name[et]=KPresenteri SVG ekspordifilter +Name[fa]=پالایۀ صادرات KPresenter SVG +Name[fi]=KPresenter SVG -vientisuodin +Name[fr]=Filtre d'exportation SVG de KPresenter +Name[fy]=SVG-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála SVG KPresenter +Name[gl]=Filtro de Exportación de SVG para KPresenter +Name[he]=KPresenter SVG מסנן יצוא +Name[hr]=KPresenter SVG filtar izvoza +Name[hu]=KPresenter SVG exportszűrő +Name[is]=KPresenter SVG útflutningssía +Name[it]=Filtro di esportazione SVG per KPresenter +Name[ja]=KPresenter SVG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ SVG សម្រាប់ KPresenter +Name[lt]=KPresenter SVG eksportavimo filtras +Name[lv]=KPresenter SVG eksporta filtrs +Name[nb]=SVG-eksportfilter for KPresenter +Name[nds]=SVG-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता एसभीजी निर्यात फिल्टर +Name[nl]=KPresenter SVG Exportfilter +Name[pl]=Filtr eksportu do formatu SVG dla KPresenter +Name[pt]=Filtro de Exportação de SVG para o KPresenter +Name[pt_BR]=Filtro de Exportação de SVG para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в SVG +Name[se]=KPresenter SVG-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter SVG +Name[sl]=Izvozni filter SVG za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у SVG +Name[sr@Latn]=KPresenter-ov filter za izvoz u SVG +Name[sv]=Kpresenter SVG-exportfilter +Name[uk]=Фільтр експорту SVG для KPresenter +Name[uz]=KPresenter SVG eksport filteri +Name[uz@cyrillic]=KPresenter SVG экспорт филтери +Name[zh_CN]=KPresenter SVG 导出过滤器 +Name[zh_TW]=KPresenter SVG 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/svg+xml +X-KDE-Weight=1 +X-KDE-Library=libkpresentersvgexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/svg/svgexport.cc b/filters/kpresenter/svg/svgexport.cc new file mode 100644 index 000000000..2be6eea1c --- /dev/null +++ b/filters/kpresenter/svg/svgexport.cc @@ -0,0 +1,100 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + code based on svgexport.cc from Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#include +#include + +#include + +#include +#include +//#include +#include + +#include "KPrDocument.h" +#include "KPrView.h" +#include "KPrCanvas.h" + +#include "svgexport.h" + + +typedef KGenericFactory SvgExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresentersvgexport, SvgExportFactory( "svgexport" ) ) + +SvgExport::SvgExport(KoFilter *, const char *, const QStringList&) + : KoFilter() +{ +} + +SvgExport::~SvgExport() +{ +} + + +KoFilter::ConversionStatus +SvgExport::convert(const QCString& from, const QCString& to) +{ + KoDocument * document = m_chain->inputDocument(); + + if ( !document ) + return KoFilter::StupidError; + + if ( strcmp(document->className(), "KPrDocument") != 0) + { + kdWarning() << "document isn't a KPrDocument but a " + << document->className() << endl; + return KoFilter::NotImplemented; + } + + // Check for proper conversion. + if ( from != "application/x-kpresenter" || to != "image/svg+xml" ) + { + kdWarning() << "Invalid mimetypes " << to << " " << from << endl; + return KoFilter::NotImplemented; + } + KPrDocument * kpresenterdoc = const_cast(static_cast(document)); + + if ( kpresenterdoc->mimeType() != "application/x-kpresenter" ) + { + kdWarning() << "Invalid document mimetype " << kpresenterdoc->mimeType() << endl; + return KoFilter::NotImplemented; + } + KoPageLayout layoutPage= kpresenterdoc->pageLayout(); + int width = int( layoutPage.ptWidth ); + int height = int( layoutPage.ptHeight ); + + QPicture picture; + QPainter painter(&picture); + QRect rect(QPoint(0, 0), QPoint(width, height)); + kpresenterdoc->paintContent(painter, rect, false); + painter.end(); + + if ( !picture.save( m_chain->outputFile(), "SVG" ) ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "SVG Export Error" ) ); + } + + return KoFilter::OK; +} + + +#include "svgexport.moc" + + diff --git a/filters/kpresenter/svg/svgexport.h b/filters/kpresenter/svg/svgexport.h new file mode 100644 index 000000000..7b4583b38 --- /dev/null +++ b/filters/kpresenter/svg/svgexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + code based on svgexport.cc from Inge Wallin + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301 USA. +*/ + +#ifndef __SVGEXPORT_H__ +#define __SVGEXPORT_H__ + +#include + +class SvgExport : public KoFilter +{ + Q_OBJECT + +public: + SvgExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~SvgExport(); + + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // __SVGEXPORT_H__ + diff --git a/filters/kpresenter/xbm/Makefile.am b/filters/kpresenter/xbm/Makefile.am new file mode 100644 index 000000000..1d794f766 --- /dev/null +++ b/filters/kpresenter/xbm/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresenterxbmexport.la + +libkpresenterxbmexport_la_SOURCES = xbmexport.cpp +libkpresenterxbmexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresenterxbmexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + xbmexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_xbm_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/xbm/kpresenter_xbm_export.desktop b/filters/kpresenter/xbm/kpresenter_xbm_export.desktop new file mode 100644 index 000000000..890a0b3ac --- /dev/null +++ b/filters/kpresenter/xbm/kpresenter_xbm_export.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=KPresenter XBM Export Filter +Name[bg]=Филтър за експортиране от KPresenter в BMP +Name[br]=Sil ezporzh XBM evit KPresenter +Name[ca]=Filtre d'exportació XBM per a KPresenter +Name[da]=KPresenter XBM-eksportfilter +Name[de]=KPresenter XBM-Exportfilter +Name[el]=Φίλτρο εξαγωγής XBM του KPresenter +Name[eo]=KPresenter XBM-eksportfiltrilo +Name[es]=Filtro de exportación a XBM para KPresenter +Name[et]=KPresenteri XBM-i filter +Name[fa]=پالایۀ صادرات KPresenter XBM +Name[fi]=KPresenter XBM -vientisuodin +Name[fr]=Filtre d'exportation XBM de KPresenter +Name[fy]=XBM-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála XBM KPresenter +Name[gl]=Filtro de Exportación de XBM para KPresenter +Name[he]=KPresenter XBM מסנן יצוא +Name[hr]=KPresenter XBM filtar izvoza +Name[hu]=KPresenter XBM exportszűrő +Name[is]=KPresenter XBM útflutningssía +Name[it]=Filtro di esportazione XBM per KPresenter +Name[ja]=KPresenter XBM エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ XBM សម្រាប់ KPresenter +Name[lt]=KPresenter XBM eksportavimo filtras +Name[lv]=KPresenter XBM eksporta filtrs +Name[nb]=XBM-eksportfilter for KPresenter +Name[nds]=XBM-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता एक्सबीएम निर्यात फिल्टर +Name[nl]=KPresenter XBM Exportfilter +Name[pl]=Filtr eksportu do formatu XBM dla KPresenter +Name[pt]=Filtro de Exportação de XBM para o KPresenter +Name[pt_BR]=Filtro de Exportação de XBM para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в XBM +Name[se]=KPresenter XBM-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter XBM +Name[sl]=Izvozni filter XBM za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у XBM +Name[sr@Latn]=KPresenter-ov filter za izvoz u XBM +Name[sv]=Kpresenter XBM-exportfilter +Name[uk]=Фільтр експорту XBM для KPresenter +Name[uz]=KPresenter XBM eksport filteri +Name[uz@cyrillic]=KPresenter XBM экспорт филтери +Name[zh_CN]=KPresenter XBM 导出过滤器 +Name[zh_TW]=KPresenter XBM 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/x-xbm +X-KDE-Weight=1 +X-KDE-Library=libkpresenterxbmexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/xbm/xbmexport.cpp b/filters/kpresenter/xbm/xbmexport.cpp new file mode 100644 index 000000000..148288dc2 --- /dev/null +++ b/filters/kpresenter/xbm/xbmexport.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "xbmexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory xbmExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresenterxbmexport, xbmExportFactory( "xbmexport" ) ) + +XbmExport::XbmExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +XbmExport::~XbmExport() +{ +} + +bool XbmExport::extraImageAttribute() +{ + bool ret = false; + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + ret = true; + kdDebug() << "Xbm Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; + return ret; +} + + +bool XbmExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "XBM" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "Xbm Export Error" ) ); + } + return ret; +} + +const char * XbmExport::exportFormat() +{ + return "image/x-xbm"; +} + +#include "xbmexport.moc" + diff --git a/filters/kpresenter/xbm/xbmexport.h b/filters/kpresenter/xbm/xbmexport.h new file mode 100644 index 000000000..065e52d57 --- /dev/null +++ b/filters/kpresenter/xbm/xbmexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XBMEXPORT_H__ +#define __XBMEXPORT_H__ + +#include "imageexport.h" + +class XbmExport : public ImageExport +{ + Q_OBJECT + +public: + XbmExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XbmExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XBMEXPORT_H__ + diff --git a/filters/kpresenter/xpm/Makefile.am b/filters/kpresenter/xpm/Makefile.am new file mode 100644 index 000000000..ffc86c253 --- /dev/null +++ b/filters/kpresenter/xpm/Makefile.am @@ -0,0 +1,24 @@ +####### General stuff + +INCLUDES= -I$(srcdir) $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/kpresenter \ + -I$(top_srcdir)/lib/kotext \ + -I$(top_srcdir)/filters/libdialogfilter \ + -I$(top_srcdir)/filters/kpresenter/libimageexport \ + $(all_includes) + +####### Files + +kde_module_LTLIBRARIES = libkpresenterxpmexport.la + +libkpresenterxpmexport_la_SOURCES = xpmexport.cpp +libkpresenterxpmexport_la_LDFLAGS = -module $(KDE_PLUGIN) -no-undefined +libkpresenterxpmexport_la_LIBADD = ../../../kpresenter/libkpresenterprivate.la ../../../filters/libdialogfilter/libdialogfilter.la ../libimageexport/libkpresenterimageexport.la $(KOFFICE_LIBS) +noinst_HEADERS = \ + xpmexport.h + +METASOURCES = AUTO + +service_DATA = kpresenter_xpm_export.desktop +servicedir = $(kde_servicesdir) + diff --git a/filters/kpresenter/xpm/kpresenter_xpm_export.desktop b/filters/kpresenter/xpm/kpresenter_xpm_export.desktop new file mode 100644 index 000000000..5174e996c --- /dev/null +++ b/filters/kpresenter/xpm/kpresenter_xpm_export.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=KPresenter XPM Export Filter +Name[bg]=Филтър за експортиране от KPresenter в XPM +Name[br]=Sil ezporzh XPM evit KPresenter +Name[ca]=Filtre d'exportació XPM per a KPresenter +Name[da]=KPresenter XPM-eksportfilter +Name[de]=KPresenter XPM-Exportfilter +Name[el]=Φίλτρο εξαγωγής XPM του KPresenter +Name[eo]=KPresenter XBM-eksportfiltrilo +Name[es]=Filtro de exportación a XPM para KPresenter +Name[et]=KPresenteri XPM-i filter +Name[fa]=پالایۀ صادرات KPresenter XPM +Name[fi]=KPresenter XPM -vientisuodin +Name[fr]=Filtre d'exportation XPM de KPresenter +Name[fy]=XPM-Eksportfilter foar KPresenter +Name[ga]=Scagaire Easpórtála XPM KPresenter +Name[gl]=Filtro de Exportación de XPM para KPresenter +Name[he]=KPresenter XPM מסנן יצוא +Name[hr]=KPresenter XPM filtar izvoza +Name[hu]=KPresenter XPM exportszűrő +Name[is]=KPresenter XPM útflutningssía +Name[it]=Filtro di esportazione XPM per KPresenter +Name[ja]=KPresenter XPM エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ XPM សម្រាប់ KPresenter +Name[lt]=KPresenter XPM eksportavimo filtras +Name[lv]=KPresenter XPM eksporta filtrs +Name[nb]=XPM_eksportfilter for KPresenter +Name[nds]=XPM-Exportfilter för KPresenter +Name[ne]=केडीई प्रस्तुतकर्ता एक्सपीएम निर्यात फिल्टर +Name[nl]=KPresenter XPM Exportfilter +Name[pl]=Filtr eksportu do formatu XPM dla KPresenter +Name[pt]=Filtro de Exportação de XPM para o KPresenter +Name[pt_BR]=Filtro de Exportação de XPM para o KPresenter +Name[ru]=Фильтр экспорта презентаций KPresenter в XPM +Name[se]=KPresenter XPM-olggosfievrridansilli +Name[sk]=Exportný filter KPresenter XPM +Name[sl]=Izvozni filter XPM za KPresenter +Name[sr]=KPresenter-ов филтер за извоз у XPM +Name[sr@Latn]=KPresenter-ov filter za izvoz u XPM +Name[sv]=Kpresenter XPM-exportfilter +Name[uk]=Фільтр експорту XPM для KPresenter +Name[uz]=KPresenter XPM eksport filteri +Name[uz@cyrillic]=KPresenter XPM экспорт филтери +Name[zh_CN]=KPresenter XPM 导出过滤器 +Name[zh_TW]=KPresenter XPM 匯出過濾程式 +X-KDE-Import=application/x-kpresenter +X-KDE-Export=image/x-xpm +X-KDE-Weight=1 +X-KDE-Library=libkpresenterxpmexport +ServiceTypes=KOfficeFilter diff --git a/filters/kpresenter/xpm/xpmexport.cpp b/filters/kpresenter/xpm/xpmexport.cpp new file mode 100644 index 000000000..1456504e5 --- /dev/null +++ b/filters/kpresenter/xpm/xpmexport.cpp @@ -0,0 +1,78 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "xpmexport.h" +#include "exportsizedia.h" + +typedef KGenericFactory xpmExportFactory; +K_EXPORT_COMPONENT_FACTORY( libkpresenterxpmexport, xpmExportFactory( "xpmexport" ) ) + +XpmExport::XpmExport(KoFilter *fil, const char *name, const QStringList&lst) + : ImageExport(fil,name,lst) +{ +} + +XpmExport::~XpmExport() +{ +} + +bool XpmExport::extraImageAttribute() +{ + bool ret = false; + ExportSizeDia *exportDialog = new ExportSizeDia( width, height, + 0, "exportdialog"); + if (exportDialog->exec()) { + width = exportDialog->width(); + height = exportDialog->height(); + ret = true; + kdDebug() << "Xpm Export: size = [" << width << "," << height << "]" << endl; + } + delete exportDialog; + return ret; +} + + +bool XpmExport::saveImage( QString fileName) +{ + bool ret = pixmap.save( fileName, "XPM" ); + // Save the image. + if ( !ret ) { + KMessageBox::error( 0, i18n( "Failed to write file." ), + i18n( "Xpm Export Error" ) ); + } + return ret; +} + +const char * XpmExport::exportFormat() +{ + return "image/x-xpm"; +} + +#include "xpmexport.moc" + diff --git a/filters/kpresenter/xpm/xpmexport.h b/filters/kpresenter/xpm/xpmexport.h new file mode 100644 index 000000000..8ccec46c0 --- /dev/null +++ b/filters/kpresenter/xpm/xpmexport.h @@ -0,0 +1,38 @@ +/* This file is part of the KDE project + Copyright (C) 2005 Laurent Montel + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef __XPMEXPORT_H__ +#define __XPMEXPORT_H__ + +#include "imageexport.h" + +class XpmExport : public ImageExport +{ + Q_OBJECT + +public: + XpmExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~XpmExport(); + virtual bool saveImage( QString fileName); + virtual bool extraImageAttribute(); + virtual const char * exportFormat(); +}; + +#endif // __XPMEXPORT_H__ + diff --git a/filters/krita/Makefile.am b/filters/krita/Makefile.am new file mode 100644 index 000000000..0d8732eb9 --- /dev/null +++ b/filters/krita/Makefile.am @@ -0,0 +1,34 @@ +if have_openexr +OPENEXR_SUBDIR=openexr +endif + +if include_imagemagick_filter +IMAGEMAGICK_SUBDIR=magick +endif + +if include_graphicsmagick_filter +GRAPHICSMAGICK_SUBDIR=gmagick +endif + +if have_png +PNG_SUBDIR=png +endif + +if include_jpeg_filter +JPEG_SUBDIR=jpeg +endif + +if include_tiff_filter +TIFF_SUBDIR=tiff +endif + +if have_exif +LIBKISEXIF=libkisexif +endif + +if include_PDF +PDF_SUBDIR=pdf +endif + +SUBDIRS = $(IMAGEMAGICK_SUBDIR) $(OPENEXR_SUBDIR) $(PNG_SUBDIR) $(LIBKISEXIF) \ + $(JPEG_SUBDIR) $(TIFF_SUBDIR) raw $(PDF_SUBDIR) $(GRAPHICSMAGICK_SUBDIR) diff --git a/filters/krita/configure.in.in b/filters/krita/configure.in.in new file mode 100644 index 000000000..6eb8d91e7 --- /dev/null +++ b/filters/krita/configure.in.in @@ -0,0 +1,66 @@ +# Check if the tiff lib is available +AC_FIND_TIFF +AM_CONDITIONAL(have_tiff, test -n "$LIBTIFF") + +AC_FIND_PNG +AM_CONDITIONAL(have_png, test -n "$LIBPNG") + +AC_FIND_JPEG +AM_CONDITIONAL(have_jpeg, test -n "$LIBJPEG") + +#--------------------------------------------------------- +# libexif detection +# taken from libkexif's configure.in.in +#--------------------------------------------------------- + +LIBEXIF=no + +#PKG_CHECK_MODULES(LIBEXIF, libexif >= 0.5.7, , +# [ AC_MSG_WARN([libexif >= 0.5.7 not found.]) +# LIBEXIF=yes ]) + + +#PKG_CHECK_MODULES(LIBEXIF06, libexif >= 0.6.9, +# AC_DEFINE(HAVE_EXIF06,1,[check for libexif > 0.6]), +# AC_MSG_WARN([Using old version of libexif.])) + +PKG_CHECK_MODULES(LIBEXIF, libexif >= 0.6.12 , , + [ AC_MSG_WARN([libexif >= 0.6.12 not found.]) + LIBEXIF=yes ]) + +AC_SUBST(LIBEXIF_LIBS) +AC_SUBST(LIBEXIF_CFLAGS) + +#--------------------------------------------------------- +# libexif detection +#--------------------------------------------------------- +AC_MSG_CHECKING([if C++ program with exif can be compiled]) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +ac_save_CXXFLAGS="$CXXFLAGS" +CXXFLAGS="$CXXFLAGS $LIBEXIF_CFLAGS" +AC_CACHE_VAL(exif_build, +[ + AC_TRY_COMPILE([ + extern "C" { +#include +#include +} + ],[ + ExifLoader *l = exif_loader_new (); + exif_loader_write_file (l,"kikoo"); + return 0; + ], exif_build=yes, + exif_build=no) +]) +AC_MSG_RESULT($exif_build) +if test "$exif_build" = "no"; then + LIBEXIF="" +fi +CXXFLAGS="$ac_save_CXXFLAGS" +AC_LANG_RESTORE + + +AM_CONDITIONAL(have_exif, test -n "$LIBEXIF") +AM_CONDITIONAL(include_jpeg_filter, test -n "$LIBJPEG" -a -n "$LIBEXIF") +AM_CONDITIONAL(include_tiff_filter, test -n "$LIBTIFF" -a -n "$LIBEXIF") diff --git a/filters/krita/gmagick/Makefile.am b/filters/krita/gmagick/Makefile.am new file mode 100644 index 000000000..845ab503d --- /dev/null +++ b/filters/krita/gmagick/Makefile.am @@ -0,0 +1,40 @@ +kde_module_LTLIBRARIES = libkritagmagickimport.la libkritagmagickexport.la + +libkritagmagickexport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBGMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBGMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritagmagickexport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBGMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +libkritagmagickimport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBGMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBGMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritagmagickimport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBGMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) $(LIBGMAGICK_CPPFLAGS) \ + $(all_includes) + +service_DATA = krita_magick_import.desktop krita_magick_export.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_magick.desktop +kdelnkdir = $(kde_appsdir)/.hidden + +libkritagmagickimport_la_SOURCES = magickimport.cpp kis_image_magick_converter.cc +libkritagmagickexport_la_SOURCES = magickexport.cpp kis_image_magick_converter.cc + +METASOURCES = AUTO + + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) diff --git a/filters/krita/gmagick/configure.in.bot b/filters/krita/gmagick/configure.in.bot new file mode 100644 index 000000000..d922dfd3d --- /dev/null +++ b/filters/krita/gmagick/configure.in.bot @@ -0,0 +1,23 @@ +if test -z "$LIBGMAGICK_LIBS" -a -z "$LIBMAGICK_LIBS"; then + echo "" + echo "You're missing GraphicsMagick (>=1.1.7). krita's GraphicsMagick import/export" + echo "filter will not be compiled. You can download GraphicsMagick from" + echo "http://www.graphicsmagick.org/. The GraphicsMagick filter allows krita to" + echo "read and write XCF, PSD, GIF, BMP, and many other image formats." + echo "" + echo "If you have problems compiling GraphicsMagick, please try configuring it using" + echo "the --without-magick-plus-plus flag, the C++ API isn't needed for krita." + echo "" + all_tests=bad + AC_DEFINE([include_imagemagick_filter],"",[don't use magick filter]) +fi + +if test -z "$LIBGMAGICK_LIBS" -a ! -z "$LIBMAGICK_LIBS"; then + + echo "" + echo "You're missing GraphicsMagick (>=1.1.7). krita's GraphicsMagick import/export" + echo "filter will not be compiled. But ImageMagick was found, which mean that krita" + echo "will be able to read and write XCF, PSD, GIF, BMP, and many other image formats." + echo "But the ImageMagick filter is deprecated and we strongly advise you to install" + echo "GraphicsMagick either from your distribution or from http://www.graphicsmagick.org/" +fi diff --git a/filters/krita/gmagick/kis_image_magick_converter.cc b/filters/krita/gmagick/kis_image_magick_converter.cc new file mode 100644 index 000000000..c94895f82 --- /dev/null +++ b/filters/krita/gmagick/kis_image_magick_converter.cc @@ -0,0 +1,1142 @@ +/* + * Copyright (c) 2002 Patrick Julien + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_undo_adapter.h" +#include "kis_image_magick_converter.h" +#include "kis_meta_registry.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_iterators_pixel.h" +#include "kis_colorspace.h" +#include "kis_profile.h" +#include "kis_annotation.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_device.h" + +#include "../../../config.h" + +namespace { + + const Q_UINT8 PIXEL_BLUE = 0; + const Q_UINT8 PIXEL_GREEN = 1; + const Q_UINT8 PIXEL_RED = 2; + const Q_UINT8 PIXEL_ALPHA = 3; + + static const Q_UINT8 PIXEL_CYAN = 0; + static const Q_UINT8 PIXEL_MAGENTA = 1; + static const Q_UINT8 PIXEL_YELLOW = 2; + static const Q_UINT8 PIXEL_BLACK = 3; + static const Q_UINT8 PIXEL_CMYK_ALPHA = 4; + + static const Q_UINT8 PIXEL_GRAY = 0; + static const Q_UINT8 PIXEL_GRAY_ALPHA = 1; + + /** + * Make this more flexible -- although... ImageMagick + * isn't that flexible either. + */ + QString getColorSpaceName(ColorspaceType type, unsigned long imageDepth = 8) + { + + if (type == GRAYColorspace) { + if (imageDepth == 8) + return "GRAYA"; + else if ( imageDepth == 16 ) + return "GRAYA16" ; + } + else if (type == CMYKColorspace) { + if (imageDepth == 8) + return "CMYK"; + else if ( imageDepth == 16 ) { + return "CMYK16"; + } + } + else if (type == LABColorspace) { + kdDebug(41008) << "Lab!\n"; + return "LABA"; + } + else if (type == RGBColorspace || type == sRGBColorspace || type == TransparentColorspace) { + if (imageDepth == 8) + return "RGBA"; + else if (imageDepth == 16) + return "RGBA16"; + } + return ""; + + } + + ColorspaceType getColorTypeforColorSpace( KisColorSpace * cs ) + { + if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") ) return GRAYColorspace; + if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") ) return RGBColorspace; + if ( cs->id() == KisID("CMYK") || cs->id() == KisID("CMYK16") ) return CMYKColorspace; + if ( cs->id() == KisID("LABA") ) return LABColorspace; + + kdDebug(41008) << "Cannot export images in " + cs->id().name() + " yet.\n"; + return RGBColorspace; + + } + + KisProfile * getProfileForProfileInfo(const Image * image) + { + size_t length; + + const unsigned char * profiledata = GetImageProfile(image, "ICM", &length); + if( profiledata == NULL ) + return 0; + QByteArray rawdata; + rawdata.resize(length); + memcpy(rawdata.data(), profiledata, length); + + KisProfile* p = new KisProfile(rawdata); + return p; + +#if 0 + return 0; + + if (image->profiles == NULL) + return 0; + + const char *name; + const StringInfo *profile; + + KisProfile * p = 0; + + ResetImageProfileIterator(image); + for (name = GetNextImageProfile(image); name != (char *) NULL; ) + { + profile = GetImageProfile(image, name); + if (profile == (StringInfo *) NULL) + continue; + + // XXX: Hardcoded for icc type -- is that correct for us? + if (QString::compare(name, "icc") == 0) { + QByteArray rawdata; + rawdata.resize(profile->length); + memcpy(rawdata.data(), profile->datum, profile->length); + + p = new KisProfile(rawdata); + if (p == 0) + return 0; + } + name = GetNextImageProfile(image); + } + return p; +#endif + } + + void setAnnotationsForImage(const Image * src, KisImageSP image) + { + size_t length; + + const unsigned char * profiledata = GetImageProfile(src, "IPTC", &length); + if( profiledata != NULL ) + { + QByteArray rawdata; + rawdata.resize(length); + memcpy(rawdata.data(), profiledata, length); + + KisAnnotation* annotation = new KisAnnotation(QString("IPTC"), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); + } + for(int i = 0; i < src->generic_profiles; i++) + { + QByteArray rawdata; + rawdata.resize(length); + memcpy(rawdata.data(), src->generic_profile[i].info, src->generic_profile[i].length); + + KisAnnotation* annotation = new KisAnnotation(QString(src->generic_profile[i].name), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); + } + + const ImageAttribute* imgAttr = GetImageAttribute(src, NULL); + while(imgAttr) + { + QByteArray rawdata; + int len = strlen(imgAttr -> value) + 1; + rawdata.resize(len); + memcpy(rawdata.data(), imgAttr -> value, len); + + KisAnnotation* annotation = new KisAnnotation( QString("krita_attribute:%1").arg(QString(imgAttr -> key)), "", rawdata ); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); + + imgAttr = imgAttr->next; + } +#if 0 + return; + if (src->profiles == NULL) + return; + + const char *name = 0; + const StringInfo *profile; + KisAnnotation* annotation = 0; + + // Profiles and so + ResetImageProfileIterator(src); + while((name = GetNextImageProfile(src))) { + profile = GetImageProfile(src, name); + if (profile == (StringInfo *) NULL) + continue; + + // XXX: icc will be written seperately? + if (QString::compare(name, "icc") == 0) + continue; + + QByteArray rawdata; + rawdata.resize(profile->length); + memcpy(rawdata.data(), profile->datum, profile->length); + + annotation = new KisAnnotation(QString(name), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); + } + + // Attributes, since we have no hint on if this is an attribute or a profile + // annotation, we prefix it with 'krita_attribute:'. XXX This needs to be rethought! + // The joys of imagemagick. From at version 6.2.1 (dfaure has 6.2.0 and confirms the + // old way of doing things) they changed the src -> attributes + // to void* and require us to use the iterator functions. So we #if around that, *sigh* +#if MagickLibVersion >= 0x621 + const ImageAttribute * attr; + ResetImageAttributeIterator(src); + while ( (attr = GetNextImageAttribute(src)) ) { +#else + ImageAttribute * attr = src -> attributes; + while (attr) { +#endif + QByteArray rawdata; + int len = strlen(attr -> value) + 1; + rawdata.resize(len); + memcpy(rawdata.data(), attr -> value, len); + + annotation = new KisAnnotation( + QString("krita_attribute:%1").arg(QString(attr -> key)), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); +#if MagickLibVersion < 0x620 + attr = attr -> next; +#endif + } + +#endif + } + } + + void exportAnnotationsForImage(Image * dst, vKisAnnotationSP_it& it, vKisAnnotationSP_it& annotationsEnd) + { + while(it != annotationsEnd) { + if (!(*it) || (*it) -> type() == QString()) { + kdDebug(41008) << "Warning: empty annotation" << endl; + ++it; + continue; + } + + kdDebug(41008) << "Trying to store annotation of type " << (*it) -> type() << " of size " << (*it) -> annotation() . size() << endl; + + if ((*it) -> type().startsWith("krita_attribute:")) { // Attribute + if (!SetImageAttribute(dst, + (*it) -> type().mid(strlen("krita_attribute:")).ascii(), + (*it) -> annotation() . data()) ) { + kdDebug(41008) << "Storing of attribute " << (*it) -> type() << "failed!\n"; + } + } else { // Profile + unsigned char * profiledata = new unsigned char[(*it) -> annotation() . size()]; + memcpy( profiledata, (*it) -> annotation() . data(), (*it) -> annotation() . size()); + if (!ProfileImage(dst, (*it) -> type().ascii(), + profiledata, (*it) -> annotation() . size(), MagickFalse)) { + kdDebug(41008) << "Storing failed!" << endl; + } + } + ++it; + } + } + + + void InitGlobalMagick() + { + static bool init = false; + + if (!init) { + KApplication *app = KApplication::kApplication(); + + InitializeMagick(*app -> argv()); + atexit(DestroyMagick); + init = true; + } + } + + /* + * ImageMagick progress monitor callback. Unfortunately it doesn't support passing in some user + * data which complicates things quite a bit. The plan was to allow the user start multiple + * import/scans if he/she so wished. However, without passing user data it's not possible to tell + * on which task we have made progress on. + * + * Additionally, ImageMagick is thread-safe, not re-entrant... i.e. IM does not relinquish held + * locks when calling user defined callbacks, this means that the same thread going back into IM + * would deadlock since it would try to acquire locks it already holds. + */ +#if 0 + MagickBooleanType monitor(const char *text, const ExtendedSignedIntegralType, const ExtendedUnsignedIntegralType, ExceptionInfo *) + { + KApplication *app = KApplication::kApplication(); + + Q_ASSERT(app); + + if (app -> hasPendingEvents()) + app -> processEvents(); + + printf("%s\n", text); + return MagickTrue; + } +#else + unsigned int monitor(const char *text, const ExtendedSignedIntegralType, const ExtendedUnsignedIntegralType, ExceptionInfo *) + { + KApplication *app = KApplication::kApplication(); + + Q_ASSERT(app); + + if (app -> hasPendingEvents()) + app -> processEvents(); + + printf("%s\n", text); + return true; + } +#endif + + + +KisImageMagickConverter::KisImageMagickConverter(KisDoc *doc, KisUndoAdapter *adapter) +{ + InitGlobalMagick(); + init(doc, adapter); + SetMonitorHandler(monitor); + m_stop = false; +} + +KisImageMagickConverter::~KisImageMagickConverter() +{ +} + +KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isBlob) +{ + Image *image; + Image *images; + ExceptionInfo ei; + ImageInfo *ii; + + if (m_stop) { + m_img = 0; + return KisImageBuilder_RESULT_INTR; + } + + GetExceptionInfo(&ei); + ii = CloneImageInfo(0); + + if (isBlob) { + + // TODO : Test. Does BlobToImage even work? + Q_ASSERT(uri.isEmpty()); + images = BlobToImage(ii, &m_data[0], m_data.size(), &ei); + } else { + + qstrncpy(ii -> filename, QFile::encodeName(uri.path()), MaxTextExtent - 1); + + if (ii -> filename[MaxTextExtent - 1]) { + emit notifyProgressError(); + return KisImageBuilder_RESULT_PATH; + } + + images = ReadImage(ii, &ei); + + } + + if (ei.severity != UndefinedException) + { + CatchException(&ei); + kdDebug(41008) << "Exceptions happen when loading" << endl; + return KisImageBuilder_RESULT_FAILURE; + } + + + if (images == 0) { + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + } + + emit notifyProgressStage(i18n("Importing..."), 0); + + m_img = 0; + + while ((image = RemoveFirstImageFromList(&images))) { + if(image->rows == 0 or image->columns == 0) return KisImageBuilder_RESULT_FAILURE; + ViewInfo *vi = OpenCacheView(image); + + // Determine image depth -- for now, all channels of an imported image are of the same depth + unsigned long imageDepth = image->depth; + kdDebug(41008) << "Image depth: " << imageDepth << "\n"; + + QString csName; + KisColorSpace * cs = 0; + ColorspaceType colorspaceType; + + // Determine image type -- rgb, grayscale or cmyk + if (GetImageType(image, &ei) == GrayscaleType || GetImageType(image, &ei) == GrayscaleMatteType) { + if (imageDepth == 8) + csName = "GRAYA"; + else if ( imageDepth == 16 ) + csName = "GRAYA16" ; + colorspaceType = GRAYColorspace; + } + else { + colorspaceType = image->colorspace; + csName = getColorSpaceName(image -> colorspace, imageDepth); + } + + kdDebug(41008) << "image has " << csName << " colorspace\n"; + + KisProfile * profile = getProfileForProfileInfo(image); + if (profile) + { + kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n"; + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile); + } + else + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),""); + + if (!cs) { + kdDebug(41008) << "Krita does not support colorspace " << image -> colorspace << "\n"; + CloseCacheView(vi); + DestroyImage(image); + DestroyExceptionInfo(&ei); + DestroyImageList(images); + DestroyImageInfo(ii); + emit notifyProgressError(); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + + if( ! m_img) { + m_img = new KisImage(m_doc->undoAdapter(), image -> columns, image -> rows, cs, "built image"); + Q_CHECK_PTR(m_img); + m_img->blockSignals(true); // Don't send out signals while we're building the image + + // XXX I'm assuming seperate layers won't have other profile things like EXIF + setAnnotationsForImage(image, m_img); + } + + if (image -> columns && image -> rows) { + + // Opacity (set by the photoshop import filter) + Q_UINT8 opacity = OPACITY_OPAQUE; + const ImageAttribute * attr = GetImageAttribute(image, "[layer-opacity]"); + if (attr != 0) { + opacity = Q_UINT8_MAX - Downscale(QString(attr->value).toInt()); + } + + KisPaintLayerSP layer = 0; + + attr = GetImageAttribute(image, "[layer-name]"); + if (attr != 0) { + layer = new KisPaintLayer(m_img, attr->value, opacity); + } + else { + layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), opacity); + } + + Q_ASSERT(layer); + + // Layerlocation (set by the photoshop import filter) + Q_INT32 x_offset = 0; + Q_INT32 y_offset = 0; + + attr = GetImageAttribute(image, "[layer-xpos]"); + if (attr != 0) { + x_offset = QString(attr->value).toInt(); + } + + attr = GetImageAttribute(image, "[layer-ypos]"); + if (attr != 0) { + y_offset = QString(attr->value).toInt(); + } + + + for (Q_UINT32 y = 0; y < image->rows; y ++) + { + const PixelPacket *pp = AcquireCacheView(vi, 0, y, image->columns, 1, &ei); + + if(!pp) + { + CloseCacheView(vi); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + } + + IndexPacket * indexes = GetCacheViewIndexes(vi); + + KisHLineIteratorPixel hiter = layer->paintDevice()->createHLineIterator(0, y, image->columns, true); + + if (colorspaceType== CMYKColorspace) { + if (imageDepth == 8) { + int x = 0; + while (!hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + *(ptr++) = Downscale(pp->red); // cyan + *(ptr++) = Downscale(pp->green); // magenta + *(ptr++) = Downscale(pp->blue); // yellow + *(ptr++) = Downscale(indexes[x]); // Black +// XXX: Warning! This ifdef messes up the paren matching big-time! +#ifdef HAVE_MAGICK6 + if (image->matte != MagickFalse) { +#else + if (image->matte == true) { +#endif + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + } + else { + *(ptr++) = OPACITY_OPAQUE; + } + ++x; + pp++; + ++hiter; + } + } + } + else if (colorspaceType == LABColorspace) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + + *(ptr++) = ScaleQuantumToShort(pp->red); + *(ptr++) = ScaleQuantumToShort(pp->green); + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + else if (colorspaceType == RGBColorspace || + colorspaceType == sRGBColorspace || + colorspaceType == TransparentColorspace) + { + if (imageDepth == 8) { + while(! hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + // XXX: not colorstrategy and bitdepth independent + *(ptr++) = Downscale(pp->blue); + *(ptr++) = Downscale(pp->green); + *(ptr++) = Downscale(pp->red); + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + + pp++; + ++hiter; + } + } + else if (imageDepth == 16) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + // XXX: not colorstrategy independent + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = ScaleQuantumToShort(pp->green); + *(ptr++) = ScaleQuantumToShort(pp->red); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + } + else if ( colorspaceType == GRAYColorspace) { + if (imageDepth == 8) { + while(! hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + // XXX: not colorstrategy and bitdepth independent + *(ptr++) = Downscale(pp->blue); + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + + pp++; + ++hiter; + } + } + else if (imageDepth == 16) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + // XXX: not colorstrategy independent + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + } + + emit notifyProgress(y * 100 / image->rows); + + if (m_stop) { + CloseCacheView(vi); + DestroyImage(image); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + m_img = 0; + return KisImageBuilder_RESULT_INTR; + } + } + m_img->addLayer(layer.data(), m_img->rootLayer()); + layer->paintDevice()->move(x_offset, y_offset); + } + + emit notifyProgressDone(); + CloseCacheView(vi); + DestroyImage(image); + } + + emit notifyProgressDone(); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + return KisImageBuilder_RESULT_OK; + } + + KisImageBuilder_Result KisImageMagickConverter::buildImage(const KURL& uri) + { + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) { + return KisImageBuilder_RESULT_NOT_EXIST; + } + + KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE; + QString tmpFile; + + if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) { + KURL uriTF; + uriTF.setPath( tmpFile ); + result = decode(uriTF, false); + KIO::NetAccess::removeTempFile(tmpFile); + } + + return result; + } + + + KisImageSP KisImageMagickConverter::image() + { + return m_img; + } + + void KisImageMagickConverter::init(KisDoc *doc, KisUndoAdapter *adapter) + { + m_doc = doc; + m_adapter = adapter; + m_job = 0; + } + + KisImageBuilder_Result KisImageMagickConverter::buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd) + { + Image *image; + ExceptionInfo ei; + ImageInfo *ii; + + if (!layer) + return KisImageBuilder_RESULT_INVALID_ARG; + + KisImageSP img = layer->image(); + if (!img) + return KisImageBuilder_RESULT_EMPTY; + + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!uri.isLocalFile()) + return KisImageBuilder_RESULT_NOT_LOCAL; + + + Q_UINT32 layerBytesPerChannel = layer->paintDevice()->pixelSize() / layer->paintDevice()->nChannels(); + + GetExceptionInfo(&ei); + + ii = CloneImageInfo(0); + + qstrncpy(ii -> filename, QFile::encodeName(uri.path()), MaxTextExtent - 1); + + if (ii -> filename[MaxTextExtent - 1]) { + emit notifyProgressError(); + return KisImageBuilder_RESULT_PATH; + } + + if (!img -> width() || !img -> height()) + return KisImageBuilder_RESULT_EMPTY; + + if (layerBytesPerChannel < 2) { + ii->depth = 8; + } + else { + ii->depth = 16; + } + + ii->colorspace = getColorTypeforColorSpace(layer->paintDevice()->colorSpace()); + + image = AllocateImage(ii); +// SetImageColorspace(image, ii->colorspace); + image -> columns = img -> width(); + image -> rows = img -> height(); + + kdDebug(41008) << "Saving with colorspace " << image->colorspace << ", (" << layer->paintDevice()->colorSpace()->id().name() << ")\n"; + kdDebug(41008) << "IM Image thinks it has depth: " << image->depth << "\n"; + +#ifdef HAVE_MAGICK6 + // if ( layer-> hasAlpha() ) + image -> matte = MagickTrue; + // else + // image -> matte = MagickFalse; +#else + // image -> matte = layer -> hasAlpha(); + image -> matte = true; +#endif + + Q_INT32 y, height, width; + + height = img -> height(); + width = img -> width(); + + bool alpha = true; + QString ext = QFileInfo(QFile::encodeName(uri.path())).extension(false).upper(); + if (ext == "BMP") { + alpha = false; + qstrncpy(ii->magick, "BMP2", MaxTextExtent - 1); + } + else if (ext == "RGB") { + qstrncpy(ii->magick, "SGI", MaxTextExtent - 1); + } + + for (y = 0; y < height; y++) { + + // Allocate pixels for this scanline + PixelPacket * pp = SetImagePixels(image, 0, y, width, 1); + + if (!pp) { + DestroyExceptionInfo(&ei); + DestroyImage(image); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + + } + + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false); + if (alpha) + SetImageType(image, TrueColorMatteType); + else + SetImageType(image, TrueColorType); + + if (image->colorspace== CMYKColorspace) { + + IndexPacket * indexes = GetIndexes(image); + int x = 0; + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_CYAN]); + pp -> green = ScaleShortToQuantum(d[PIXEL_MAGENTA]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_YELLOW]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_CMYK_ALPHA]); + indexes[x] = ScaleShortToQuantum(d[PIXEL_BLACK]); + x++; + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_CYAN]); + pp -> green = Upscale(d[PIXEL_MAGENTA]); + pp -> blue = Upscale(d[PIXEL_YELLOW]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_CMYK_ALPHA]); + + indexes[x]= Upscale(d[PIXEL_BLACK]); + + x++; + pp++; + ++it; + } + } + } + else if (image->colorspace== RGBColorspace || + image->colorspace == sRGBColorspace || + image->colorspace == TransparentColorspace) + { + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_RED]); + pp -> green = ScaleShortToQuantum(d[PIXEL_GREEN]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_BLUE]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_ALPHA]); + + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_RED]); + pp -> green = Upscale(d[PIXEL_GREEN]); + pp -> blue = Upscale(d[PIXEL_BLUE]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_ALPHA]); + + pp++; + ++it; + } + } + } + else if (image->colorspace == GRAYColorspace) + { + SetImageType(image, GrayscaleMatteType); + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_GRAY]); + pp -> green = ScaleShortToQuantum(d[PIXEL_GRAY]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_GRAY]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_GRAY_ALPHA]); + + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_GRAY]); + pp -> green = Upscale(d[PIXEL_GRAY]); + pp -> blue = Upscale(d[PIXEL_GRAY]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_GRAY_ALPHA]); + + pp++; + ++it; + } + } + } + else { + kdDebug(41008) << "Unsupported image format\n"; + return KisImageBuilder_RESULT_INVALID_ARG; + } + + emit notifyProgressStage(i18n("Saving..."), y * 100 / height); + +#ifdef HAVE_MAGICK6 + if (SyncImagePixels(image) == MagickFalse) + kdDebug(41008) << "Syncing pixels failed\n"; +#else + if (!SyncImagePixels(image)) + kdDebug(41008) << "Syncing pixels failed\n"; +#endif + } + + // set the annotations + exportAnnotationsForImage(image, annotationsStart, annotationsEnd); + + // XXX: Write to a temp file, then have Krita use KIO to copy temp + // image to remote location. + + WriteImage(ii, image); + DestroyExceptionInfo(&ei); + DestroyImage(image); + emit notifyProgressDone(); + return KisImageBuilder_RESULT_OK; + } + + void KisImageMagickConverter::ioData(KIO::Job *job, const QByteArray& data) + { + if (data.isNull() || data.isEmpty()) { + emit notifyProgressStage(i18n("Loading..."), 0); + return; + } + + if (m_data.empty()) { + Image *image; + ImageInfo *ii; + ExceptionInfo ei; + + ii = CloneImageInfo(0); + GetExceptionInfo(&ei); + image = PingBlob(ii, data.data(), data.size(), &ei); + + if (image == 0 || ei.severity == BlobError) { + DestroyExceptionInfo(&ei); + DestroyImageInfo(ii); + job -> kill(); + emit notifyProgressError(); + return; + } + + DestroyImage(image); + DestroyExceptionInfo(&ei); + DestroyImageInfo(ii); + emit notifyProgressStage(i18n("Loading..."), 0); + } + + Q_ASSERT(data.size() + m_data.size() <= m_size); + memcpy(&m_data[m_data.size()], data.data(), data.count()); + m_data.resize(m_data.size() + data.count()); + emit notifyProgressStage(i18n("Loading..."), m_data.size() * 100 / m_size); + + if (m_stop) + job -> kill(); + } + + void KisImageMagickConverter::ioResult(KIO::Job *job) + { + m_job = 0; + + if (job -> error()) + emit notifyProgressError(); + + decode(KURL(), true); + } + + void KisImageMagickConverter::ioTotalSize(KIO::Job * /*job*/, KIO::filesize_t size) + { + m_size = size; + m_data.reserve(size); + emit notifyProgressStage(i18n("Loading..."), 0); + } + + void KisImageMagickConverter::cancel() + { + m_stop = true; + } + + /** + * @name readFilters + * @return Provide a list of file formats the application can read. + */ + QString KisImageMagickConverter::readFilters() + { + QString s; + QString all; + QString name; + QString description; + unsigned long matches; + +/*#ifdef HAVE_MAGICK6 +#ifdef HAVE_OLD_GETMAGICKINFOLIST + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches); +#else // HAVE_OLD_GETMAGICKINFOLIST + ExceptionInfo ei; + GetExceptionInfo(&ei); + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches, &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_OLD_GETMAGICKINFOLIST +#else // HAVE_MAGICK6*/ + const MagickInfo *mi; + ExceptionInfo ei; + GetExceptionInfo(&ei); + mi = GetMagickInfo("*", &ei); + DestroyExceptionInfo(&ei); +// #endif // HAVE_MAGICK6 + + if (!mi) + return s; + +/*#ifdef HAVE_MAGICK6 + for (unsigned long i = 0; i < matches; i++) { + const MagickInfo *info = mi[i]; + if (info -> stealth) + continue; + + if (info -> decoder) { + name = info -> name; + description = info -> description; + kdDebug(41008) << "Found import filter for: " << name << "\n"; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#else*/ + for (; mi; mi = reinterpret_cast(mi -> next)) { + if (mi -> stealth) + continue; + if (mi -> decoder) { + name = mi -> name; + description = mi -> description; + kdDebug(41008) << "Found import filter for: " << name << "\n"; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +// #endif + + all += "|" + i18n("All Images"); + all += "\n"; + + return all + s; + } + + QString KisImageMagickConverter::writeFilters() + { + QString s; + QString all; + QString name; + QString description; + unsigned long matches; + +/*#ifdef HAVE_MAGICK6 +#ifdef HAVE_OLD_GETMAGICKINFOLIST + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches); +#else // HAVE_OLD_GETMAGICKINFOLIST + ExceptionInfo ei; + GetExceptionInfo(&ei); + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches, &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_OLD_GETMAGICKINFOLIST +#else // HAVE_MAGICK6*/ + const MagickInfo *mi; + ExceptionInfo ei; + GetExceptionInfo(&ei); + mi = GetMagickInfo("*", &ei); + DestroyExceptionInfo(&ei); +// #endif // HAVE_MAGICK6 + + if (!mi) { + kdDebug(41008) << "Eek, no magick info!\n"; + return s; + } + +/*#ifdef HAVE_MAGICK6 + for (unsigned long i = 0; i < matches; i++) { + const MagickInfo *info = mi[i]; + kdDebug(41008) << "Found export filter for: " << info -> name << "\n"; + if (info -> stealth) + continue; + + if (info -> encoder) { + name = info -> name; + + description = info -> description; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#else*/ + for (; mi; mi = reinterpret_cast(mi -> next)) { + kdDebug(41008) << "Found export filter for: " << mi -> name << "\n"; + if (mi -> stealth) + continue; + + if (mi -> encoder) { + name = mi -> name; + + description = mi -> description; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +// #endif + + + all += "|" + i18n("All Images"); + all += "\n"; + + return all + s; + } + +#include "kis_image_magick_converter.moc" + diff --git a/filters/krita/gmagick/kis_image_magick_converter.h b/filters/krita/gmagick/kis_image_magick_converter.h new file mode 100644 index 000000000..9b3b6bc09 --- /dev/null +++ b/filters/krita/gmagick/kis_image_magick_converter.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KIS_IMAGE_MAGICK_CONVERTER_H_ +#define KIS_IMAGE_MAGICK_CONVERTER_H_ + +#include +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_progress_subject.h" + +class QString; +class KURL; +class KisDoc; +class KisNameServer; +class KisUndoAdapter; +/** + * Image import/export plugins can use these results to report about success or failure. + */ +enum KisImageBuilder_Result { + KisImageBuilder_RESULT_FAILURE = -400, + KisImageBuilder_RESULT_NOT_EXIST = -300, + KisImageBuilder_RESULT_NOT_LOCAL = -200, + KisImageBuilder_RESULT_BAD_FETCH = -100, + KisImageBuilder_RESULT_INVALID_ARG = -50, + KisImageBuilder_RESULT_OK = 0, + KisImageBuilder_RESULT_PROGRESS = 1, + KisImageBuilder_RESULT_EMPTY = 100, + KisImageBuilder_RESULT_BUSY = 150, + KisImageBuilder_RESULT_NO_URI = 200, + KisImageBuilder_RESULT_UNSUPPORTED = 300, + KisImageBuilder_RESULT_INTR = 400, + KisImageBuilder_RESULT_PATH = 500, + KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE = 600 +}; + + + +/** + * Build a KisImage representation of an image file. + */ +class KisImageMagickConverter : public KisProgressSubject { + typedef QObject super; + Q_OBJECT + +public: + KisImageMagickConverter(KisDoc *doc, KisUndoAdapter *adapter); + virtual ~KisImageMagickConverter(); + +public slots: + virtual void cancel(); + +public: + KisImageBuilder_Result buildImage(const KURL& uri); + KisImageBuilder_Result buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd); + KisImageSP image(); + +public: + static QString readFilters(); + static QString writeFilters(); + +private slots: + void ioData(KIO::Job *job, const QByteArray& data); + void ioResult(KIO::Job *job); + void ioTotalSize(KIO::Job *job, KIO::filesize_t size); + +private: + KisImageMagickConverter(const KisImageMagickConverter&); + KisImageMagickConverter& operator=(const KisImageMagickConverter&); + void init(KisDoc *doc, KisUndoAdapter *adapter); + KisImageBuilder_Result decode(const KURL& uri, bool isBlob); + +private: + KisImageSP m_img; + KisDoc *m_doc; + KisUndoAdapter *m_adapter; + QValueVector m_data; + KIO::TransferJob *m_job; + KIO::filesize_t m_size; + bool m_stop; +}; + +#endif // KIS_IMAGE_MAGICK_CONVERTER_H_ + diff --git a/filters/krita/gmagick/krita_magick.desktop b/filters/krita/gmagick/krita_magick.desktop new file mode 100644 index 000000000..486b3645d --- /dev/null +++ b/filters/krita/gmagick/krita_magick.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +MimeType=image/x-xcf-gimp;image/gif;image/cgm;image/x-bmp;image/x-ico;image/x-pcx;image/x-portable-pixmap;image/x-targa;image/x-xbm;image/x-xcf;image/x-xpm;image/x-vnd.adobe.photoshop;image/x-rgb +Type=Application +Icon=krita +Categories= +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi diff --git a/filters/krita/gmagick/krita_magick_export.desktop b/filters/krita/gmagick/krita_magick_export.desktop new file mode 100644 index 000000000..cd348c6ab --- /dev/null +++ b/filters/krita/gmagick/krita_magick_export.desktop @@ -0,0 +1,55 @@ +[Desktop Entry] +Name=Krita Magick Export Filter +Name[bg]=Филтър за експортиране от Krita в Magick +Name[br]=Sil ezporzh Magick evit Krita +Name[ca]=Filtre d'exportació Magick per a Krita +Name[cy]=Hidl Allforio Magick Krita +Name[da]=Krita Magick-eksportfilter +Name[de]=Krita Magick-Exportfilter +Name[el]=Φίλτρο εξαγωγής Magick του Krita +Name[eo]=Krita Magick-eksportfiltrilo +Name[es]=Filtro de exportación a Magick de Krita +Name[et]=Krita Magick'i ekspordifilter +Name[eu]=Krita-ren Magick esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Krita Magick +Name[fi]=Krita Magick -vientisuodin +Name[fr]=Filtre d'exportation Magick de Krita +Name[fy]=Krita Magick Eksportfilter +Name[ga]=Scagaire Easpórtála Magick Krita +Name[gl]=Filtro de Exportación de Magick para Krita +Name[he]=מסנן יצוא מ־Krita ל־Magick +Name[hr]=Krita Magick filtar izvoza +Name[hu]=Krita Magick exportszűrő +Name[is]=Krita Magick útflutningssía +Name[it]=Filtro di esportazione Magick per Krita +Name[ja]=Krita Magick エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ Magick សម្រាប់ Krita +Name[lt]=Krita Magick eksportavimo filtras +Name[lv]=Krita Magick eksporta filtrs +Name[ms]=Penapis Eksport Krita Magick +Name[nb]=Magick-eksportfilter for Krita +Name[nds]=Magick-Exportfilter för Krita +Name[ne]=क्रिता म्याजिक निर्यात फिल्टर +Name[nl]=Krita Magick Exportfilter +Name[nn]=Magick-eksportfilter for Krita +Name[pl]=Filtr eksportu do formatu Magick z Krita +Name[pt]=Filtro de Exportação de Magick para o Krita +Name[pt_BR]=Filtro de exportação Magick para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в Magick +Name[se]=Krita Magick-olggosfievrridansilli +Name[sk]=Magick filter pre export do Krita +Name[sl]=Izvozni filter Magick za Krito +Name[sr]=Krita-ин филтер за извоз у Magick +Name[sr@Latn]=Krita-in filter za izvoz u Magick +Name[sv]=Krita Magick-exportfilter +Name[uk]=Фільтр експорту Magick для Krita +Name[uz]=Krita Magick eksport filteri +Name[uz@cyrillic]=Krita Magick экспорт филтери +Name[zh_CN]=Krita Magick 导出过滤器 +Name[zh_TW]=Krita Magick 匯出過濾程式 +X-KDE-Export=image/gif,image/cgm,image/x-pcx,image/x-portable-pixmap,image/x-targa,image/x-xbm,image/x-xpm,image/x-rgb,image/x-eps +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Import=application/x-krita +X-KDE-Weight=1 +X-KDE-Library=libkritagmagickexport diff --git a/filters/krita/gmagick/krita_magick_import.desktop b/filters/krita/gmagick/krita_magick_import.desktop new file mode 100644 index 000000000..486a094b4 --- /dev/null +++ b/filters/krita/gmagick/krita_magick_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Krita Magick Import Filter +Name[bg]=Филтър за импортиране от Magick в Krita +Name[br]=Sil enporzh Magick evit Krita +Name[ca]=Filtre d'importació Magick per a Krita +Name[cs]=Importní filtr formátu Magick pro Kritu +Name[cy]=Hidl Mewnforio Krita Magick +Name[da]=Krita Magick-importfilter +Name[de]=Krita Magick-Importfilter +Name[el]=Φίλτρο εισαγωγής Magick του Krita +Name[eo]=Krita Magick-importfiltrilo +Name[es]=Filtro de importación a Magick de Krita +Name[et]=Krita Magick'i impordifilter +Name[eu]=Krita-ren Magick inportaziorako iragazkia +Name[fa]=پالایۀ واردات Krita Magick +Name[fi]=Krita Magick-tuontisuodin +Name[fr]=Filtre d'importation Magick de Krita +Name[fy]=Krita Magick Ymportfilter +Name[ga]=Scagaire Iompórtála Magick Krita +Name[gl]=Filtro de Importación de Magick para Krita +Name[he]=מסנן יבוא מ־Magick ל־Krita +Name[hi]=के-रीता मैजिक आयात फ़िल्टर +Name[hr]=Krita Magick filtar uvoza +Name[hu]=Krita Magick importszűrő +Name[is]=Krita Magick innflutningssía +Name[it]=Filtro di importazione Magick per Krita +Name[ja]=Krita Magick インポートフィルタ +Name[km]=តម្រង​នាំចូល Magick សម្រាប់ Krita +Name[lo]= ຕົວຕອງການນຳເຂົ້າ WML ຂອງເອກະສານຂໍ້ຄວາມ K +Name[lt]=Krita Magick importavimo filtras +Name[lv]=Krita Magick importa filtrs +Name[ms]=Penapis Import Krita Magick +Name[nb]=Magick-importfilter for Krita +Name[nds]=Magick-Importfilter för Krita +Name[ne]=क्रिता म्याजिक आयात फिल्टर +Name[nl]=Krita Magick Importfilter +Name[nn]=Magick-importfilter for Krita +Name[pl]=Filtr importu formatu Magick do Krita +Name[pt]=Filtro de Importação de Magick para o Krita +Name[pt_BR]=Filtro de importação Magick para o Krita +Name[ru]=Фильтр импорта рисунков Magick в Krita +Name[se]=Krita Magick-sisafievrridansilli +Name[sk]=Magick filter pre import do Krita +Name[sl]=Uvozni filter Magick za Krito +Name[sr]=Krita-ин филтер за увоз из Magick-а +Name[sr@Latn]=Krita-in filter za uvoz iz Magick-a +Name[sv]=Krita Magick-importfilter +Name[ta]=Krita மாயk இறக்குமதி வடிகட்டி +Name[tg]=Филтри Воридоти Krita Magick +Name[tr]=Krita Magick Alma Filtresi +Name[uk]=Фільтр імпорту Magick для Krita +Name[uz]=Krita Magick import filteri +Name[uz@cyrillic]=Krita Magick импорт филтери +Name[zh_CN]=Krita Magick 导入过滤器 +Name[zh_TW]=Krita Magick 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-xcf-gimp,image/gif,image/cgm,image/x-bmp,image/x-ico,image/x-pcx,image/x-portable-pixmap,image/x-targa,image/x-xbm,image/x-xcf,image/x-xpm,image/x-vnd.adobe.photoshop,image/x-rgb,image/x-eps +X-KDE-Weight=1 +X-KDE-Library=libkritagmagickimport +ServiceTypes=KOfficeFilter diff --git a/filters/krita/gmagick/magickexport.cpp b/filters/krita/gmagick/magickexport.cpp new file mode 100644 index 000000000..b47f198cb --- /dev/null +++ b/filters/krita/gmagick/magickexport.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MagickExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritagmagickexport, MagickExportFactory("kofficefilters")) + +MagickExport::MagickExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +MagickExport::~MagickExport() +{ +} + +KoFilter::ConversionStatus MagickExport::convert(const QCString& from, const QCString& to) +{ + kdDebug(41008) << "magick export! From: " << from << ", To: " << to << "\n"; + + if (from != "application/x-krita") + return KoFilter::NotImplemented; + + // XXX: Add dialog about flattening layers here + + KisDoc *output = dynamic_cast(m_chain->inputDocument()); + QString filename = m_chain->outputFile(); + + if (!output) + return KoFilter::CreationError; + + if (filename.isEmpty()) return KoFilter::FileNotFound; + + KURL url; + url.setPath(filename); + + KisImageSP img = output->currentImage(); + + KisImageMagickConverter ib(output, output->undoAdapter()); + + KisPaintDeviceSP pd = new KisPaintDevice(*img->projection()); + KisPaintLayerSP l = new KisPaintLayer(img, "projection", OPACITY_OPAQUE, pd); + + vKisAnnotationSP_it beginIt = img->beginAnnotations(); + vKisAnnotationSP_it endIt = img->endAnnotations(); + if (ib.buildFile(url, l, beginIt, endIt) == KisImageBuilder_RESULT_OK) { + return KoFilter::OK; + } + return KoFilter::InternalError; +} + +#include + diff --git a/filters/krita/gmagick/magickexport.h b/filters/krita/gmagick/magickexport.h new file mode 100644 index 000000000..3c499ebda --- /dev/null +++ b/filters/krita/gmagick/magickexport.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef MAGICKEXPORT_H_ +#define MAGICKEXPORT_H_ + +#include + +class MagickExport : public KoFilter { + Q_OBJECT + +public: + MagickExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MagickExport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // MAGICKEXPORT_H_ + diff --git a/filters/krita/gmagick/magickimport.cpp b/filters/krita/gmagick/magickimport.cpp new file mode 100644 index 000000000..5b04d6ff7 --- /dev/null +++ b/filters/krita/gmagick/magickimport.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MagickImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritagmagickimport, MagickImportFactory("kofficefilters")) + +MagickImport::MagickImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +MagickImport::~MagickImport() +{ +} + +KoFilter::ConversionStatus MagickImport::convert(const QCString&, const QCString& to) +{ + kdDebug(41008) << "Importing using MagickImport!\n"; + + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + KisView * view = static_cast(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc -> prepareForImport(); + + + if (!filename.isEmpty()) { + + KURL url; + url.setPath(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisImageMagickConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + +#include + diff --git a/filters/krita/gmagick/magickimport.h b/filters/krita/gmagick/magickimport.h new file mode 100644 index 000000000..011566429 --- /dev/null +++ b/filters/krita/gmagick/magickimport.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef MAGICKIMPORT_H_ +#define MAGICKIMPORT_H_ + +#include + +class MagickImport : public KoFilter { + Q_OBJECT + +public: + MagickImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MagickImport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // MAGICKIMPORT_H_ + diff --git a/filters/krita/jpeg/Makefile.am b/filters/krita/jpeg/Makefile.am new file mode 100644 index 000000000..5795b1147 --- /dev/null +++ b/filters/krita/jpeg/Makefile.am @@ -0,0 +1,45 @@ +noinst_LTLIBRARIES = libkritaconverter.la +kde_module_LTLIBRARIES = libkritajpegimport.la libkritajpegexport.la + +libkritaconverter_la_LDFLAGS = $(all_libraries) +libkritaconverter_la_SOURCES = kis_jpeg_converter.cc iccjpeg.c +libkritaconverter_la_LIBADD = $(top_builddir)/filters/krita/libkisexif/libkisexif.la + +libkritajpegexport_la_LDFLAGS = -avoid-version -module -no-undefined \ + $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) +libkritajpegexport_la_LIBADD = $(top_builddir)/krita/libkritacommon.la \ + libkritaconverter.la $(KOFFICE_LIBS) -ljpeg -lexif + +libkritajpegimport_la_LDFLAGS = -avoid-version -module -no-undefined \ + $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) +libkritajpegimport_la_LIBADD = $(top_builddir)/krita/libkritacommon.la \ + libkritaconverter.la $(KOFFICE_LIBS) -ljpeg -lexif + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + -I$(top_srcdir)/filters/krita/libkisexif \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) \ + $(all_includes) + +service_DATA = krita_jpeg_import.desktop krita_jpeg_export.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_jpeg.desktop +kdelnkdir = $(kde_appsdir)/.hidden + +libkritajpegimport_la_SOURCES = kis_jpeg_import.cc +libkritajpegexport_la_SOURCES = kis_wdg_options_jpeg.ui kis_jpeg_export.cc + +METASOURCES = AUTO + + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + diff --git a/filters/krita/jpeg/configure.in.bot b/filters/krita/jpeg/configure.in.bot new file mode 100644 index 000000000..8ebad273c --- /dev/null +++ b/filters/krita/jpeg/configure.in.bot @@ -0,0 +1,7 @@ +if test -z "$LIBJPEG" -o -z "$LIBEXIF"; then + echo "" + echo "You're missing libjpeg or libexif 0.6.12 or later (binaries and/or headers)." + echo "krita won't be able to import/export jpeg" + echo "" + all_tests=bad +fi diff --git a/filters/krita/jpeg/iccjpeg.c b/filters/krita/jpeg/iccjpeg.c new file mode 100644 index 000000000..fefa95096 --- /dev/null +++ b/filters/krita/jpeg/iccjpeg.c @@ -0,0 +1,270 @@ +/* + * Little cms + * Copyright (C) 1998-2004 Marti Maria + * + * 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. + * + * iccprofile.c + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. If you need to do that, + * change all the "unsigned int" variables to "INT32". You'll also need + * to find a malloc() replacement that can allocate more than 64K. + */ + +#include "iccjpeg.h" +#include /* define malloc() */ + + +/* + * Since an ICC profile can be larger than the maximum size of a JPEG marker + * (64K), we need provisions to split it into multiple markers. The format + * defined by the ICC specifies one or more APP2 markers containing the + * following data: + * Identifying string ASCII "ICC_PROFILE\0" (12 bytes) + * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte) + * Number of markers Total number of APP2's used (1 byte) + * Profile data (remainder of APP2 data) + * Decoders should use the marker sequence numbers to reassemble the profile, + * rather than assuming that the APP2 markers appear in the correct sequence. + */ + +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +void +write_icc_profile (j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len) +{ + unsigned int num_markers; /* total number of markers we'll write */ + int cur_marker = 1; /* per spec, counting starts at 1 */ + unsigned int length; /* number of bytes to write in this marker */ + + /* Calculate the number of markers we'll need, rounding up of course */ + num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER; + if (num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) + num_markers++; + + while (icc_data_len > 0) { + /* length of profile to put in this marker */ + length = icc_data_len; + if (length > MAX_DATA_BYTES_IN_MARKER) + length = MAX_DATA_BYTES_IN_MARKER; + icc_data_len -= length; + + /* Write the JPEG marker header (APP2 code and marker length) */ + jpeg_write_m_header(cinfo, ICC_MARKER, + (unsigned int) (length + ICC_OVERHEAD_LEN)); + + /* Write the marker identifying string "ICC_PROFILE" (null-terminated). + * We code it in this less-than-transparent way so that the code works + * even if the local character set is not ASCII. + */ + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x43); + jpeg_write_m_byte(cinfo, 0x5F); + jpeg_write_m_byte(cinfo, 0x50); + jpeg_write_m_byte(cinfo, 0x52); + jpeg_write_m_byte(cinfo, 0x4F); + jpeg_write_m_byte(cinfo, 0x46); + jpeg_write_m_byte(cinfo, 0x49); + jpeg_write_m_byte(cinfo, 0x4C); + jpeg_write_m_byte(cinfo, 0x45); + jpeg_write_m_byte(cinfo, 0x0); + + /* Add the sequencing info */ + jpeg_write_m_byte(cinfo, cur_marker); + jpeg_write_m_byte(cinfo, (int) num_markers); + + /* Add the profile data */ + while (length--) { + jpeg_write_m_byte(cinfo, *icc_data_ptr); + icc_data_ptr++; + } + cur_marker++; + } +} + + +/* + * Prepare for reading an ICC profile + */ + +void +setup_read_icc_profile (j_decompress_ptr cinfo) +{ + /* Tell the library to keep any APP2 data it may find */ + jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF); +} + + +/* + * Handy subroutine to test whether a saved marker is an ICC profile marker. + */ + +static boolean +marker_is_icc (jpeg_saved_marker_ptr marker) +{ + return + marker->marker == ICC_MARKER && + marker->data_length >= ICC_OVERHEAD_LEN && + /* verify the identifying string */ + GETJOCTET(marker->data[0]) == 0x49 && + GETJOCTET(marker->data[1]) == 0x43 && + GETJOCTET(marker->data[2]) == 0x43 && + GETJOCTET(marker->data[3]) == 0x5F && + GETJOCTET(marker->data[4]) == 0x50 && + GETJOCTET(marker->data[5]) == 0x52 && + GETJOCTET(marker->data[6]) == 0x4F && + GETJOCTET(marker->data[7]) == 0x46 && + GETJOCTET(marker->data[8]) == 0x49 && + GETJOCTET(marker->data[9]) == 0x4C && + GETJOCTET(marker->data[10]) == 0x45 && + GETJOCTET(marker->data[11]) == 0x0; +} + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + * + * NOTE: if the file contains invalid ICC APP2 markers, we just silently + * return FALSE. You might want to issue an error message instead. + */ + +boolean +read_icc_profile (j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len) +{ + jpeg_saved_marker_ptr marker; + int num_markers = 0; + int seq_no; + JOCTET *icc_data; + unsigned int total_length; +#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */ + char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */ + unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */ + unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */ + + *icc_data_ptr = NULL; /* avoid confusion if FALSE return */ + *icc_data_len = 0; + + /* This first pass over the saved markers discovers whether there are + * any ICC markers and verifies the consistency of the marker numbering. + */ + + for (seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++) + marker_present[seq_no] = 0; + + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + if (num_markers == 0) + num_markers = GETJOCTET(marker->data[13]); + else if (num_markers != GETJOCTET(marker->data[13])) + return FALSE; /* inconsistent num_markers fields */ + seq_no = GETJOCTET(marker->data[12]); + if (seq_no <= 0 || seq_no > num_markers) + return FALSE; /* bogus sequence number */ + if (marker_present[seq_no]) + return FALSE; /* duplicate sequence numbers */ + marker_present[seq_no] = 1; + data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN; + } + } + + if (num_markers == 0) + return FALSE; + + /* Check for missing markers, count total space needed, + * compute offset of each marker's part of the data. + */ + + total_length = 0; + for (seq_no = 1; seq_no <= num_markers; seq_no++) { + if (marker_present[seq_no] == 0) + return FALSE; /* missing sequence number */ + data_offset[seq_no] = total_length; + total_length += data_length[seq_no]; + } + + if (total_length <= 0) + return FALSE; /* found only empty markers? */ + + /* Allocate space for assembled data */ + icc_data = (JOCTET *) malloc(total_length * sizeof(JOCTET)); + if (icc_data == NULL) + return FALSE; /* oops, out of memory */ + + /* and fill it in */ + for (marker = cinfo->marker_list; marker != NULL; marker = marker->next) { + if (marker_is_icc(marker)) { + JOCTET FAR *src_ptr; + JOCTET *dst_ptr; + unsigned int length; + seq_no = GETJOCTET(marker->data[12]); + dst_ptr = icc_data + data_offset[seq_no]; + src_ptr = marker->data + ICC_OVERHEAD_LEN; + length = data_length[seq_no]; + while (length--) { + *dst_ptr++ = *src_ptr++; + } + } + } + + *icc_data_ptr = icc_data; + *icc_data_len = total_length; + + return TRUE; +} diff --git a/filters/krita/jpeg/iccjpeg.h b/filters/krita/jpeg/iccjpeg.h new file mode 100644 index 000000000..8828dc991 --- /dev/null +++ b/filters/krita/jpeg/iccjpeg.h @@ -0,0 +1,99 @@ +/* + * Little cms + * Copyright (C) 1998-2004 Marti Maria + * + * 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. + * + * iccprofile.h + * + * This file provides code to read and write International Color Consortium + * (ICC) device profiles embedded in JFIF JPEG image files. The ICC has + * defined a standard format for including such data in JPEG "APP2" markers. + * The code given here does not know anything about the internal structure + * of the ICC profile data; it just knows how to put the profile data into + * a JPEG file being written, or get it back out when reading. + * + * This code depends on new features added to the IJG JPEG library as of + * IJG release 6b; it will not compile or work with older IJG versions. + * + * NOTE: this code would need surgery to work on 16-bit-int machines + * with ICC profiles exceeding 64K bytes in size. See iccprofile.c + * for details. + */ +#ifndef ICCJPEG +#define ICCJPEG + +#include /* needed to define "FILE", "NULL" */ +#include "jpeglib.h" + + +/* + * This routine writes the given ICC profile data into a JPEG file. + * It *must* be called AFTER calling jpeg_start_compress() and BEFORE + * the first call to jpeg_write_scanlines(). + * (This ordering ensures that the APP2 marker(s) will appear after the + * SOI and JFIF or Adobe markers, but before all else.) + */ + +extern void write_icc_profile JPP((j_compress_ptr cinfo, + const JOCTET *icc_data_ptr, + unsigned int icc_data_len)); + + +/* + * Reading a JPEG file that may contain an ICC profile requires two steps: + * + * 1. After jpeg_create_decompress() but before jpeg_read_header(), + * call setup_read_icc_profile(). This routine tells the IJG library + * to save in memory any APP2 markers it may find in the file. + * + * 2. After jpeg_read_header(), call read_icc_profile() to find out + * whether there was a profile and obtain it if so. + */ + + +/* + * Prepare for reading an ICC profile + */ + +extern void setup_read_icc_profile JPP((j_decompress_ptr cinfo)); + + +/* + * See if there was an ICC profile in the JPEG file being read; + * if so, reassemble and return the profile data. + * + * TRUE is returned if an ICC profile was found, FALSE if not. + * If TRUE is returned, *icc_data_ptr is set to point to the + * returned data, and *icc_data_len is set to its length. + * + * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc() + * and must be freed by the caller with free() when the caller no longer + * needs it. (Alternatively, we could write this routine to use the + * IJG library's memory allocator, so that the data would be freed implicitly + * at jpeg_finish_decompress() time. But it seems likely that many apps + * will prefer to have the data stick around after decompression finishes.) + */ + +extern boolean read_icc_profile JPP((j_decompress_ptr cinfo, + JOCTET **icc_data_ptr, + unsigned int *icc_data_len)); + +#endif diff --git a/filters/krita/jpeg/kis_jpeg_converter.cc b/filters/krita/jpeg/kis_jpeg_converter.cc new file mode 100644 index 000000000..2ceaa68cc --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_converter.cc @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_jpeg_converter.h" + +#include + +extern "C" { +#include +} + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +extern "C" { +#include +#include +} + +#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */ +#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */ +#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */ +#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN) + +namespace { + + J_COLOR_SPACE getColorTypeforColorSpace( KisColorSpace * cs) + { + if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") ) + { + return JCS_GRAYSCALE; + } + if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") ) + { + return JCS_RGB; + } + if ( cs->id() == KisID("CMYK") || cs->id() == KisID("CMYK16") ) + { + return JCS_CMYK; + } + KMessageBox::error(0, i18n("Cannot export images in %1.\n").arg(cs->id().name()) ) ; + return JCS_UNKNOWN; + } + + QString getColorSpaceForColorType(J_COLOR_SPACE color_type) { + kdDebug(41008) << "color_type = " << color_type << endl; + if(color_type == JCS_GRAYSCALE) + { + return "GRAYA"; + } else if(color_type == JCS_RGB) { + return "RGBA"; + } else if(color_type == JCS_CMYK) { + return "CMYK"; + } + return ""; + } + +} + +KisJPEGConverter::KisJPEGConverter(KisDoc *doc, KisUndoAdapter *adapter) +{ + m_doc = doc; + m_adapter = adapter; + m_job = 0; + m_stop = false; +} + +KisJPEGConverter::~KisJPEGConverter() +{ +} + +KisImageBuilder_Result KisJPEGConverter::decode(const KURL& uri) +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + + // open the file + FILE *fp = fopen(QFile::encodeName(uri.path()), "rb"); + if (!fp) + { + return (KisImageBuilder_RESULT_NOT_EXIST); + } + jpeg_stdio_src(&cinfo, fp); + + jpeg_save_markers (&cinfo, JPEG_COM, 0xFFFF); + /* Save APP0..APP15 markers */ + for (int m = 0; m < 16; m++) + jpeg_save_markers (&cinfo, JPEG_APP0 + m, 0xFFFF); + + +// setup_read_icc_profile(&cinfo); + // read header + jpeg_read_header(&cinfo, true); + + // start reading + jpeg_start_decompress(&cinfo); + + // Get the colorspace + QString csName = getColorSpaceForColorType(cinfo.out_color_space); + if(csName.isEmpty()) { + kdDebug(41008) << "unsupported colorspace : " << cinfo.out_color_space << endl; + jpeg_destroy_decompress(&cinfo); + fclose(fp); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + uchar* profile_data; + uint profile_len; + KisProfile* profile = 0; + QByteArray profile_rawdata; + if( read_icc_profile (&cinfo, &profile_data, &profile_len)) + { + profile_rawdata.resize(profile_len); + memcpy(profile_rawdata.data(), profile_data, profile_len); + cmsHPROFILE hProfile = cmsOpenProfileFromMem(profile_data, (DWORD)profile_len); + + if (hProfile != (cmsHPROFILE) NULL) { + profile = new KisProfile( profile_rawdata); + Q_CHECK_PTR(profile); + kdDebug(41008) << "profile name: " << profile->productName() << " profile description: " << profile->productDescription() << " information sur le produit: " << profile->productInfo() << endl; + if(!profile->isSuitableForOutput()) + { + kdDebug(41008) << "the profile is not suitable for output and therefore cannot be used in krita, we need to convert the image to a standard profile" << endl; // TODO: in ko2 popup a selection menu to inform the user + } + } + } + + // Retrieve a pointer to the colorspace + KisColorSpace* cs; + if (profile && profile->isSuitableForOutput()) + { + kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n"; + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile); + } + else + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),""); + + if(cs == 0) + { + kdDebug(41008) << "unknown colorspace" << endl; + jpeg_destroy_decompress(&cinfo); + fclose(fp); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + + // Create the cmsTransform if needed + + cmsHTRANSFORM transform = 0; + if(profile && !profile->isSuitableForOutput()) + { + transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(), + cs->getProfile()->profile() , cs->colorSpaceType(), + INTENT_PERCEPTUAL, 0); + } + + // Creating the KisImageSP + if( ! m_img) { + m_img = new KisImage(m_doc->undoAdapter(), cinfo.image_width, cinfo.image_height, cs, "built image"); + Q_CHECK_PTR(m_img); + if(profile && !profile->isSuitableForOutput()) + { + m_img -> addAnnotation( new KisAnnotation( profile->productName(), "", profile_rawdata) ); + } + } + + KisPaintLayerSP layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), Q_UINT8_MAX); + + // Read exif information if any + + // Read data + JSAMPROW row_pointer = new JSAMPLE[cinfo.image_width *cinfo.num_components]; + + for (; cinfo.output_scanline < cinfo.image_height;) { + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, cinfo.output_scanline, cinfo.image_width, true); + jpeg_read_scanlines(&cinfo, &row_pointer, 1); + Q_UINT8 *src = row_pointer; + switch(cinfo.out_color_space) + { + case JCS_GRAYSCALE: + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + d[1] = Q_UINT8_MAX; + ++it; + } + break; + case JCS_RGB: + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + d[2] = *(src++); + d[1] = *(src++); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + d[3] = Q_UINT8_MAX; + ++it; + } + break; + case JCS_CMYK: + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + d[0] = Q_UINT8_MAX - *(src++); + d[1] = Q_UINT8_MAX - *(src++); + d[2] = Q_UINT8_MAX - *(src++); + d[3] = Q_UINT8_MAX - *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + d[4] = Q_UINT8_MAX; + ++it; + } + break; + default: + return KisImageBuilder_RESULT_UNSUPPORTED; + } + } + + m_img->addLayer(layer.data(), m_img->rootLayer(), 0); + + // Read exif informations + + kdDebug(41008) << "Looking for exif information" << endl; + + for (jpeg_saved_marker_ptr marker = cinfo.marker_list; marker != NULL; marker = marker->next) { + kdDebug(41008) << "Marker is " << marker->marker << endl; + if (marker->marker != (JOCTET) (JPEG_APP0 + 1) || + marker->data_length < 14) + continue; /* Exif data is in an APP1 marker of at least 14 octets */ + + if (GETJOCTET (marker->data[0]) != (JOCTET) 0x45 || + GETJOCTET (marker->data[1]) != (JOCTET) 0x78 || + GETJOCTET (marker->data[2]) != (JOCTET) 0x69 || + GETJOCTET (marker->data[3]) != (JOCTET) 0x66 || + GETJOCTET (marker->data[4]) != (JOCTET) 0x00 || + GETJOCTET (marker->data[5]) != (JOCTET) 0x00) + continue; /* no Exif header */ + kdDebug(41008) << "Found exif information of length : "<< marker->data_length << endl; + KisExifIO exifIO(layer->paintDevice()->exifInfo()); + exifIO.readExifFromMem( marker->data , marker->data_length ); + // Interpret orientation tag + ExifValue v; + if( layer->paintDevice()->exifInfo()->getValue("Orientation", v) && v.type() == ExifValue::EXIF_TYPE_SHORT) + { + switch(v.asShort(0)) // + { + case 2: + layer->paintDevice()->mirrorY(); + break; + case 3: + image()->rotate(M_PI, 0); + break; + case 4: + layer->paintDevice()->mirrorX(); + break; + case 5: + image()->rotate(M_PI/2, 0); + layer->paintDevice()->mirrorY(); + break; + case 6: + image()->rotate(M_PI/2, 0); + break; + case 7: + image()->rotate(M_PI/2, 0); + layer->paintDevice()->mirrorX(); + break; + case 8: + image()->rotate(-M_PI/2 + 2*M_PI, 0); + break; + default: + break; + } + v.setValue(0, (Q_UINT16)1); + layer->paintDevice()->exifInfo()->setValue("Orientation", v); + } + break; + } + + // Finish decompression + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + fclose(fp); + delete []row_pointer; + return KisImageBuilder_RESULT_OK; +} + + + +KisImageBuilder_Result KisJPEGConverter::buildImage(const KURL& uri) +{ + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) { + return KisImageBuilder_RESULT_NOT_EXIST; + } + + // We're not set up to handle asynchronous loading at the moment. + KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE; + QString tmpFile; + + if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) { + KURL uriTF; + uriTF.setPath( tmpFile ); + result = decode(uriTF); + KIO::NetAccess::removeTempFile(tmpFile); + } + + return result; +} + + +KisImageSP KisJPEGConverter::image() +{ + return m_img; +} + + +KisImageBuilder_Result KisJPEGConverter::buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd, KisJPEGOptions options, KisExifInfo* exifInfo) +{ + if (!layer) + return KisImageBuilder_RESULT_INVALID_ARG; + + KisImageSP img = layer -> image(); + if (!img) + return KisImageBuilder_RESULT_EMPTY; + + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!uri.isLocalFile()) + return KisImageBuilder_RESULT_NOT_LOCAL; + // Open file for writing + FILE *fp = fopen(QFile::encodeName(uri.path()), "wb"); + if (!fp) + { + return (KisImageBuilder_RESULT_FAILURE); + } + uint height = img->height(); + uint width = img->width(); + // Initialize structure + struct jpeg_compress_struct cinfo; + jpeg_create_compress(&cinfo); + // Initialize error output + struct jpeg_error_mgr jerr; + cinfo.err = jpeg_std_error(&jerr); + // Initialize output stream + jpeg_stdio_dest(&cinfo, fp); + + cinfo.image_width = width; // image width and height, in pixels + cinfo.image_height = height; + cinfo.input_components = img->colorSpace()->nColorChannels(); // number of color channels per pixel */ + J_COLOR_SPACE color_type = getColorTypeforColorSpace(img->colorSpace()); + if(color_type == JCS_UNKNOWN) + { + KIO::del(uri); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + cinfo.in_color_space = color_type; // colorspace of input image + + + // Set default compression parameters + jpeg_set_defaults(&cinfo); + // Customize them + jpeg_set_quality(&cinfo, options.quality, true); + + if(options.progressive) + { + jpeg_simple_progression (&cinfo); + } + + // Start compression + jpeg_start_compress(&cinfo, true); + // Save exif information if any available + if(exifInfo) + { + kdDebug(41008) << "Trying to save exif information" << endl; + KisExifIO exifIO(exifInfo); + unsigned char* exif_data; + unsigned int exif_size; + exifIO.saveExifToMem( &exif_data, &exif_size); + kdDebug(41008) << "Exif informations size is " << exif_size << endl; + if (exif_size < MAX_DATA_BYTES_IN_MARKER) + { + jpeg_write_marker(&cinfo, JPEG_APP0 + 1, exif_data, exif_size); + } else { + kdDebug(41008) << "exif informations couldn't be saved." << endl; + } + } + + + // Save annotation + vKisAnnotationSP_it it = annotationsStart; + while(it != annotationsEnd) { + if (!(*it) || (*it) -> type() == QString()) { + kdDebug(41008) << "Warning: empty annotation" << endl; + ++it; + continue; + } + + kdDebug(41008) << "Trying to store annotation of type " << (*it) -> type() << " of size " << (*it) -> annotation() . size() << endl; + + if ((*it) -> type().startsWith("krita_attribute:")) { // Attribute + // FIXME + kdDebug(41008) << "can't save this annotation : " << (*it) -> type() << endl; + } else { // Profile + //char* name = new char[(*it)->type().length()+1]; + write_icc_profile(& cinfo, (uchar*)(*it)->annotation().data(), (*it)->annotation().size()); + } + ++it; + } + + + // Write data information + + JSAMPROW row_pointer = new JSAMPLE[width*cinfo.input_components]; + int color_nb_bits = 8 * layer->paintDevice()->pixelSize() / layer->paintDevice()->nChannels(); + + for (; cinfo.next_scanline < height;) { + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, cinfo.next_scanline, width, false); + Q_UINT8 *dst = row_pointer; + switch(color_type) + { + case JCS_GRAYSCALE: + if(color_nb_bits == 16) + { + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + *(dst++) = d[0] / Q_UINT8_MAX; + ++it; + } + } else { + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + *(dst++) = d[0]; + ++it; + } + } + break; + case JCS_RGB: + if(color_nb_bits == 16) + { + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + *(dst++) = d[2] / Q_UINT8_MAX; + *(dst++) = d[1] / Q_UINT8_MAX; + *(dst++) = d[0] / Q_UINT8_MAX; + ++it; + } + } else { + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + *(dst++) = d[2]; + *(dst++) = d[1]; + *(dst++) = d[0]; + ++it; + } + } + break; + case JCS_CMYK: + if(color_nb_bits == 16) + { + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + *(dst++) = Q_UINT8_MAX - d[0] / Q_UINT8_MAX; + *(dst++) = Q_UINT8_MAX - d[1] / Q_UINT8_MAX; + *(dst++) = Q_UINT8_MAX - d[2] / Q_UINT8_MAX; + *(dst++) = Q_UINT8_MAX - d[3] / Q_UINT8_MAX; + ++it; + } + } else { + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + *(dst++) = Q_UINT8_MAX - d[0]; + *(dst++) = Q_UINT8_MAX - d[1]; + *(dst++) = Q_UINT8_MAX - d[2]; + *(dst++) = Q_UINT8_MAX - d[3]; + ++it; + } + } + break; + default: + KIO::del(uri); + return KisImageBuilder_RESULT_UNSUPPORTED; + } + jpeg_write_scanlines(&cinfo, &row_pointer, 1); + } + + + // Writting is over + jpeg_finish_compress(&cinfo); + fclose(fp); + + delete [] row_pointer; + // Free memory + jpeg_destroy_compress(&cinfo); + + return KisImageBuilder_RESULT_OK; +} + + +void KisJPEGConverter::cancel() +{ + m_stop = true; +} + +#include "kis_jpeg_converter.moc" + diff --git a/filters/krita/jpeg/kis_jpeg_converter.h b/filters/krita/jpeg/kis_jpeg_converter.h new file mode 100644 index 000000000..99b7eadf7 --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_converter.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_JPEG_CONVERTER_H_ +#define _KIS_JPEG_CONVERTER_H_ + +#include + +extern "C" { +#include +} + +#include + +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_annotation.h" +class KisDoc; +class KisUndoAdapter; +class KisExifInfo; + +/** + * Image import/export plugins can use these results to report about success or failure. + */ +enum KisImageBuilder_Result { + KisImageBuilder_RESULT_FAILURE = -400, + KisImageBuilder_RESULT_NOT_EXIST = -300, + KisImageBuilder_RESULT_NOT_LOCAL = -200, + KisImageBuilder_RESULT_BAD_FETCH = -100, + KisImageBuilder_RESULT_INVALID_ARG = -50, + KisImageBuilder_RESULT_OK = 0, + KisImageBuilder_RESULT_PROGRESS = 1, + KisImageBuilder_RESULT_EMPTY = 100, + KisImageBuilder_RESULT_BUSY = 150, + KisImageBuilder_RESULT_NO_URI = 200, + KisImageBuilder_RESULT_UNSUPPORTED = 300, + KisImageBuilder_RESULT_INTR = 400, + KisImageBuilder_RESULT_PATH = 500, + KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE = 600 +}; + +struct KisJPEGOptions { + int quality; + bool progressive; +}; + +class KisJPEGConverter : public KisProgressSubject { + Q_OBJECT + public: + KisJPEGConverter(KisDoc *doc, KisUndoAdapter *adapter); + virtual ~KisJPEGConverter(); + public: + KisImageBuilder_Result buildImage(const KURL& uri); + KisImageBuilder_Result buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd, KisJPEGOptions options, KisExifInfo* exifInfo); + /** Retrieve the constructed image + */ + KisImageSP image(); + public slots: + virtual void cancel(); + private: + KisImageBuilder_Result decode(const KURL& uri); + private: + KisImageSP m_img; + KisDoc *m_doc; + KisUndoAdapter *m_adapter; + bool m_stop; + KIO::TransferJob *m_job; +}; + +#endif diff --git a/filters/krita/jpeg/kis_jpeg_export.cc b/filters/krita/jpeg/kis_jpeg_export.cc new file mode 100644 index 000000000..394198339 --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_export.cc @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_jpeg_export.h" + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "kis_jpeg_converter.h" +#include "kis_wdg_options_jpeg.h" + + +class KisExifInfoVisitor : public KisLayerVisitor +{ + public: + KisExifInfoVisitor() : + m_exifInfo(0), + m_countPaintLayer(0) + { }; + public: + virtual bool visit(KisPaintLayer* layer) { + m_countPaintLayer++; + if( layer->paintDevice()->hasExifInfo()) + m_exifInfo = layer->paintDevice()->exifInfo(); + return true; + }; + virtual bool visit(KisGroupLayer* layer) + { + kdDebug(41008) << "Visiting on grouplayer " << layer->name() << "\n"; + KisLayerSP child = layer->firstChild(); + while (child) { + child->accept(*this); + child = child->nextSibling(); + } + return true; + } + virtual bool visit(KisPartLayer *) { return true; }; + virtual bool visit(KisAdjustmentLayer* ) { return true; }; + public: + inline uint countPaintLayer() { return m_countPaintLayer; } + inline KisExifInfo* exifInfo() {return m_exifInfo; } + private: + KisExifInfo* m_exifInfo; + uint m_countPaintLayer; +}; + + +typedef KGenericFactory KisJPEGExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritajpegexport, KisJPEGExportFactory("kofficefilters")) + +KisJPEGExport::KisJPEGExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisJPEGExport::~KisJPEGExport() +{ +} + +KoFilter::ConversionStatus KisJPEGExport::convert(const QCString& from, const QCString& to) +{ + kdDebug(41008) << "JPEG export! From: " << from << ", To: " << to << "\n"; + + if (from != "application/x-krita") + return KoFilter::NotImplemented; + + + KDialogBase* kdb = new KDialogBase(0, "", false, i18n("JPEG Export Options"), KDialogBase::Ok | KDialogBase::Cancel); + + KisWdgOptionsJPEG* wdg = new KisWdgOptionsJPEG(kdb); + kdb->setMainWidget(wdg); + kapp->restoreOverrideCursor(); + if(kdb->exec() == QDialog::Rejected) + { + return KoFilter::OK; // FIXME Cancel doesn't exist :( + } + KisJPEGOptions options; + options.progressive = wdg->progressive->isChecked(); + options.quality = wdg->qualityLevel->value(); + + delete kdb; + // XXX: Add dialog about flattening layers here + + KisDoc *output = dynamic_cast(m_chain->inputDocument()); + QString filename = m_chain->outputFile(); + + if (!output) + return KoFilter::CreationError; + + + if (filename.isEmpty()) return KoFilter::FileNotFound; + + KURL url; + url.setPath(filename); + + KisImageSP img = output->currentImage(); + Q_CHECK_PTR(img); + + KisJPEGConverter kpc(output, output->undoAdapter()); + + KisPaintDeviceSP pd = new KisPaintDevice(*img->projection()); + KisPaintLayerSP l = new KisPaintLayer(img, "projection", OPACITY_OPAQUE, pd); + + vKisAnnotationSP_it beginIt = img->beginAnnotations(); + vKisAnnotationSP_it endIt = img->endAnnotations(); + KisImageBuilder_Result res; + + KisExifInfoVisitor eIV; + eIV.visit( img->rootLayer() ); + + KisExifInfo* eI = 0; + if(eIV.countPaintLayer() == 1) + eI = eIV.exifInfo(); + + if ( (res = kpc.buildFile(url, l, beginIt, endIt, options, eI)) == KisImageBuilder_RESULT_OK) { + kdDebug(41008) << "success !" << endl; + return KoFilter::OK; + } + kdDebug(41008) << " Result = " << res << endl; + return KoFilter::InternalError; +} + +#include + diff --git a/filters/krita/jpeg/kis_jpeg_export.h b/filters/krita/jpeg/kis_jpeg_export.h new file mode 100644 index 000000000..38e04b201 --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_export.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_JPEG_EXPORT_H_ +#define _KIS_JPEG_EXPORT_H_ + +#include + +class KisJPEGExport : public KoFilter { + Q_OBJECT + public: + KisJPEGExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisJPEGExport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/jpeg/kis_jpeg_import.cc b/filters/krita/jpeg/kis_jpeg_import.cc new file mode 100644 index 000000000..e9b867e03 --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_import.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_jpeg_import.h" + +#include + +#include + +#include +#include +#include +#include + +#include "kis_jpeg_converter.h" + +typedef KGenericFactory JPEGImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritajpegimport, JPEGImportFactory("kofficefilters")) + +KisJPEGImport::KisJPEGImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisJPEGImport::~KisJPEGImport() +{ +} + +KoFilter::ConversionStatus KisJPEGImport::convert(const QCString&, const QCString& to) +{ + kdDebug(41008) << "Importing using JPEGImport!\n"; + + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + KisView * view = static_cast(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc->prepareForImport(); + + + if (!filename.isEmpty()) { + + KURL url; + url.setPath(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisJPEGConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + +#include + diff --git a/filters/krita/jpeg/kis_jpeg_import.h b/filters/krita/jpeg/kis_jpeg_import.h new file mode 100644 index 000000000..6e60c84b8 --- /dev/null +++ b/filters/krita/jpeg/kis_jpeg_import.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_JPEG_IMPORT_H_ +#define _KIS_JPEG_IMPORT_H_ + +#include + +class KisJPEGImport : public KoFilter { + Q_OBJECT + public: + KisJPEGImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisJPEGImport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/jpeg/kis_wdg_options_jpeg.ui b/filters/krita/jpeg/kis_wdg_options_jpeg.ui new file mode 100644 index 000000000..17f5eb369 --- /dev/null +++ b/filters/krita/jpeg/kis_wdg_options_jpeg.ui @@ -0,0 +1,149 @@ + +KisWdgOptionsJPEG + + + KisWdgOptionsJPEG + + + + 0 + 0 + 167 + 87 + + + + + unnamed + + + 0 + + + + layout4 + + + + unnamed + + + + textLabel1 + + + Quality: + + + AlignTop + + + + + layout5 + + + + unnamed + + + + qualityLevel + + + 0 + + + 100 + + + 1 + + + 1 + + + 80 + + + Horizontal + + + Below + + + 10 + + + These settings determine how much information is lost during compression + + + + + layout4 + + + + unnamed + + + + textLabel3 + + + Smallest + + + + + textLabel4 + + + Best + + + AlignVCenter|AlignRight + + + + + + + + + + + progressive + + + Pr&ogressive + + + Use progressive when publishing on the Internet + + + <p>Progressive is useful if you intend to publish your image on the Internet.<br> +Enabling progressive will cause the image to be displayed by the browser even while downloading.</p> + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 61 + + + + + + + diff --git a/filters/krita/jpeg/krita_jpeg.desktop b/filters/krita/jpeg/krita_jpeg.desktop new file mode 100644 index 000000000..48d669cad --- /dev/null +++ b/filters/krita/jpeg/krita_jpeg.desktop @@ -0,0 +1,58 @@ +[Desktop Entry] +Categories= +Exec=krita %u +GenericName=Application for Drawing and Handling of Images +GenericName[bg]=Приложение за рисуване и обработка на изображения +GenericName[ca]=Aplicació per a dibuix i modificació d'imatges +GenericName[da]=Tegne- og billedbehandlingsprogram +GenericName[de]=Programm zum Zeichnen und Bearbeiten von Bildern +GenericName[el]=Εφαρμογή για επεξεργασία και χειρισμό εικόνων +GenericName[eo]=Aplikaĵo por Desegnado kaj Mastrumado de Bildoj +GenericName[es]=Aplicación para dibujo y manipulación de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[fa]=کاربرد برای ترسیم و به کار بردن تصاویر +GenericName[fi]=Ohjelma kuvien piirtämiseen ja käsittelyyn +GenericName[fr]=Application pour dessiner et manipuler des images +GenericName[fy]=Aplikaasje om ôfbyldings mei te tekenjen en te bewurkjen +GenericName[gl]=Aplicación de Debuxo e Manipulación de Imaxes +GenericName[he]=יישום לצביעה וניהול תמונות +GenericName[hu]=Rajzoló és képkezelő +GenericName[is]=Teikni og myndvinnsluforrit +GenericName[it]=Applicazione di disegno e gestione di immagini +GenericName[ja]=描画と画像操作のためのアプリケーション +GenericName[km]=កម្មវិធី​សម្រាប់​គូរ និង​ដោះស្រាយ​នៃ​រូបភាព +GenericName[lv]=Programma zīmēšanai un attēlu apstrādei +GenericName[nb]=Program for tegning og bildehåndtering +GenericName[nds]=Programm för't Teken un Bildhanteren +GenericName[ne]=रेखाचित्र र छविहरूको ह्यान्डल गर्न अनुप्रयोग +GenericName[nl]=Toepassing om afbeeldingen te tekenen en te bewerken +GenericName[pl]=Program do rysowania i obróbki obrazków +GenericName[pt]=Aplicação de Desenho e Manipulação de Imagens +GenericName[pt_BR]=Aplicação de Desenho e Manipulação de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Prográmma sárgumii ja govvegieđaheapmái +GenericName[sk]=Aplikácia na kresnenie a manilupáciu s obrázkami +GenericName[sl]=Program za risanje in rokovanje s slikami +GenericName[sr]=Програм за цртање и обраду слика +GenericName[sr@Latn]=Program za crtanje i obradu slika +GenericName[sv]=Program för att rita och hantera bilder +GenericName[uk]=Програма для малювання і обробки зображень +GenericName[uz]=Rasm chizish dasturi +GenericName[uz@cyrillic]=Расм чизиш дастури +GenericName[zh_CN]=绘制和操纵图像的应用程序 +GenericName[zh_TW]=影像繪製與處理應用程式 +Icon=krita +MimeType=image/jpeg +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Path= +StartupNotify=true +Terminal=false +Type=Application +X-DCOP-ServiceType=multi +X-KDE-StartupNotify=true +X-KDE-SubstituteUID=false +X-KDE-Username= diff --git a/filters/krita/jpeg/krita_jpeg_export.desktop b/filters/krita/jpeg/krita_jpeg_export.desktop new file mode 100644 index 000000000..25929d8e2 --- /dev/null +++ b/filters/krita/jpeg/krita_jpeg_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Icon= +Name=Krita PNG Export Filter +Name[bg]=Филтър за експортиране от Krita в PNG +Name[br]=Sil ezporzh PNG evit Krita +Name[ca]=Filtre d'exportació PNG per a Krita +Name[da]=Krita PNG-eksportfilter +Name[de]=Krita PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του Krita +Name[eo]=Krita PNG-eksportfiltrilo +Name[es]=Filtro de exportación a PNG de Krita +Name[et]=Krita PNG ekspordifilter +Name[fa]=پالایۀ صادرات Krita PNG +Name[fi]=Krita PNG -viestisuodin +Name[fr]=Filtre d'exportation PNG de Krita +Name[fy]=Krita PNG Eksportfilter +Name[ga]=Scagaire Easpórtála PNG Krita +Name[gl]=Filtro de Exportación de PNG para Krita +Name[he]=Krita PNG מסנן יצוא +Name[hr]=Krita PNG filtar izvoza +Name[hu]=Krita PNG exportszűrő +Name[is]=Krita PNG útflutningssía +Name[it]=Filtro di esportazione PNG per Krita +Name[ja]=Krita PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ Krita +Name[lt]=Krita PNG eksportavimo filtras +Name[lv]=Krita PNG eksporta filtrs +Name[nb]=PNG-eksportfilter for Krita +Name[nds]=PNG-Exportfilter för Krita +Name[ne]=क्रिता पीएनजी निर्यात फिल्टर +Name[nl]=Krita PNG Exportfilter +Name[pl]=Filtr eksportu do formatu PNG dla Krita +Name[pt]=Filtro de Exportação de PNG para o Krita +Name[pt_BR]=Filtro de Exportação de PNG para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в PNG +Name[se]=Krita PNG-olggosfievrridansilli +Name[sk]=Exportný filter Krita PNG +Name[sl]=Izvozni filter PNG za Krito +Name[sr]=Krita-ин филтер за извоз у PNG +Name[sr@Latn]=Krita-in filter za izvoz u PNG +Name[sv]=Krita PNG-exportfilter +Name[uk]=Фільтр експорту PNG для Krita +Name[uz]=Krita PNG eksport filteri +Name[uz@cyrillic]=Krita PNG экспорт филтери +Name[zh_CN]=Krita PNG 导出过滤器 +Name[zh_TW]=Krita PNG 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/jpeg +X-KDE-Import=application/x-krita +X-KDE-Library=libkritajpegexport +X-KDE-Weight=1 diff --git a/filters/krita/jpeg/krita_jpeg_import.desktop b/filters/krita/jpeg/krita_jpeg_import.desktop new file mode 100644 index 000000000..4b3772f77 --- /dev/null +++ b/filters/krita/jpeg/krita_jpeg_import.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Icon= +Name=Krita PNG Import Filter +Name[bg]=Филтър за импортиране от PNG в Krita +Name[br]=Sil enporzh PNG evit Krita +Name[ca]=Filtre d'importació PNG per a Krita +Name[da]=Krita PNG-importfilter +Name[de]=Krita PNG-Importfilter +Name[el]=Φίλτρο εισαγωγής PNG του Krita +Name[eo]=Krita PNG-importfiltrilo +Name[es]=Filtro de importación a PNG de Krita +Name[et]=Krita PNG impordifilter +Name[fa]=پالایۀ واردات Krita PNG +Name[fi]=Krita PNG -tuontisuodin +Name[fr]=Filtre d'importation PNG de Krita +Name[fy]=Krita PNG Ymportfilter +Name[ga]=Scagaire Iompórtála PNG Krita +Name[gl]=Filtro de Importación de PNG para Krita +Name[he]=Krita PNG מסנן יבוא +Name[hr]=Krita PNG filtar uvoza +Name[hu]=Krita PNG importszűrő +Name[is]=Krita PNG innflutningssía +Name[it]=Filtro di importazione PNG per Krita +Name[ja]=Krita PNG インポートフィルタ +Name[km]=តម្រង​នាំចូល PNG សម្រាប់ Krita +Name[lt]=Krita PNG importavimo filtras +Name[lv]=Krita PNG importa filtrs +Name[nb]=PNG-importfilter for Krita +Name[nds]=PNG-Importfilter för Krita +Name[ne]=क्रिता पीएनजी आयात फिल्टर +Name[nl]=Krita PNG Importfilter +Name[pl]=Filtr importu z formatu PNG dla Krita +Name[pt]=Filtro de Importação de PNG para o Krita +Name[pt_BR]=Filtro de Importação de PNG para o Krita +Name[ru]=Фильтр импорта рисунков PNG в Krita +Name[se]=Krita PNG-olggosfievrridansilli +Name[sk]=PNG filter pre import do Krita +Name[sl]=Uvozni filter PNG za Krito +Name[sr]=Krita-ин филтер за увоз из PNG-а +Name[sr@Latn]=Krita-in filter za uvoz iz PNG-a +Name[sv]=Krita PNG-importfilter +Name[uk]=Фільтр імпорту PNG для Krita +Name[uz]=Krita PNG import filteri +Name[uz@cyrillic]=Krita PNG импорт филтери +Name[zh_CN]=Krita PNG 导入过滤器 +Name[zh_TW]=Krita PNG 匯入過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=application/x-krita +X-KDE-Import=image/jpeg +X-KDE-Library=libkritajpegimport +X-KDE-Weight=1 diff --git a/filters/krita/libkisexif/Makefile.am b/filters/krita/libkisexif/Makefile.am new file mode 100644 index 000000000..a7aa9b4bc --- /dev/null +++ b/filters/krita/libkisexif/Makefile.am @@ -0,0 +1,18 @@ +INCLUDES = \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) \ + $(all_includes) +METASOURCES = AUTO +libkisexif_la_LDFLAGS = $(all_libraries) +noinst_LTLIBRARIES = libkisexif.la + + +libkisexif_la_SOURCES = kis_exif_io.cpp diff --git a/filters/krita/libkisexif/kis_exif_io.cpp b/filters/krita/libkisexif/kis_exif_io.cpp new file mode 100644 index 000000000..a5e5dbd71 --- /dev/null +++ b/filters/krita/libkisexif/kis_exif_io.cpp @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_exif_io.h" + +#include + +extern "C" { +#include +#include +} + +KisExifIO::KisExifIO(KisExifInfo* ei) : m_exifInfo(ei) +{ +} + +void KisExifIO::readExifFromFile( const char* fileName) +{ + readExifData( exif_data_new_from_file(fileName) ); +} + +void KisExifIO::readExifFromMem( const unsigned char* data , unsigned int size) +{ + readExifData( exif_data_new_from_data(data, size) ); +} + +void KisExifIO::saveExifToMem( unsigned char** data, unsigned int *size) +{ + ExifData* exifData = exif_data_new(); + writeExifData( exifData ); + exif_data_save_data( exifData, data, size); +} + +ExifValue::ExifType KisExifIO::format2type(ExifFormat format) +{ + switch(format) + { + case EXIF_FORMAT_BYTE: + return ExifValue::EXIF_TYPE_BYTE; + case EXIF_FORMAT_ASCII: + return ExifValue::EXIF_TYPE_ASCII; + case EXIF_FORMAT_SHORT: + return ExifValue::EXIF_TYPE_SHORT; + case EXIF_FORMAT_LONG: + return ExifValue::EXIF_TYPE_LONG; + case EXIF_FORMAT_RATIONAL: + return ExifValue::EXIF_TYPE_RATIONAL; + case EXIF_FORMAT_SBYTE: + return ExifValue::EXIF_TYPE_SBYTE; + case EXIF_FORMAT_SSHORT: + return ExifValue::EXIF_TYPE_SSHORT; + case EXIF_FORMAT_SLONG: + return ExifValue::EXIF_TYPE_SLONG; + case EXIF_FORMAT_SRATIONAL: + return ExifValue::EXIF_TYPE_SRATIONAL; + case EXIF_FORMAT_FLOAT: + return ExifValue::EXIF_TYPE_FLOAT; + case EXIF_FORMAT_DOUBLE: + return ExifValue::EXIF_TYPE_DOUBLE; + default: + case EXIF_FORMAT_UNDEFINED: + return ExifValue::EXIF_TYPE_UNDEFINED; + } +} + +void KisExifIO::readExifData( ExifData* exifData) +{ + ExifValue::ByteOrder bO; + if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA) + { + bO = ExifValue::BYTE_ORDER_MOTOROLA; + } else { + bO = ExifValue::BYTE_ORDER_INTEL; + } + static ExifIfd ifds[5] = { + EXIF_IFD_0, + EXIF_IFD_1, + EXIF_IFD_EXIF, + EXIF_IFD_INTEROPERABILITY, + EXIF_IFD_GPS + }; + for(int ifd = 0; ifd < 5; ifd ++) + { + ExifContent* content = exifData->ifd[ifds[ifd]]; + kdDebug() << "There are " << content->count << " values in ifd=" << ifd << endl; + for (uint i = 0; i < content->count; i++) + { + ExifEntry* entry = content->entries[i]; + QString tagname = exif_tag_get_name ( entry->tag ); +// kdDebug() << "found tag : " << tagname << endl; + // QString tagname = exif_tag_get_name_in_ifd ( entry->tag, EXIF_IFD_0 ); TODO: would be better to rely on 0.6.13 when it becomes more common, as it supports better other IFD (GPS and interoperrabilibity) + ExifValue value( format2type(entry->format), entry->data, entry->size, ifds[ifd], entry->components, bO ); +// exif_entry_dump( entry, 4); +// kdDebug() << "value = " << value.toString() << endl; + m_exifInfo->setValue( tagname, value); + } + } + +} + +ExifFormat KisExifIO::type2format( ExifValue::ExifType type) +{ + switch(type) + { + case ExifValue::EXIF_TYPE_BYTE: + return EXIF_FORMAT_BYTE; + case ExifValue::EXIF_TYPE_ASCII: + return EXIF_FORMAT_ASCII; + case ExifValue::EXIF_TYPE_SHORT: + return EXIF_FORMAT_SHORT; + case ExifValue::EXIF_TYPE_LONG: + return EXIF_FORMAT_LONG; + case ExifValue::EXIF_TYPE_RATIONAL: + return EXIF_FORMAT_RATIONAL; + case ExifValue::EXIF_TYPE_SBYTE: + return EXIF_FORMAT_SBYTE; + case ExifValue::EXIF_TYPE_SSHORT: + return EXIF_FORMAT_SSHORT; + case ExifValue::EXIF_TYPE_SLONG: + return EXIF_FORMAT_SLONG; + case ExifValue::EXIF_TYPE_SRATIONAL: + return EXIF_FORMAT_SRATIONAL; + case ExifValue::EXIF_TYPE_FLOAT: + return EXIF_FORMAT_FLOAT; + case ExifValue::EXIF_TYPE_DOUBLE: + return EXIF_FORMAT_DOUBLE; + default: + case ExifValue::EXIF_TYPE_UNDEFINED: + return EXIF_FORMAT_UNDEFINED; + } +} + + +void KisExifIO::writeExifData( ExifData* exifData) +{ + ExifValue::ByteOrder bO; + if(exif_data_get_byte_order( exifData) == EXIF_BYTE_ORDER_MOTOROLA) + { + bO = ExifValue::BYTE_ORDER_MOTOROLA; + } else { + bO = ExifValue::BYTE_ORDER_INTEL; + } + + for( KisExifInfo::evMap::const_iterator it = m_exifInfo->begin(); it != m_exifInfo->end(); ++it) + { + ExifValue ev = it.data(); + if(ev.ifd() != -1) + { + ExifEntry * entry = exif_entry_new(); + ExifContent* content = exifData->ifd[ev.ifd()]; + exif_content_add_entry(content, entry); + kdDebug() << "Saving tag:" << it.key() << " " << ev.toString() << endl; + ExifTag tag = exif_tag_from_name( it.key().ascii()); + entry->components = ev.components(); + entry->format = type2format( ev.type()); + entry->tag = tag; +// exif_entry_dump(entry, 2); + ev.convertToData(&entry->data, &entry->size, bO); + } + } +} diff --git a/filters/krita/libkisexif/kis_exif_io.h b/filters/krita/libkisexif/kis_exif_io.h new file mode 100644 index 000000000..589288117 --- /dev/null +++ b/filters/krita/libkisexif/kis_exif_io.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_EXIF_IO_H +#define KIS_EXIF_IO_H + +extern "C" { +#include +} + +#include + +class KisExifIO { + public: + KisExifIO( KisExifInfo* ei); + public: + void readExifFromFile( const char* fileName ); + void readExifFromMem( const unsigned char* data , unsigned int size); + void saveExifToMem( unsigned char** data , unsigned int *size); + private: + void readExifData( ExifData* exifData ); + void writeExifData( ExifData* exifData ); + ExifFormat type2format( ExifValue::ExifType type); + ExifValue::ExifType format2type(ExifFormat format); + private: + KisExifInfo* m_exifInfo; +}; + +#endif diff --git a/filters/krita/magick/Makefile.am b/filters/krita/magick/Makefile.am new file mode 100644 index 000000000..f90c79e88 --- /dev/null +++ b/filters/krita/magick/Makefile.am @@ -0,0 +1,40 @@ +kde_module_LTLIBRARIES = libkritamagickimport.la libkritamagickexport.la + +libkritamagickexport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritamagickexport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +libkritamagickimport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritamagickimport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) $(LIBMAGICK_CPPFLAGS) \ + $(all_includes) + +service_DATA = krita_magick_import.desktop krita_magick_export.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_magick.desktop +kdelnkdir = $(kde_appsdir)/Office + +libkritamagickimport_la_SOURCES = magickimport.cpp kis_image_magick_converter.cc +libkritamagickexport_la_SOURCES = magickexport.cpp kis_image_magick_converter.cc + +METASOURCES = AUTO + + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) diff --git a/filters/krita/magick/configure.in.bot b/filters/krita/magick/configure.in.bot new file mode 100644 index 000000000..a5767def5 --- /dev/null +++ b/filters/krita/magick/configure.in.bot @@ -0,0 +1,15 @@ +# ImageMagick is deprecated, we don't care anymore if it's not here +# +#if test -z "$LIBMAGICK_LIBS"; then +# echo "" +# echo "You're missing ImageMagick (>=6.1.0). krita's ImageMagick import/export" +# echo "filter will not be compiled. You can download ImageMagick from" +# echo "http://www.imagemagick.org/. The ImageMagick filter allows krita to" +# echo "read and write XCF, PSD, GIF, BMP, and many other image formats." +# echo "" +# echo "If you have problems compiling ImageMagick, please try configuring it using" +# echo "the --without-magick-plus-plus flag, the C++ API isn't needed for krita." +# echo "" +# all_tests=bad +#fi + diff --git a/filters/krita/magick/kis_image_magick_converter.cc b/filters/krita/magick/kis_image_magick_converter.cc new file mode 100644 index 000000000..e54070370 --- /dev/null +++ b/filters/krita/magick/kis_image_magick_converter.cc @@ -0,0 +1,1087 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_undo_adapter.h" +#include "kis_image_magick_converter.h" +#include "kis_meta_registry.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_iterators_pixel.h" +#include "kis_colorspace.h" +#include "kis_profile.h" +#include "kis_annotation.h" +#include "kis_paint_layer.h" +#include "kis_group_layer.h" +#include "kis_paint_device.h" + +#include "../../../config.h" + +namespace { + + const Q_UINT8 PIXEL_BLUE = 0; + const Q_UINT8 PIXEL_GREEN = 1; + const Q_UINT8 PIXEL_RED = 2; + const Q_UINT8 PIXEL_ALPHA = 3; + + static const Q_UINT8 PIXEL_CYAN = 0; + static const Q_UINT8 PIXEL_MAGENTA = 1; + static const Q_UINT8 PIXEL_YELLOW = 2; + static const Q_UINT8 PIXEL_BLACK = 3; + static const Q_UINT8 PIXEL_CMYK_ALPHA = 4; + + static const Q_UINT8 PIXEL_GRAY = 0; + static const Q_UINT8 PIXEL_GRAY_ALPHA = 1; + + /** + * Make this more flexible -- although... ImageMagick + * isn't that flexible either. + */ + QString getColorSpaceName(ColorspaceType type, unsigned long imageDepth = 8) + { + + if (type == GRAYColorspace) { + if (imageDepth == 8) + return "GRAYA"; + else if ( imageDepth == 16 ) + return "GRAYA16" ; + } + else if (type == CMYKColorspace) { + if (imageDepth == 8) + return "CMYK"; + else if ( imageDepth == 16 ) { + return "CMYK16"; + } + } + else if (type == LABColorspace) { + kdDebug(41008) << "Lab!\n"; + return "LABA"; + } + else if (type == RGBColorspace || type == sRGBColorspace || type == TransparentColorspace) { + if (imageDepth == 8) + return "RGBA"; + else if (imageDepth == 16) + return "RGBA16"; + } + return ""; + + } + + ColorspaceType getColorTypeforColorSpace( KisColorSpace * cs ) + { + if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") ) return GRAYColorspace; + if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") ) return RGBColorspace; + if ( cs->id() == KisID("CMYK") || cs->id() == KisID("CMYK16") ) return CMYKColorspace; + if ( cs->id() == KisID("LABA") ) return LABColorspace; + + kdDebug(41008) << "Cannot export images in " + cs->id().name() + " yet.\n"; + return RGBColorspace; + + } + + KisProfile * getProfileForProfileInfo(const Image * image) + { +#ifndef HAVE_MAGICK6 + return 0; +#else + + if (image->profiles == NULL) + return 0; + + const char *name; + const StringInfo *profile; + + KisProfile * p = 0; + + ResetImageProfileIterator(image); + for (name = GetNextImageProfile(image); name != (char *) NULL; ) + { + profile = GetImageProfile(image, name); + if (profile == (StringInfo *) NULL) + continue; + + // XXX: Hardcoded for icc type -- is that correct for us? + if (QString::compare(name, "icc") == 0) { + QByteArray rawdata; + rawdata.resize(profile->length); + memcpy(rawdata.data(), profile->datum, profile->length); + + p = new KisProfile(rawdata); + if (p == 0) + return 0; + } + name = GetNextImageProfile(image); + } + return p; +#endif + } + + void setAnnotationsForImage(const Image * src, KisImageSP image) + { +#ifndef HAVE_MAGICK6 + return; +#else + if (src->profiles == NULL) + return; + + const char *name = 0; + const StringInfo *profile; + KisAnnotation* annotation = 0; + + // Profiles and so + ResetImageProfileIterator(src); + while((name = GetNextImageProfile(src))) { + profile = GetImageProfile(src, name); + if (profile == (StringInfo *) NULL) + continue; + + // XXX: icc will be written seperately? + if (QString::compare(name, "icc") == 0) + continue; + + QByteArray rawdata; + rawdata.resize(profile->length); + memcpy(rawdata.data(), profile->datum, profile->length); + + annotation = new KisAnnotation(QString(name), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); + } + + // Attributes, since we have no hint on if this is an attribute or a profile + // annotation, we prefix it with 'krita_attribute:'. XXX This needs to be rethought! + // The joys of imagemagick. From at version 6.2.1 (dfaure has 6.2.0 and confirms the + // old way of doing things) they changed the src -> attributes + // to void* and require us to use the iterator functions. So we #if around that, *sigh* +#if MagickLibVersion >= 0x621 + const ImageAttribute * attr; + ResetImageAttributeIterator(src); + while ( (attr = GetNextImageAttribute(src)) ) { +#else + ImageAttribute * attr = src -> attributes; + while (attr) { +#endif + QByteArray rawdata; + int len = strlen(attr -> value) + 1; + rawdata.resize(len); + memcpy(rawdata.data(), attr -> value, len); + + annotation = new KisAnnotation( + QString("krita_attribute:%1").arg(QString(attr -> key)), "", rawdata); + Q_CHECK_PTR(annotation); + + image -> addAnnotation(annotation); +#if MagickLibVersion < 0x620 + attr = attr -> next; +#endif + } + +#endif + } + } + + void exportAnnotationsForImage(Image * dst, vKisAnnotationSP_it& it, vKisAnnotationSP_it& annotationsEnd) + { +#ifndef HAVE_MAGICK6 + return; +#else + while(it != annotationsEnd) { + if (!(*it) || (*it) -> type() == QString()) { + kdDebug(41008) << "Warning: empty annotation" << endl; + ++it; + continue; + } + + kdDebug(41008) << "Trying to store annotation of type " << (*it) -> type() << " of size " << (*it) -> annotation() . size() << endl; + + if ((*it) -> type().startsWith("krita_attribute:")) { // Attribute + if (!SetImageAttribute(dst, + (*it) -> type().mid(strlen("krita_attribute:")).ascii(), + (*it) -> annotation() . data()) ) { + kdDebug(41008) << "Storing of attribute " << (*it) -> type() << "failed!\n"; + } + } else { // Profile + if (!ProfileImage(dst, (*it) -> type().ascii(), + (unsigned char*)(*it) -> annotation() . data(), + (*it) -> annotation() . size(), MagickFalse)) { + kdDebug(41008) << "Storing failed!" << endl; + } + } + ++it; + } +#endif + } + + + void InitGlobalMagick() + { + static bool init = false; + + if (!init) { + KApplication *app = KApplication::kApplication(); + + InitializeMagick(*app -> argv()); + atexit(DestroyMagick); + init = true; + } + } + + /* + * ImageMagick progress monitor callback. Unfortunately it doesn't support passing in some user + * data which complicates things quite a bit. The plan was to allow the user start multiple + * import/scans if he/she so wished. However, without passing user data it's not possible to tell + * on which task we have made progress on. + * + * Additionally, ImageMagick is thread-safe, not re-entrant... i.e. IM does not relinquish held + * locks when calling user defined callbacks, this means that the same thread going back into IM + * would deadlock since it would try to acquire locks it already holds. + */ +#ifdef HAVE_MAGICK6 + MagickBooleanType monitor(const char *text, const ExtendedSignedIntegralType, const ExtendedUnsignedIntegralType, ExceptionInfo *) + { + KApplication *app = KApplication::kApplication(); + + Q_ASSERT(app); + + if (app -> hasPendingEvents()) + app -> processEvents(); + + printf("%s\n", text); + return MagickTrue; + } +#else + unsigned int monitor(const char *text, const ExtendedSignedIntegralType, const ExtendedUnsignedIntegralType, ExceptionInfo *) + { + KApplication *app = KApplication::kApplication(); + + Q_ASSERT(app); + + if (app -> hasPendingEvents()) + app -> processEvents(); + + printf("%s\n", text); + return true; + } +#endif + + + +KisImageMagickConverter::KisImageMagickConverter(KisDoc *doc, KisUndoAdapter *adapter) +{ + InitGlobalMagick(); + init(doc, adapter); + SetMonitorHandler(monitor); + m_stop = false; +} + +KisImageMagickConverter::~KisImageMagickConverter() +{ +} + +KisImageBuilder_Result KisImageMagickConverter::decode(const KURL& uri, bool isBlob) +{ + Image *image; + Image *images; + ExceptionInfo ei; + ImageInfo *ii; + + if (m_stop) { + m_img = 0; + return KisImageBuilder_RESULT_INTR; + } + + GetExceptionInfo(&ei); + ii = CloneImageInfo(0); + + if (isBlob) { + + // TODO : Test. Does BlobToImage even work? + Q_ASSERT(uri.isEmpty()); + images = BlobToImage(ii, &m_data[0], m_data.size(), &ei); + } else { + + qstrncpy(ii -> filename, QFile::encodeName(uri.path()), MaxTextExtent - 1); + + if (ii -> filename[MaxTextExtent - 1]) { + emit notifyProgressError(); + return KisImageBuilder_RESULT_PATH; + } + + images = ReadImage(ii, &ei); + + } + + if (ei.severity != UndefinedException) + CatchException(&ei); + + if (images == 0) { + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + } + + emit notifyProgressStage(i18n("Importing..."), 0); + + m_img = 0; + + while ((image = RemoveFirstImageFromList(&images))) { + ViewInfo *vi = OpenCacheView(image); + + // Determine image depth -- for now, all channels of an imported image are of the same depth + unsigned long imageDepth = image->depth; + kdDebug(41008) << "Image depth: " << imageDepth << "\n"; + + QString csName; + KisColorSpace * cs = 0; + ColorspaceType colorspaceType; + + // Determine image type -- rgb, grayscale or cmyk + if (GetImageType(image, &ei) == GrayscaleType || GetImageType(image, &ei) == GrayscaleMatteType) { + if (imageDepth == 8) + csName = "GRAYA"; + else if ( imageDepth == 16 ) + csName = "GRAYA16" ; + colorspaceType = GRAYColorspace; + } + else { + colorspaceType = image->colorspace; + csName = getColorSpaceName(image -> colorspace, imageDepth); + } + + kdDebug(41008) << "image has " << csName << " colorspace\n"; + + KisProfile * profile = getProfileForProfileInfo(image); + if (profile) + { + kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n"; + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile); + } + else + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),""); + + if (!cs) { + kdDebug(41008) << "Krita does not support colorspace " << image -> colorspace << "\n"; + CloseCacheView(vi); + DestroyImage(image); + DestroyExceptionInfo(&ei); + DestroyImageList(images); + DestroyImageInfo(ii); + emit notifyProgressError(); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + + if( ! m_img) { + m_img = new KisImage(m_doc->undoAdapter(), image -> columns, image -> rows, cs, "built image"); + Q_CHECK_PTR(m_img); + m_img->blockSignals(true); // Don't send out signals while we're building the image + + // XXX I'm assuming seperate layers won't have other profile things like EXIF + setAnnotationsForImage(image, m_img); + } + + if (image -> columns && image -> rows) { + + // Opacity (set by the photoshop import filter) + Q_UINT8 opacity = OPACITY_OPAQUE; + const ImageAttribute * attr = GetImageAttribute(image, "[layer-opacity]"); + if (attr != 0) { + opacity = Q_UINT8_MAX - Downscale(QString(attr->value).toInt()); + } + + KisPaintLayerSP layer = 0; + + attr = GetImageAttribute(image, "[layer-name]"); + if (attr != 0) { + layer = new KisPaintLayer(m_img, attr->value, opacity); + } + else { + layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), opacity); + } + + Q_ASSERT(layer); + + // Layerlocation (set by the photoshop import filter) + Q_INT32 x_offset = 0; + Q_INT32 y_offset = 0; + + attr = GetImageAttribute(image, "[layer-xpos]"); + if (attr != 0) { + x_offset = QString(attr->value).toInt(); + } + + attr = GetImageAttribute(image, "[layer-ypos]"); + if (attr != 0) { + y_offset = QString(attr->value).toInt(); + } + + + for (Q_UINT32 y = 0; y < image->rows; y ++) + { + const PixelPacket *pp = AcquireCacheView(vi, 0, y, image->columns, 1, &ei); + + if(!pp) + { + CloseCacheView(vi); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + } + + IndexPacket * indexes = GetCacheViewIndexes(vi); + + KisHLineIteratorPixel hiter = layer->paintDevice()->createHLineIterator(0, y, image->columns, true); + + if (colorspaceType== CMYKColorspace) { + if (imageDepth == 8) { + int x = 0; + while (!hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + *(ptr++) = Downscale(pp->red); // cyan + *(ptr++) = Downscale(pp->green); // magenta + *(ptr++) = Downscale(pp->blue); // yellow + *(ptr++) = Downscale(indexes[x]); // Black +// XXX: Warning! This ifdef messes up the paren matching big-time! +#ifdef HAVE_MAGICK6 + if (image->matte != MagickFalse) { +#else + if (image->matte == true) { +#endif + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + } + else { + *(ptr++) = OPACITY_OPAQUE; + } + ++x; + pp++; + ++hiter; + } + } + } + else if (colorspaceType == LABColorspace) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + + *(ptr++) = ScaleQuantumToShort(pp->red); + *(ptr++) = ScaleQuantumToShort(pp->green); + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + else if (colorspaceType == RGBColorspace || + colorspaceType == sRGBColorspace || + colorspaceType == TransparentColorspace) + { + if (imageDepth == 8) { + while(! hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + // XXX: not colorstrategy and bitdepth independent + *(ptr++) = Downscale(pp->blue); + *(ptr++) = Downscale(pp->green); + *(ptr++) = Downscale(pp->red); + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + + pp++; + ++hiter; + } + } + else if (imageDepth == 16) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + // XXX: not colorstrategy independent + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = ScaleQuantumToShort(pp->green); + *(ptr++) = ScaleQuantumToShort(pp->red); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + } + else if ( colorspaceType == GRAYColorspace) { + if (imageDepth == 8) { + while(! hiter.isDone()) + { + Q_UINT8 *ptr= hiter.rawData(); + // XXX: not colorstrategy and bitdepth independent + *(ptr++) = Downscale(pp->blue); + *(ptr++) = OPACITY_OPAQUE - Downscale(pp->opacity); + + pp++; + ++hiter; + } + } + else if (imageDepth == 16) { + while(! hiter.isDone()) + { + Q_UINT16 *ptr = reinterpret_cast(hiter.rawData()); + // XXX: not colorstrategy independent + *(ptr++) = ScaleQuantumToShort(pp->blue); + *(ptr++) = 65535/*OPACITY_OPAQUE*/ - ScaleQuantumToShort(pp->opacity); + + pp++; + ++hiter; + } + } + } + + emit notifyProgress(y * 100 / image->rows); + + if (m_stop) { + CloseCacheView(vi); + DestroyImage(image); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + m_img = 0; + return KisImageBuilder_RESULT_INTR; + } + } + m_img->addLayer(layer.data(), m_img->rootLayer()); + layer->paintDevice()->move(x_offset, y_offset); + } + + emit notifyProgressDone(); + CloseCacheView(vi); + DestroyImage(image); + } + + emit notifyProgressDone(); + DestroyImageList(images); + DestroyImageInfo(ii); + DestroyExceptionInfo(&ei); + return KisImageBuilder_RESULT_OK; + } + + KisImageBuilder_Result KisImageMagickConverter::buildImage(const KURL& uri) + { + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) { + return KisImageBuilder_RESULT_NOT_EXIST; + } + + KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE; + QString tmpFile; + + if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) { + KURL uriTF; + uriTF.setPath( tmpFile ); + result = decode(uriTF, false); + KIO::NetAccess::removeTempFile(tmpFile); + } + + return result; + } + + + KisImageSP KisImageMagickConverter::image() + { + return m_img; + } + + void KisImageMagickConverter::init(KisDoc *doc, KisUndoAdapter *adapter) + { + m_doc = doc; + m_adapter = adapter; + m_job = 0; + } + + KisImageBuilder_Result KisImageMagickConverter::buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd) + { + Image *image; + ExceptionInfo ei; + ImageInfo *ii; + + if (!layer) + return KisImageBuilder_RESULT_INVALID_ARG; + + KisImageSP img = layer->image(); + if (!img) + return KisImageBuilder_RESULT_EMPTY; + + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!uri.isLocalFile()) + return KisImageBuilder_RESULT_NOT_LOCAL; + + + Q_UINT32 layerBytesPerChannel = layer->paintDevice()->pixelSize() / layer->paintDevice()->nChannels(); + + GetExceptionInfo(&ei); + + ii = CloneImageInfo(0); + + qstrncpy(ii -> filename, QFile::encodeName(uri.path()), MaxTextExtent - 1); + + if (ii -> filename[MaxTextExtent - 1]) { + emit notifyProgressError(); + return KisImageBuilder_RESULT_PATH; + } + + if (!img -> width() || !img -> height()) + return KisImageBuilder_RESULT_EMPTY; + + if (layerBytesPerChannel < 2) { + ii->depth = 8; + } + else { + ii->depth = 16; + } + + ii->colorspace = getColorTypeforColorSpace(layer->paintDevice()->colorSpace()); + + image = AllocateImage(ii); + SetImageColorspace(image, ii->colorspace); + image -> columns = img -> width(); + image -> rows = img -> height(); + + kdDebug(41008) << "Saving with colorspace " << image->colorspace << ", (" << layer->paintDevice()->colorSpace()->id().name() << ")\n"; + kdDebug(41008) << "IM Image thinks it has depth: " << image->depth << "\n"; + +#ifdef HAVE_MAGICK6 + // if ( layer-> hasAlpha() ) + image -> matte = MagickTrue; + // else + // image -> matte = MagickFalse; +#else + // image -> matte = layer -> hasAlpha(); + image -> matte = true; +#endif + + Q_INT32 y, height, width; + + height = img -> height(); + width = img -> width(); + + bool alpha = true; + QString ext = QFileInfo(QFile::encodeName(uri.path())).extension(false).upper(); + if (ext == "BMP") { + alpha = false; + qstrncpy(ii->magick, "BMP2", MaxTextExtent - 1); + } + else if (ext == "RGB") { + qstrncpy(ii->magick, "SGI", MaxTextExtent - 1); + } + + for (y = 0; y < height; y++) { + + // Allocate pixels for this scanline + PixelPacket * pp = SetImagePixels(image, 0, y, width, 1); + + if (!pp) { + DestroyExceptionInfo(&ei); + DestroyImage(image); + emit notifyProgressError(); + return KisImageBuilder_RESULT_FAILURE; + + } + + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false); + if (alpha) + SetImageType(image, TrueColorMatteType); + else + SetImageType(image, TrueColorType); + + if (image->colorspace== CMYKColorspace) { + + IndexPacket * indexes = GetIndexes(image); + int x = 0; + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_CYAN]); + pp -> green = ScaleShortToQuantum(d[PIXEL_MAGENTA]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_YELLOW]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_CMYK_ALPHA]); + indexes[x] = ScaleShortToQuantum(d[PIXEL_BLACK]); + x++; + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_CYAN]); + pp -> green = Upscale(d[PIXEL_MAGENTA]); + pp -> blue = Upscale(d[PIXEL_YELLOW]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_CMYK_ALPHA]); + + indexes[x]= Upscale(d[PIXEL_BLACK]); + + x++; + pp++; + ++it; + } + } + } + else if (image->colorspace== RGBColorspace || + image->colorspace == sRGBColorspace || + image->colorspace == TransparentColorspace) + { + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_RED]); + pp -> green = ScaleShortToQuantum(d[PIXEL_GREEN]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_BLUE]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_ALPHA]); + + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_RED]); + pp -> green = Upscale(d[PIXEL_GREEN]); + pp -> blue = Upscale(d[PIXEL_BLUE]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_ALPHA]); + + pp++; + ++it; + } + } + } + else if (image->colorspace == GRAYColorspace) + { + SetImageType(image, GrayscaleMatteType); + if (layerBytesPerChannel == 2) { + while (!it.isDone()) { + + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + pp -> red = ScaleShortToQuantum(d[PIXEL_GRAY]); + pp -> green = ScaleShortToQuantum(d[PIXEL_GRAY]); + pp -> blue = ScaleShortToQuantum(d[PIXEL_GRAY]); + if (alpha) + pp -> opacity = ScaleShortToQuantum(65535/*OPACITY_OPAQUE*/ - d[PIXEL_GRAY_ALPHA]); + + pp++; + ++it; + } + } + else { + while (!it.isDone()) { + Q_UINT8 * d = it.rawData(); + pp -> red = Upscale(d[PIXEL_GRAY]); + pp -> green = Upscale(d[PIXEL_GRAY]); + pp -> blue = Upscale(d[PIXEL_GRAY]); + if (alpha) + pp -> opacity = Upscale(OPACITY_OPAQUE - d[PIXEL_GRAY_ALPHA]); + + pp++; + ++it; + } + } + } + else { + kdDebug(41008) << "Unsupported image format\n"; + return KisImageBuilder_RESULT_INVALID_ARG; + } + + emit notifyProgressStage(i18n("Saving..."), y * 100 / height); + +#ifdef HAVE_MAGICK6 + if (SyncImagePixels(image) == MagickFalse) + kdDebug(41008) << "Syncing pixels failed\n"; +#else + if (!SyncImagePixels(image)) + kdDebug(41008) << "Syncing pixels failed\n"; +#endif + } + + // set the annotations + exportAnnotationsForImage(image, annotationsStart, annotationsEnd); + + // XXX: Write to a temp file, then have Krita use KIO to copy temp + // image to remote location. + + WriteImage(ii, image); + DestroyExceptionInfo(&ei); + DestroyImage(image); + emit notifyProgressDone(); + return KisImageBuilder_RESULT_OK; + } + + void KisImageMagickConverter::ioData(KIO::Job *job, const QByteArray& data) + { + if (data.isNull() || data.isEmpty()) { + emit notifyProgressStage(i18n("Loading..."), 0); + return; + } + + if (m_data.empty()) { + Image *image; + ImageInfo *ii; + ExceptionInfo ei; + + ii = CloneImageInfo(0); + GetExceptionInfo(&ei); + image = PingBlob(ii, data.data(), data.size(), &ei); + + if (image == 0 || ei.severity == BlobError) { + DestroyExceptionInfo(&ei); + DestroyImageInfo(ii); + job -> kill(); + emit notifyProgressError(); + return; + } + + DestroyImage(image); + DestroyExceptionInfo(&ei); + DestroyImageInfo(ii); + emit notifyProgressStage(i18n("Loading..."), 0); + } + + Q_ASSERT(data.size() + m_data.size() <= m_size); + memcpy(&m_data[m_data.size()], data.data(), data.count()); + m_data.resize(m_data.size() + data.count()); + emit notifyProgressStage(i18n("Loading..."), m_data.size() * 100 / m_size); + + if (m_stop) + job -> kill(); + } + + void KisImageMagickConverter::ioResult(KIO::Job *job) + { + m_job = 0; + + if (job -> error()) + emit notifyProgressError(); + + decode(KURL(), true); + } + + void KisImageMagickConverter::ioTotalSize(KIO::Job * /*job*/, KIO::filesize_t size) + { + m_size = size; + m_data.reserve(size); + emit notifyProgressStage(i18n("Loading..."), 0); + } + + void KisImageMagickConverter::cancel() + { + m_stop = true; + } + + /** + * @name readFilters + * @return Provide a list of file formats the application can read. + */ + QString KisImageMagickConverter::readFilters() + { + QString s; + QString all; + QString name; + QString description; + unsigned long matches; + +#ifdef HAVE_MAGICK6 +#ifdef HAVE_OLD_GETMAGICKINFOLIST + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches); +#else // HAVE_OLD_GETMAGICKINFOLIST + ExceptionInfo ei; + GetExceptionInfo(&ei); + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches, &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_OLD_GETMAGICKINFOLIST +#else // HAVE_MAGICK6 + const MagickInfo *mi; + ExceptionInfo ei; + GetExceptionInfo(&ei); + mi = GetMagickInfo("*", &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_MAGICK6 + + if (!mi) + return s; + +#ifdef HAVE_MAGICK6 + for (unsigned long i = 0; i < matches; i++) { + const MagickInfo *info = mi[i]; + if (info -> stealth) + continue; + + if (info -> decoder) { + name = info -> name; + description = info -> description; + kdDebug(41008) << "Found import filter for: " << name << "\n"; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#else + for (; mi; mi = reinterpret_cast(mi -> next)) { + if (mi -> stealth) + continue; + if (mi -> decoder) { + name = mi -> name; + description = mi -> description; + kdDebug(41008) << "Found import filter for: " << name << "\n"; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#endif + + all += "|" + i18n("All Images"); + all += "\n"; + + return all + s; + } + + QString KisImageMagickConverter::writeFilters() + { + QString s; + QString all; + QString name; + QString description; + unsigned long matches; + +#ifdef HAVE_MAGICK6 +#ifdef HAVE_OLD_GETMAGICKINFOLIST + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches); +#else // HAVE_OLD_GETMAGICKINFOLIST + ExceptionInfo ei; + GetExceptionInfo(&ei); + const MagickInfo **mi; + mi = GetMagickInfoList("*", &matches, &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_OLD_GETMAGICKINFOLIST +#else // HAVE_MAGICK6 + const MagickInfo *mi; + ExceptionInfo ei; + GetExceptionInfo(&ei); + mi = GetMagickInfo("*", &ei); + DestroyExceptionInfo(&ei); +#endif // HAVE_MAGICK6 + + if (!mi) { + kdDebug(41008) << "Eek, no magick info!\n"; + return s; + } + +#ifdef HAVE_MAGICK6 + for (unsigned long i = 0; i < matches; i++) { + const MagickInfo *info = mi[i]; + kdDebug(41008) << "Found export filter for: " << info -> name << "\n"; + if (info -> stealth) + continue; + + if (info -> encoder) { + name = info -> name; + + description = info -> description; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#else + for (; mi; mi = reinterpret_cast(mi -> next)) { + kdDebug(41008) << "Found export filter for: " << mi -> name << "\n"; + if (mi -> stealth) + continue; + + if (mi -> encoder) { + name = mi -> name; + + description = mi -> description; + + if (!description.isEmpty() && !description.contains('/')) { + all += "*." + name.lower() + " *." + name + " "; + s += "*." + name.lower() + " *." + name + "|"; + s += i18n(description.utf8()); + s += "\n"; + } + } + } +#endif + + + all += "|" + i18n("All Images"); + all += "\n"; + + return all + s; + } + +#include "kis_image_magick_converter.moc" + diff --git a/filters/krita/magick/kis_image_magick_converter.h b/filters/krita/magick/kis_image_magick_converter.h new file mode 100644 index 000000000..9b3b6bc09 --- /dev/null +++ b/filters/krita/magick/kis_image_magick_converter.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef KIS_IMAGE_MAGICK_CONVERTER_H_ +#define KIS_IMAGE_MAGICK_CONVERTER_H_ + +#include +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_progress_subject.h" + +class QString; +class KURL; +class KisDoc; +class KisNameServer; +class KisUndoAdapter; +/** + * Image import/export plugins can use these results to report about success or failure. + */ +enum KisImageBuilder_Result { + KisImageBuilder_RESULT_FAILURE = -400, + KisImageBuilder_RESULT_NOT_EXIST = -300, + KisImageBuilder_RESULT_NOT_LOCAL = -200, + KisImageBuilder_RESULT_BAD_FETCH = -100, + KisImageBuilder_RESULT_INVALID_ARG = -50, + KisImageBuilder_RESULT_OK = 0, + KisImageBuilder_RESULT_PROGRESS = 1, + KisImageBuilder_RESULT_EMPTY = 100, + KisImageBuilder_RESULT_BUSY = 150, + KisImageBuilder_RESULT_NO_URI = 200, + KisImageBuilder_RESULT_UNSUPPORTED = 300, + KisImageBuilder_RESULT_INTR = 400, + KisImageBuilder_RESULT_PATH = 500, + KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE = 600 +}; + + + +/** + * Build a KisImage representation of an image file. + */ +class KisImageMagickConverter : public KisProgressSubject { + typedef QObject super; + Q_OBJECT + +public: + KisImageMagickConverter(KisDoc *doc, KisUndoAdapter *adapter); + virtual ~KisImageMagickConverter(); + +public slots: + virtual void cancel(); + +public: + KisImageBuilder_Result buildImage(const KURL& uri); + KisImageBuilder_Result buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd); + KisImageSP image(); + +public: + static QString readFilters(); + static QString writeFilters(); + +private slots: + void ioData(KIO::Job *job, const QByteArray& data); + void ioResult(KIO::Job *job); + void ioTotalSize(KIO::Job *job, KIO::filesize_t size); + +private: + KisImageMagickConverter(const KisImageMagickConverter&); + KisImageMagickConverter& operator=(const KisImageMagickConverter&); + void init(KisDoc *doc, KisUndoAdapter *adapter); + KisImageBuilder_Result decode(const KURL& uri, bool isBlob); + +private: + KisImageSP m_img; + KisDoc *m_doc; + KisUndoAdapter *m_adapter; + QValueVector m_data; + KIO::TransferJob *m_job; + KIO::filesize_t m_size; + bool m_stop; +}; + +#endif // KIS_IMAGE_MAGICK_CONVERTER_H_ + diff --git a/filters/krita/magick/krita_magick.desktop b/filters/krita/magick/krita_magick.desktop new file mode 100644 index 000000000..eed0aa2d1 --- /dev/null +++ b/filters/krita/magick/krita_magick.desktop @@ -0,0 +1,58 @@ +[Desktop Entry] +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +MimeType=image/x-xcf-gimp;image/gif;image/cgm;image/x-bmp;image/x-ico;image/x-pcx;image/x-portable-pixmap;image/x-targa;image/x-xbm;image/x-xcf;image/x-xpm;image/x-vnd.adobe.photoshop;image/x-rgb +Type=Application +Icon=krita +Categories=Qt;KDE;Office;Graphics; +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi +NoDisplay=true diff --git a/filters/krita/magick/krita_magick_export.desktop b/filters/krita/magick/krita_magick_export.desktop new file mode 100644 index 000000000..7df00026c --- /dev/null +++ b/filters/krita/magick/krita_magick_export.desktop @@ -0,0 +1,55 @@ +[Desktop Entry] +Name=Krita Magick Export Filter +Name[bg]=Филтър за експортиране от Krita в Magick +Name[br]=Sil ezporzh Magick evit Krita +Name[ca]=Filtre d'exportació Magick per a Krita +Name[cy]=Hidl Allforio Magick Krita +Name[da]=Krita Magick-eksportfilter +Name[de]=Krita Magick-Exportfilter +Name[el]=Φίλτρο εξαγωγής Magick του Krita +Name[eo]=Krita Magick-eksportfiltrilo +Name[es]=Filtro de exportación a Magick de Krita +Name[et]=Krita Magick'i ekspordifilter +Name[eu]=Krita-ren Magick esportaziorako iragazkia +Name[fa]=پالایۀ صادرات Krita Magick +Name[fi]=Krita Magick -vientisuodin +Name[fr]=Filtre d'exportation Magick de Krita +Name[fy]=Krita Magick Eksportfilter +Name[ga]=Scagaire Easpórtála Magick Krita +Name[gl]=Filtro de Exportación de Magick para Krita +Name[he]=מסנן יצוא מ־Krita ל־Magick +Name[hr]=Krita Magick filtar izvoza +Name[hu]=Krita Magick exportszűrő +Name[is]=Krita Magick útflutningssía +Name[it]=Filtro di esportazione Magick per Krita +Name[ja]=Krita Magick エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ Magick សម្រាប់ Krita +Name[lt]=Krita Magick eksportavimo filtras +Name[lv]=Krita Magick eksporta filtrs +Name[ms]=Penapis Eksport Krita Magick +Name[nb]=Magick-eksportfilter for Krita +Name[nds]=Magick-Exportfilter för Krita +Name[ne]=क्रिता म्याजिक निर्यात फिल्टर +Name[nl]=Krita Magick Exportfilter +Name[nn]=Magick-eksportfilter for Krita +Name[pl]=Filtr eksportu do formatu Magick z Krita +Name[pt]=Filtro de Exportação de Magick para o Krita +Name[pt_BR]=Filtro de exportação Magick para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в Magick +Name[se]=Krita Magick-olggosfievrridansilli +Name[sk]=Magick filter pre export do Krita +Name[sl]=Izvozni filter Magick za Krito +Name[sr]=Krita-ин филтер за извоз у Magick +Name[sr@Latn]=Krita-in filter za izvoz u Magick +Name[sv]=Krita Magick-exportfilter +Name[uk]=Фільтр експорту Magick для Krita +Name[uz]=Krita Magick eksport filteri +Name[uz@cyrillic]=Krita Magick экспорт филтери +Name[zh_CN]=Krita Magick 导出过滤器 +Name[zh_TW]=Krita Magick 匯出過濾程式 +X-KDE-Export=image/gif,image/cgm,image/x-ico,image/x-pcx,image/x-portable-pixmap,image/x-targa,image/x-xbm,image/x-xpm,image/x-rgb,image/x-eps +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Import=application/x-krita +X-KDE-Weight=1 +X-KDE-Library=libkritamagickexport diff --git a/filters/krita/magick/krita_magick_import.desktop b/filters/krita/magick/krita_magick_import.desktop new file mode 100644 index 000000000..702d67f7f --- /dev/null +++ b/filters/krita/magick/krita_magick_import.desktop @@ -0,0 +1,61 @@ +[Desktop Entry] +Type=Service +Name=Krita Magick Import Filter +Name[bg]=Филтър за импортиране от Magick в Krita +Name[br]=Sil enporzh Magick evit Krita +Name[ca]=Filtre d'importació Magick per a Krita +Name[cs]=Importní filtr formátu Magick pro Kritu +Name[cy]=Hidl Mewnforio Krita Magick +Name[da]=Krita Magick-importfilter +Name[de]=Krita Magick-Importfilter +Name[el]=Φίλτρο εισαγωγής Magick του Krita +Name[eo]=Krita Magick-importfiltrilo +Name[es]=Filtro de importación a Magick de Krita +Name[et]=Krita Magick'i impordifilter +Name[eu]=Krita-ren Magick inportaziorako iragazkia +Name[fa]=پالایۀ واردات Krita Magick +Name[fi]=Krita Magick-tuontisuodin +Name[fr]=Filtre d'importation Magick de Krita +Name[fy]=Krita Magick Ymportfilter +Name[ga]=Scagaire Iompórtála Magick Krita +Name[gl]=Filtro de Importación de Magick para Krita +Name[he]=מסנן יבוא מ־Magick ל־Krita +Name[hi]=के-रीता मैजिक आयात फ़िल्टर +Name[hr]=Krita Magick filtar uvoza +Name[hu]=Krita Magick importszűrő +Name[is]=Krita Magick innflutningssía +Name[it]=Filtro di importazione Magick per Krita +Name[ja]=Krita Magick インポートフィルタ +Name[km]=តម្រង​នាំចូល Magick សម្រាប់ Krita +Name[lo]= ຕົວຕອງການນຳເຂົ້າ WML ຂອງເອກະສານຂໍ້ຄວາມ K +Name[lt]=Krita Magick importavimo filtras +Name[lv]=Krita Magick importa filtrs +Name[ms]=Penapis Import Krita Magick +Name[nb]=Magick-importfilter for Krita +Name[nds]=Magick-Importfilter för Krita +Name[ne]=क्रिता म्याजिक आयात फिल्टर +Name[nl]=Krita Magick Importfilter +Name[nn]=Magick-importfilter for Krita +Name[pl]=Filtr importu formatu Magick do Krita +Name[pt]=Filtro de Importação de Magick para o Krita +Name[pt_BR]=Filtro de importação Magick para o Krita +Name[ru]=Фильтр импорта рисунков Magick в Krita +Name[se]=Krita Magick-sisafievrridansilli +Name[sk]=Magick filter pre import do Krita +Name[sl]=Uvozni filter Magick za Krito +Name[sr]=Krita-ин филтер за увоз из Magick-а +Name[sr@Latn]=Krita-in filter za uvoz iz Magick-a +Name[sv]=Krita Magick-importfilter +Name[ta]=Krita மாயk இறக்குமதி வடிகட்டி +Name[tg]=Филтри Воридоти Krita Magick +Name[tr]=Krita Magick Alma Filtresi +Name[uk]=Фільтр імпорту Magick для Krita +Name[uz]=Krita Magick import filteri +Name[uz@cyrillic]=Krita Magick импорт филтери +Name[zh_CN]=Krita Magick 导入过滤器 +Name[zh_TW]=Krita Magick 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-xcf-gimp,image/gif,image/cgm,image/x-bmp,image/x-ico,image/x-pcx,image/x-portable-pixmap,image/x-targa,image/x-xbm,image/x-xcf,image/x-xpm,image/x-vnd.adobe.photoshop,image/x-rgb,image/x-eps +X-KDE-Weight=1 +X-KDE-Library=libkritamagickimport +ServiceTypes=KOfficeFilter diff --git a/filters/krita/magick/magickexport.cpp b/filters/krita/magick/magickexport.cpp new file mode 100644 index 000000000..301135034 --- /dev/null +++ b/filters/krita/magick/magickexport.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MagickExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritamagickexport, MagickExportFactory("kofficefilters")) + +MagickExport::MagickExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +MagickExport::~MagickExport() +{ +} + +KoFilter::ConversionStatus MagickExport::convert(const QCString& from, const QCString& to) +{ + kdDebug(41008) << "magick export! From: " << from << ", To: " << to << "\n"; + + if (from != "application/x-krita") + return KoFilter::NotImplemented; + + // XXX: Add dialog about flattening layers here + + KisDoc *output = dynamic_cast(m_chain->inputDocument()); + QString filename = m_chain->outputFile(); + + if (!output) + return KoFilter::CreationError; + + if (filename.isEmpty()) return KoFilter::FileNotFound; + + KURL url; + url.setPath(filename); + + KisImageSP img = output->currentImage(); + + KisImageMagickConverter ib(output, output->undoAdapter()); + + KisPaintDeviceSP pd = new KisPaintDevice(*img->projection()); + KisPaintLayerSP l = new KisPaintLayer(img, "projection", OPACITY_OPAQUE, pd); + + vKisAnnotationSP_it beginIt = img->beginAnnotations(); + vKisAnnotationSP_it endIt = img->endAnnotations(); + if (ib.buildFile(url, l, beginIt, endIt) == KisImageBuilder_RESULT_OK) { + return KoFilter::OK; + } + return KoFilter::InternalError; +} + +#include + diff --git a/filters/krita/magick/magickexport.h b/filters/krita/magick/magickexport.h new file mode 100644 index 000000000..3c499ebda --- /dev/null +++ b/filters/krita/magick/magickexport.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef MAGICKEXPORT_H_ +#define MAGICKEXPORT_H_ + +#include + +class MagickExport : public KoFilter { + Q_OBJECT + +public: + MagickExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MagickExport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // MAGICKEXPORT_H_ + diff --git a/filters/krita/magick/magickimport.cpp b/filters/krita/magick/magickimport.cpp new file mode 100644 index 000000000..331777239 --- /dev/null +++ b/filters/krita/magick/magickimport.cpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +typedef KGenericFactory MagickImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritamagickimport, MagickImportFactory("kofficefilters")) + +MagickImport::MagickImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +MagickImport::~MagickImport() +{ +} + +KoFilter::ConversionStatus MagickImport::convert(const QCString&, const QCString& to) +{ + kdDebug(41008) << "Importing using MagickImport!\n"; + + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + KisView * view = static_cast(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc -> prepareForImport(); + + + if (!filename.isEmpty()) { + + KURL url; + url.setPath(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisImageMagickConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + +#include + diff --git a/filters/krita/magick/magickimport.h b/filters/krita/magick/magickimport.h new file mode 100644 index 000000000..011566429 --- /dev/null +++ b/filters/krita/magick/magickimport.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2002 Patrick Julien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef MAGICKIMPORT_H_ +#define MAGICKIMPORT_H_ + +#include + +class MagickImport : public KoFilter { + Q_OBJECT + +public: + MagickImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~MagickImport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // MAGICKIMPORT_H_ + diff --git a/filters/krita/openexr/Makefile.am b/filters/krita/openexr/Makefile.am new file mode 100644 index 000000000..ffdce031a --- /dev/null +++ b/filters/krita/openexr/Makefile.am @@ -0,0 +1,48 @@ +AM_CPPFLAGS= \ + -I$(srcdir) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + -I$(top_srcdir)/krita/colorspaces/rgb_f32 \ + -I$(top_srcdir)/krita/colorspaces/rgb_f16half \ + $(KOFFICE_INCLUDES) \ + -I$(interfacedir) \ + $(OPENEXR_CFLAGS) \ + $(all_includes) + +kde_module_LTLIBRARIES = libkrita_openexr_import.la libkrita_openexr_export.la + +libkrita_openexr_export_la_LDFLAGS = $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkrita_openexr_export_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(OPENEXR_LIBS) \ + $(top_builddir)/krita/libkritacommon.la \ + $(top_builddir)/krita/colorspaces/rgb_f32/libkrita_rgb_f32.la \ + $(top_builddir)/krita/colorspaces/rgb_f16half/libkrita_rgb_f16half.la + + +libkrita_openexr_import_la_LDFLAGS = $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkrita_openexr_import_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(OPENEXR_LIBS) \ + $(top_builddir)/krita/libkritacommon.la \ + $(top_builddir)/krita/colorspaces/rgb_f32/libkrita_rgb_f32.la \ + $(top_builddir)/krita/colorspaces/rgb_f16half/libkrita_rgb_f16half.la + + +service_DATA = krita_openexr_import.desktop krita_openexr_export.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_openexr.desktop +kdelnkdir = $(kde_appsdir)/.hidden + +libkrita_openexr_import_la_SOURCES = kis_openexr_import.cpp +libkrita_openexr_export_la_SOURCES = kis_openexr_export.cpp + +METASOURCES = AUTO + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + diff --git a/filters/krita/openexr/configure.in.bot b/filters/krita/openexr/configure.in.bot new file mode 100644 index 000000000..cc420abb3 --- /dev/null +++ b/filters/krita/openexr/configure.in.bot @@ -0,0 +1,9 @@ +if test -z "$OPENEXR_LIBS"; then + echo "" + echo "You're missing the OpenEXR library. Krita's OpenEXR import/export filter will " + echo "not be compiled. You can download OpenEXR from http://www.openexr.com or " + echo "install it from an appropriate binary package." + echo "" + all_tests=bad +fi + diff --git a/filters/krita/openexr/kis_openexr_export.cpp b/filters/krita/openexr/kis_openexr_export.cpp new file mode 100644 index 000000000..724d07d0c --- /dev/null +++ b/filters/krita/openexr/kis_openexr_export.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include + +#include + +#include +#include + +#include +#include +#include + +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_annotation.h" +#include "kis_types.h" +#include "kis_iterators_pixel.h" +#include "kis_abstract_colorspace.h" +#include "kis_paint_device.h" +#include "kis_rgb_f32_colorspace.h" +#include "kis_rgb_f16half_colorspace.h" + +#include "kis_openexr_export.h" + +using namespace std; +using namespace Imf; +using namespace Imath; + +typedef KGenericFactory KisOpenEXRExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkrita_openexr_export, KisOpenEXRExportFactory("kofficefilters")) + +KisOpenEXRExport::KisOpenEXRExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisOpenEXRExport::~KisOpenEXRExport() +{ +} + +KoFilter::ConversionStatus KisOpenEXRExport::convert(const QCString& from, const QCString& to) +{ + if (to != "image/x-exr" || from != "application/x-krita") { + return KoFilter::NotImplemented; + } + + kdDebug(41008) << "Krita exporting to OpenEXR\n"; + + // XXX: Add dialog about flattening layers here + + KisDoc *doc = dynamic_cast(m_chain -> inputDocument()); + QString filename = m_chain -> outputFile(); + + if (!doc) { + return KoFilter::CreationError; + } + + if (filename.isEmpty()) { + return KoFilter::FileNotFound; + } + + KisImageSP img = new KisImage(*doc -> currentImage()); + Q_CHECK_PTR(img); + + // Don't store this information in the document's undo adapter + bool undo = doc -> undoAdapter() -> undo(); + doc -> undoAdapter() -> setUndo(false); + + img -> flatten(); + + KisPaintLayerSP layer = dynamic_cast(img->activeLayer().data()); + Q_ASSERT(layer); + + doc -> undoAdapter() -> setUndo(undo); + + //KisF32RgbColorSpace * cs = static_cast((KisColorSpaceRegistry::instance() -> get(KisID("RGBAF32", "")))); + KisRgbF16HalfColorSpace *cs = dynamic_cast(layer->paintDevice()->colorSpace()); + + if (cs == 0) { + // We could convert automatically, but the conversion wants to be done with + // selectable profiles and rendering intent. + KMessageBox::information(0, i18n("The image is using an unsupported color space. " + "Please convert to 16-bit floating point RGB/Alpha " + "before saving in the OpenEXR format.")); + + // Don't show the couldn't save error dialog. + doc -> setErrorMessage("USER_CANCELED"); + + return KoFilter::WrongFormat; + } + + Box2i displayWindow(V2i(0, 0), V2i(img -> width() - 1, img -> height() - 1)); + + QRect dataExtent = layer -> exactBounds(); + int dataWidth = dataExtent.width(); + int dataHeight = dataExtent.height(); + + Box2i dataWindow(V2i(dataExtent.left(), dataExtent.top()), V2i(dataExtent.right(), dataExtent.bottom())); + + RgbaOutputFile file(QFile::encodeName(filename), displayWindow, dataWindow, WRITE_RGBA); + + QMemArray pixels(dataWidth); + + for (int y = 0; y < dataHeight; ++y) { + + file.setFrameBuffer(pixels.data() - dataWindow.min.x - (dataWindow.min.y + y) * dataWidth, 1, dataWidth); + + KisHLineIterator it = layer->paintDevice()->createHLineIterator(dataWindow.min.x, dataWindow.min.y + y, dataWidth, false); + Rgba *rgba = pixels.data(); + + while (!it.isDone()) { + + // XXX: Currently we use unmultiplied data so premult it. + half unmultipliedRed; + half unmultipliedGreen; + half unmultipliedBlue; + half alpha; + + cs -> getPixel(it.rawData(), &unmultipliedRed, &unmultipliedGreen, &unmultipliedBlue, &alpha); + rgba -> r = unmultipliedRed * alpha; + rgba -> g = unmultipliedGreen * alpha; + rgba -> b = unmultipliedBlue * alpha; + rgba -> a = alpha; + ++it; + ++rgba; + } + file.writePixels(); + } + + //vKisAnnotationSP_it beginIt = img -> beginAnnotations(); + //vKisAnnotationSP_it endIt = img -> endAnnotations(); + return KoFilter::OK; +} + +#include "kis_openexr_export.moc" + diff --git a/filters/krita/openexr/kis_openexr_export.h b/filters/krita/openexr/kis_openexr_export.h new file mode 100644 index 000000000..059a799d8 --- /dev/null +++ b/filters/krita/openexr/kis_openexr_export.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_OPENEXR_EXPORT_H_ +#define KIS_OPENEXR_EXPORT_H_ + +#include + +class KisOpenEXRExport : public KoFilter { + Q_OBJECT + +public: + KisOpenEXRExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisOpenEXRExport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // KIS_OPENEXR_EXPORT_H_ + diff --git a/filters/krita/openexr/kis_openexr_import.cpp b/filters/krita/openexr/kis_openexr_import.cpp new file mode 100644 index 000000000..c2db3385a --- /dev/null +++ b/filters/krita/openexr/kis_openexr_import.cpp @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include +#include + +#include +#include +#include + +#include +#include +//#include +//#include +//#include +//#include + +#include + +#include "kis_types.h" +#include "kis_openexr_import.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_meta_registry.h" +#include "kis_layer.h" +#include "kis_paint_layer.h" +#include "kis_annotation.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_iterators_pixel.h" +#include "kis_abstract_colorspace.h" +#include "kis_rgb_f32_colorspace.h" +#include "kis_rgb_f16half_colorspace.h" + +using namespace std; +using namespace Imf; +using namespace Imath; + +typedef KGenericFactory KisOpenEXRImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkrita_openexr_import, KisOpenEXRImportFactory("kofficefilters")) + +KisOpenEXRImport::KisOpenEXRImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisOpenEXRImport::~KisOpenEXRImport() +{ +} + +KoFilter::ConversionStatus KisOpenEXRImport::convert(const QCString& from, const QCString& to) +{ + if (from != "image/x-exr" || to != "application/x-krita") { + return KoFilter::NotImplemented; + } + + kdDebug(41008) << "\n\n\nKrita importing from OpenEXR\n"; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + if (!doc) { + return KoFilter::CreationError; + } + + doc -> prepareForImport(); + + QString filename = m_chain -> inputFile(); + + if (filename.isEmpty()) { + return KoFilter::FileNotFound; + } + + RgbaInputFile file(QFile::encodeName(filename)); + Box2i dataWindow = file.dataWindow(); + Box2i displayWindow = file.displayWindow(); + + kdDebug(41008) << "Data window: " << QRect(dataWindow.min.x, dataWindow.min.y, dataWindow.max.x - dataWindow.min.x + 1, dataWindow.max.y - dataWindow.min.y + 1) << endl; + kdDebug(41008) << "Display window: " << QRect(displayWindow.min.x, displayWindow.min.y, displayWindow.max.x - displayWindow.min.x + 1, displayWindow.max.y - displayWindow.min.y + 1) << endl; + + int imageWidth = displayWindow.max.x - displayWindow.min.x + 1; + int imageHeight = displayWindow.max.y - displayWindow.min.y + 1; + + QString imageName = "Imported from OpenEXR"; + + int dataWidth = dataWindow.max.x - dataWindow.min.x + 1; + int dataHeight = dataWindow.max.y - dataWindow.min.y + 1; + + KisRgbF16HalfColorSpace *cs = static_cast((KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBAF16HALF", ""),""))); + + if (cs == 0) { + return KoFilter::InternalError; + } + + doc -> undoAdapter() -> setUndo(false); + + KisImageSP image = new KisImage(doc->undoAdapter(), imageWidth, imageHeight, cs, imageName); + + if (image == 0) { + return KoFilter::CreationError; + } + + KisPaintLayerSP layer = dynamic_cast(image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data()); + + if (layer == 0) { + return KoFilter::CreationError; + } + + QMemArray pixels(dataWidth); + + for (int y = 0; y < dataHeight; ++y) { + + file.setFrameBuffer(pixels.data() - dataWindow.min.x - (dataWindow.min.y + y) * dataWidth, 1, dataWidth); + file.readPixels(dataWindow.min.y + y); + + KisHLineIterator it = layer->paintDevice()->createHLineIterator(dataWindow.min.x, dataWindow.min.y + y, dataWidth, true); + Rgba *rgba = pixels.data(); + + while (!it.isDone()) { + + // XXX: For now unmultiply the alpha, though compositing will be faster if we + // keep it premultiplied. + half unmultipliedRed = rgba -> r; + half unmultipliedGreen = rgba -> g; + half unmultipliedBlue = rgba -> b; + + if (rgba -> a >= HALF_EPSILON) { + unmultipliedRed /= rgba -> a; + unmultipliedGreen /= rgba -> a; + unmultipliedBlue /= rgba -> a; + } + + cs -> setPixel(it.rawData(), unmultipliedRed, unmultipliedGreen, unmultipliedBlue, rgba -> a); + ++it; + ++rgba; + } + } + + layer->setDirty(); + doc -> setCurrentImage(image); + doc -> undoAdapter() -> setUndo(true); + doc -> setModified(false); + + return KoFilter::OK; +} + +#include "kis_openexr_import.moc" + diff --git a/filters/krita/openexr/kis_openexr_import.h b/filters/krita/openexr/kis_openexr_import.h new file mode 100644 index 000000000..98858537d --- /dev/null +++ b/filters/krita/openexr/kis_openexr_import.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2005 Adrian Page + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_OPENEXR_IMPORT_H_ +#define KIS_OPENEXR_IMPORT_H_ + +#include + +class KisOpenEXRImport : public KoFilter { + Q_OBJECT + +public: + KisOpenEXRImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisOpenEXRImport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif // KIS_OPENEXR_IMPORT_H_ + diff --git a/filters/krita/openexr/krita_openexr.desktop b/filters/krita/openexr/krita_openexr.desktop new file mode 100644 index 000000000..ef026a84d --- /dev/null +++ b/filters/krita/openexr/krita_openexr.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +MimeType=image/x-exr +Type=Application +Icon=krita +Categories= +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi diff --git a/filters/krita/openexr/krita_openexr_export.desktop b/filters/krita/openexr/krita_openexr_export.desktop new file mode 100644 index 000000000..3e2a8d7f1 --- /dev/null +++ b/filters/krita/openexr/krita_openexr_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Name=Krita OpenEXR Export Filter +Name[bg]=Филтър за експортиране от Krita в OpenEXR +Name[br]=Sil ezporzh OpenEXR evit Krita +Name[ca]=Filtre d'exportació OpenEXR per a Krita +Name[cy]=Hidl Allforio OpenEXR Krita +Name[da]=Krita OpenEXR-eksportfilter +Name[de]=Krita OpenEXR-Exportfilter +Name[el]=Φίλτρο εξαγωγής OpenEXR του Krita +Name[eo]=Krita OpenEXR-eksportfiltrilo +Name[es]=Filtro de exportación a OpenEXR de Krita +Name[et]=Krita OpenEXR'i ekspordifilter +Name[fa]=پالایۀ صادرات Krita OpenEXR +Name[fi]=Krita OpenEXR -vientisuodin +Name[fr]=Filtre d'exportation OpenEXR de Krita +Name[fy]=Krita OpenEXR Eksportfilter +Name[ga]=Scagaire Easpórtála OpenEXR Krita +Name[gl]=Filtro de Exportación de OpenEXR de Krita +Name[he]=Krita OpenEXR מסנן יצוא +Name[hr]=Krita OpenEXR filtar izvoza +Name[hu]=Krita OpenEXR exportszűrő +Name[is]=Krita OpenEXR útflutningssía +Name[it]=Filtro di esportazione OpenEXR per Krita +Name[ja]=Krita OpenEXR エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ OpenEXR សម្រាប់ Krita +Name[lt]=Krita OpenEXR eksportavimo filtras +Name[lv]=Krita OpenEXR eksporta filtrs +Name[nb]=OpenEXR-eksportfilter for Krita +Name[nds]=OpenEXR-Exportfilter för Krita +Name[ne]=क्रिता खुलाEXR निर्यात फिल्टर +Name[nl]=Krita OpenEXR Exportfilter +Name[pl]=Filtr eksportu do formatu OpenEXR z Krita +Name[pt]=Filtro de Exportação de OpenEXR do Krita +Name[pt_BR]=Filtro de Exportação de OpenEXR do Krita +Name[ru]=Фильтр экспорта рисунков Krita в OpenEXR +Name[se]=Krita OpenEXR-olggosfievrridansilli +Name[sk]=Exportný filter Krita OpenEXR +Name[sl]=Izvozni filter OpenEXR za Krito +Name[sr]=Krita-ин филтер за извоз у OpenEXR +Name[sr@Latn]=Krita-in filter za izvoz u OpenEXR +Name[sv]=Krita OpenEXR-exportfilter +Name[uk]=Фільтр експорту OpenEXR для Krita +Name[uz]=Krita OpenEXR eksport filteri +Name[uz@cyrillic]=Krita OpenEXR экспорт филтери +Name[zh_CN]=Krita OpenEXR 导出过滤器 +Name[zh_TW]=Krita OpenEXR 匯出過濾程式 +X-KDE-Export=image/x-exr +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Import=application/x-krita +X-KDE-Weight=1 +X-KDE-Library=libkrita_openexr_export diff --git a/filters/krita/openexr/krita_openexr_import.desktop b/filters/krita/openexr/krita_openexr_import.desktop new file mode 100644 index 000000000..521320deb --- /dev/null +++ b/filters/krita/openexr/krita_openexr_import.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=Krita OpenEXR Import Filter +Name[bg]=Филтър за импортиране от OpenEXR в Krita +Name[br]=Sil enporzh OpenEXR evit Krita +Name[ca]=Filtre d'importació OpenEXR per a Krita +Name[cy]=Hidl Mewnforio OpenEXR Krita +Name[da]=Krita OpenEXR-importfilter +Name[de]=Krita OpenEXR-Importfilter +Name[el]=Φίλτρο εισαγωγής OpenEXR του Krita +Name[eo]=Krita OpenEXR-importfiltrilo +Name[es]=Filtro de importación a OpenEXR de Krita +Name[et]=Krita OpenEXR'i impordifilter +Name[fa]=پالایۀ واردات Krita OpenEXR +Name[fi]=Krita OpenEXR -tuontisuodin +Name[fr]=Filtre d'importation OpenEXT de Krita +Name[fy]=Krita OpenEXR Ymportfilter +Name[ga]=Scagaire Iompórtála OpenEXR Krita +Name[gl]=Filtro de Importación de OpenEXR para Krita +Name[he]=Krita OpenEXR מסנן יבוא +Name[hr]=Krita OpenEXR filtar uvoza +Name[hu]=Krita OpenEXR importszűrő +Name[is]=Krita OpenEXR innflutningssía +Name[it]=Filtro di importazione OpenEXR per Krita +Name[ja]=Krita OpenEXR インポートフィルタ +Name[km]=តម្រង​នាំចូល OpenEXR សម្រាប់ Krita +Name[lt]=Krita OpenEXR importavimo filtras +Name[lv]=Krita OpenEXR importa filtrs +Name[nb]=OpenEXR-importfilter for Krita +Name[nds]=OpenEXR-Importfilter för Krita +Name[ne]=क्रिता खुलाEXR आयात फिल्टर +Name[nl]=Krita OpenEXR Importfilter +Name[pl]=Filtr importu formatu OpenEXR do Krita +Name[pt]=Filtro de Importação de OpenEXR para o Krita +Name[pt_BR]=Filtro de Importação de OpenEXR para o Krita +Name[ru]=Фильтр импорта рисунков OpenEXR в Krita +Name[se]=Krita OpenEXR-sisafievrridansilli +Name[sk]=OpenEXR filter pre import do Krita +Name[sl]=Uvozni filter OpenEXR za Krito +Name[sr]=Krita-ин филтер за увоз из OpenEXR-а +Name[sr@Latn]=Krita-in filter za uvoz iz OpenEXR-a +Name[sv]=Krita OpenEXR-importfilter +Name[uk]=Фільтр імпорту OpenEXR для Krita +Name[uz]=Krita OpenEXR import filteri +Name[uz@cyrillic]=Krita OpenEXR импорт филтери +Name[zh_CN]=Krita OpenEXR 导入过滤器 +Name[zh_TW]=Krita OpenEXR 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-exr +X-KDE-Weight=1 +X-KDE-Library=libkrita_openexr_import +ServiceTypes=KOfficeFilter diff --git a/filters/krita/pdf/Makefile.am b/filters/krita/pdf/Makefile.am new file mode 100644 index 000000000..7f2366bcd --- /dev/null +++ b/filters/krita/pdf/Makefile.am @@ -0,0 +1,28 @@ +INCLUDES = \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) \ + $(all_includes) $(POPPLER_CFLAGS) + +servicedir = $(kde_servicesdir) + +kdelnkdir = $(kde_appsdir)/.hidden + +METASOURCES = AUTO +kde_module_LTLIBRARIES = libkritapdfimport.la +libkritapdfimport_la_LDFLAGS = -avoid-version -module -no-undefined $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) +libkritapdfimport_la_LIBADD = $(top_builddir)/krita/libkritacommon.la \ + -lpoppler-qt $(KOFFICE_LIBS) $(POPPLER_LIBS) + +noinst_HEADERS = kis_pdf_import.h kis_pdf_import_widget.h +libkritapdfimport_la_SOURCES = kis_pdf_import.cpp pdfimportwidgetbase.ui \ + kis_pdf_import_widget.cpp +kde_services_DATA = krita_pdf_import.desktop +kdelnk_DATA = krita_pdf.desktop diff --git a/filters/krita/pdf/configure.in.bot b/filters/krita/pdf/configure.in.bot new file mode 100644 index 000000000..9802779d7 --- /dev/null +++ b/filters/krita/pdf/configure.in.bot @@ -0,0 +1,7 @@ +if test -z "$POPPLER_LIBS"; then + echo "" + echo "You're missing libpoppler 0.5.1 or later (binaries and/or headers)." + echo "krita won't be able to import pdf" + echo "note that the qt-binding of libpoppler is required" + echo "" +fi diff --git a/filters/krita/pdf/configure.in.in b/filters/krita/pdf/configure.in.in new file mode 100644 index 000000000..e43432778 --- /dev/null +++ b/filters/krita/pdf/configure.in.in @@ -0,0 +1,4 @@ +# Compile the pdf import filter only if Poppler is available +PKG_CHECK_MODULES(POPPLER, poppler-qt >= 0.5.1, have_poppler=yes, have_poppler=no) + +AM_CONDITIONAL(include_PDF, test "x$have_poppler" = xyes) diff --git a/filters/krita/pdf/kis_pdf_import.cpp b/filters/krita/pdf/kis_pdf_import.cpp new file mode 100644 index 000000000..ad2004148 --- /dev/null +++ b/filters/krita/pdf/kis_pdf_import.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_pdf_import.h" + +// poppler's headers +#include + +// Qt's headers +#include +#include // TODO that too +#include + +// KDE's headers +#include +#include +#include +#include +#include +#include + +#include + +// koffice's headers +#include + +// krita's headers +#include +#include +#include +#include +#include +#include +#include + +// plugins's headers +#include "kis_pdf_import_widget.h" + +typedef KGenericFactory PDFImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritapdfimport, PDFImportFactory("kofficefilters")) + +KisPDFImport::KisPDFImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisPDFImport::~KisPDFImport() +{ +} + +KisPDFImport::ConversionStatus KisPDFImport::convert(const QCString& , const QCString& ) +{ + QString filename = m_chain -> inputFile(); + kdDebug(41008) << "Importing using PDFImport!" << filename << endl; + + if (filename.isEmpty()) + return KoFilter::FileNotFound; + + + KURL url; + url.setPath(filename); + + if (!KIO::NetAccess::exists(url, false, qApp -> mainWidget())) { + return KoFilter::FileNotFound; + } + + // We're not set up to handle asynchronous loading at the moment. + QString tmpFile; + if (KIO::NetAccess::download(url, tmpFile, qApp -> mainWidget())) { + url.setPath( tmpFile ); + } + + Poppler::Document* pdoc = Poppler::Document::load( QFile::encodeName(url.path() ) ); + + + if ( !pdoc) + { + kdDebug(41008) << "Error when reading the PDF" << endl; + return KoFilter::StorageCreationError; + } + + + while( pdoc->isLocked() ) + { + QCString password; + int result = KPasswordDialog::getPassword(password, i18n("A password is required to read that pdf")); + if (result == KPasswordDialog::Accepted) + { + pdoc->unlock(password); + } else { + kdDebug(41008) << "Password canceled" << endl; + return KoFilter::StorageCreationError; + } + } + + KDialogBase* kdb = new KDialogBase(0, "", false, i18n("PDF Import Options"), KDialogBase::Ok | KDialogBase::Cancel); + + KisPDFImportWidget* wdg = new KisPDFImportWidget(pdoc, kdb); + kdb->setMainWidget(wdg); + kapp->restoreOverrideCursor(); + if(kdb->exec() == QDialog::Rejected) + { + delete pdoc; + delete kdb; + return KoFilter::StorageCreationError; // FIXME Cancel doesn't exist :( + } + + // Init kis's doc + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + if (!doc) + { + delete pdoc; + delete kdb; + return KoFilter::CreationError; + } + + doc -> prepareForImport(); + // Create the krita image + KisColorSpace* cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID("RGBA"), ""); + int width = wdg->intWidth->value(); + int height = wdg->intHeight->value(); + KisImageSP img = new KisImage(doc->undoAdapter(), width, height, cs, "built image"); + img->blockSignals(true); // Don't send out signals while we're building the image + + // create a layer + QValueList pages = wdg->pages(); + for(QValueList::const_iterator it = pages.begin(); it != pages.end(); ++it) + { + KisPaintLayer* layer = new KisPaintLayer(img, QString(i18n("Page %1")).arg( QString::number(*it) + 1), Q_UINT8_MAX); + layer->paintDevice()->convertFromQImage( pdoc->getPage( *it )->renderToImage(wdg->intHorizontal->value(), wdg->intVertical->value() ), ""); + img->addLayer(layer, img->rootLayer(), 0); + } + + img->blockSignals(false); + doc -> setCurrentImage( img); + + KIO::NetAccess::removeTempFile(tmpFile); + + delete pdoc; + delete kdb; + return KoFilter::OK; +} + diff --git a/filters/krita/pdf/kis_pdf_import.h b/filters/krita/pdf/kis_pdf_import.h new file mode 100644 index 000000000..217319db2 --- /dev/null +++ b/filters/krita/pdf/kis_pdf_import.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_PDF_IMPORT_H +#define KIS_PDF_IMPORT_H + +#include + +class KisPDFImport : public KoFilter{ + Q_OBJECT + public: + KisPDFImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisPDFImport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/pdf/kis_pdf_import_widget.cpp b/filters/krita/pdf/kis_pdf_import_widget.cpp new file mode 100644 index 000000000..b3d370155 --- /dev/null +++ b/filters/krita/pdf/kis_pdf_import_widget.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_pdf_import_widget.h" + +// poppler's headers +#include + +// Qt's headers +#include + +// KDE's headers +#include +#include +#include + +KisPDFImportWidget::KisPDFImportWidget(Poppler::Document* pdfDoc, QWidget * parent, const char * name) + : PDFImportWidgetBase(parent, name), m_pdfDoc(pdfDoc) +{ + m_pages.push_back(0); // The first page is selected + updateMaxCanvasSize(); + + for(int i = 1; i <= m_pdfDoc->getNumPages(); i++) + { + listPages->insertItem(QString::number( i ) ); + } + + connect(intWidth, SIGNAL( valueChanged ( int ) ), this, SLOT( updateHRes() ) ); + connect(intHeight, SIGNAL( valueChanged ( int ) ), this, SLOT( updateHVer() ) ); + connect(intHorizontal, SIGNAL( valueChanged ( int ) ), this, SLOT( updateWidth() ) ); + connect(intVertical, SIGNAL( valueChanged ( int ) ), this, SLOT( updateHeight() ) ); + connect(boolAllPages, SIGNAL( toggled ( bool ) ), this, SLOT( selectAllPages( bool ) ) ); + connect(boolFirstPage, SIGNAL( toggled ( bool ) ), this, SLOT( selectFirstPage( bool ) ) ); + connect(boolSelectionPage, SIGNAL( toggled ( bool ) ), this, SLOT( selectSelectionOfPages( bool ) ) ); + connect(listPages, SIGNAL(selectionChanged () ), this, SLOT(updateSelectionOfPages())); +} + + +KisPDFImportWidget::~KisPDFImportWidget() +{ +} + +void KisPDFImportWidget::selectAllPages(bool v) +{ + if(v) + { + m_pages.clear(); + for(int i = 0; i < m_pdfDoc->getNumPages(); i++) + { + m_pages.push_back(i); + } + updateMaxCanvasSize(); + } +} +void KisPDFImportWidget::selectFirstPage(bool v) +{ + if(v) + { + m_pages.clear(); + m_pages.push_back(0); // The first page is selected + } +} +void KisPDFImportWidget::selectSelectionOfPages(bool v) +{ + if(v) + { + updateSelectionOfPages(); + updateMaxCanvasSize(); + } + +} + +void KisPDFImportWidget::updateSelectionOfPages() +{ + if(! boolSelectionPage->isChecked ()) boolSelectionPage->toggle(); + m_pages.clear(); + for(int i = 0; i < m_pdfDoc->getNumPages(); i++) + { + if(listPages->isSelected(i)) m_pages.push_back(i); + } +} + + +void KisPDFImportWidget::updateMaxCanvasSize() { + m_maxWidthInch = 0., m_maxHeightInch =0.; + for(QValueList::const_iterator it = m_pages.begin(); it != m_pages.end(); ++it) + { + Poppler::Page *p = m_pdfDoc->getPage(*it ); + QSize size = p->pageSize(); + if(size.width() > m_maxWidthInch) + { + m_maxWidthInch = size.width(); + } + if(size.height() > m_maxHeightInch) + { + m_maxHeightInch = size.height(); + } + } + m_maxWidthInch /= 72.; + m_maxHeightInch /= 72.; + kdDebug() << m_maxWidthInch << " " << m_maxHeightInch << endl; + updateWidth(); + updateHeight(); +} + +void KisPDFImportWidget::updateWidth() +{ + intWidth->blockSignals(true); + intWidth->setValue( (int) m_maxWidthInch * intHorizontal->value() + 1 ); + intWidth->blockSignals(false); +} +void KisPDFImportWidget::updateHeight() +{ + intHeight->blockSignals(true); + intHeight->setValue( (int) m_maxHeightInch * intVertical->value() + 1 ); + intHeight->blockSignals(false); +} +void KisPDFImportWidget::updateHRes() +{ + intHorizontal->blockSignals(true); + intHorizontal->setValue( (int) (intWidth->value() / m_maxWidthInch ) ); + intHorizontal->blockSignals(false); +} +void KisPDFImportWidget::updateHVer() +{ + intVertical->blockSignals(true); + intVertical->setValue( (int) (intHeight->value() / m_maxHeightInch ) ); + intVertical->blockSignals(false); +} + +#include "kis_pdf_import_widget.moc" diff --git a/filters/krita/pdf/kis_pdf_import_widget.h b/filters/krita/pdf/kis_pdf_import_widget.h new file mode 100644 index 000000000..debc0f0ea --- /dev/null +++ b/filters/krita/pdf/kis_pdf_import_widget.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_PDF_IMPORT_WIDGET_H +#define KIS_PDF_IMPORT_WIDGET_H + +#include + +namespace Poppler { +class Document; +} + +class KisPDFImportWidget : public PDFImportWidgetBase +{ + Q_OBJECT + public: + KisPDFImportWidget(Poppler::Document* pdfDoc, QWidget * parent, const char * name = ""); + + ~KisPDFImportWidget(); + public: + inline QValueList pages() { return m_pages; } + private slots: + void selectAllPages(bool v); + void selectFirstPage(bool v); + void selectSelectionOfPages(bool v); + void updateSelectionOfPages(); + void updateWidth(); + void updateHeight(); + void updateHRes(); + void updateHVer(); + void updateMaxCanvasSize(); + private: + Poppler::Document* m_pdfDoc; + QValueList m_pages; + double m_maxWidthInch, m_maxHeightInch; +}; + +#endif diff --git a/filters/krita/pdf/krita_pdf.desktop b/filters/krita/pdf/krita_pdf.desktop new file mode 100644 index 000000000..0f8828661 --- /dev/null +++ b/filters/krita/pdf/krita_pdf.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Categories= +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +Icon=krita +MimeType=application/pdf +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Path= +StartupNotify=true +Terminal=false +TerminalOptions= +Type=Application +X-DCOP-ServiceType=multi +X-KDE-StartupNotify=true +X-KDE-SubstituteUID=false +X-KDE-Username= diff --git a/filters/krita/pdf/krita_pdf_import.desktop b/filters/krita/pdf/krita_pdf_import.desktop new file mode 100644 index 000000000..fe49fb734 --- /dev/null +++ b/filters/krita/pdf/krita_pdf_import.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=Krita PDF Import Filter +Name[bg]=Филтър за импортиране от PDF в Krita +Name[br]=Sil enporzh PDF evit Krita +Name[ca]=Filtre d'importació PDF per a Krita +Name[da]=Krita PDF-importfilter +Name[de]=Krita PDF-Importfilter +Name[el]=Φίλτρο εισαγωγής PDF του Krita +Name[eo]=Krita PD-importfiltrilo +Name[es]=Filtro de importación a PDF de Krita +Name[et]=Krita PDF impordifilter +Name[fa]=پالایۀ واردات Krita PDF +Name[fr]=Filtre d'importation PDF de Krita +Name[fy]=Krita PDF Ymportfilter +Name[ga]=Scagaire Iompórtála PDF Krita +Name[gl]=Filtro de Importación de PDF para Krita +Name[hr]=Krita PDF filtar uvoza +Name[hu]=Krita PDF importszűrő +Name[it]=Filtro di importazione PDF per Krita +Name[ja]=Krita PDF インポートフィルタ +Name[km]=តម្រង​នាំចូល PNG របស់​រាប់ Krita +Name[lt]=Krita PDF importavimo filtras +Name[lv]=Krita PDF importa filtrs +Name[nb]=PDF-importfilter for Krita +Name[nds]=PDF-Importfilter för Krita +Name[ne]=क्रिता PDF आयात फिल्टर +Name[nl]=Krita PDF Importfilter +Name[pl]=Filtr importu formatu PDF do Krita +Name[pt]=Filtro de Importação de PDF para o Krita +Name[pt_BR]=Filtro de Importação de PDF para o Krita +Name[ru]=Фильтр импорта документов PDF в Krita +Name[se]=Krita PDF-sisafievrridansilli +Name[sk]=PDF filter pre import do Krita +Name[sl]=Uvozni filter PDF za Krito +Name[sr]=Krita-ин филтер за увоз из PDF-а +Name[sr@Latn]=Krita-in filter za uvoz iz PDF-a +Name[sv]=Krita PDF-importfilter +Name[uk]=Фільтр імпорту PDF для Krita +Name[uz]=Krita uchun PDF import filteri +Name[uz@cyrillic]=Krita учун PDF импорт филтери +Name[zh_TW]=Krita PDF 匯入過濾程式 +Comment= +Comment[uz]=PDF-fayllarni Krita bilan oʻqish vositasi +Comment[uz@cyrillic]=PDF-файлларни Krita билан ўқиш воситаси +ServiceTypes=KOfficeFilter +X-KDE-Available= +X-KDE-Export=application/x-krita +X-KDE-Import=application/pdf +X-KDE-Weight=1 +X-KDE-Library=libkritapdfimport diff --git a/filters/krita/pdf/pdfimportwidgetbase.ui b/filters/krita/pdf/pdfimportwidgetbase.ui new file mode 100644 index 000000000..148e72a2a --- /dev/null +++ b/filters/krita/pdf/pdfimportwidgetbase.ui @@ -0,0 +1,321 @@ + +PDFImportWidgetBase + + + PDFImportWidgetBase + + + + 0 + 0 + 462 + 210 + + + + PDFImportWidget + + + + unnamed + + + + groupBox1 + + + Dimensions + + + + unnamed + + + + textLabel1 + + + Resolution: + + + + + layout6 + + + + unnamed + + + + spacer2_2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + layout2 + + + + unnamed + + + + intVerticalqsdf + + + Vertical: + + + + + + Dots/inch + + + + kComboBox1 + + + + + intHorizontal + + + 999 + + + 72 + + + + + intVertical + + + 999 + + + 72 + + + + + textLabel5 + + + Horizontal: + + + + + + Dots/inch + + + + kComboBox2 + + + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 31 + 20 + + + + + + + + textLabel2 + + + Size: + + + + + layout4 + + + + unnamed + + + + spacer2 + + + Horizontal + + + Fixed + + + + 20 + 20 + + + + + + layout3 + + + + unnamed + + + + intHeight + + + 99999 + + + + + intWidthzqffs + + + Width: + + + + + intWidth + + + 99999 + + + + + intHeightqsdfq + + + Height: + + + + + + + spacer1 + + + Horizontal + + + Expanding + + + + 51 + 20 + + + + + + + + + + buttonGroup1 + + + Pages + + + + unnamed + + + + boolAllPages + + + &All pages + + + + + boolFirstPage + + + &First page + + + true + + + + + boolSelectionPage + + + &Selection of page + + + + + listPages + + + Multi + + + + + + + + + + boolFirstPage + listPages + intHorizontal + kComboBox1 + intVertical + kComboBox2 + intWidth + intHeight + + + + kcombobox.h + knuminput.h + knuminput.h + kcombobox.h + knuminput.h + knuminput.h + klistbox.h + + diff --git a/filters/krita/png/Makefile.am b/filters/krita/png/Makefile.am new file mode 100644 index 000000000..881601562 --- /dev/null +++ b/filters/krita/png/Makefile.am @@ -0,0 +1,40 @@ +kde_module_LTLIBRARIES = libkritapngimport.la libkritapngexport.la + +libkritapngexport_la_LDFLAGS = $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritapngexport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(top_builddir)/krita/libkritacommon.la \ + -lpng + +libkritapngimport_la_LDFLAGS = $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritapngimport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(top_builddir)/krita/libkritacommon.la \ + -lpng + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) \ + $(all_includes) + +service_DATA = krita_png_import.desktop krita_png_export.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_png.desktop +kdelnkdir = $(kde_appsdir)/.hidden + +libkritapngimport_la_SOURCES = kis_png_import.cc kis_png_converter.cc +libkritapngexport_la_SOURCES = kis_wdg_options_png.ui kis_png_export.cc kis_png_converter.cc + +METASOURCES = AUTO + + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) diff --git a/filters/krita/png/configure.in.bot b/filters/krita/png/configure.in.bot new file mode 100644 index 000000000..0df5c7cab --- /dev/null +++ b/filters/krita/png/configure.in.bot @@ -0,0 +1,8 @@ +if test -z "$LIBPNG"; then + echo "" + echo "You're missing libpng (binaries and/or headers), krita won't be able" + echo "to import/export png" + echo "" + all_tests=bad +fi + diff --git a/filters/krita/png/kis_png_converter.cc b/filters/krita/png/kis_png_converter.cc new file mode 100644 index 000000000..0beb0b74e --- /dev/null +++ b/filters/krita/png/kis_png_converter.cc @@ -0,0 +1,794 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + + // A big thank to Glenn Randers-Pehrson for it's wonderfull documentation of libpng available at http://www.libpng.org/pub/png/libpng-1.2.5-manual.html +#include "kis_png_converter.h" + +#include + +#include + +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace { + + const Q_UINT8 PIXEL_BLUE = 0; + const Q_UINT8 PIXEL_GREEN = 1; + const Q_UINT8 PIXEL_RED = 2; + const Q_UINT8 PIXEL_ALPHA = 3; + + + int getColorTypeforColorSpace( KisColorSpace * cs , bool alpha) + { + if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") ) + { + return alpha ? PNG_COLOR_TYPE_GRAY_ALPHA : PNG_COLOR_TYPE_GRAY; + } + if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") ) + { + return alpha ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_RGB; + } + + KMessageBox::error(0, i18n("Cannot export images in %1.\n").arg(cs->id().name()) ) ; + return -1; + + } + + + QString getColorSpaceForColorType(int color_type,int color_nb_bits) { + if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + switch(color_nb_bits) + { + case 8: + return "GRAYA"; + case 16: + return "GRAYA16"; + } + } else if(color_type == PNG_COLOR_TYPE_RGB_ALPHA || color_type == PNG_COLOR_TYPE_RGB) { + switch(color_nb_bits) + { + case 8: + return "RGBA"; + case 16: + return "RGBA16"; + } + } else if(color_type == PNG_COLOR_TYPE_PALETTE) { + return "RGBA"; // <-- we will convert the index image to RGBA + } + return ""; + } + + + void fillText(png_text* p_text, char* key, QString& text) + { + p_text->compression = PNG_TEXT_COMPRESSION_zTXt; + p_text->key = key; + char* textc = new char[text.length()+1]; + strcpy(textc, text.ascii()); + p_text->text = textc; + p_text->text_length = text.length()+1; + } + +} + +KisPNGConverter::KisPNGConverter(KisDoc *doc, KisUndoAdapter *adapter) +{ + Q_ASSERT(doc); + Q_ASSERT(adapter); + + m_doc = doc; + m_adapter = adapter; + m_stop = false; + m_max_row = 0; + m_img = 0; +} + +KisPNGConverter::~KisPNGConverter() +{ +} + +class KisPNGStream { + public: + KisPNGStream(Q_UINT8* buf, Q_UINT32 depth ) : m_posinc(8),m_depth(depth), m_buf(buf) { *m_buf = 0;}; + int nextValue() + { + if( m_posinc == 0) + { + m_posinc = 8; + m_buf++; + } + m_posinc -= m_depth; + return (( (*m_buf) >> (m_posinc) ) & ( ( 1 << m_depth ) - 1 ) ); + } + void setNextValue(int v) + { + if( m_posinc == 0) + { + m_posinc = 8; + m_buf++; + *m_buf = 0; + } + m_posinc -= m_depth; + *m_buf = (v << m_posinc) | *m_buf; + } + private: + Q_UINT32 m_posinc, m_depth; + Q_UINT8* m_buf; +}; + +KisImageBuilder_Result KisPNGConverter::decode(const KURL& uri) +{ + kdDebug(41008) << "Start decoding PNG File" << endl; + // open the file + kdDebug(41008) << QFile::encodeName(uri.path()) << " " << uri.path() << " " << uri << endl; + FILE *fp = fopen(QFile::encodeName(uri.path()), "rb"); + if (!fp) + { + return (KisImageBuilder_RESULT_NOT_EXIST); + } + png_byte signature[8]; + fread(signature, 1, 8, fp); + if (!png_check_sig(signature, 8)) + { + return (KisImageBuilder_RESULT_BAD_FETCH); + } + + // Initialize the internal structures + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL); + if (!KisImageBuilder_RESULT_FAILURE) + return (KisImageBuilder_RESULT_FAILURE); + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + return (KisImageBuilder_RESULT_FAILURE); + } + + png_infop end_info = png_create_info_struct(png_ptr); + if (!end_info) + { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + return (KisImageBuilder_RESULT_FAILURE); + } + + // Catch errors + if (setjmp(png_jmpbuf(png_ptr))) + { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fp); + return (KisImageBuilder_RESULT_FAILURE); + } + + png_init_io(png_ptr, fp); + png_set_sig_bytes(png_ptr, 8); + + // read all PNG info up to image data + png_read_info(png_ptr, info_ptr); + + // Read information about the png + png_uint_32 width, height; + int color_nb_bits, color_type, interlace_type; + png_get_IHDR(png_ptr, info_ptr, &width, &height, &color_nb_bits, &color_type, &interlace_type, NULL, NULL); + kdDebug(41008) << "it's an " << color_nb_bits << " depth image" << endl; + + // swap byteorder on little endian machines. + #ifndef WORDS_BIGENDIAN + if (color_nb_bits > 8 ) + png_set_swap(png_ptr); + #endif + + // Determine the colorspace + QString csName = getColorSpaceForColorType(color_type, color_nb_bits); + if(csName.isEmpty()) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + bool hasalpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA || color_type == PNG_COLOR_TYPE_GRAY_ALPHA); + + // Read image profile + png_charp profile_name, profile_data; + int compression_type; + png_uint_32 proflen; + int number_of_passes = 1; + + if (interlace_type == PNG_INTERLACE_ADAM7) + number_of_passes = png_set_interlace_handling(png_ptr); + + KisProfile* profile = 0; + if(png_get_iCCP(png_ptr, info_ptr, &profile_name, &compression_type, &profile_data, &proflen)) + { + QByteArray profile_rawdata; + // XXX: Hardcoded for icc type -- is that correct for us? + if (QString::compare(profile_name, "icc") == 0) { + profile_rawdata.resize(proflen); + memcpy(profile_rawdata.data(), profile_data, proflen); + profile = new KisProfile(profile_rawdata); + Q_CHECK_PTR(profile); + if (profile) { + kdDebug(41008) << "profile name: " << profile->productName() << " profile description: " << profile->productDescription() << " information sur le produit: " << profile->productInfo() << endl; + if(!profile->isSuitableForOutput()) + { + kdDebug(41008) << "the profile is not suitable for output and therefore cannot be used in krita, we need to convert the image to a standard profile" << endl; // TODO: in ko2 popup a selection menu to inform the user + } + } + } + } + + // Retrieve a pointer to the colorspace + KisColorSpace* cs; + if (profile && profile->isSuitableForOutput()) + { + kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n"; + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile); + } + else + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),""); + + if(cs == 0) + { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + + // Create the cmsTransform if needed + cmsHTRANSFORM transform = 0; + if(profile && !profile->isSuitableForOutput()) + { + transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(), + cs->getProfile()->profile() , cs->colorSpaceType(), + INTENT_PERCEPTUAL, 0); + } + + // Read comments/texts... + png_text* text_ptr; + int num_comments; + png_get_text(png_ptr, info_ptr, &text_ptr, &num_comments); + KoDocumentInfo * info = m_doc->documentInfo(); + KoDocumentInfoAbout * aboutPage = static_cast(info->page( "about" )); + KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author")); + kdDebug(41008) << "There are " << num_comments << " comments in the text" << endl; + for(int i = 0; i < num_comments; i++) + { + kdDebug(41008) << "key is " << text_ptr[i].key << " containing " << text_ptr[i].text << endl; + if(QString::compare(text_ptr[i].key, "title") == 0) + { + aboutPage->setTitle(text_ptr[i].text); + } else if(QString::compare(text_ptr[i].key, "abstract") == 0) + { + aboutPage->setAbstract(text_ptr[i].text); + } else if(QString::compare(text_ptr[i].key, "author") == 0) + { + authorPage->setFullName(text_ptr[i].text); + } + } + + // Read image data + png_bytep row_pointer = 0; + try + { + png_uint_32 rowbytes = png_get_rowbytes(png_ptr, info_ptr); + row_pointer = new png_byte[rowbytes]; + } + catch(std::bad_alloc& e) + { + // new png_byte[] may raise such an exception if the image + // is invalid / to large. + kdDebug(41008) << "bad alloc: " << e.what() << endl; + // Free only the already allocated png_byte instances. + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + return (KisImageBuilder_RESULT_FAILURE); + } + + // Read the palette if the file is indexed + png_colorp palette ; + int num_palette; + if(color_type == PNG_COLOR_TYPE_PALETTE) { + png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette); + } +// png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL ); +// png_bytepp row_pointers = png_get_rows(png_ptr, info_ptr); // By using this function libpng will take care of freeing memory +// png_read_image(png_ptr, row_pointers); + + // Finish reading the file +// png_read_end(png_ptr, end_info); +// fclose(fp); + + // Creating the KisImageSP + if( ! m_img) { + m_img = new KisImage(m_doc->undoAdapter(), width, height, cs, "built image"); + m_img->blockSignals(true); // Don't send out signals while we're building the image + Q_CHECK_PTR(m_img); + if(profile && !profile->isSuitableForOutput()) + { + m_img -> addAnnotation( profile->annotation() ); + } + } + + KisPaintLayer* layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), Q_UINT8_MAX); + for (int i = 0; i < number_of_passes; i++) + { + for (png_uint_32 y = 0; y < height; y++) { + KisHLineIterator it = layer -> paintDevice() -> createHLineIterator(0, y, width, true); + png_read_rows(png_ptr, &row_pointer, NULL, 1); + + switch(color_type) + { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: + if(color_nb_bits == 16) + { + Q_UINT16 *src = reinterpret_cast(row_pointer); + while (!it.isDone()) { + Q_UINT16 *d = reinterpret_cast(it.rawData()); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + if(hasalpha) d[1] = *(src++); + else d[1] = Q_UINT16_MAX; + ++it; + } + } else { + Q_UINT8 *src = row_pointer; + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + if(hasalpha) d[1] = *(src++); + else d[1] = Q_UINT8_MAX; + ++it; + } + } + //FIXME:should be able to read 1 and 4 bits depth and scale them to 8 bits + break; + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + if(color_nb_bits == 16) + { + Q_UINT16 *src = reinterpret_cast(row_pointer); + while (!it.isDone()) { + Q_UINT16 *d = reinterpret_cast(it.rawData()); + d[2] = *(src++); + d[1] = *(src++); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + if(hasalpha) d[3] = *(src++); + else d[3] = Q_UINT16_MAX; + ++it; + } + } else { + Q_UINT8 *src = row_pointer; + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + d[2] = *(src++); + d[1] = *(src++); + d[0] = *(src++); + if(transform) cmsDoTransform(transform, d, d, 1); + if(hasalpha) d[3] = *(src++); + else d[3] = Q_UINT8_MAX; + ++it; + } + } + break; + case PNG_COLOR_TYPE_PALETTE: + { + KisPNGStream stream(row_pointer, color_nb_bits); + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + png_color c = palette[ stream.nextValue() ]; + d[2] = c.red; + d[1] = c.green; + d[0] = c.blue; + d[3] = Q_UINT8_MAX; + ++it; + } + } + break; + default: + return KisImageBuilder_RESULT_UNSUPPORTED; + } + } + } + m_img->addLayer(layer, m_img->rootLayer(), 0); + + png_read_end(png_ptr, end_info); + fclose(fp); + + // Freeing memory + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + + delete [] row_pointer; + + return KisImageBuilder_RESULT_OK; + +} + +KisImageBuilder_Result KisPNGConverter::buildImage(const KURL& uri) +{ + kdDebug(41008) << QFile::encodeName(uri.path()) << " " << uri.path() << " " << uri << endl; + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) { + return KisImageBuilder_RESULT_NOT_EXIST; + } + + // We're not set up to handle asynchronous loading at the moment. + KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE; + QString tmpFile; + + if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) { + KURL uriTF; + uriTF.setPath( tmpFile ); + result = decode(uriTF); + KIO::NetAccess::removeTempFile(tmpFile); + } + + return result; +} + + +KisImageSP KisPNGConverter::image() +{ + return m_img; +} + +KisImageBuilder_Result KisPNGConverter::buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd, int compression, bool interlace, bool alpha) +{ + kdDebug(41008) << "Start writing PNG File" << endl; + if (!layer) + return KisImageBuilder_RESULT_INVALID_ARG; + + KisImageSP img = layer -> image(); + if (!img) + return KisImageBuilder_RESULT_EMPTY; + + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!uri.isLocalFile()) + return KisImageBuilder_RESULT_NOT_LOCAL; + // Open file for writing + FILE *fp = fopen(QFile::encodeName(uri.path()), "wb"); + if (!fp) + { + return (KisImageBuilder_RESULT_FAILURE); + } + int height = img->height(); + int width = img->width(); + // Initialize structures + png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL); + if (!png_ptr) + { + KIO::del(uri); + return (KisImageBuilder_RESULT_FAILURE); + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) + { + KIO::del(uri); + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + return (KisImageBuilder_RESULT_FAILURE); + } + + // If an error occurs during writing, libpng will jump here + if (setjmp(png_jmpbuf(png_ptr))) + { + KIO::del(uri); + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fp); + return (KisImageBuilder_RESULT_FAILURE); + } + // Initialize the writing + png_init_io(png_ptr, fp); + // Setup the progress function +// FIXME png_set_write_status_fn(png_ptr, progress); +// setProgressTotalSteps(100/*height*/); + + + /* set the zlib compression level */ + png_set_compression_level(png_ptr, compression); + + /* set other zlib parameters */ + png_set_compression_mem_level(png_ptr, 8); + png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY); + png_set_compression_window_bits(png_ptr, 15); + png_set_compression_method(png_ptr, 8); + png_set_compression_buffer_size(png_ptr, 8192); + + int color_nb_bits = 8 * layer->paintDevice()->pixelSize() / layer->paintDevice()->nChannels(); + int color_type = getColorTypeforColorSpace(layer->paintDevice()->colorSpace(), alpha); + + if(color_type == -1) + { + return KisImageBuilder_RESULT_UNSUPPORTED; + } + + // Try to compute a table of color if the colorspace is RGB8f + png_colorp palette ; + int num_palette = 0; + if(!alpha && layer->paintDevice()->colorSpace()->id() == KisID("RGBA") ) + { // png doesn't handle indexed images and alpha, and only have indexed for RGB8 + palette = new png_color[255]; + KisRectIteratorPixel it = layer->paintDevice()->createRectIterator(0,0, img->width(), img->height(), false); + bool toomuchcolor = false; + while( !it.isDone() ) + { + const Q_UINT8* c = it.rawData(); + bool findit = false; + for(int i = 0; i < num_palette; i++) + { + if(palette[i].red == c[2] && + palette[i].green == c[1] && + palette[i].blue == c[0] ) + { + findit = true; + break; + } + } + if(!findit) + { + if( num_palette == 255) + { + toomuchcolor = true; + break; + } + palette[num_palette].red = c[2]; + palette[num_palette].green = c[1]; + palette[num_palette].blue = c[0]; + num_palette++; + } + ++it; + } + if(!toomuchcolor) + { + kdDebug(41008) << "Found a palette of " << num_palette << " colors" << endl; + color_type = PNG_COLOR_TYPE_PALETTE; + if( num_palette <= 2) + { + color_nb_bits = 1; + } else if( num_palette <= 4) + { + color_nb_bits = 2; + } else if( num_palette <= 16) + { + color_nb_bits = 4; + } else { + color_nb_bits = 8; + } + } else { + delete palette; + } + } + + int interlacetype = interlace ? PNG_INTERLACE_ADAM7 : PNG_INTERLACE_NONE; + + png_set_IHDR(png_ptr, info_ptr, + width, + height, + color_nb_bits, + color_type, interlacetype, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + png_set_sRGB(png_ptr, info_ptr, PNG_sRGB_INTENT_ABSOLUTE); + // set the palette + if( color_type == PNG_COLOR_TYPE_PALETTE) + { + png_set_PLTE(png_ptr, info_ptr, palette, num_palette); + } + // Save annotation + vKisAnnotationSP_it it = annotationsStart; + while(it != annotationsEnd) { + if (!(*it) || (*it) -> type() == QString()) { + kdDebug(41008) << "Warning: empty annotation" << endl; + ++it; + continue; + } + + kdDebug(41008) << "Trying to store annotation of type " << (*it) -> type() << " of size " << (*it) -> annotation() . size() << endl; + + if ((*it) -> type().startsWith("krita_attribute:")) { // Attribute + // FIXME: it should be possible to save krita_attributes in the "CHUNKs" + kdDebug(41008) << "can't save this annotation : " << (*it) -> type() << endl; + } else { // Profile + char* name = new char[(*it)->type().length()+1]; + strcpy(name, (*it)->type().ascii()); + png_set_iCCP(png_ptr, info_ptr, name, PNG_COMPRESSION_TYPE_BASE, (char*)(*it)->annotation().data(), (*it) -> annotation() . size()); + } + ++it; + } + + // read comments from the document information + png_text texts[3]; + int nbtexts = 0; + KoDocumentInfo * info = m_doc->documentInfo(); + KoDocumentInfoAbout * aboutPage = static_cast(info->page( "about" )); + QString title = aboutPage->title(); + if(!title.isEmpty()) + { + fillText(texts+nbtexts, "title", title); + nbtexts++; + } + QString abstract = aboutPage->abstract(); + if(!abstract.isEmpty()) + { + fillText(texts+nbtexts, "abstract", abstract); + nbtexts++; + } + KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author" )); + QString author = authorPage->fullName(); + if(!author.isEmpty()) + { + fillText(texts+nbtexts, "author", author); + nbtexts++; + } + + png_set_text(png_ptr, info_ptr, texts, nbtexts); + + // Save the information to the file + png_write_info(png_ptr, info_ptr); + png_write_flush(png_ptr); + + // swap byteorder on little endian machines. + #ifndef WORDS_BIGENDIAN + if (color_nb_bits > 8 ) + png_set_swap(png_ptr); + #endif + + // Write the PNG +// png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + // Fill the data structure + png_byte** row_pointers= new png_byte*[height]; + + for (int y = 0; y < height; y++) { + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false); + row_pointers[y] = new png_byte[width*layer->paintDevice()->pixelSize()]; + switch(color_type) + { + case PNG_COLOR_TYPE_GRAY: + case PNG_COLOR_TYPE_GRAY_ALPHA: + if(color_nb_bits == 16) + { + Q_UINT16 *dst = reinterpret_cast(row_pointers[y]); + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + *(dst++) = d[0]; + if(alpha) *(dst++) = d[1]; + ++it; + } + } else { + Q_UINT8 *dst = row_pointers[y]; + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + *(dst++) = d[0]; + if(alpha) *(dst++) = d[1]; + ++it; + } + } + break; + case PNG_COLOR_TYPE_RGB: + case PNG_COLOR_TYPE_RGB_ALPHA: + if(color_nb_bits == 16) + { + Q_UINT16 *dst = reinterpret_cast(row_pointers[y]); + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + *(dst++) = d[2]; + *(dst++) = d[1]; + *(dst++) = d[0]; + if(alpha) *(dst++) = d[3]; + ++it; + } + } else { + Q_UINT8 *dst = row_pointers[y]; + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + *(dst++) = d[2]; + *(dst++) = d[1]; + *(dst++) = d[0]; + if(alpha) *(dst++) = d[3]; + ++it; + } + } + break; + case PNG_COLOR_TYPE_PALETTE: + { + Q_UINT8 *dst = row_pointers[y]; + KisPNGStream writestream(dst, color_nb_bits); + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + int i; + for(i = 0; i < num_palette; i++) + { + if(palette[i].red == d[2] && + palette[i].green == d[1] && + palette[i].blue == d[0] ) + { + break; + } + } + writestream.setNextValue(i); + ++it; + } + } + break; + default: + kdDebug(41008) << "Unsupported color type for writting : " << color_type << endl; + KIO::del(uri); + return KisImageBuilder_RESULT_UNSUPPORTED; + } + } + + png_write_image(png_ptr, row_pointers); + + + // Writting is over + png_write_end(png_ptr, info_ptr); + + // Free memory + png_destroy_write_struct(&png_ptr, &info_ptr); + for (int y = 0; y < height; y++) { + delete[] row_pointers[y]; + } + delete[] row_pointers; + + if( color_type == PNG_COLOR_TYPE_PALETTE) + { + delete palette; + } + + fclose(fp); + + return KisImageBuilder_RESULT_OK; +} + + +void KisPNGConverter::cancel() +{ + m_stop = true; +} + +void KisPNGConverter::progress(png_structp png_ptr, png_uint_32 row_number, int pass) +{ + if(png_ptr == NULL || row_number > PNG_MAX_UINT || pass > 7) return; +// setProgress(row_number); +} + + +#include "kis_png_converter.moc" + diff --git a/filters/krita/png/kis_png_converter.h b/filters/krita/png/kis_png_converter.h new file mode 100644 index 000000000..6fd8b2072 --- /dev/null +++ b/filters/krita/png/kis_png_converter.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_PNG_CONVERTER_H_ +#define _KIS_PNG_CONVERTER_H_ + +#include + +#include + +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_annotation.h" +class KisDoc; +class KisUndoAdapter; + +/** + * Image import/export plugins can use these results to report about success or failure. + */ +enum KisImageBuilder_Result { + KisImageBuilder_RESULT_FAILURE = -400, + KisImageBuilder_RESULT_NOT_EXIST = -300, + KisImageBuilder_RESULT_NOT_LOCAL = -200, + KisImageBuilder_RESULT_BAD_FETCH = -100, + KisImageBuilder_RESULT_INVALID_ARG = -50, + KisImageBuilder_RESULT_OK = 0, + KisImageBuilder_RESULT_PROGRESS = 1, + KisImageBuilder_RESULT_EMPTY = 100, + KisImageBuilder_RESULT_BUSY = 150, + KisImageBuilder_RESULT_NO_URI = 200, + KisImageBuilder_RESULT_UNSUPPORTED = 300, + KisImageBuilder_RESULT_INTR = 400, + KisImageBuilder_RESULT_PATH = 500, + KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE = 600 +}; + +class KisPNGConverter : public KisProgressSubject { + Q_OBJECT + public: + KisPNGConverter(KisDoc *doc, KisUndoAdapter *adapter); + virtual ~KisPNGConverter(); + public: + KisImageBuilder_Result buildImage(const KURL& uri); + KisImageBuilder_Result buildFile(const KURL& uri, KisPaintLayerSP layer, vKisAnnotationSP_it annotationsStart, vKisAnnotationSP_it annotationsEnd, int compression, bool interlace, bool alpha); + /** Retrieve the constructed image + */ + KisImageSP image(); + public slots: + virtual void cancel(); + private: + KisImageBuilder_Result decode(const KURL& uri); + void progress(png_structp png_ptr, png_uint_32 row_number, int pass); + private: + png_uint_32 m_max_row; + KisImageSP m_img; + KisDoc *m_doc; + KisUndoAdapter *m_adapter; + bool m_stop; +}; + +#endif diff --git a/filters/krita/png/kis_png_export.cc b/filters/krita/png/kis_png_export.cc new file mode 100644 index 000000000..b1df098cc --- /dev/null +++ b/filters/krita/png/kis_png_export.cc @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_png_export.h" + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "kis_png_converter.h" +#include "kis_wdg_options_png.h" + +typedef KGenericFactory KisPNGExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritapngexport, KisPNGExportFactory("kofficefilters")) + +KisPNGExport::KisPNGExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisPNGExport::~KisPNGExport() +{ +} + +KoFilter::ConversionStatus KisPNGExport::convert(const QCString& from, const QCString& to) +{ + kdDebug(41008) << "Png export! From: " << from << ", To: " << to << "\n"; + + KisDoc *output = dynamic_cast(m_chain->inputDocument()); + QString filename = m_chain->outputFile(); + + if (!output) + return KoFilter::CreationError; + + + if (filename.isEmpty()) return KoFilter::FileNotFound; + + if (from != "application/x-krita") + return KoFilter::NotImplemented; + + + KDialogBase* kdb = new KDialogBase(0, "", false, i18n("PNG Export Options"), KDialogBase::Ok | KDialogBase::Cancel); + + KisImageSP img = output->currentImage(); + KisPaintDeviceSP pd = new KisPaintDevice(*img->projection()); + KisPaintLayerSP l = new KisPaintLayer(img, "projection", OPACITY_OPAQUE, pd); + + KisRectIteratorPixel it = l->paintDevice()->createRectIterator(0,0, img->width(), img->height(), false); + KisColorSpace* cs = l->paintDevice()->colorSpace(); + bool isThereAlpha = false; + while( !it.isDone() ) + { + if(cs->getAlpha( it.rawData() ) != 255) + { + isThereAlpha = true; + break; + } + ++it; + } + + KisWdgOptionsPNG* wdg = new KisWdgOptionsPNG(kdb); + wdg->alpha->setChecked(isThereAlpha); + wdg->alpha->setEnabled(isThereAlpha); + kdb->setMainWidget(wdg); + kapp->restoreOverrideCursor(); + if(kdb->exec() == QDialog::Rejected) + { + return KoFilter::OK; // FIXME Cancel doesn't exist :( + } + + bool alpha = wdg->alpha->isChecked(); + bool interlace = wdg->interlacing->isChecked(); + int compression = wdg->compressionLevel->value(); + + delete kdb; + + + KURL url; + url.setPath(filename); + + KisPNGConverter kpc(output, output->undoAdapter()); + + vKisAnnotationSP_it beginIt = img->beginAnnotations(); + vKisAnnotationSP_it endIt = img->endAnnotations(); + KisImageBuilder_Result res; + + + if ( (res = kpc.buildFile(url, l, beginIt, endIt, compression, interlace, alpha)) == KisImageBuilder_RESULT_OK) { + kdDebug(41008) << "success !" << endl; + return KoFilter::OK; + } + kdDebug(41008) << " Result = " << res << endl; + return KoFilter::InternalError; +} + +#include + diff --git a/filters/krita/png/kis_png_export.h b/filters/krita/png/kis_png_export.h new file mode 100644 index 000000000..1c99d7c9e --- /dev/null +++ b/filters/krita/png/kis_png_export.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_PNG_EXPORT_H_ +#define _KIS_PNG_EXPORT_H_ + +#include + +class KisPNGExport : public KoFilter { + Q_OBJECT + public: + KisPNGExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisPNGExport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/png/kis_png_import.cc b/filters/krita/png/kis_png_import.cc new file mode 100644 index 000000000..5b824081a --- /dev/null +++ b/filters/krita/png/kis_png_import.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_png_import.h" + +#include + +#include + +#include +#include +#include +#include + +#include "kis_png_converter.h" + +typedef KGenericFactory PNGImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritapngimport, PNGImportFactory("kofficefilters")) + +KisPNGImport::KisPNGImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisPNGImport::~KisPNGImport() +{ +} + +KoFilter::ConversionStatus KisPNGImport::convert(const QCString&, const QCString& to) +{ + kdDebug(41008) << "Importing using PNGImport!\n"; + + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + KisView * view = static_cast(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc -> prepareForImport(); + + + if (!filename.isEmpty()) { + + KURL url; + url.setPath(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisPNGConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + +#include + diff --git a/filters/krita/png/kis_png_import.h b/filters/krita/png/kis_png_import.h new file mode 100644 index 000000000..8c952c967 --- /dev/null +++ b/filters/krita/png/kis_png_import.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_PNG_IMPORT_H_ +#define _KIS_PNG_IMPORT_H_ + +#include + +class KisPNGImport : public KoFilter { + Q_OBJECT + public: + KisPNGImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisPNGImport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/png/kis_wdg_options_png.ui b/filters/krita/png/kis_wdg_options_png.ui new file mode 100644 index 000000000..b8d11c3a0 --- /dev/null +++ b/filters/krita/png/kis_wdg_options_png.ui @@ -0,0 +1,183 @@ + +KisWdgOptionsPNG + + + KisWdgOptionsPNG + + + + 0 + 0 + 286 + 106 + + + + Options of Your PNG + + + + unnamed + + + 0 + + + + layout6 + + + + unnamed + + + + textLabel1 + + + Compress: + + + AlignTop + + + Note: the compression level does not change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level does not change the quality of the result.</p> + + + + + layout5 + + + + unnamed + + + + compressionLevel + + + 1 + + + 9 + + + 1 + + + 9 + + + Horizontal + + + Below + + + Note: the compression level doesn't change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + layout4 + + + + unnamed + + + + textLabel3 + + + Fast + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + textLabel4 + + + Small + + + AlignVCenter|AlignRight + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + + + + + + + spacer1 + + + Vertical + + + Expanding + + + + 20 + 5 + + + + + + interlacing + + + Interlacing + + + Use interlacing when publishing on the Internet + + + <p>Interlacing is useful if you intend to publish your image on the Internet.<br> +Enabling interlacing will cause the image to be displayed by the browser even while downloading.</p> + + + + + alpha + + + Store alpha channel (transparency) + + + true + + + Disable to get smaller files if your image has no transparency + + + <p>The Portable Network Graphics (PNG) file format allows transparency in your image to be stored by saving an alpha channel. +You can uncheck the box if you are not using transparency and you want to make the resulting file smaller .<br>Always saving the alpha channel is recommended.</p> + + + + + + diff --git a/filters/krita/png/krita_png.desktop b/filters/krita/png/krita_png.desktop new file mode 100644 index 000000000..367dfcc01 --- /dev/null +++ b/filters/krita/png/krita_png.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +MimeType=image/png +Type=Application +Icon=krita +Categories= +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi diff --git a/filters/krita/png/krita_png_export.desktop b/filters/krita/png/krita_png_export.desktop new file mode 100644 index 000000000..7109175ce --- /dev/null +++ b/filters/krita/png/krita_png_export.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Name=Krita PNG Export Filter +Name[bg]=Филтър за експортиране от Krita в PNG +Name[br]=Sil ezporzh PNG evit Krita +Name[ca]=Filtre d'exportació PNG per a Krita +Name[da]=Krita PNG-eksportfilter +Name[de]=Krita PNG-Exportfilter +Name[el]=Φίλτρο εξαγωγής PNG του Krita +Name[eo]=Krita PNG-eksportfiltrilo +Name[es]=Filtro de exportación a PNG de Krita +Name[et]=Krita PNG ekspordifilter +Name[fa]=پالایۀ صادرات Krita PNG +Name[fi]=Krita PNG -viestisuodin +Name[fr]=Filtre d'exportation PNG de Krita +Name[fy]=Krita PNG Eksportfilter +Name[ga]=Scagaire Easpórtála PNG Krita +Name[gl]=Filtro de Exportación de PNG para Krita +Name[he]=Krita PNG מסנן יצוא +Name[hr]=Krita PNG filtar izvoza +Name[hu]=Krita PNG exportszűrő +Name[is]=Krita PNG útflutningssía +Name[it]=Filtro di esportazione PNG per Krita +Name[ja]=Krita PNG エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ PNG សម្រាប់ Krita +Name[lt]=Krita PNG eksportavimo filtras +Name[lv]=Krita PNG eksporta filtrs +Name[nb]=PNG-eksportfilter for Krita +Name[nds]=PNG-Exportfilter för Krita +Name[ne]=क्रिता पीएनजी निर्यात फिल्टर +Name[nl]=Krita PNG Exportfilter +Name[pl]=Filtr eksportu do formatu PNG dla Krita +Name[pt]=Filtro de Exportação de PNG para o Krita +Name[pt_BR]=Filtro de Exportação de PNG para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в PNG +Name[se]=Krita PNG-olggosfievrridansilli +Name[sk]=Exportný filter Krita PNG +Name[sl]=Izvozni filter PNG za Krito +Name[sr]=Krita-ин филтер за извоз у PNG +Name[sr@Latn]=Krita-in filter za izvoz u PNG +Name[sv]=Krita PNG-exportfilter +Name[uk]=Фільтр експорту PNG для Krita +Name[uz]=Krita PNG eksport filteri +Name[uz@cyrillic]=Krita PNG экспорт филтери +Name[zh_CN]=Krita PNG 导出过滤器 +Name[zh_TW]=Krita PNG 匯出過濾程式 +X-KDE-Export=image/png +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Import=application/x-krita +X-KDE-Weight=1 +X-KDE-Library=libkritapngexport diff --git a/filters/krita/png/krita_png_import.desktop b/filters/krita/png/krita_png_import.desktop new file mode 100644 index 000000000..99944a77b --- /dev/null +++ b/filters/krita/png/krita_png_import.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=Krita PNG Import Filter +Name[bg]=Филтър за импортиране от PNG в Krita +Name[br]=Sil enporzh PNG evit Krita +Name[ca]=Filtre d'importació PNG per a Krita +Name[da]=Krita PNG-importfilter +Name[de]=Krita PNG-Importfilter +Name[el]=Φίλτρο εισαγωγής PNG του Krita +Name[eo]=Krita PNG-importfiltrilo +Name[es]=Filtro de importación a PNG de Krita +Name[et]=Krita PNG impordifilter +Name[fa]=پالایۀ واردات Krita PNG +Name[fi]=Krita PNG -tuontisuodin +Name[fr]=Filtre d'importation PNG de Krita +Name[fy]=Krita PNG Ymportfilter +Name[ga]=Scagaire Iompórtála PNG Krita +Name[gl]=Filtro de Importación de PNG para Krita +Name[he]=Krita PNG מסנן יבוא +Name[hr]=Krita PNG filtar uvoza +Name[hu]=Krita PNG importszűrő +Name[is]=Krita PNG innflutningssía +Name[it]=Filtro di importazione PNG per Krita +Name[ja]=Krita PNG インポートフィルタ +Name[km]=តម្រង​នាំចូល PNG សម្រាប់ Krita +Name[lt]=Krita PNG importavimo filtras +Name[lv]=Krita PNG importa filtrs +Name[nb]=PNG-importfilter for Krita +Name[nds]=PNG-Importfilter för Krita +Name[ne]=क्रिता पीएनजी आयात फिल्टर +Name[nl]=Krita PNG Importfilter +Name[pl]=Filtr importu z formatu PNG dla Krita +Name[pt]=Filtro de Importação de PNG para o Krita +Name[pt_BR]=Filtro de Importação de PNG para o Krita +Name[ru]=Фильтр импорта рисунков PNG в Krita +Name[se]=Krita PNG-olggosfievrridansilli +Name[sk]=PNG filter pre import do Krita +Name[sl]=Uvozni filter PNG za Krito +Name[sr]=Krita-ин филтер за увоз из PNG-а +Name[sr@Latn]=Krita-in filter za uvoz iz PNG-a +Name[sv]=Krita PNG-importfilter +Name[uk]=Фільтр імпорту PNG для Krita +Name[uz]=Krita PNG import filteri +Name[uz@cyrillic]=Krita PNG импорт филтери +Name[zh_CN]=Krita PNG 导入过滤器 +Name[zh_TW]=Krita PNG 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/png +X-KDE-Weight=1 +X-KDE-Library=libkritapngimport +ServiceTypes=KOfficeFilter diff --git a/filters/krita/raw/Makefile.am b/filters/krita/raw/Makefile.am new file mode 100644 index 000000000..cd29902b7 --- /dev/null +++ b/filters/krita/raw/Makefile.am @@ -0,0 +1,33 @@ +AM_CPPFLAGS= \ + -I$(srcdir) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + -I$(top_srcdir)/filters/krita/magick \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = libkrita_raw_import.la + +libkrita_raw_import_la_LDFLAGS = $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkrita_raw_import_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(raw_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + + +service_DATA = krita_raw_import.desktop +servicedir = $(kde_servicesdir) + +kdelnk_DATA = krita_raw.desktop +kdelnkdir = $(kde_appsdir)/.hidden + +libkrita_raw_import_la_SOURCES = kis_raw_import.cpp wdgrawimport.ui + +METASOURCES = AUTO + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + + diff --git a/filters/krita/raw/dcraw.1 b/filters/krita/raw/dcraw.1 new file mode 100644 index 000000000..10a690b86 --- /dev/null +++ b/filters/krita/raw/dcraw.1 @@ -0,0 +1,182 @@ +.\" +.\" Man page for dcraw (Raw Photo Decoder) +.\" +.\" Copyright (c) 2005 by David Coffin +.\" +.\" You may distribute without restriction. +.\" +.\" David Coffin +.\" dcoffin a cybercom o net +.\" http://www.cybercom.net/~dcoffin +.\" +.TH dcraw 1 "September 29, 2005" +.LO 1 +.SH NAME +dcraw - convert raw digital photos to PPM format +.SH SYNOPSIS +.B dcraw +[\fIOPTION\fR]... [\fIFILE\fR]... +.SH DESCRIPTION +.B dcraw +converts raw digital photos to +.BR ppm (5) +format. +.SH OPTIONS +.TP +.B -v +Print verbose messages. The default is to print only warnings +and errors. +.TP +.B -z +Change the access and modification times of a JPEG or raw file to +when the photo was taken, assuming that the camera clock was set +to Universal Time. +.TP +.B -i +Identify files but don't decode them. +Exit status is 0 if +.B dcraw +can decode the last file, 1 if it can't. +.TP +.B "" +.B dcraw +cannot decode JPEG files!! +.TP +.B -c +Write binary image data to standard output. +By default, +.B dcraw +creates files with a ".ppm" extension. +.TP +.B -d +Show the raw data as a grayscale image with no interpolation. +Good for photographing black-and-white documents. +.TP +.B -q [0-3] +Set the interpolation quality (default is 3): + +.B \t0 +\ \ Bilinear (very fast, low quality) +.br +.B \t1 +\ \ Reserved +.br +.B \t2 +\ \ Variable Number of Gradients (VNG) +.br +.B \t3 +\ \ Adaptive Homogeneity-Directed (AHD) +.TP +.B -h +Output a half-size image. Twice as fast as +.BR -q\ 0 . +.TP +.B -f +Interpolate RGB as four colors. This blurs the image a little, +but it eliminates false 2x2 mesh patterns. +.TP +.B -B sigma_domain sigma_range +Use a bilateral filter to smooth noise while preserving edges. +.B sigma_domain +is in units of pixels, while +.B sigma_range +is in units of CIELab colorspace. +Try +.B -B\ 2\ 4 +to start. +.TP +.B -a +Automatic color balance. The default is to use a fixed +color balance based on a white card photographed in sunlight. +.TP +.B -w +Use the color balance specified by the camera. +If this can't be found, +.B dcraw +prints a warning and reverts to the default. +.TP +.B -r red_mul -l blue_mul +Further adjust the color balance by multiplying the red and +blue output channels by these values. Both default to 1.0. +.TP +.B -b brightness +Change the output brightness. Default is 1.0. +.TP +.B -k black +Set the black point. Default depends on the camera. +.TP +.B -n +By default, +.B dcraw +clips all colors to prevent pink hues in the highlights. +Combine this option with +.B -b 0.25 +to leave the image data completely unclipped. +.TP +.B -m +Write raw camera colors to the output file. By default, +.B dcraw +converts to sRGB colorspace. +.TP +.B -j +For Fuji\ Super\ CCD cameras, show the image tilted 45 degrees +so that each output pixel corresponds to one raw pixel. +.TP +.B -s +For Fuji\ Super\ CCD\ SR cameras, use the secondary sensors, in +effect underexposing the image by four stops to reveal detail +in the highlights. +.TP +.B "" +For all other cameras, +.B -j +and +.B -s +are silently ignored. +.TP +.B -t [0-7] +Flip the output image. The most common flips are 5 +(90 degrees CCW) and 6 (90 degrees clockwise). By default, +dcraw tries to use the flip specified by the camera. +.RB \^" -t\ 0 \^" +forces +.B dcraw +not to flip images. +.TP +.B -2 +Write eight bits per color value with a 99th-percentile white +point and the standard 0.45 gamma curve. Double the height if +necessary to correct the aspect ratio. This is the default. +.TP +.B -4 +Write sixteen bits per color value. Output is linear with +input -- no white point, no gamma, same aspect ratio. +.TP +.B -3 +Same image as +.BR -4 , +written in Adobe PhotoShop format. File extension is ".psd". +.SH "SEE ALSO" +.BR ppm (5), +.BR ppm2tiff (1), +.BR pnmtotiff (1), +.BR pnmtopng (1), +.BR gphoto2 (1), +.BR djpeg (1) +.SH BUGS +The +.B -w +option does not work with many cameras. +.P +No attempt is made to save camera settings or thumbnail images. +.P +The author stubbornly refuses to add more output formats. +.P +Don't expect +.B dcraw +to produce the same images as software provided by the camera +vendor. Sometimes +.B dcraw +gives better results! +.SH AUTHOR +Written by David Coffin, dcoffin a cybercom o net diff --git a/filters/krita/raw/dcraw.c b/filters/krita/raw/dcraw.c new file mode 100644 index 000000000..b562dd749 --- /dev/null +++ b/filters/krita/raw/dcraw.c @@ -0,0 +1,5999 @@ +/* + dcraw.c -- Dave Coffin's raw photo decoder + Copyright 1997-2005 by Dave Coffin, dcoffin a cybercom o net + + This is a command-line ANSI C program to convert raw photos from + any digital camera on any computer running any operating system. + + Attention! Some parts of this program are restricted under the + terms of the GNU General Public License. Such code is enclosed + in "BEGIN GPL BLOCK" and "END GPL BLOCK" declarations. + Any code not declared GPL is free for all uses. + + Starting in Revision 1.237, the code to support Foveon cameras + is under GPL. + + To lawfully redistribute dcraw.c, you must either (a) include + full source code for all executable files containing restricted + functions, (b) remove these functions, re-implement them, or + copy them from an earlier, non-GPL Revision of dcraw.c, or (c) + purchase a license from the author. + + $Revision: 1.296 $ + $Date: 2005/11/04 07:11:14 $ + */ + +#define _GNU_SOURCE +#define _USE_MATH_DEFINES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* + By defining NO_JPEG, you lose only the ability to + decode compressed .KDC files from the Kodak DC120. + */ +#ifndef NO_JPEG +#include +#endif + +#ifdef __CYGWIN__ +#include +#endif +#ifdef WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#define strcasecmp stricmp +typedef __int64 INT64; +typedef unsigned __int64 UINT64; +#else +#include +#include +#include +typedef long long INT64; +typedef unsigned long long UINT64; +#endif + +#ifdef LJPEG_DECODE +#error Please compile dcraw.c by itself. +#error Do not link it with ljpeg_decode. +#endif + +#ifndef LONG_BIT +#define LONG_BIT (8 * sizeof (long)) +#endif + +#define ushort UshORt +typedef unsigned char uchar; +typedef unsigned short ushort; + +/* + All global variables are defined here, and all functions that + access them are prefixed with "CLASS". Note that a thread-safe + C++ class cannot have non-const static local variables. + */ +FILE *ifp; +short order; +char *ifname, make[64], model[70], model2[64], *meta_data; +float flash_used, canon_5814; +time_t timestamp; +unsigned shot_order, kodak_cbpp; +int data_offset, meta_offset, meta_length, nikon_curve_offset; +int tiff_bps, tiff_data_compression, kodak_data_compression; +int raw_height, raw_width, top_margin, left_margin; +int height, width, fuji_width, colors, tiff_samples; +int black, maximum, clip_max, clip_color=1; +int iheight, iwidth, shrink; +int dng_version, is_foveon, raw_color, use_gamma; +int flip, xmag, ymag; +int zero_after_ff; +unsigned filters; +ushort (*image)[4], white[8][8], curve[0x1000]; +void (*load_raw)(); +float bright=1, red_scale=1, blue_scale=1, sigma_d=0, sigma_r=0; +int four_color_rgb=0, document_mode=0; +int verbose=0, use_auto_wb=0, use_camera_wb=0, use_camera_rgb=0; +int fuji_layout, fuji_secondary, use_secondary=0; +float cam_mul[4], pre_mul[4], rgb_cam[3][4]; /* RGB from camera color */ +const double xyz_rgb[3][3] = { /* XYZ from RGB */ + { 0.412453, 0.357580, 0.180423 }, + { 0.212671, 0.715160, 0.072169 }, + { 0.019334, 0.119193, 0.950227 } }; +#define camera_red cam_mul[0] +#define camera_blue cam_mul[2] +int histogram[3][0x2000]; +void write_ppm(FILE *); +void (*write_fun)(FILE *) = write_ppm; +jmp_buf failure; + +#define USE_LCMS +#ifdef USE_LCMS +#include +int profile_offset, profile_length; +#endif + +struct decode { + struct decode *branch[2]; + int leaf; +} first_decode[2048], *second_decode, *free_decode; + +#define CLASS + +#define FORC3 for (c=0; c < 3; c++) +#define FORC4 for (c=0; c < 4; c++) +#define FORCC for (c=0; c < colors; c++) + +#define SQR(x) ((x)*(x)) +#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +#define LIM(x,min,max) MAX(min,MIN(x,max)) +#define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) +#define CLIP(x) LIM(x,0,clip_max) + +/* + In order to inline this calculation, I make the risky + assumption that all filter patterns can be described + by a repeating pattern of eight rows and two columns + + Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 + */ +#define FC(row,col) \ + (filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3) + +#define BAYER(row,col) \ + image[((row) >> shrink)*iwidth + ((col) >> shrink)][FC(row,col)] + +/* + PowerShot 600 PowerShot A50 PowerShot Pro70 Pro90 & G1 + 0xe1e4e1e4: 0x1b4e4b1e: 0x1e4b4e1b: 0xb4b4b4b4: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 G M G M G M 0 C Y C Y C Y 0 Y C Y C Y C 0 G M G M G M + 1 C Y C Y C Y 1 M G M G M G 1 M G M G M G 1 Y C Y C Y C + 2 M G M G M G 2 Y C Y C Y C 2 C Y C Y C Y + 3 C Y C Y C Y 3 G M G M G M 3 G M G M G M + 4 C Y C Y C Y 4 Y C Y C Y C + PowerShot A5 5 G M G M G M 5 G M G M G M + 0x1e4e1e4e: 6 Y C Y C Y C 6 C Y C Y C Y + 7 M G M G M G 7 M G M G M G + 0 1 2 3 4 5 + 0 C Y C Y C Y + 1 G M G M G M + 2 C Y C Y C Y + 3 M G M G M G + + All RGB cameras use one of these Bayer grids: + + 0x16161616: 0x61616161: 0x49494949: 0x94949494: + + 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 0 1 2 3 4 5 + 0 B G B G B G 0 G R G R G R 0 G B G B G B 0 R G R G R G + 1 G R G R G R 1 B G B G B G 1 R G R G R G 1 G B G B G B + 2 B G B G B G 2 G R G R G R 2 G B G B G B 2 R G R G R G + 3 G R G R G R 3 B G B G B G 3 R G R G R G 3 G B G B G B + */ + +#ifndef __GLIBC__ +char *memmem (char *haystack, size_t haystacklen, + char *needle, size_t needlelen) +{ + char *c; + for (c = haystack; c <= haystack + haystacklen - needlelen; c++) + if (!memcmp (c, needle, needlelen)) + return c; + return NULL; +} +#endif + +void CLASS merror (void *ptr, char *where) +{ + if (ptr) return; + fprintf (stderr, "%s: Out of memory in %s\n", ifname, where); + longjmp (failure, 1); +} + +ushort CLASS sget2 (uchar *s) +{ + if (order == 0x4949) /* "II" means little-endian */ + return s[0] | s[1] << 8; + else /* "MM" means big-endian */ + return s[0] << 8 | s[1]; +} + +ushort CLASS get2() +{ + uchar str[2] = { 0xff,0xff }; + fread (str, 1, 2, ifp); + return sget2(str); +} + +int CLASS sget4 (uchar *s) +{ + if (order == 0x4949) + return s[0] | s[1] << 8 | s[2] << 16 | s[3] << 24; + else + return s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]; +} +#define sget4(s) sget4((uchar *)s) + +int CLASS get4() +{ + uchar str[4] = { 0xff,0xff,0xff,0xff }; + fread (str, 1, 4, ifp); + return sget4(str); +} + +double CLASS getrat() +{ + double num = get4(); + return num / get4(); +} + +float CLASS int_to_float (int i) +{ + union { int i; float f; } u; + u.i = i; + return u.f; +} + +void CLASS read_shorts (ushort *pixel, int count) +{ + fread (pixel, 2, count, ifp); + if ((order == 0x4949) == (ntohs(0x1234) == 0x1234)) + swab (pixel, pixel, count*2); +} + +void CLASS canon_600_fixed_wb (int temp) +{ + static const short mul[4][5] = { + { 667, 358,397,565,452 }, + { 731, 390,367,499,517 }, + { 1119, 396,348,448,537 }, + { 1399, 485,431,508,688 } }; + int lo, hi, i; + float frac=0; + + for (lo=4; --lo; ) + if (*mul[lo] <= temp) break; + for (hi=0; hi < 3; hi++) + if (*mul[hi] >= temp) break; + if (lo != hi) + frac = (float) (temp - *mul[lo]) / (*mul[hi] - *mul[lo]); + for (i=1; i < 5; i++) + pre_mul[i-1] = 1 / (frac * mul[hi][i] + (1-frac) * mul[lo][i]); +} + +/* Return values: 0 = white 1 = near white 2 = not white */ +int CLASS canon_600_color (int ratio[2], int mar) +{ + int clipped=0, target, miss; + + if (flash_used) { + if (ratio[1] < -104) + { ratio[1] = -104; clipped = 1; } + if (ratio[1] > 12) + { ratio[1] = 12; clipped = 1; } + } else { + if (ratio[1] < -264 || ratio[1] > 461) return 2; + if (ratio[1] < -50) + { ratio[1] = -50; clipped = 1; } + if (ratio[1] > 307) + { ratio[1] = 307; clipped = 1; } + } + target = flash_used || ratio[1] < 197 + ? -38 - (398 * ratio[1] >> 10) + : -123 + (48 * ratio[1] >> 10); + if (target - mar <= ratio[0] && + target + 20 >= ratio[0] && !clipped) return 0; + miss = target - ratio[0]; + if (abs(miss) >= mar*4) return 2; + if (miss < -20) miss = -20; + if (miss > mar) miss = mar; + ratio[0] = target - miss; + return 1; +} + +void CLASS canon_600_auto_wb () +{ + int mar, row, col, i, j, st, count[] = { 0,0 }; + int test[8], total[2][8], ratio[2][2], stat[2]; + + memset (&total, 0, sizeof total); + i = canon_5814 + 0.5; + if (i < 10) mar = 150; + else if (i > 12) mar = 20; + else mar = 280 - 20 * i; + if (flash_used) mar = 80; + for (row=14; row < height-14; row+=4) + for (col=10; col < width; col+=2) { + for (i=0; i < 8; i++) + test[(i & 4) + FC(row+(i >> 1),col+(i & 1))] = + BAYER(row+(i >> 1),col+(i & 1)); + for (i=0; i < 8; i++) + if (test[i] < 150 || test[i] > 1500) goto next; + for (i=0; i < 4; i++) + if (abs(test[i] - test[i+4]) > 50) goto next; + for (i=0; i < 2; i++) { + for (j=0; j < 4; j+=2) + ratio[i][j >> 1] = ((test[i*4+j+1]-test[i*4+j]) << 10) / test[i*4+j]; + stat[i] = canon_600_color (ratio[i], mar); + } + if ((st = stat[0] | stat[1]) > 1) goto next; + for (i=0; i < 2; i++) + if (stat[i]) + for (j=0; j < 2; j++) + test[i*4+j*2+1] = test[i*4+j*2] * (0x400 + ratio[i][j]) >> 10; + for (i=0; i < 8; i++) + total[st][i] += test[i]; + count[st]++; +next: continue; + } + if (count[0] | count[1]) { + st = count[0]*200 < count[1]; + for (i=0; i < 4; i++) + pre_mul[i] = 1.0 / (total[st][i] + total[st][i+4]); + } +} + +void CLASS canon_600_coeff () +{ + static const short table[6][12] = { + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -1203,1715,-1136,1648, 1388,-876,267,245, -1641,2153,3921,-3409 }, + { -615,1127,-1563,2075, 1437,-925,509,3, -756,1268,2519,-2007 }, + { -190,702,-1886,2398, 2153,-1641,763,-251, -452,964,3040,-2528 }, + { -190,702,-1878,2390, 1861,-1349,905,-393, -432,944,2617,-2105 }, + { -807,1319,-1785,2297, 1388,-876,769,-257, -230,742,2067,-1555 } }; + int t=0, i, c; + float mc, yc; + + mc = pre_mul[1] / pre_mul[2]; + yc = pre_mul[3] / pre_mul[2]; + if (mc > 1 && mc <= 1.28 && yc < 0.8789) t=1; + if (mc > 1.28 && mc <= 2) { + if (yc < 0.8789) t=3; + else if (yc <= 2) t=4; + } + if (flash_used) t=5; + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[t][i*4 + c] / 1024.0; +} + +void CLASS canon_600_load_raw() +{ + uchar data[1120], *dp; + ushort pixel[896], *pix; + int irow, row, col, val; + static const short mul[4][2] = + { { 1141,1145 }, { 1128,1109 }, { 1178,1149 }, { 1128,1109 } }; + + for (irow=row=0; irow < height; irow++) + { + fread (data, 1120, 1, ifp); + for (dp=data, pix=pixel; dp < data+1120; dp+=10, pix+=8) + { + pix[0] = (dp[0] << 2) + (dp[1] >> 6 ); + pix[1] = (dp[2] << 2) + (dp[1] >> 4 & 3); + pix[2] = (dp[3] << 2) + (dp[1] >> 2 & 3); + pix[3] = (dp[4] << 2) + (dp[1] & 3); + pix[4] = (dp[5] << 2) + (dp[9] & 3); + pix[5] = (dp[6] << 2) + (dp[9] >> 2 & 3); + pix[6] = (dp[7] << 2) + (dp[9] >> 4 & 3); + pix[7] = (dp[8] << 2) + (dp[9] >> 6 ); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + for (col=width; col < 896; col++) + black += pixel[col]; + if ((row+=2) > height) row = 1; + } + black = black / ((896 - width) * height) - 4; + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + val = (BAYER(row,col) - black) * mul[row & 3][col & 1] >> 9; + if (val < 0) val = 0; + BAYER(row,col) = val; + } + canon_600_fixed_wb(1311); + canon_600_auto_wb(); + canon_600_coeff(); + maximum = (0x3ff - black) * 1109 >> 9; + black = 0; +} + +void CLASS canon_a5_load_raw() +{ + uchar data[1940], *dp; + ushort pixel[1552], *pix; + int row, col; + + for (row=0; row < height; row++) { + fread (data, raw_width * 10 / 8, 1, ifp); + for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=10, pix+=8) + { + pix[0] = (dp[1] << 2) + (dp[0] >> 6); + pix[1] = (dp[0] << 4) + (dp[3] >> 4); + pix[2] = (dp[3] << 6) + (dp[2] >> 2); + pix[3] = (dp[2] << 8) + (dp[5] ); + pix[4] = (dp[4] << 2) + (dp[7] >> 6); + pix[5] = (dp[7] << 4) + (dp[6] >> 4); + pix[6] = (dp[6] << 6) + (dp[9] >> 2); + pix[7] = (dp[9] << 8) + (dp[8] ); + } + for (col=0; col < width; col++) + BAYER(row,col) = (pixel[col] & 0x3ff); + for (col=width; col < raw_width; col++) + black += pixel[col] & 0x3ff; + } + if (raw_width > width) + black /= (raw_width - width) * height; + maximum = 0x3ff; +} + +/* + getbits(-1) initializes the buffer + getbits(n) where 0 <= n <= 25 returns an n-bit integer + */ +unsigned CLASS getbits (int nbits) +{ + static unsigned bitbuf=0; + static int vbits=0, reset=0; + unsigned c; + + if (nbits == -1) + return bitbuf = vbits = reset = 0; + if (nbits == 0 || reset) return 0; + while (vbits < nbits) { + c = fgetc(ifp); + if ((reset = zero_after_ff && c == 0xff && fgetc(ifp))) return 0; + bitbuf = (bitbuf << 8) + c; + vbits += 8; + } + vbits -= nbits; + return bitbuf << (32-nbits-vbits) >> (32-nbits); +} + +void CLASS init_decoder () +{ + memset (first_decode, 0, sizeof first_decode); + free_decode = first_decode; +} + +/* + Construct a decode tree according the specification in *source. + The first 16 bytes specify how many codes should be 1-bit, 2-bit + 3-bit, etc. Bytes after that are the leaf values. + + For example, if the source is + + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + + then the code is + + 00 0x04 + 010 0x03 + 011 0x05 + 100 0x06 + 101 0x02 + 1100 0x07 + 1101 0x01 + 11100 0x08 + 11101 0x09 + 11110 0x00 + 111110 0x0a + 1111110 0x0b + 1111111 0xff + */ +uchar * CLASS make_decoder (const uchar *source, int level) +{ + struct decode *cur; + static int leaf; + int i, next; + + if (level==0) leaf=0; + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr, "%s: decoder table overflow\n", ifname); + longjmp (failure, 2); + } + for (i=next=0; i <= leaf && next < 16; ) + i += source[next++]; + if (i > leaf) { + if (level < next) { + cur->branch[0] = free_decode; + make_decoder (source, level+1); + cur->branch[1] = free_decode; + make_decoder (source, level+1); + } else + cur->leaf = source[16 + leaf++]; + } + return (uchar *) source + 16 + leaf; +} + +void CLASS crw_init_tables (unsigned table) +{ + static const uchar first_tree[3][29] = { + { 0,1,4,2,3,1,2,0,0,0,0,0,0,0,0,0, + 0x04,0x03,0x05,0x06,0x02,0x07,0x01,0x08,0x09,0x00,0x0a,0x0b,0xff }, + { 0,2,2,3,1,1,1,1,2,0,0,0,0,0,0,0, + 0x03,0x02,0x04,0x01,0x05,0x00,0x06,0x07,0x09,0x08,0x0a,0x0b,0xff }, + { 0,0,6,3,1,1,2,0,0,0,0,0,0,0,0,0, + 0x06,0x05,0x07,0x04,0x08,0x03,0x09,0x02,0x00,0x0a,0x01,0x0b,0xff }, + }; + static const uchar second_tree[3][180] = { + { 0,2,2,2,1,4,2,1,2,5,1,1,0,0,0,139, + 0x03,0x04,0x02,0x05,0x01,0x06,0x07,0x08, + 0x12,0x13,0x11,0x14,0x09,0x15,0x22,0x00,0x21,0x16,0x0a,0xf0, + 0x23,0x17,0x24,0x31,0x32,0x18,0x19,0x33,0x25,0x41,0x34,0x42, + 0x35,0x51,0x36,0x37,0x38,0x29,0x79,0x26,0x1a,0x39,0x56,0x57, + 0x28,0x27,0x52,0x55,0x58,0x43,0x76,0x59,0x77,0x54,0x61,0xf9, + 0x71,0x78,0x75,0x96,0x97,0x49,0xb7,0x53,0xd7,0x74,0xb6,0x98, + 0x47,0x48,0x95,0x69,0x99,0x91,0xfa,0xb8,0x68,0xb5,0xb9,0xd6, + 0xf7,0xd8,0x67,0x46,0x45,0x94,0x89,0xf8,0x81,0xd5,0xf6,0xb4, + 0x88,0xb1,0x2a,0x44,0x72,0xd9,0x87,0x66,0xd4,0xf5,0x3a,0xa7, + 0x73,0xa9,0xa8,0x86,0x62,0xc7,0x65,0xc8,0xc9,0xa1,0xf4,0xd1, + 0xe9,0x5a,0x92,0x85,0xa6,0xe7,0x93,0xe8,0xc1,0xc6,0x7a,0x64, + 0xe1,0x4a,0x6a,0xe6,0xb3,0xf1,0xd3,0xa5,0x8a,0xb2,0x9a,0xba, + 0x84,0xa4,0x63,0xe5,0xc5,0xf3,0xd2,0xc4,0x82,0xaa,0xda,0xe4, + 0xf2,0xca,0x83,0xa3,0xa2,0xc3,0xea,0xc2,0xe2,0xe3,0xff,0xff }, + { 0,2,2,1,4,1,4,1,3,3,1,0,0,0,0,140, + 0x02,0x03,0x01,0x04,0x05,0x12,0x11,0x06, + 0x13,0x07,0x08,0x14,0x22,0x09,0x21,0x00,0x23,0x15,0x31,0x32, + 0x0a,0x16,0xf0,0x24,0x33,0x41,0x42,0x19,0x17,0x25,0x18,0x51, + 0x34,0x43,0x52,0x29,0x35,0x61,0x39,0x71,0x62,0x36,0x53,0x26, + 0x38,0x1a,0x37,0x81,0x27,0x91,0x79,0x55,0x45,0x28,0x72,0x59, + 0xa1,0xb1,0x44,0x69,0x54,0x58,0xd1,0xfa,0x57,0xe1,0xf1,0xb9, + 0x49,0x47,0x63,0x6a,0xf9,0x56,0x46,0xa8,0x2a,0x4a,0x78,0x99, + 0x3a,0x75,0x74,0x86,0x65,0xc1,0x76,0xb6,0x96,0xd6,0x89,0x85, + 0xc9,0xf5,0x95,0xb4,0xc7,0xf7,0x8a,0x97,0xb8,0x73,0xb7,0xd8, + 0xd9,0x87,0xa7,0x7a,0x48,0x82,0x84,0xea,0xf4,0xa6,0xc5,0x5a, + 0x94,0xa4,0xc6,0x92,0xc3,0x68,0xb5,0xc8,0xe4,0xe5,0xe6,0xe9, + 0xa2,0xa3,0xe3,0xc2,0x66,0x67,0x93,0xaa,0xd4,0xd5,0xe7,0xf8, + 0x88,0x9a,0xd7,0x77,0xc4,0x64,0xe2,0x98,0xa5,0xca,0xda,0xe8, + 0xf3,0xf6,0xa9,0xb2,0xb3,0xf2,0xd2,0x83,0xba,0xd3,0xff,0xff }, + { 0,0,6,2,1,3,3,2,5,1,2,2,8,10,0,117, + 0x04,0x05,0x03,0x06,0x02,0x07,0x01,0x08, + 0x09,0x12,0x13,0x14,0x11,0x15,0x0a,0x16,0x17,0xf0,0x00,0x22, + 0x21,0x18,0x23,0x19,0x24,0x32,0x31,0x25,0x33,0x38,0x37,0x34, + 0x35,0x36,0x39,0x79,0x57,0x58,0x59,0x28,0x56,0x78,0x27,0x41, + 0x29,0x77,0x26,0x42,0x76,0x99,0x1a,0x55,0x98,0x97,0xf9,0x48, + 0x54,0x96,0x89,0x47,0xb7,0x49,0xfa,0x75,0x68,0xb6,0x67,0x69, + 0xb9,0xb8,0xd8,0x52,0xd7,0x88,0xb5,0x74,0x51,0x46,0xd9,0xf8, + 0x3a,0xd6,0x87,0x45,0x7a,0x95,0xd5,0xf6,0x86,0xb4,0xa9,0x94, + 0x53,0x2a,0xa8,0x43,0xf5,0xf7,0xd4,0x66,0xa7,0x5a,0x44,0x8a, + 0xc9,0xe8,0xc8,0xe7,0x9a,0x6a,0x73,0x4a,0x61,0xc7,0xf4,0xc6, + 0x65,0xe9,0x72,0xe6,0x71,0x91,0x93,0xa6,0xda,0x92,0x85,0x62, + 0xf3,0xc5,0xb2,0xa4,0x84,0xba,0x64,0xa5,0xb3,0xd2,0x81,0xe5, + 0xd3,0xaa,0xc4,0xca,0xf2,0xb1,0xe4,0xd1,0x83,0x63,0xea,0xc3, + 0xe2,0x82,0xf1,0xa3,0xc2,0xa1,0xc1,0xe3,0xa2,0xe1,0xff,0xff } + }; + if (table > 2) table = 2; + init_decoder(); + make_decoder ( first_tree[table], 0); + second_decode = free_decode; + make_decoder (second_tree[table], 0); +} + +/* + Return 0 if the image starts with compressed data, + 1 if it starts with uncompressed low-order bits. + + In Canon compressed data, 0xff is always followed by 0x00. + */ +int CLASS canon_has_lowbits() +{ + uchar test[0x4000]; + int ret=1, i; + + fseek (ifp, 0, SEEK_SET); + fread (test, 1, sizeof test, ifp); + for (i=540; i < sizeof test - 1; i++) + if (test[i] == 0xff) { + if (test[i+1]) return 1; + ret=0; + } + return ret; +} + +void CLASS canon_compressed_load_raw() +{ + ushort *pixel, *prow; + int lowbits, i, row, r, col, save, val; + unsigned irow, icol; + struct decode *decode, *dindex; + int block, diffbuf[64], leaf, len, diff, carry=0, pnum=0, base[2]; + uchar c; + + pixel = calloc (raw_width*8, sizeof *pixel); + merror (pixel, "canon_compressed_load_raw()"); + lowbits = canon_has_lowbits(); + if (!lowbits) maximum = 0x3ff; + fseek (ifp, 540 + lowbits*raw_height*raw_width/4, SEEK_SET); + zero_after_ff = 1; + getbits(-1); + for (row = 0; row < raw_height; row += 8) { + for (block=0; block < raw_width >> 3; block++) { + memset (diffbuf, 0, sizeof diffbuf); + decode = first_decode; + for (i=0; i < 64; i++ ) { + for (dindex=decode; dindex->branch[0]; ) + dindex = dindex->branch[getbits(1)]; + leaf = dindex->leaf; + decode = second_decode; + if (leaf == 0 && i) break; + if (leaf == 0xff) continue; + i += leaf >> 4; + len = leaf & 15; + if (len == 0) continue; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + if (i < 64) diffbuf[i] = diff; + } + diffbuf[0] += carry; + carry = diffbuf[0]; + for (i=0; i < 64; i++ ) { + if (pnum++ % raw_width == 0) + base[0] = base[1] = 512; + pixel[(block << 6) + i] = ( base[i & 1] += diffbuf[i] ); + } + } + if (lowbits) { + save = ftell(ifp); + fseek (ifp, 26 + row*raw_width/4, SEEK_SET); + for (prow=pixel, i=0; i < raw_width*2; i++) { + c = fgetc(ifp); + for (r=0; r < 8; r+=2, prow++) { + val = (*prow << 2) + ((c >> r) & 3); + if (raw_width == 2672 && val < 512) val += 2; + *prow = val; + } + } + fseek (ifp, save, SEEK_SET); + } + for (r=0; r < 8; r++) { + irow = row - top_margin + r; + if (irow >= height) continue; + for (col = 0; col < raw_width; col++) { + icol = col - left_margin; + if (icol < width) + BAYER(irow,icol) = pixel[r*raw_width+col]; + else + black += pixel[r*raw_width+col]; + } + } + } + free (pixel); + if (raw_width > width) + black /= (raw_width - width) * height; +} + +/* + Not a full implementation of Lossless JPEG, just + enough to decode Canon, Kodak and Adobe DNG images. + */ +struct jhead { + int bits, high, wide, clrs, restart, vpred[4]; + struct decode *huff[4]; + ushort *row; +}; + +int CLASS ljpeg_start (struct jhead *jh) +{ + int i, tag, len; + uchar data[256], *dp; + + init_decoder(); + for (i=0; i < 4; i++) + jh->huff[i] = free_decode; + jh->restart = INT_MAX; + fread (data, 2, 1, ifp); + if (data[0] != 0xff || data[1] != 0xd8) return 0; + do { + fread (data, 2, 2, ifp); + tag = data[0] << 8 | data[1]; + len = (data[2] << 8 | data[3]) - 2; + if (tag <= 0xff00 || len > 255) return 0; + fread (data, 1, len, ifp); + switch (tag) { + case 0xffc3: + jh->bits = data[0]; + jh->high = data[1] << 8 | data[2]; + jh->wide = data[3] << 8 | data[4]; + jh->clrs = data[5]; + break; + case 0xffc4: + for (dp = data; dp < data+len && *dp < 4; ) { + jh->huff[*dp] = free_decode; + dp = make_decoder (++dp, 0); + } + break; + case 0xffdd: + jh->restart = data[0] << 8 | data[1]; + } + } while (tag != 0xffda); + jh->row = calloc (jh->wide*jh->clrs, 2); + merror (jh->row, " jpeg_start()"); + zero_after_ff = 1; + return 1; +} + +int CLASS ljpeg_diff (struct decode *dindex) +{ + int len, diff; + + while (dindex->branch[0]) + dindex = dindex->branch[getbits(1)]; + len = dindex->leaf; + if (len == 16 && (!dng_version || dng_version >= 0x1010000)) + return -32768; + diff = getbits(len); + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + return diff; +} + +void CLASS ljpeg_row (int jrow, struct jhead *jh) +{ + int col, c, diff; + ushort *outp=jh->row; + + if (jrow * jh->wide % jh->restart == 0) { + FORC4 jh->vpred[c] = 1 << (jh->bits-1); + if (jrow) get2(); /* Eat the FF Dx marker */ + getbits(-1); + } + for (col=0; col < jh->wide; col++) + for (c=0; c < jh->clrs; c++) { + diff = ljpeg_diff (jh->huff[c]); + *outp = col ? outp[-jh->clrs]+diff : (jh->vpred[c] += diff); + outp++; + } +} + +void CLASS lossless_jpeg_load_raw() +{ + int jwide, jrow, jcol, val, jidx, i, row, col; + struct jhead jh; + int min=INT_MAX; + + if (!ljpeg_start (&jh)) return; + jwide = jh.wide * jh.clrs; + + for (jrow=0; jrow < jh.high; jrow++) { + ljpeg_row (jrow, &jh); + for (jcol=0; jcol < jwide; jcol++) { + val = jh.row[jcol]; + if (jh.bits <= 12) + val = curve[val]; + jidx = jrow*jwide + jcol; + if (raw_width == 5108) { + i = jidx / (1680*jh.high); + if (i < 2) { + row = jidx / 1680 % jh.high; + col = jidx % 1680 + i*1680; + } else { + jidx -= 2*1680*jh.high; + row = jidx / 1748; + col = jidx % 1748 + 2*1680; + } + } else if (raw_width == 4476 || raw_width == 3516) { + row = jidx / (raw_width/2); + col = jidx % (raw_width/2); + if (row >= raw_height) { + row -= raw_height; + col += raw_width/2; + } + } else { + row = jidx / raw_width; + col = jidx % raw_width; + } + if ((unsigned) (row-top_margin) >= height) continue; + if ((unsigned) (col-left_margin) < width) { + BAYER(row-top_margin,col-left_margin) = val; + if (min > val) min = val; + } else + black += val; + } + } + free (jh.row); + if (raw_width > width) + black /= (raw_width - width) * height; + if (!strcasecmp(make,"KODAK")) + black = min; +} + +void CLASS adobe_copy_pixel (int row, int col, ushort **rp) +{ + unsigned r, c; + + r = row -= top_margin; + c = col -= left_margin; + if (fuji_secondary && use_secondary) (*rp)++; + if (filters) { + if (fuji_width) { + r = row + fuji_width - 1 - (col >> 1); + c = row + ((col+1) >> 1); + } + if (r < height && c < width) + BAYER(r,c) = **rp < 0x1000 ? curve[**rp] : **rp; + *rp += 1 + fuji_secondary; + } else { + if (r < height && c < width) + for (c=0; c < tiff_samples; c++) + image[row*width+col][c] = (*rp)[c] < 0x1000 ? curve[(*rp)[c]]:(*rp)[c]; + *rp += tiff_samples; + } + if (fuji_secondary && use_secondary) (*rp)--; +} + +void CLASS adobe_dng_load_raw_lj() +{ + int save, twide, trow=0, tcol=0, jrow, jcol; + struct jhead jh; + ushort *rp; + + while (1) { + save = ftell(ifp); + fseek (ifp, get4(), SEEK_SET); + if (!ljpeg_start (&jh)) break; + if (trow >= raw_height) break; + if (jh.high > raw_height-trow) + jh.high = raw_height-trow; + twide = jh.wide; + if (filters) twide *= jh.clrs; + else colors = jh.clrs; + if (fuji_secondary) twide /= 2; + if (twide > raw_width-tcol) + twide = raw_width-tcol; + + for (jrow=0; jrow < jh.high; jrow++) { + ljpeg_row (jrow, &jh); + for (rp=jh.row, jcol=0; jcol < twide; jcol++) + adobe_copy_pixel (trow+jrow, tcol+jcol, &rp); + } + fseek (ifp, save+4, SEEK_SET); + if ((tcol += twide) >= raw_width) { + tcol = 0; + trow += jh.high; + } + free (jh.row); + } +} + +void CLASS adobe_dng_load_raw_nc() +{ + ushort *pixel, *rp; + int row, col; + + pixel = calloc (raw_width * tiff_samples, sizeof *pixel); + merror (pixel, "adobe_dng_load_raw_nc()"); + for (row=0; row < raw_height; row++) { + if (tiff_bps == 16) + read_shorts (pixel, raw_width * tiff_samples); + else { + getbits(-1); + for (col=0; col < raw_width * tiff_samples; col++) + pixel[col] = getbits(tiff_bps); + } + for (rp=pixel, col=0; col < raw_width; col++) + adobe_copy_pixel (row, col, &rp); + } + free (pixel); +} + +void CLASS nikon_compressed_load_raw() +{ + static const uchar nikon_tree[] = { + 0,1,5,1,1,1,1,1,1,2,0,0,0,0,0,0, + 5,4,3,6,2,7,1,0,8,9,11,10,12 + }; + int csize, row, col, i, diff; + ushort vpred[4], hpred[2], *curve; + + init_decoder(); + make_decoder (nikon_tree, 0); + + fseek (ifp, nikon_curve_offset, SEEK_SET); + read_shorts (vpred, 4); + csize = get2(); + curve = calloc (csize, sizeof *curve); + merror (curve, "nikon_compressed_load_raw()"); + read_shorts (curve, csize); + + fseek (ifp, data_offset, SEEK_SET); + getbits(-1); + + for (row=0; row < height; row++) + for (col=0; col < raw_width; col++) + { + diff = ljpeg_diff (first_decode); + if (col < 2) { + i = 2*(row & 1) + (col & 1); + vpred[i] += diff; + hpred[col] = vpred[i]; + } else + hpred[col & 1] += diff; + if ((unsigned) (col-left_margin) >= width) continue; + diff = hpred[col & 1]; + if (diff >= csize) diff = csize-1; + BAYER(row,col-left_margin) = curve[diff]; + } + free (curve); +} + +void CLASS nikon_load_raw() +{ + int irow, row, col, i; + + getbits(-1); + for (irow=0; irow < height; irow++) { + row = irow; + if (model[0] == 'E') { + row = irow * 2 % height + irow / (height/2); + if (row == 1 && data_offset == 0) { + fseek (ifp, 0, SEEK_END); + fseek (ifp, ftell(ifp)/2, SEEK_SET); + getbits(-1); + } + } + for (col=0; col < raw_width; col++) { + i = getbits(12); + if ((unsigned) (col-left_margin) < width) + BAYER(row,col-left_margin) = i; + if (tiff_data_compression == 34713 && (col % 10) == 9) + getbits(8); + } + } +} + +/* + Figure out if a NEF file is compressed. These fancy heuristics + are only needed for the D100, thanks to a bug in some cameras + that tags all images as "compressed". + */ +int CLASS nikon_is_compressed() +{ + uchar test[256]; + int i; + + if (tiff_data_compression != 34713) + return 0; + if (strcmp(model,"D100")) + return 1; + fseek (ifp, data_offset, SEEK_SET); + fread (test, 1, 256, ifp); + for (i=15; i < 256; i+=16) + if (test[i]) return 1; + return 0; +} + +/* + Returns 1 for a Coolpix 990, 0 for a Coolpix 995. + */ +int CLASS nikon_e990() +{ + int i, histo[256]; + const uchar often[] = { 0x00, 0x55, 0xaa, 0xff }; + + memset (histo, 0, sizeof histo); + fseek (ifp, 2064*1540*3/4, SEEK_SET); + for (i=0; i < 2000; i++) + histo[fgetc(ifp)]++; + for (i=0; i < 4; i++) + if (histo[often[i]] > 400) + return 1; + return 0; +} + +/* + Returns 1 for a Coolpix 2100, 0 for anything else. + */ +int CLASS nikon_e2100() +{ + uchar t[12]; + int i; + + fseek (ifp, 0, SEEK_SET); + for (i=0; i < 1024; i++) { + fread (t, 1, 12, ifp); + if (((t[2] & t[4] & t[7] & t[9]) >> 4 + & t[1] & t[6] & t[8] & t[11] & 3) != 3) + return 0; + } + return 1; +} + +/* + Returns 0 for a Pentax Optio 33WR, + 1 for a Nikon E3700, + 2 for an Olympus C740UZ. + */ +int CLASS nikon_3700() +{ + int i, sum[] = { 0, 0 }; + uchar tail[952]; + + fseek (ifp, -sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (i=0; i < sizeof tail; i++) + sum[(i>>2) & 1] += tail[i]; + if (sum[1] > 4*sum[0]) return 2; + return sum[0] > 4*sum[1]; +} + +/* + Separates a Minolta DiMAGE Z2 from a Nikon E4300. + */ +int CLASS minolta_z2() +{ + int i; + char tail[424]; + + fseek (ifp, -sizeof tail, SEEK_END); + fread (tail, 1, sizeof tail, ifp); + for (i=0; i < sizeof tail; i++) + if (tail[i]) return 1; + return 0; +} + +/* Here raw_width is in bytes, not pixels. */ +void CLASS nikon_e900_load_raw() +{ + int offset=0, irow, row, col; + + for (irow=0; irow < height; irow++) { + row = irow * 2 % height; + if (row == 1) + offset = - (-offset & -4096); + fseek (ifp, offset, SEEK_SET); + offset += raw_width; + getbits(-1); + for (col=0; col < width; col++) + BAYER(row,col) = getbits(10); + } +} + +void CLASS nikon_e2100_load_raw() +{ + uchar data[3456], *dp; + ushort pixel[2304], *pix; + int row, col; + + for (row=0; row <= height; row+=2) { + if (row == height) { + fseek (ifp, ((width==1616) << 13) - (-ftell(ifp) & -2048), SEEK_SET); + row = 1; + } + fread (data, 1, width*3/2, ifp); + for (dp=data, pix=pixel; pix < pixel+width; dp+=12, pix+=8) { + pix[0] = (dp[2] >> 4) + (dp[ 3] << 4); + pix[1] = (dp[2] << 8) + dp[ 1]; + pix[2] = (dp[7] >> 4) + (dp[ 0] << 4); + pix[3] = (dp[7] << 8) + dp[ 6]; + pix[4] = (dp[4] >> 4) + (dp[ 5] << 4); + pix[5] = (dp[4] << 8) + dp[11]; + pix[6] = (dp[9] >> 4) + (dp[10] << 4); + pix[7] = (dp[9] << 8) + dp[ 8]; + } + for (col=0; col < width; col++) + BAYER(row,col) = (pixel[col] & 0xfff); + } +} + +/* + The Fuji Super CCD is just a Bayer grid rotated 45 degrees. + */ +void CLASS fuji_load_raw() +{ + ushort *pixel; + int row, col, r, c; + + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "fuji_load_raw()"); + for (row=0; row < raw_height; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < fuji_width << !fuji_layout; col++) { + if (fuji_layout) { + r = fuji_width - 1 - col + (row >> 1); + c = col + ((row+1) >> 1); + } else { + r = fuji_width - 1 + row - (col >> 1); + c = row + ((col+1) >> 1); + } + BAYER(r,c) = pixel[col]; + } + } + free (pixel); +} + +void CLASS rollei_load_raw() +{ + uchar pixel[10]; + unsigned iten=0, isix, i, buffer=0, row, col, todo[16]; + + isix = raw_width * raw_height * 5 / 8; + while (fread (pixel, 1, 10, ifp) == 10) { + for (i=0; i < 10; i+=2) { + todo[i] = iten++; + todo[i+1] = pixel[i] << 8 | pixel[i+1]; + buffer = pixel[i] >> 2 | buffer << 6; + } + for ( ; i < 16; i+=2) { + todo[i] = isix++; + todo[i+1] = buffer >> (14-i)*5; + } + for (i=0; i < 16; i+=2) { + row = todo[i] / raw_width - top_margin; + col = todo[i] % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = (todo[i+1] & 0x3ff); + } + } + maximum = 0x3ff; +} + +void CLASS phase_one_load_raw() +{ + int row, col, a, b; + ushort *pixel, akey, bkey, mask; + + fseek (ifp, nikon_curve_offset, SEEK_SET); + akey = get2(); + bkey = get2(); + mask = tiff_data_compression == 1 ? 0x5555:0x1354; + fseek (ifp, data_offset + top_margin*raw_width*2, SEEK_SET); + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "phase_one_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < raw_width; col+=2) { + a = pixel[col+0] ^ akey; + b = pixel[col+1] ^ bkey; + pixel[col+0] = (a & mask) | (b & ~mask); + pixel[col+1] = (b & mask) | (a & ~mask); + } + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col+left_margin]; + } + free (pixel); + maximum = 0xffff; +} + +unsigned CLASS ph1_bits (int nbits) +{ + static UINT64 bitbuf=0; + static int vbits=0; + + if (nbits == 0) + return bitbuf = vbits = 0; + if (vbits < nbits) { + bitbuf = bitbuf << 32 | (unsigned) get4(); + vbits += 32; + } + vbits -= nbits; + return bitbuf << (64 - nbits - vbits) >> (64 - nbits); +} + +void CLASS phase_one_load_raw_c() +{ + static const int length[] = { 8,7,6,9,11,10,5,12,14,13 }; + int len[2], pred[2], row, col, ncols, i, j; + ushort *pixel; + + ncols = (raw_width + 7) & -8; + pixel = calloc (ncols, sizeof *pixel); + merror (pixel, "phase_one_load_raw_c()"); + for (row=0; row < raw_height; row++) { + ph1_bits(0); + pred[0] = pred[1] = 0; + for (col=0; col < ncols; col++) { + if (col >= (raw_width & -8)) + len[0] = len[1] = 14; + else if ((col & 7) == 0) + for (i=0; i < 2; i++) { + for (j=0; j < 5 && !ph1_bits(1); j++); + if (j--) len[i] = length[j*2 + ph1_bits(1)]; + } + if ((i = len[col & 1]) == 14) + pixel[col] = pred[col & 1] = ph1_bits(16); + else + pixel[col] = pred[col & 1] += ph1_bits(i) + 1 - (1 << (i - 1)); + } + if ((unsigned) (row-top_margin) < height) + for (col=0; col < width; col++) + BAYER(row-top_margin,col) = pixel[col+left_margin]; + } + free (pixel); + maximum = 0x3fff; +} + +void CLASS leaf_load_raw() +{ + ushort *pixel; + int r, c, row, col; + + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "leaf_load_raw()"); + for (r=0; r < height-32; r+=32) + FORC3 for (row=r; row < r+32; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < width; col++) + image[row*width+col][c] = pixel[col]; + } + free (pixel); +} + +/* Here raw_width is in bytes, not pixels. */ +void CLASS packed_12_load_raw() +{ + int row, col; + + getbits(-1); + for (row=0; row < height; row++) { + for (col=0; col < width; col++) + BAYER(row,col) = getbits(12); + for (col = width*3/2; col < raw_width; col++) + getbits(8); + } +} + +void CLASS unpacked_load_raw() +{ + ushort *pixel; + int row, col; + + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "unpacked_load_raw()"); + for (row=0; row < height; row++) { + read_shorts (pixel, raw_width); + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + } + free (pixel); +} + +void CLASS olympus_e300_load_raw() +{ + uchar *data, *dp; + ushort *pixel, *pix; + int dwide, row, col; + + dwide = raw_width * 16 / 10; + data = malloc (dwide + raw_width*2); + merror (data, "olympus_e300_load_raw()"); + pixel = (ushort *) (data + dwide); + for (row=0; row < height; row++) { + fread (data, 1, dwide, ifp); + for (dp=data, pix=pixel; pix < pixel+raw_width; dp+=3, pix+=2) { + if (((dp-data) & 15) == 15) dp++; + pix[0] = dp[1] << 8 | dp[0]; + pix[1] = dp[2] << 4 | dp[1] >> 4; + } + for (col=0; col < width; col++) + BAYER(row,col) = (pixel[col] & 0xfff); + for (col=width+4; col < raw_width; col++) + black += pixel[col] & 0xfff; + } + black /= (raw_width - width - 4) * height; + free (data); +} + +void CLASS olympus_cseries_load_raw() +{ + int irow, row, col; + + for (irow=0; irow < height; irow++) { + row = irow * 2 % height + irow / (height/2); + if (row < 2) { + fseek (ifp, data_offset - row*(-width*height*3/4 & -2048), SEEK_SET); + getbits(-1); + } + for (col=0; col < width; col++) + BAYER(row,col) = getbits(12); + } +} + +void CLASS minolta_rd175_load_raw() +{ + uchar pixel[768]; + unsigned irow, box, row, col; + + for (irow=0; irow < 1481; irow++) { + fread (pixel, 1, 768, ifp); + box = irow / 82; + row = irow % 82 * 12 + ((box < 12) ? box | 1 : (box-12)*2); + switch (irow) { + case 1477: case 1479: continue; + case 1476: row = 984; break; + case 1480: row = 985; break; + case 1478: row = 985; box = 1; + } + if ((box < 12) && (box & 1)) { + for (col=0; col < 1533; col++, row ^= 1) + if (col != 1) BAYER(row,col) = (col+1) & 2 ? + pixel[col/2-1] + pixel[col/2+1] : pixel[col/2] << 1; + BAYER(row,1) = pixel[1] << 1; + BAYER(row,1533) = pixel[765] << 1; + } else + for (col=row & 1; col < 1534; col+=2) + BAYER(row,col) = pixel[col/2] << 1; + } + maximum = 0xff << 1; +} + +void CLASS eight_bit_load_raw() +{ + uchar *pixel; + int row, col; + + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "eight_bit_load_raw()"); + for (row=0; row < height; row++) { + fread (pixel, 1, raw_width, ifp); + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + } + free (pixel); + maximum = 0xff; +} + +void CLASS casio_qv5700_load_raw() +{ + uchar data[3232], *dp; + ushort pixel[2576], *pix; + int row, col; + + for (row=0; row < height; row++) { + fread (data, 1, 3232, ifp); + for (dp=data, pix=pixel; dp < data+3220; dp+=5, pix+=4) { + pix[0] = (dp[0] << 2) + (dp[1] >> 6); + pix[1] = (dp[1] << 4) + (dp[2] >> 4); + pix[2] = (dp[2] << 6) + (dp[3] >> 2); + pix[3] = (dp[3] << 8) + (dp[4] ); + } + for (col=0; col < width; col++) + BAYER(row,col) = (pixel[col] & 0x3ff); + } + maximum = 0x3fc; +} + +void CLASS nucore_load_raw() +{ + ushort *pixel; + int irow, row, col; + + pixel = calloc (width, 2); + merror (pixel, "nucore_load_raw()"); + for (irow=0; irow < height; irow++) { + read_shorts (pixel, width); + row = irow/2 + height/2 * (irow & 1); + for (col=0; col < width; col++) + BAYER(row,col) = pixel[col]; + } + free (pixel); +} + +const int * CLASS make_decoder_int (const int *source, int level) +{ + struct decode *cur; + + cur = free_decode++; + if (level < source[0]) { + cur->branch[0] = free_decode; + source = make_decoder_int (source, level+1); + cur->branch[1] = free_decode; + source = make_decoder_int (source, level+1); + } else { + cur->leaf = source[1]; + source += 2; + } + return source; +} + +int CLASS radc_token (int tree) +{ + int t; + static struct decode *dstart[18], *dindex; + static const int *s, source[] = { + 1,1, 2,3, 3,4, 4,2, 5,7, 6,5, 7,6, 7,8, + 1,0, 2,1, 3,3, 4,4, 5,2, 6,7, 7,6, 8,5, 8,8, + 2,1, 2,3, 3,0, 3,2, 3,4, 4,6, 5,5, 6,7, 6,8, + 2,0, 2,1, 2,3, 3,2, 4,4, 5,6, 6,7, 7,5, 7,8, + 2,1, 2,4, 3,0, 3,2, 3,3, 4,7, 5,5, 6,6, 6,8, + 2,3, 3,1, 3,2, 3,4, 3,5, 3,6, 4,7, 5,0, 5,8, + 2,3, 2,6, 3,0, 3,1, 4,4, 4,5, 4,7, 5,2, 5,8, + 2,4, 2,7, 3,3, 3,6, 4,1, 4,2, 4,5, 5,0, 5,8, + 2,6, 3,1, 3,3, 3,5, 3,7, 3,8, 4,0, 5,2, 5,4, + 2,0, 2,1, 3,2, 3,3, 4,4, 4,5, 5,6, 5,7, 4,8, + 1,0, 2,2, 2,-2, + 1,-3, 1,3, + 2,-17, 2,-5, 2,5, 2,17, + 2,-7, 2,2, 2,9, 2,18, + 2,-18, 2,-9, 2,-2, 2,7, + 2,-28, 2,28, 3,-49, 3,-9, 3,9, 4,49, 5,-79, 5,79, + 2,-1, 2,13, 2,26, 3,39, 4,-16, 5,55, 6,-37, 6,76, + 2,-26, 2,-13, 2,1, 3,-39, 4,16, 5,-55, 6,-76, 6,37 + }; + + if (free_decode == first_decode) + for (s=source, t=0; t < 18; t++) { + dstart[t] = free_decode; + s = make_decoder_int (s, 0); + } + if (tree == 18) { + if (kodak_cbpp == 243) + return (getbits(6) << 2) + 2; /* most DC50 photos */ + else + return (getbits(5) << 3) + 4; /* DC40, Fotoman Pixtura */ + } + for (dindex = dstart[tree]; dindex->branch[0]; ) + dindex = dindex->branch[getbits(1)]; + return dindex->leaf; +} + +#define FORYX for (y=1; y < 3; y++) for (x=col+1; x >= col; x--) + +#define PREDICTOR (c ? (buf[c][y-1][x] + buf[c][y][x+1]) / 2 \ +: (buf[c][y-1][x+1] + 2*buf[c][y-1][x] + buf[c][y][x+1]) / 4) + +void CLASS kodak_radc_load_raw() +{ + int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val; + short last[3] = { 16,16,16 }, mul[3], buf[3][3][386]; + + init_decoder(); + getbits(-1); + for (i=0; i < sizeof(buf)/sizeof(short); i++) + buf[0][0][i] = 2048; + for (row=0; row < height; row+=4) { + FORC3 mul[c] = getbits(6); + FORC3 { + val = ((0x1000000/last[c] + 0x7ff) >> 12) * mul[c]; + s = val > 65564 ? 10:12; + x = ~(-1 << (s-1)); + val <<= 12-s; + for (i=0; i < sizeof(buf[0])/sizeof(short); i++) + buf[c][0][i] = (buf[c][0][i] * val + x) >> s; + last[c] = mul[c]; + for (r=0; r <= !c; r++) { + buf[c][1][width/2] = buf[c][2][width/2] = mul[c] << 7; + for (tree=1, col=width/2; col > 0; ) { + if ((tree = radc_token(tree))) { + col -= 2; + if (tree == 8) + FORYX buf[c][y][x] = radc_token(tree+10) * mul[c]; + else + FORYX buf[c][y][x] = radc_token(tree+10) * 16 + PREDICTOR; + } else + do { + nreps = (col > 2) ? radc_token(9) + 1 : 1; + for (rep=0; rep < 8 && rep < nreps && col > 0; rep++) { + col -= 2; + FORYX buf[c][y][x] = PREDICTOR; + if (rep & 1) { + step = radc_token(10) << 4; + FORYX buf[c][y][x] += step; + } + } + } while (nreps == 9); + } + for (y=0; y < 2; y++) + for (x=0; x < width/2; x++) { + val = (buf[c][y+1][x] << 4) / mul[c]; + if (val < 0) val = 0; + if (c) + BAYER(row+y*2+c-1,x*2+2-c) = val; + else + BAYER(row+r*2+y,x*2+y) = val; + } + memcpy (buf[c][0]+!c, buf[c][2], sizeof buf[c][0]-2*!c); + } + } + for (y=row; y < row+4; y++) + for (x=0; x < width; x++) + if ((x+y) & 1) { + val = (BAYER(y,x)-2048)*2 + (BAYER(y,x-1)+BAYER(y,x+1))/2; + if (val < 0) val = 0; + BAYER(y,x) = val; + } + } + maximum = 10000; +} + +#undef FORYX +#undef PREDICTOR + +#ifdef NO_JPEG +void CLASS kodak_jpeg_load_raw() {} +#else + +METHODDEF(boolean) +fill_input_buffer (j_decompress_ptr cinfo) +{ + static uchar jpeg_buffer[4096]; + size_t nbytes; + + nbytes = fread (jpeg_buffer, 1, 4096, ifp); + swab (jpeg_buffer, jpeg_buffer, nbytes); + cinfo->src->next_input_byte = jpeg_buffer; + cinfo->src->bytes_in_buffer = nbytes; + return TRUE; +} + +void CLASS kodak_jpeg_load_raw() +{ + struct jpeg_decompress_struct cinfo; + struct jpeg_error_mgr jerr; + JSAMPARRAY buf; + JSAMPLE (*pixel)[3]; + int row, col; + + cinfo.err = jpeg_std_error (&jerr); + jpeg_create_decompress (&cinfo); + jpeg_stdio_src (&cinfo, ifp); + cinfo.src->fill_input_buffer = fill_input_buffer; + jpeg_read_header (&cinfo, TRUE); + jpeg_start_decompress (&cinfo); + if ((cinfo.output_width != width ) || + (cinfo.output_height*2 != height ) || + (cinfo.output_components != 3 )) { + fprintf (stderr, "%s: incorrect JPEG dimensions\n", ifname); + jpeg_destroy_decompress (&cinfo); + longjmp (failure, 3); + } + buf = (*cinfo.mem->alloc_sarray) + ((j_common_ptr) &cinfo, JPOOL_IMAGE, width*3, 1); + + while (cinfo.output_scanline < cinfo.output_height) { + row = cinfo.output_scanline * 2; + jpeg_read_scanlines (&cinfo, buf, 1); + pixel = (void *) buf[0]; + for (col=0; col < width; col+=2) { + BAYER(row+0,col+0) = pixel[col+0][1] << 1; + BAYER(row+1,col+1) = pixel[col+1][1] << 1; + BAYER(row+0,col+1) = pixel[col][0] + pixel[col+1][0]; + BAYER(row+1,col+0) = pixel[col][2] + pixel[col+1][2]; + } + } + jpeg_finish_decompress (&cinfo); + jpeg_destroy_decompress (&cinfo); + maximum = 0xff << 1; +} + +#endif + +void CLASS kodak_dc120_load_raw() +{ + static const int mul[4] = { 162, 192, 187, 92 }; + static const int add[4] = { 0, 636, 424, 212 }; + uchar pixel[848]; + int row, shift, col; + + for (row=0; row < height; row++) { + fread (pixel, 848, 1, ifp); + shift = row * mul[row & 3] + add[row & 3]; + for (col=0; col < width; col++) + BAYER(row,col) = (ushort) pixel[(col + shift) % 848]; + } + maximum = 0xff; +} + +void CLASS kodak_easy_load_raw() +{ + uchar *pixel; + unsigned row, col, icol; + + if (raw_width > width) + black = 0; + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "kodak_easy_load_raw()"); + for (row=0; row < height; row++) { + fread (pixel, 1, raw_width, ifp); + for (col=0; col < raw_width; col++) { + icol = col - left_margin; + if (icol < width) + BAYER(row,icol) = (ushort) curve[pixel[col]]; + else + black += curve[pixel[col]]; + } + } + free (pixel); + if (raw_width > width) + black /= (raw_width - width) * height; + if (!strncmp(model,"DC2",3)) + black = 0; + maximum = curve[0xff]; +} + +void CLASS kodak_compressed_load_raw() +{ + uchar c, blen[256]; + ushort raw[6]; + unsigned row, col, len, save, i, israw=0, bits=0, pred[2]; + INT64 bitbuf=0; + int diff; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) + { + if ((col & 255) == 0) { /* Get the bit-lengths of the */ + len = width - col; /* next 256 pixel values */ + if (len > 256) len = 256; + save = ftell(ifp); + for (israw=i=0; i < len; i+=2) { + c = fgetc(ifp); + if ((blen[i+0] = c & 15) > 12 || + (blen[i+1] = c >> 4) > 12 ) + israw = 1; + } + bitbuf = bits = pred[0] = pred[1] = 0; + if (len % 8 == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + if (israw) + fseek (ifp, save, SEEK_SET); + } + if (israw) { /* If the data is not compressed */ + switch (col & 7) { + case 0: + read_shorts (raw, 6); + diff = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12; + break; + case 1: + diff = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12; + break; + default: + diff = raw[(col & 7) - 2] & 0xfff; + } + } else { /* If the data is compressed */ + len = blen[col & 255]; /* Number of bits for this pixel */ + if (bits < len) { /* Got enough bits in the buffer? */ + for (i=0; i < 32; i+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(i^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); /* Pull bits from buffer */ + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + pred[col & 1] += diff; + diff = pred[col & 1]; + } + BAYER(row,col) = curve[diff]; + } +} + +void CLASS kodak_yuv_load_raw() +{ + uchar c, blen[384]; + unsigned row, col, len, bits=0; + INT64 bitbuf=0; + int i, li=0, si, diff, six[6], y[4], cb=0, cr=0, rgb[3]; + ushort *ip; + + for (row=0; row < height; row+=2) + for (col=0; col < width; col+=2) { + if ((col & 127) == 0) { + len = (width - col + 1) * 3 & -4; + if (len > 384) len = 384; + for (i=0; i < len; ) { + c = fgetc(ifp); + blen[i++] = c & 15; + blen[i++] = c >> 4; + } + li = bitbuf = bits = y[1] = y[3] = cb = cr = 0; + if (len % 8 == 4) { + bitbuf = fgetc(ifp) << 8; + bitbuf += fgetc(ifp); + bits = 16; + } + } + for (si=0; si < 6; si++) { + len = blen[li++]; + if (bits < len) { + for (i=0; i < 32; i+=8) + bitbuf += (INT64) fgetc(ifp) << (bits+(i^8)); + bits += 32; + } + diff = bitbuf & (0xffff >> (16-len)); + bitbuf >>= len; + bits -= len; + if ((diff & (1 << (len-1))) == 0) + diff -= (1 << len) - 1; + six[si] = diff; + } + y[0] = six[0] + y[1]; + y[1] = six[1] + y[0]; + y[2] = six[2] + y[3]; + y[3] = six[3] + y[2]; + cb += six[4]; + cr += six[5]; + for (i=0; i < 4; i++) { + ip = image[(row+(i >> 1))*width + col+(i & 1)]; + rgb[0] = y[i] + cr; + rgb[1] = y[i]; + rgb[2] = y[i] + cb; + FORC3 if (rgb[c] > 0) ip[c] = curve[rgb[c]]; + } + } +} + +void CLASS sony_decrypt (unsigned *data, int len, int start, int key) +{ + static unsigned pad[128], p; + + if (start) { + for (p=0; p < 4; p++) + pad[p] = key = key * 48828125 + 1; + pad[3] = pad[3] << 1 | (pad[0]^pad[2]) >> 31; + for (p=4; p < 127; p++) + pad[p] = (pad[p-4]^pad[p-2]) << 1 | (pad[p-3]^pad[p-1]) >> 31; + for (p=0; p < 127; p++) + pad[p] = htonl(pad[p]); + } + while (len--) + *data++ ^= pad[p++ & 127] = pad[(p+1) & 127] ^ pad[(p+65) & 127]; +} + +void CLASS sony_load_raw() +{ + uchar head[40]; + ushort *pixel; + unsigned i, key, row, col; + + fseek (ifp, 200896, SEEK_SET); + fseek (ifp, (unsigned) fgetc(ifp)*4 - 1, SEEK_CUR); + order = 0x4d4d; + key = get4(); + fseek (ifp, 164600, SEEK_SET); + fread (head, 1, 40, ifp); + sony_decrypt ((void *) head, 10, 1, key); + for (i=26; i-- > 22; ) + key = key << 8 | head[i]; + fseek (ifp, data_offset, SEEK_SET); + pixel = calloc (raw_width, sizeof *pixel); + merror (pixel, "sony_load_raw()"); + for (row=0; row < height; row++) { + fread (pixel, 2, raw_width, ifp); + sony_decrypt ((void *) pixel, raw_width/2, !row, key); + for (col=9; col < left_margin; col++) + black += ntohs(pixel[col]); + for (col=0; col < width; col++) + BAYER(row,col) = ntohs(pixel[col+left_margin]); + } + free (pixel); + if (left_margin > 9) + black /= (left_margin-9) * height; + maximum = 0x3ff0; +} + +#define HOLE(row) ((holes >> (((row) - raw_height) & 7)) & 1) + +/* Kudos to Rich Taylor for figuring out SMaL's compression algorithm. */ +void CLASS smal_decode_segment (unsigned seg[2][2], int holes) +{ + uchar hist[3][13] = { + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 7, 7, 0, 0, 63, 55, 47, 39, 31, 23, 15, 7, 0 }, + { 3, 3, 0, 0, 63, 47, 31, 15, 0 } }; + int low, high=0xff, carry=0, nbits=8; + int s, count, bin, next, i, sym[3]; + uchar diff, pred[]={0,0}; + ushort data=0, range=0; + unsigned pix, row, col; + + fseek (ifp, seg[0][1]+1, SEEK_SET); + getbits(-1); + for (pix=seg[0][0]; pix < seg[1][0]; pix++) { + for (s=0; s < 3; s++) { + data = data << nbits | getbits(nbits); + if (carry < 0) + carry = (nbits += carry+1) < 1 ? nbits-1 : 0; + while (--nbits >= 0) + if ((data >> nbits & 0xff) == 0xff) break; + if (nbits > 0) + data = ((data & ((1 << (nbits-1)) - 1)) << 1) | + ((data + (((data & (1 << (nbits-1)))) << 1)) & (-1 << nbits)); + if (nbits >= 0) { + data += getbits(1); + carry = nbits - 8; + } + count = ((((data-range+1) & 0xffff) << 2) - 1) / (high >> 4); + for (bin=0; hist[s][bin+5] > count; bin++); + low = hist[s][bin+5] * (high >> 4) >> 2; + if (bin) high = hist[s][bin+4] * (high >> 4) >> 2; + high -= low; + for (nbits=0; high << nbits < 128; nbits++); + range = (range+low) << nbits; + high <<= nbits; + next = hist[s][1]; + if (++hist[s][2] > hist[s][3]) { + next = (next+1) & hist[s][0]; + hist[s][3] = (hist[s][next+4] - hist[s][next+5]) >> 2; + hist[s][2] = 1; + } + if (hist[s][hist[s][1]+4] - hist[s][hist[s][1]+5] > 1) { + if (bin < hist[s][1]) + for (i=bin; i < hist[s][1]; i++) hist[s][i+5]--; + else if (next <= bin) + for (i=hist[s][1]; i < bin; i++) hist[s][i+5]++; + } + hist[s][1] = next; + sym[s] = bin; + } + diff = sym[2] << 5 | sym[1] << 2 | (sym[0] & 3); + if (sym[0] & 4) + diff = diff ? -diff : 0x80; + if (ftell(ifp) + 12 >= seg[1][1]) + diff = 0; + pred[pix & 1] += diff; + row = pix / raw_width - top_margin; + col = pix % raw_width - left_margin; + if (row < height && col < width) + BAYER(row,col) = pred[pix & 1]; + if (!(pix & 1) && HOLE(row)) pix += 2; + } + maximum = 0xff; +} + +void CLASS smal_v6_load_raw() +{ + unsigned seg[2][2]; + + fseek (ifp, 16, SEEK_SET); + seg[0][0] = 0; + seg[0][1] = get2(); + seg[1][0] = raw_width * raw_height; + seg[1][1] = INT_MAX; + smal_decode_segment (seg, 0); + use_gamma = 0; +} + +int CLASS median4 (int *p) +{ + int min, max, sum, i; + + min = max = sum = p[0]; + for (i=1; i < 4; i++) { + sum += p[i]; + if (min > p[i]) min = p[i]; + if (max < p[i]) max = p[i]; + } + return (sum - min - max) >> 1; +} + +void CLASS fill_holes (int holes) +{ + int row, col, val[4]; + + for (row=2; row < height-2; row++) { + if (!HOLE(row)) continue; + for (col=1; col < width-1; col+=4) { + val[0] = BAYER(row-1,col-1); + val[1] = BAYER(row-1,col+1); + val[2] = BAYER(row+1,col-1); + val[3] = BAYER(row+1,col+1); + BAYER(row,col) = median4(val); + } + for (col=2; col < width-2; col+=4) + if (HOLE(row-2) || HOLE(row+2)) + BAYER(row,col) = (BAYER(row,col-2) + BAYER(row,col+2)) >> 1; + else { + val[0] = BAYER(row,col-2); + val[1] = BAYER(row,col+2); + val[2] = BAYER(row-2,col); + val[3] = BAYER(row+2,col); + BAYER(row,col) = median4(val); + } + } +} + +void CLASS smal_v9_load_raw() +{ + unsigned seg[256][2], offset, nseg, holes, i; + + fseek (ifp, 67, SEEK_SET); + offset = get4(); + nseg = fgetc(ifp); + fseek (ifp, offset, SEEK_SET); + for (i=0; i < nseg*2; i++) + seg[0][i] = get4() + data_offset*(i & 1); + fseek (ifp, 78, SEEK_SET); + holes = fgetc(ifp); + fseek (ifp, 88, SEEK_SET); + seg[nseg][0] = raw_height * raw_width; + seg[nseg][1] = get4() + data_offset; + for (i=0; i < nseg; i++) + smal_decode_segment (seg+i, holes); + if (holes) fill_holes (holes); +} + +/* BEGIN GPL BLOCK */ + +void CLASS foveon_decoder (unsigned huff[1024], unsigned code) +{ + struct decode *cur; + int i, len; + + cur = free_decode++; + if (free_decode > first_decode+2048) { + fprintf (stderr, "%s: decoder table overflow\n", ifname); + longjmp (failure, 2); + } + if (code) + for (i=0; i < 1024; i++) + if (huff[i] == code) { + cur->leaf = i; + return; + } + if ((len = code >> 27) > 26) return; + code = (len+1) << 27 | (code & 0x3ffffff) << 1; + + cur->branch[0] = free_decode; + foveon_decoder (huff, code); + cur->branch[1] = free_decode; + foveon_decoder (huff, code+1); +} + +void CLASS foveon_load_camf() +{ + unsigned key, i, val; + + fseek (ifp, meta_offset, SEEK_SET); + key = get4(); + fread (meta_data, 1, meta_length, ifp); + for (i=0; i < meta_length; i++) { + key = (key * 1597 + 51749) % 244944; + val = key * (INT64) 301593171 >> 24; + meta_data[i] ^= ((((key << 8) - val) >> 1) + val) >> 17; + } +} + +void CLASS foveon_load_raw() +{ + struct decode *dindex; + short diff[1024], pred[3]; + unsigned huff[1024], bitbuf=0; + int fixed, row, col, bit=-1, c, i; + + fixed = get4(); + read_shorts ((ushort *) diff, 1024); + if (!fixed) { + for (i=0; i < 1024; i++) + huff[i] = get4(); + init_decoder(); + foveon_decoder (huff, 0); + } + for (row=0; row < height; row++) { + memset (pred, 0, sizeof pred); + if (!bit && !fixed) get4(); + for (col=bit=0; col < width; col++) { + if (fixed) { + bitbuf = get4(); + FORC3 pred[2-c] += diff[bitbuf >> c*10 & 0x3ff]; + } + else FORC3 { + for (dindex=first_decode; dindex->branch[0]; ) { + if ((bit = (bit-1) & 31) == 31) + for (i=0; i < 4; i++) + bitbuf = (bitbuf << 8) + fgetc(ifp); + dindex = dindex->branch[bitbuf >> bit & 1]; + } + pred[c] += diff[dindex->leaf]; + } + FORC3 image[row*width+col][c] = pred[c]; + } + } + foveon_load_camf(); + maximum = clip_max = 0xffff; +} + +char * CLASS foveon_camf_param (char *block, char *param) +{ + unsigned idx, num; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'P') continue; + if (strcmp (block, pos+sget4(pos+12))) continue; + cp = pos + sget4(pos+16); + num = sget4(cp); + dp = pos + sget4(cp+4); + while (num--) { + cp += 8; + if (!strcmp (param, dp+sget4(cp))) + return dp+sget4(cp+4); + } + } + return NULL; +} + +void * CLASS foveon_camf_matrix (int dim[3], char *name) +{ + unsigned i, idx, type, ndim, size, *mat; + char *pos, *cp, *dp; + + for (idx=0; idx < meta_length; idx += sget4(pos+8)) { + pos = meta_data + idx; + if (strncmp (pos, "CMb", 3)) break; + if (pos[3] != 'M') continue; + if (strcmp (name, pos+sget4(pos+12))) continue; + dim[0] = dim[1] = dim[2] = 1; + cp = pos + sget4(pos+16); + type = sget4(cp); + if ((ndim = sget4(cp+4)) > 3) break; + dp = pos + sget4(cp+8); + for (i=ndim; i--; ) { + cp += 12; + dim[i] = sget4(cp); + } + if ((size = dim[0]*dim[1]*dim[2]) > meta_length/4) break; + mat = malloc (size * 4); + merror (mat, "foveon_camf_matrix()"); + for (i=0; i < size; i++) + if (type && type != 6) + mat[i] = sget4(dp + i*4); + else + mat[i] = sget4(dp + i*2) & 0xffff; + return mat; + } + fprintf (stderr, "%s: \"%s\" matrix not found!\n", ifname, name); + return NULL; +} + +int CLASS foveon_fixed (void *ptr, int size, char *name) +{ + void *dp; + int dim[3]; + + dp = foveon_camf_matrix (dim, name); + if (!dp) return 0; + memcpy (ptr, dp, size*4); + free (dp); + return 1; +} + +float CLASS foveon_avg (short *pix, int range[2], float cfilt) +{ + int i; + float val, min=FLT_MAX, max=-FLT_MAX, sum=0; + + for (i=range[0]; i <= range[1]; i++) { + sum += val = pix[i*4] + (pix[i*4]-pix[(i-1)*4]) * cfilt; + if (min > val) min = val; + if (max < val) max = val; + } + return (sum - min - max) / (range[1] - range[0] - 1); +} + +short * CLASS foveon_make_curve (double max, double mul, double filt) +{ + short *curve; + int i, size; + double x; + + if (!filt) filt = 0.8; + size = 4*M_PI*max / filt; + curve = calloc (size+1, sizeof *curve); + merror (curve, "foveon_make_curve()"); + curve[0] = size; + for (i=0; i < size; i++) { + x = i*filt/max/4; + curve[i+1] = (cos(x)+1)/2 * tanh(i*filt/mul) * mul + 0.5; + } + return curve; +} + +void CLASS foveon_make_curves + (short **curvep, float dq[3], float div[3], float filt) +{ + double mul[3], max=0; + int c; + + FORC3 mul[c] = dq[c]/div[c]; + FORC3 if (max < mul[c]) max = mul[c]; + FORC3 curvep[c] = foveon_make_curve (max, mul[c], filt); +} + +int CLASS foveon_apply_curve (short *curve, int i) +{ + if (abs(i) >= curve[0]) return 0; + return i < 0 ? -curve[1-i] : curve[1+i]; +} + +#define image ((short (*)[4]) image) + +void CLASS foveon_interpolate() +{ + static const short hood[] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; + short *pix, prev[3], *curve[8], (*shrink)[3]; + float cfilt=0, ddft[3][3][2], ppm[3][3][3]; + float cam_xyz[3][3], correct[3][3], last[3][3], trans[3][3]; + float chroma_dq[3], color_dq[3], diag[3][3], div[3]; + float (*black)[3], (*sgain)[3], (*sgrow)[3]; + float fsum[3], val, frow, num; + int row, col, c, i, j, diff, sgx, irow, sum, min, max, limit; + int dim[3], dscr[2][2], dstb[4], (*smrow[7])[3], total[4], ipix[3]; + int work[3][3], smlast, smred, smred_p=0, dev[3]; + int satlev[3], keep[4], active[4]; + unsigned *badpix; + double dsum=0, trsum[3]; + char str[128], *cp; + + if (verbose) + fprintf (stderr, "Foveon interpolation...\n"); + + foveon_fixed (dscr, 4, "DarkShieldColRange"); + foveon_fixed (ppm[0][0], 27, "PostPolyMatrix"); + foveon_fixed (satlev, 3, "SaturationLevel"); + foveon_fixed (keep, 4, "KeepImageArea"); + foveon_fixed (active, 4, "ActiveImageArea"); + foveon_fixed (chroma_dq, 3, "ChromaDQ"); + foveon_fixed (color_dq, 3, + foveon_camf_param ("IncludeBlocks", "ColorDQ") ? + "ColorDQ" : "ColorDQCamRGB"); + if (foveon_camf_param ("IncludeBlocks", "ColumnFilter")) + foveon_fixed (&cfilt, 1, "ColumnFilter"); + + memset (ddft, 0, sizeof ddft); + if (!foveon_camf_param ("IncludeBlocks", "DarkDrift") + || !foveon_fixed (ddft[1][0], 12, "DarkDrift")) + for (i=0; i < 2; i++) { + foveon_fixed (dstb, 4, i ? "DarkShieldBottom":"DarkShieldTop"); + for (row = dstb[1]; row <= dstb[3]; row++) + for (col = dstb[0]; col <= dstb[2]; col++) + FORC3 ddft[i+1][c][1] += (short) image[row*width+col][c]; + FORC3 ddft[i+1][c][1] /= (dstb[3]-dstb[1]+1) * (dstb[2]-dstb[0]+1); + } + + if (!(cp = foveon_camf_param ("WhiteBalanceIlluminants", model2))) + { fprintf (stderr, "%s: Invalid white balance \"%s\"\n", ifname, model2); + return; } + foveon_fixed (cam_xyz, 9, cp); + foveon_fixed (correct, 9, + foveon_camf_param ("WhiteBalanceCorrections", model2)); + memset (last, 0, sizeof last); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 last[i][j] += correct[i][c] * cam_xyz[c][j]; + + sprintf (str, "%sRGBNeutral", model2); + if (foveon_camf_param ("IncludeBlocks", str)) + foveon_fixed (div, 3, str); + else { + #define LAST(x,y) last[(i+x)%3][(c+y)%3] + for (i=0; i < 3; i++) + FORC3 diag[c][i] = LAST(1,1)*LAST(2,2) - LAST(1,2)*LAST(2,1); + #undef LAST + FORC3 div[c] = diag[c][0]*0.3127 + diag[c][1]*0.329 + diag[c][2]*0.3583; + } + num = 0; + FORC3 if (num < div[c]) num = div[c]; + FORC3 div[c] /= num; + + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += rgb_cam[i][c] * last[c][j] * div[j]; + FORC3 trsum[c] = trans[c][0] + trans[c][1] + trans[c][2]; + dsum = (6*trsum[0] + 11*trsum[1] + 3*trsum[2]) / 20; + for (i=0; i < 3; i++) + FORC3 last[i][c] = trans[i][c] * dsum / trsum[i]; + memset (trans, 0, sizeof trans); + for (i=0; i < 3; i++) + for (j=0; j < 3; j++) + FORC3 trans[i][j] += (i==c ? 32 : -1) * last[c][j] / 30; + + foveon_make_curves (curve, color_dq, div, cfilt); + FORC3 chroma_dq[c] /= 3; + foveon_make_curves (curve+3, chroma_dq, div, cfilt); + FORC3 dsum += chroma_dq[c] / div[c]; + curve[6] = foveon_make_curve (dsum, dsum, cfilt); + curve[7] = foveon_make_curve (dsum*2, dsum*2, cfilt); + + sgain = foveon_camf_matrix (dim, "SpatialGain"); + if (!sgain) return; + sgrow = calloc (dim[1], sizeof *sgrow); + sgx = (width + dim[1]-2) / (dim[1]-1); + + black = calloc (height, sizeof *black); + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + FORC3 black[row][c] = + ( foveon_avg (image[row*width]+c, dscr[0], cfilt) + + foveon_avg (image[row*width]+c, dscr[1], cfilt) * 3 + - ddft[0][c][0] ) / 4 - ddft[0][c][1]; + } + memcpy (black, black+8, sizeof *black*8); + memcpy (black+height-11, black+height-22, 11*sizeof *black); + memcpy (last, black, sizeof last); + + for (row=1; row < height-1; row++) { + FORC3 if (last[1][c] > last[0][c]) { + if (last[1][c] > last[2][c]) + black[row][c] = (last[0][c] > last[2][c]) ? last[0][c]:last[2][c]; + } else + if (last[1][c] < last[2][c]) + black[row][c] = (last[0][c] < last[2][c]) ? last[0][c]:last[2][c]; + memmove (last, last+1, 2*sizeof last[0]); + memcpy (last[2], black[row+1], sizeof last[2]); + } + FORC3 black[row][c] = (last[0][c] + last[1][c])/2; + FORC3 black[0][c] = (black[1][c] + black[3][c])/2; + + val = 1 - exp(-1/24.0); + memcpy (fsum, black, sizeof fsum); + for (row=1; row < height; row++) + FORC3 fsum[c] += black[row][c] = + (black[row][c] - black[row-1][c])*val + black[row-1][c]; + memcpy (last[0], black[height-1], sizeof last[0]); + FORC3 fsum[c] /= height; + for (row = height; row--; ) + FORC3 last[0][c] = black[row][c] = + (black[row][c] - fsum[c] - last[0][c])*val + last[0][c]; + + memset (total, 0, sizeof total); + for (row=2; row < height; row+=4) + for (col=2; col < width; col+=4) { + FORC3 total[c] += (short) image[row*width+col][c]; + total[3]++; + } + for (row=0; row < height; row++) + FORC3 black[row][c] += fsum[c]/2 + total[c]/(total[3]*100.0); + + for (row=0; row < height; row++) { + for (i=0; i < 6; i++) + ddft[0][0][i] = ddft[1][0][i] + + row / (height-1.0) * (ddft[2][0][i] - ddft[1][0][i]); + pix = image[row*width]; + memcpy (prev, pix, sizeof prev); + frow = row / (height-1.0) * (dim[2]-1); + if ((irow = frow) == dim[2]-1) irow--; + frow -= irow; + for (i=0; i < dim[1]; i++) + FORC3 sgrow[i][c] = sgain[ irow *dim[1]+i][c] * (1-frow) + + sgain[(irow+1)*dim[1]+i][c] * frow; + for (col=0; col < width; col++) { + FORC3 { + diff = pix[c] - prev[c]; + prev[c] = pix[c]; + ipix[c] = pix[c] + floor ((diff + (diff*diff >> 14)) * cfilt + - ddft[0][c][1] - ddft[0][c][0] * ((float) col/width - 0.5) + - black[row][c] ); + } + FORC3 { + work[0][c] = ipix[c] * ipix[c] >> 14; + work[2][c] = ipix[c] * work[0][c] >> 14; + work[1][2-c] = ipix[(c+1) % 3] * ipix[(c+2) % 3] >> 14; + } + FORC3 { + for (val=i=0; i < 3; i++) + for ( j=0; j < 3; j++) + val += ppm[c][i][j] * work[i][j]; + ipix[c] = floor ((ipix[c] + floor(val)) * + ( sgrow[col/sgx ][c] * (sgx - col%sgx) + + sgrow[col/sgx+1][c] * (col%sgx) ) / sgx / div[c]); + if (ipix[c] > 32000) ipix[c] = 32000; + pix[c] = ipix[c]; + } + pix += 4; + } + } + free (black); + free (sgrow); + free (sgain); + + if ((badpix = foveon_camf_matrix (dim, "BadPixels"))) { + for (i=0; i < dim[0]; i++) { + col = (badpix[i] >> 8 & 0xfff) - keep[0]; + row = (badpix[i] >> 20 ) - keep[1]; + if ((unsigned)(row-1) > height-3 || (unsigned)(col-1) > width-3) + continue; + memset (fsum, 0, sizeof fsum); + for (sum=j=0; j < 8; j++) + if (badpix[i] & (1 << j)) { + FORC3 fsum[c] += (short) + image[(row+hood[j*2])*width+col+hood[j*2+1]][c]; + sum++; + } + if (sum) FORC3 image[row*width+col][c] = fsum[c]/sum; + } + free (badpix); + } + + /* Array for 5x5 Gaussian averaging of red values */ + smrow[6] = calloc (width*5, sizeof **smrow); + merror (smrow[6], "foveon_interpolate()"); + for (i=0; i < 5; i++) + smrow[i] = smrow[6] + i*width; + + /* Sharpen the reds against these Gaussian averages */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + smrow[4][col][0] = + (pix[0]*6 + (pix[-4]+pix[4])*4 + pix[-8]+pix[8] + 8) >> 4; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + smred = ( 6 * smrow[2][col][0] + + 4 * (smrow[1][col][0] + smrow[3][col][0]) + + smrow[0][col][0] + smrow[4][col][0] + 8 ) >> 4; + if (col == 2) + smred_p = smred; + i = pix[0] + ((pix[0] - ((smred*7 + smred_p) >> 3)) >> 3); + if (i > 32000) i = 32000; + pix[0] = i; + smred_p = smred; + pix += 4; + } + } + + /* Adjust the brighter pixels for better linearity */ + min = 0xffff; + FORC3 { + i = satlev[c] / div[c]; + if (min > i) min = i; + } + limit = min * 9 >> 4; + for (pix=image[0]; pix < image[height*width]; pix+=4) { + if (pix[0] <= limit || pix[1] <= limit || pix[2] <= limit) + continue; + min = max = pix[0]; + for (c=1; c < 3; c++) { + if (min > pix[c]) min = pix[c]; + if (max < pix[c]) max = pix[c]; + } + if (min >= limit*2) { + pix[0] = pix[1] = pix[2] = max; + } else { + i = 0x4000 - ((min - limit) << 14) / limit; + i = 0x4000 - (i*i >> 14); + i = i*i >> 14; + FORC3 pix[c] += (max - pix[c]) * i >> 14; + } + } +/* + Because photons that miss one detector often hit another, + the sum R+G+B is much less noisy than the individual colors. + So smooth the hues without smoothing the total. + */ + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = (pix[c-4]+2*pix[c]+pix[c+4]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + FORC3 dev[c] = -foveon_apply_curve (curve[7], pix[c] - + ((smrow[1][col][c] + 2*smrow[2][col][c] + smrow[3][col][c]) >> 2)); + sum = (dev[0] + dev[1] + dev[2]) >> 3; + FORC3 pix[c] += dev[c] - sum; + pix += 4; + } + } + for (smlast=-1, row=2; row < height-2; row++) { + while (smlast < row+2) { + for (i=0; i < 6; i++) + smrow[(i+5) % 6] = smrow[i]; + pix = image[++smlast*width+2]; + for (col=2; col < width-2; col++) { + FORC3 smrow[4][col][c] = + (pix[c-8]+pix[c-4]+pix[c]+pix[c+4]+pix[c+8]+2) >> 2; + pix += 4; + } + } + pix = image[row*width+2]; + for (col=2; col < width-2; col++) { + for (total[3]=375, sum=60, c=0; c < 3; c++) { + for (total[c]=i=0; i < 5; i++) + total[c] += smrow[i][col][c]; + total[3] += total[c]; + sum += pix[c]; + } + if (sum < 0) sum = 0; + j = total[3] > 375 ? (sum << 16) / total[3] : sum * 174; + FORC3 pix[c] += foveon_apply_curve (curve[6], + ((j*total[c] + 0x8000) >> 16) - pix[c]); + pix += 4; + } + } + + /* Transform the image to a different colorspace */ + for (pix=image[0]; pix < image[height*width]; pix+=4) { + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]); + sum = (pix[0]+pix[1]+pix[1]+pix[2]) >> 2; + FORC3 pix[c] -= foveon_apply_curve (curve[c], pix[c]-sum); + FORC3 { + for (dsum=i=0; i < 3; i++) + dsum += trans[c][i] * pix[i]; + if (dsum < 0) dsum = 0; + if (dsum > 24000) dsum = 24000; + ipix[c] = dsum + 0.5; + } + FORC3 pix[c] = ipix[c]; + } + + /* Smooth the image bottom-to-top and save at 1/4 scale */ + shrink = calloc ((width/4) * (height/4), sizeof *shrink); + merror (shrink, "foveon_interpolate()"); + for (row = height/4; row--; ) + for (col=0; col < width/4; col++) { + ipix[0] = ipix[1] = ipix[2] = 0; + for (i=0; i < 4; i++) + for (j=0; j < 4; j++) + FORC3 ipix[c] += image[(row*4+i)*width+col*4+j][c]; + FORC3 + if (row+2 > height/4) + shrink[row*(width/4)+col][c] = ipix[c] >> 4; + else + shrink[row*(width/4)+col][c] = + (shrink[(row+1)*(width/4)+col][c]*1840 + ipix[c]*141 + 2048) >> 12; + } + /* From the 1/4-scale image, smooth right-to-left */ + for (row=0; row < (height & ~3); row++) { + ipix[0] = ipix[1] = ipix[2] = 0; + if ((row & 3) == 0) + for (col = width & ~3 ; col--; ) + FORC3 smrow[0][col][c] = ipix[c] = + (shrink[(row/4)*(width/4)+col/4][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Then smooth left-to-right */ + ipix[0] = ipix[1] = ipix[2] = 0; + for (col=0; col < (width & ~3); col++) + FORC3 smrow[1][col][c] = ipix[c] = + (smrow[0][col][c]*1485 + ipix[c]*6707 + 4096) >> 13; + + /* Smooth top-to-bottom */ + if (row == 0) + memcpy (smrow[2], smrow[1], sizeof **smrow * width); + else + for (col=0; col < (width & ~3); col++) + FORC3 smrow[2][col][c] = + (smrow[2][col][c]*6707 + smrow[1][col][c]*1485 + 4096) >> 13; + + /* Adjust the chroma toward the smooth values */ + for (col=0; col < (width & ~3); col++) { + for (i=j=30, c=0; c < 3; c++) { + i += smrow[2][col][c]; + j += image[row*width+col][c]; + } + j = (j << 16) / i; + for (sum=c=0; c < 3; c++) { + ipix[c] = foveon_apply_curve (curve[c+3], + ((smrow[2][col][c] * j + 0x8000) >> 16) - image[row*width+col][c]); + sum += ipix[c]; + } + sum >>= 3; + FORC3 { + i = image[row*width+col][c] + ipix[c] - sum; + if (i < 0) i = 0; + image[row*width+col][c] = i; + } + } + } + free (shrink); + free (smrow[6]); + for (i=0; i < 8; i++) + free (curve[i]); + + /* Trim off the black border */ + active[1] -= keep[1]; + active[3] -= 2; + i = active[2] - active[0]; + for (row = 0; row < active[3]-active[1]; row++) + memcpy (image[row*i], image[(row+active[1])*width+active[0]], + i * sizeof *image); + width = i; + height = row; +} +#undef image + +/* END GPL BLOCK */ + +/* + Seach from the current directory up to the root looking for + a ".badpixels" file, and fix those pixels now. + */ +void CLASS bad_pixels() +{ + FILE *fp=NULL; + char *fname, *cp, line[128]; + int len, time, row, col, r, c, rad, tot, n, fixed=0; + + if (!filters) return; + for (len=16 ; ; len *= 2) { + fname = malloc (len); + if (!fname) return; + if (getcwd (fname, len-12)) break; + free (fname); + if (errno != ERANGE) return; + } +#ifdef WIN32 + if (fname[1] == ':') + memmove (fname, fname+2, len-2); + for (cp=fname; *cp; cp++) + if (*cp == '\\') *cp = '/'; +#endif + cp = fname + strlen(fname); + if (cp[-1] == '/') cp--; + while (*fname == '/') { + strcpy (cp, "/.badpixels"); + if ((fp = fopen (fname, "r"))) break; + if (cp == fname) break; + while (*--cp != '/'); + } + free (fname); + if (!fp) return; + while (fgets (line, 128, fp)) { + cp = strchr (line, '#'); + if (cp) *cp = 0; + if (sscanf (line, "%d %d %d", &col, &row, &time) != 3) continue; + if ((unsigned) col >= width || (unsigned) row >= height) continue; + if (time > timestamp) continue; + for (tot=n=0, rad=1; rad < 3 && n==0; rad++) + for (r = row-rad; r <= row+rad; r++) + for (c = col-rad; c <= col+rad; c++) + if ((unsigned) r < height && (unsigned) c < width && + (r != row || c != col) && FC(r,c) == FC(row,col)) { + tot += BAYER(r,c); + n++; + } + BAYER(row,col) = tot/n; + if (verbose) { + if (!fixed++) + fprintf (stderr, "Fixed bad pixels at:"); + fprintf (stderr, " %d,%d", col, row); + } + } + if (fixed) fputc ('\n', stderr); + fclose (fp); +} + +void CLASS pseudoinverse (const double (*in)[3], double (*out)[3], int size) +{ + double work[3][6], num; + int i, j, k; + + for (i=0; i < 3; i++) { + for (j=0; j < 6; j++) + work[i][j] = j == i+3; + for (j=0; j < 3; j++) + for (k=0; k < size; k++) + work[i][j] += in[k][i] * in[k][j]; + } + for (i=0; i < 3; i++) { + num = work[i][i]; + for (j=0; j < 6; j++) + work[i][j] /= num; + for (k=0; k < 3; k++) { + if (k==i) continue; + num = work[k][i]; + for (j=0; j < 6; j++) + work[k][j] -= work[i][j] * num; + } + } + for (i=0; i < size; i++) + for (j=0; j < 3; j++) + for (out[i][j]=k=0; k < 3; k++) + out[i][j] += work[j][k+3] * in[i][k]; +} + +void CLASS cam_xyz_coeff (double cam_xyz[4][3]) +{ + double cam_rgb[4][3], inverse[4][3], num; + int i, j, k; + + for (i=0; i < colors; i++) /* Multiply out XYZ colorspace */ + for (j=0; j < 3; j++) + for (cam_rgb[i][j] = k=0; k < 3; k++) + cam_rgb[i][j] += cam_xyz[i][k] * xyz_rgb[k][j]; + + for (i=0; i < colors; i++) { /* Normalize cam_rgb so that */ + for (num=j=0; j < 3; j++) /* cam_rgb * (1,1,1) is (1,1,1,1) */ + num += cam_rgb[i][j]; + for (j=0; j < 3; j++) + cam_rgb[i][j] /= num; + pre_mul[i] = 1 / num; + } + pseudoinverse ((const double (*)[3]) cam_rgb, inverse, colors); + for (raw_color = i=0; i < 3; i++) + for (j=0; j < colors; j++) + rgb_cam[i][j] = inverse[j][i]; +} + +#ifdef COLORCHECK +void CLASS colorcheck() +{ +#define NSQ 24 +// Coordinates of the GretagMacbeth ColorChecker squares +// width, height, 1st_column, 1st_row + static const int cut[NSQ][4] = { + { 241, 231, 234, 274 }, + { 251, 235, 534, 274 }, + { 255, 239, 838, 272 }, + { 255, 240, 1146, 274 }, + { 251, 237, 1452, 278 }, + { 243, 238, 1758, 288 }, + { 253, 253, 218, 558 }, + { 255, 249, 524, 562 }, + { 261, 253, 830, 562 }, + { 260, 255, 1144, 564 }, + { 261, 255, 1450, 566 }, + { 247, 247, 1764, 576 }, + { 255, 251, 212, 862 }, + { 259, 259, 518, 862 }, + { 263, 261, 826, 864 }, + { 265, 263, 1138, 866 }, + { 265, 257, 1450, 872 }, + { 257, 255, 1762, 874 }, + { 257, 253, 212, 1164 }, + { 262, 251, 516, 1172 }, + { 263, 257, 826, 1172 }, + { 263, 255, 1136, 1176 }, + { 255, 252, 1452, 1182 }, + { 257, 253, 1760, 1180 } }; +// ColorChecker Chart under 6500-kelvin illumination + static const double gmb_xyz[NSQ][3] = { + { 11.078, 9.870, 6.738 }, // Dark Skin + { 37.471, 35.004, 26.057 }, // Light Skin + { 18.187, 19.306, 35.425 }, // Blue Sky + { 10.825, 13.827, 7.600 }, // Foliage + { 24.769, 23.304, 43.943 }, // Blue Flower + { 31.174, 42.684, 45.277 }, // Bluish Green + { 36.238, 29.188, 6.222 }, // Orange + { 13.661, 11.845, 38.929 }, // Purplish Blue + { 27.999, 19.272, 14.265 }, // Moderate Red + { 8.398, 6.309, 14.211 }, // Purple + { 33.692, 44.346, 11.288 }, // Yellow Green + { 45.000, 42.144, 8.429 }, // Orange Yellow + { 8.721, 6.130, 31.181 }, // Blue + { 14.743, 24.049, 9.778 }, // Green + { 19.777, 11.530, 5.101 }, // Red + { 55.978, 59.599, 10.047 }, // Yellow + { 29.421, 19.271, 31.167 }, // Magenta + { 13.972, 18.952, 37.646 }, // Cyan + { 82.819, 87.727, 94.479 }, // White + { 55.950, 58.959, 64.375 }, // Neutral 8 + { 32.877, 34.536, 38.097 }, // Neutral 6.5 + { 18.556, 19.701, 21.487 }, // Neutral 5 + { 8.353, 8.849, 9.812 }, // Neutral 3.5 + { 2.841, 2.980, 3.332 } }; // Black + double inverse[NSQ][3], gmb_cam[NSQ][4], cam_xyz[4][3]; + double num, error, minerr=DBL_MAX, best[4][3]; + int b, c, i, j, k, sq, row, col, count[4]; + + memset (gmb_cam, 0, sizeof gmb_cam); + for (sq=0; sq < NSQ; sq++) { + FORCC count[c] = 0; + for (row=cut[sq][3]; row < cut[sq][3]+cut[sq][1]; row++) + for (col=cut[sq][2]; col < cut[sq][2]+cut[sq][0]; col++) { + c = FC(row,col); + if (c >= colors) c -= 2; + gmb_cam[sq][c] += BAYER(row,col); + count[c]++; + } + FORCC gmb_cam[sq][c] /= count[c]; + } + for (b=0; b < 2000; b++) { + pseudoinverse (gmb_xyz, inverse, NSQ); + for (i=0; i < colors; i++) + for (j=0; j < 3; j++) + for (cam_xyz[i][j] = k=0; k < NSQ; k++) + cam_xyz[i][j] += gmb_cam[k][i] * inverse[k][j]; + + for (error=sq=0; sq < NSQ; sq++) + FORCC { + for (num=j=0; j < 3; j++) + num += cam_xyz[c][j] * gmb_xyz[sq][j]; + if (num < 0) num=0; + error += pow (num - gmb_cam[sq][c], 2); + gmb_cam[sq][c]--; // for the next black value + } + if (error < minerr) { + black = b; + minerr = error; + memcpy (best, cam_xyz, sizeof best); + } + } + cam_xyz_coeff (best); + if (verbose) { + fprintf (stderr, " { \"%s %s\",\n\t{ ", make, model); + num = 10000 / (best[1][0] + best[1][1] + best[1][2]); + FORCC for (j=0; j < 3; j++) + fprintf (stderr, "%d,", (int) (best[c][j] * num + 0.5)); + fprintf (stderr, "\b } },\n"); + } +#undef NSQ +} +#endif + +void CLASS scale_colors() +{ + int row, col, c, val, shift=0; + int min[4], max[4], count[4]; + double sum[4], dmin; + + maximum -= black; + if (use_auto_wb || (use_camera_wb && camera_red == -1)) { + FORC4 min[c] = INT_MAX; + FORC4 max[c] = count[c] = sum[c] = 0; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + FORC4 { + val = image[row*width+col][c]; + if (!val) continue; + if (min[c] > val) min[c] = val; + if (max[c] < val) max[c] = val; + val -= black; + if (val > maximum-25) continue; + if (val < 0) val = 0; + sum[c] += val; + count[c]++; + } + FORC4 if (sum[c]) pre_mul[c] = count[c] / sum[c]; + } + if (use_camera_wb && camera_red != -1) { + FORC4 count[c] = sum[c] = 0; + for (row=0; row < 8; row++) + for (col=0; col < 8; col++) { + c = FC(row,col); + if ((val = white[row][col] - black) > 0) + sum[c] += val; + count[c]++; + } + if (sum[0] && sum[1] && sum[2] && sum[3]) + FORC4 pre_mul[c] = count[c] / sum[c]; + else if (camera_red && camera_blue) + memcpy (pre_mul, cam_mul, sizeof pre_mul); + else + fprintf (stderr, "%s: Cannot use camera white balance.\n", ifname); + } + if (raw_color) { + pre_mul[0] *= red_scale; + pre_mul[2] *= blue_scale; + } + if (pre_mul[3] == 0) pre_mul[3] = colors < 4 ? pre_mul[1] : 1; + dmin = DBL_MAX; + FORC4 if (dmin > pre_mul[c]) + dmin = pre_mul[c]; + FORC4 pre_mul[c] /= dmin; + + while (maximum << shift < 0x8000) shift++; + FORC4 pre_mul[c] *= 1 << shift; + maximum <<= shift; + + if (write_fun != write_ppm || bright < 1) { + maximum *= bright; + if (maximum > 0xffff) + maximum = 0xffff; + FORC4 pre_mul[c] *= bright; + } + if (verbose) { + fprintf (stderr, "Scaling with black=%d, pre_mul[] =", black); + FORC4 fprintf (stderr, " %f", pre_mul[c]); + fputc ('\n', stderr); + } + clip_max = clip_color ? maximum : 0xffff; + for (row=0; row < height; row++) + for (col=0; col < width; col++) + FORC4 { + val = image[row*width+col][c]; + if (!val) continue; + val -= black; + val *= pre_mul[c]; + image[row*width+col][c] = CLIP(val); + } + if (filters && colors == 3) { + if (four_color_rgb) { + colors++; + FORC3 rgb_cam[c][3] = rgb_cam[c][1] /= 2; + } else { + for (row = FC(1,0) >> 1; row < height; row+=2) + for (col = FC(row,1) & 1; col < width; col+=2) + image[row*width+col][1] = image[row*width+col][3]; + filters &= ~((filters & 0x55555555) << 1); + } + } +} + +void CLASS border_interpolate (int border) +{ + unsigned row, col, y, x, c, sum[8]; + + for (row=0; row < height; row++) + for (col=0; col < width; col++) { + if (col==border && row >= border && row < height-border) + col = width-border; + memset (sum, 0, sizeof sum); + for (y=row-1; y != row+2; y++) + for (x=col-1; x != col+2; x++) + if (y < height && x < width) { + sum[FC(y,x)] += BAYER(y,x); + sum[FC(y,x)+4]++; + } + FORCC if (c != FC(row,col)) + image[row*width+col][c] = sum[c] / sum[c+4]; + } +} + +void CLASS lin_interpolate() +{ + int code[8][2][32], *ip, sum[4]; + int c, i, x, y, row, col, shift, color; + ushort *pix; + + if (verbose) fprintf (stderr, "Bilinear interpolation...\n"); + + border_interpolate(1); + for (row=0; row < 8; row++) + for (col=0; col < 2; col++) { + ip = code[row][col]; + memset (sum, 0, sizeof sum); + for (y=-1; y <= 1; y++) + for (x=-1; x <= 1; x++) { + shift = (y==0) + (x==0); + if (shift == 2) continue; + color = FC(row+y,col+x); + *ip++ = (width*y + x)*4 + color; + *ip++ = shift; + *ip++ = color; + sum[color] += 1 << shift; + } + FORCC + if (c != FC(row,col)) { + *ip++ = c; + *ip++ = sum[c]; + } + } + for (row=1; row < height-1; row++) + for (col=1; col < width-1; col++) { + pix = image[row*width+col]; + ip = code[row & 7][col & 1]; + memset (sum, 0, sizeof sum); + for (i=8; i--; ip+=3) + sum[ip[2]] += pix[ip[0]] << ip[1]; + for (i=colors; --i; ip+=2) + pix[ip[0]] = sum[ip[0]] / ip[1]; + } +} + +/* + This algorithm is officially called: + + "Interpolation using a Threshold-based variable number of gradients" + + described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html + + I've extended the basic idea to work with non-Bayer filter arrays. + Gradients are numbered clockwise from NW=0 to W=7. + */ +void CLASS vng_interpolate() +{ + static const signed char *cp, terms[] = { + -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01, + -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01, + -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03, + -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06, + -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04, + -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01, + -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40, + -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11, + -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11, + -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22, + -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44, + -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10, + -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04, + +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40, + +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20, + +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08, + +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20, + +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44, + +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60, + +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80, + +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40, + +1,+0,+2,+1,0,0x10 + }, chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 }; + ushort (*brow[5])[4], *pix; + int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4]; + int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag; + int g, diff, thold, num, c; + + lin_interpolate(); + if (verbose) fprintf (stderr, "VNG interpolation...\n"); + + for (row=0; row < 8; row++) { /* Precalculate for VNG */ + for (col=0; col < 2; col++) { + ip = code[row][col]; + for (cp=terms, t=0; t < 64; t++) { + y1 = *cp++; x1 = *cp++; + y2 = *cp++; x2 = *cp++; + weight = *cp++; + grads = *cp++; + color = FC(row+y1,col+x1); + if (FC(row+y2,col+x2) != color) continue; + diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1; + if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue; + *ip++ = (y1*width + x1)*4 + color; + *ip++ = (y2*width + x2)*4 + color; + *ip++ = weight; + for (g=0; g < 8; g++) + if (grads & 1< gval[g]) gmin = gval[g]; + if (gmax < gval[g]) gmax = gval[g]; + } + if (gmax == 0) { + memcpy (brow[2][col], pix, sizeof *image); + continue; + } + thold = gmin + (gmax >> 1); + memset (sum, 0, sizeof sum); + color = FC(row,col); + for (num=g=0; g < 8; g++,ip+=2) { /* Average the neighbors */ + if (gval[g] <= thold) { + FORCC + if (c == color && ip[1]) + sum[c] += (pix[c] + pix[ip[1]]) >> 1; + else + sum[c] += pix[ip[0] + c]; + num++; + } + } + FORCC { /* Save to buffer */ + t = pix[color]; + if (c != color) + t += (sum[c] - sum[color]) / num; + brow[2][col][c] = CLIP(t); + } + } + if (row > 3) /* Write buffer to image */ + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + for (g=0; g < 4; g++) + brow[(g-1) & 3] = brow[g]; + } + memcpy (image[(row-2)*width+2], brow[0]+2, (width-4)*sizeof *image); + memcpy (image[(row-1)*width+2], brow[1]+2, (width-4)*sizeof *image); + free (brow[4]); +} + +void CLASS cam_to_cielab (ushort cam[4], float lab[3]) +{ + int c, i, j, k; + float r, xyz[3]; + static const float d65[3] = { 0.950456, 1, 1.088754 }; + static float cbrt[0x10000], xyz_cam[3][4]; + + if (cam == NULL) { + for (i=0; i < 0x10000; i++) { + r = (float) i / maximum; + cbrt[i] = r > 0.008856 ? pow(r,1/3.0) : 7.787*r + 16/116.0; + } + for (i=0; i < 3; i++) + for (j=0; j < colors; j++) + for (xyz_cam[i][j] = k=0; k < 3; k++) + xyz_cam[i][j] += xyz_rgb[i][k] * rgb_cam[k][j] / d65[i]; + } else { + for (i=0; i < 3; i++) { + for (xyz[i]=0.5, c=0; c < colors; c++) + xyz[i] += xyz_cam[i][c] * cam[c]; + xyz[i] = cbrt[CLIP((int) xyz[i])]; + } + lab[0] = 116 * xyz[1] - 16; + lab[1] = 500 * (xyz[0] - xyz[1]); + lab[2] = 200 * (xyz[1] - xyz[2]); + } +} + +/* + Adaptive Homogeneity-Directed interpolation is based on + the work of Keigo Hirakawa, Thomas Parks, and Paul Lee. + */ +#define TS 256 /* Tile Size */ + +void CLASS ahd_interpolate() +{ + int i, j, top, left, row, col, tr, tc, fc, c, d, val, hm[2]; + ushort (*pix)[4], (*rix)[3]; + static const int dir[4] = { -1, 1, -TS, TS }; + unsigned ldiff[2][4], abdiff[2][4], leps, abeps; + float flab[3]; + ushort (*rgb)[TS][TS][3]; + short (*lab)[TS][TS][3]; + char (*homo)[TS][TS], *buffer; + + if (verbose) fprintf (stderr, "AHD interpolation...\n"); + + border_interpolate(3); + buffer = malloc (26*TS*TS); /* 1664 kB */ + merror (buffer, "ahd_interpolate()"); + rgb = (void *) buffer; + lab = (void *) (buffer + 12*TS*TS); + homo = (void *) (buffer + 24*TS*TS); + + for (top=0; top < height; top += TS-6) + for (left=0; left < width; left += TS-6) { + memset (rgb, 0, 12*TS*TS); + +/* Interpolate green horizontally and vertically: */ + for (row = top < 2 ? 2:top; row < top+TS && row < height-2; row++) { + col = left + (FC(row,left) == 1); + if (col < 2) col += 2; + for (fc = FC(row,col); col < left+TS && col < width-2; col+=2) { + pix = image + row*width+col; + val = ((pix[-1][1] + pix[0][fc] + pix[1][1]) * 2 + - pix[-2][fc] - pix[2][fc]) >> 2; + rgb[0][row-top][col-left][1] = ULIM(val,pix[-1][1],pix[1][1]); + val = ((pix[-width][1] + pix[0][fc] + pix[width][1]) * 2 + - pix[-2*width][fc] - pix[2*width][fc]) >> 2; + rgb[1][row-top][col-left][1] = ULIM(val,pix[-width][1],pix[width][1]); + } + } +/* Interpolate red and blue, and convert to CIELab: */ + for (d=0; d < 2; d++) + for (row=top+1; row < top+TS-1 && row < height-1; row++) + for (col=left+1; col < left+TS-1 && col < width-1; col++) { + pix = image + row*width+col; + rix = &rgb[d][row-top][col-left]; + if ((c = 2 - FC(row,col)) == 1) { + c = FC(row+1,col); + val = pix[0][1] + (( pix[-1][2-c] + pix[1][2-c] + - rix[-1][1] - rix[1][1] ) >> 1); + rix[0][2-c] = CLIP(val); + val = pix[0][1] + (( pix[-width][c] + pix[width][c] + - rix[-TS][1] - rix[TS][1] ) >> 1); + } else + val = rix[0][1] + (( pix[-width-1][c] + pix[-width+1][c] + + pix[+width-1][c] + pix[+width+1][c] + - rix[-TS-1][1] - rix[-TS+1][1] + - rix[+TS-1][1] - rix[+TS+1][1] + 1) >> 2); + rix[0][c] = CLIP(val); + c = FC(row,col); + rix[0][c] = pix[0][c]; + cam_to_cielab (rix[0], flab); + FORC3 lab[d][row-top][col-left][c] = 64*flab[c]; + } +/* Build homogeneity maps from the CIELab images: */ + memset (homo, 0, 2*TS*TS); + for (row=top+2; row < top+TS-2 && row < height; row++) { + tr = row-top; + for (col=left+2; col < left+TS-2 && col < width; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + ldiff[d][i] = ABS(lab[d][tr][tc][0]-lab[d][tr][tc+dir[i]][0]); + leps = MIN(MAX(ldiff[0][0],ldiff[0][1]), + MAX(ldiff[1][2],ldiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (i >> 1 == d || ldiff[d][i] <= leps) + abdiff[d][i] = SQR(lab[d][tr][tc][1]-lab[d][tr][tc+dir[i]][1]) + + SQR(lab[d][tr][tc][2]-lab[d][tr][tc+dir[i]][2]); + abeps = MIN(MAX(abdiff[0][0],abdiff[0][1]), + MAX(abdiff[1][2],abdiff[1][3])); + for (d=0; d < 2; d++) + for (i=0; i < 4; i++) + if (ldiff[d][i] <= leps && abdiff[d][i] <= abeps) + homo[d][tr][tc]++; + } + } +/* Combine the most homogenous pixels for the final result: */ + for (row=top+3; row < top+TS-3 && row < height-3; row++) { + tr = row-top; + for (col=left+3; col < left+TS-3 && col < width-3; col++) { + tc = col-left; + for (d=0; d < 2; d++) + for (hm[d]=0, i=tr-1; i <= tr+1; i++) + for (j=tc-1; j <= tc+1; j++) + hm[d] += homo[d][i][j]; + if (hm[0] != hm[1]) + FORC3 image[row*width+col][c] = rgb[hm[1] > hm[0]][tr][tc][c]; + else + FORC3 image[row*width+col][c] = + (rgb[0][tr][tc][c] + rgb[1][tr][tc][c]) >> 1; + } + } + } + free (buffer); +} +#undef TS + +/* + Bilateral Filtering was developed by C. Tomasi and R. Manduchi. + */ +void CLASS bilateral_filter() +{ + float (**window)[7], *kernel, scale_r, elut[1024], sum[5]; + int c, i, wr, ws, wlast, row, col, y, x; + unsigned sep; + + if (verbose) fprintf (stderr, "Bilateral filtering...\n"); + + wr = ceil(sigma_d*2); /* window radius */ + ws = 2*wr + 1; /* window size */ + window = calloc ((ws+1)*sizeof *window + + ws*width*sizeof **window + ws*sizeof *kernel, 1); + merror (window, "bilateral_filter()"); + for (i=0; i <= ws; i++) + window[i] = (float(*)[7]) (window+ws+1) + i*width; + kernel = (float *) window[ws] + wr; + for (i=-wr; i <= wr; i++) + kernel[i] = 256 / (2*SQR(sigma_d)) * i*i + 0.25; + scale_r = 256 / (2*SQR(sigma_r)); + for (i=0; i < 1024; i++) + elut[i] = exp (-i/256.0); + + for (wlast=-1, row=0; row < height; row++) { + while (wlast < row+wr) { + wlast++; + for (i=0; i <= ws; i++) /* rotate window rows */ + window[(ws+i) % (ws+1)] = window[i]; + if (wlast < height) + for (col=0; col < width; col++) { + FORCC window[ws-1][col][c] = image[wlast*width+col][c]; + cam_to_cielab (image[wlast*width+col], window[ws-1][col]+4); + } + } + for (col=0; col < width; col++) { + memset (sum, 0, sizeof sum); + for (y=-wr; y <= wr; y++) + if ((unsigned)(row+y) < height) + for (x=-wr; x <= wr; x++) + if ((unsigned)(col+x) < width) { + sep = ( SQR(window[wr+y][col+x][4] - window[wr][col][4]) + + SQR(window[wr+y][col+x][5] - window[wr][col][5]) + + SQR(window[wr+y][col+x][6] - window[wr][col][6]) ) + * scale_r + kernel[y] + kernel[x]; + if (sep < 1024) { + FORCC sum[c] += elut[sep] * window[wr+y][col+x][c]; + sum[4] += elut[sep]; + } + } + FORCC image[row*width+col][c] = sum[c]/sum[4]; + } + } + free (window); +} + +void CLASS parse_makernote() +{ + static const uchar xlat[2][256] = { + { 0xc1,0xbf,0x6d,0x0d,0x59,0xc5,0x13,0x9d,0x83,0x61,0x6b,0x4f,0xc7,0x7f,0x3d,0x3d, + 0x53,0x59,0xe3,0xc7,0xe9,0x2f,0x95,0xa7,0x95,0x1f,0xdf,0x7f,0x2b,0x29,0xc7,0x0d, + 0xdf,0x07,0xef,0x71,0x89,0x3d,0x13,0x3d,0x3b,0x13,0xfb,0x0d,0x89,0xc1,0x65,0x1f, + 0xb3,0x0d,0x6b,0x29,0xe3,0xfb,0xef,0xa3,0x6b,0x47,0x7f,0x95,0x35,0xa7,0x47,0x4f, + 0xc7,0xf1,0x59,0x95,0x35,0x11,0x29,0x61,0xf1,0x3d,0xb3,0x2b,0x0d,0x43,0x89,0xc1, + 0x9d,0x9d,0x89,0x65,0xf1,0xe9,0xdf,0xbf,0x3d,0x7f,0x53,0x97,0xe5,0xe9,0x95,0x17, + 0x1d,0x3d,0x8b,0xfb,0xc7,0xe3,0x67,0xa7,0x07,0xf1,0x71,0xa7,0x53,0xb5,0x29,0x89, + 0xe5,0x2b,0xa7,0x17,0x29,0xe9,0x4f,0xc5,0x65,0x6d,0x6b,0xef,0x0d,0x89,0x49,0x2f, + 0xb3,0x43,0x53,0x65,0x1d,0x49,0xa3,0x13,0x89,0x59,0xef,0x6b,0xef,0x65,0x1d,0x0b, + 0x59,0x13,0xe3,0x4f,0x9d,0xb3,0x29,0x43,0x2b,0x07,0x1d,0x95,0x59,0x59,0x47,0xfb, + 0xe5,0xe9,0x61,0x47,0x2f,0x35,0x7f,0x17,0x7f,0xef,0x7f,0x95,0x95,0x71,0xd3,0xa3, + 0x0b,0x71,0xa3,0xad,0x0b,0x3b,0xb5,0xfb,0xa3,0xbf,0x4f,0x83,0x1d,0xad,0xe9,0x2f, + 0x71,0x65,0xa3,0xe5,0x07,0x35,0x3d,0x0d,0xb5,0xe9,0xe5,0x47,0x3b,0x9d,0xef,0x35, + 0xa3,0xbf,0xb3,0xdf,0x53,0xd3,0x97,0x53,0x49,0x71,0x07,0x35,0x61,0x71,0x2f,0x43, + 0x2f,0x11,0xdf,0x17,0x97,0xfb,0x95,0x3b,0x7f,0x6b,0xd3,0x25,0xbf,0xad,0xc7,0xc5, + 0xc5,0xb5,0x8b,0xef,0x2f,0xd3,0x07,0x6b,0x25,0x49,0x95,0x25,0x49,0x6d,0x71,0xc7 }, + { 0xa7,0xbc,0xc9,0xad,0x91,0xdf,0x85,0xe5,0xd4,0x78,0xd5,0x17,0x46,0x7c,0x29,0x4c, + 0x4d,0x03,0xe9,0x25,0x68,0x11,0x86,0xb3,0xbd,0xf7,0x6f,0x61,0x22,0xa2,0x26,0x34, + 0x2a,0xbe,0x1e,0x46,0x14,0x68,0x9d,0x44,0x18,0xc2,0x40,0xf4,0x7e,0x5f,0x1b,0xad, + 0x0b,0x94,0xb6,0x67,0xb4,0x0b,0xe1,0xea,0x95,0x9c,0x66,0xdc,0xe7,0x5d,0x6c,0x05, + 0xda,0xd5,0xdf,0x7a,0xef,0xf6,0xdb,0x1f,0x82,0x4c,0xc0,0x68,0x47,0xa1,0xbd,0xee, + 0x39,0x50,0x56,0x4a,0xdd,0xdf,0xa5,0xf8,0xc6,0xda,0xca,0x90,0xca,0x01,0x42,0x9d, + 0x8b,0x0c,0x73,0x43,0x75,0x05,0x94,0xde,0x24,0xb3,0x80,0x34,0xe5,0x2c,0xdc,0x9b, + 0x3f,0xca,0x33,0x45,0xd0,0xdb,0x5f,0xf5,0x52,0xc3,0x21,0xda,0xe2,0x22,0x72,0x6b, + 0x3e,0xd0,0x5b,0xa8,0x87,0x8c,0x06,0x5d,0x0f,0xdd,0x09,0x19,0x93,0xd0,0xb9,0xfc, + 0x8b,0x0f,0x84,0x60,0x33,0x1c,0x9b,0x45,0xf1,0xf0,0xa3,0x94,0x3a,0x12,0x77,0x33, + 0x4d,0x44,0x78,0x28,0x3c,0x9e,0xfd,0x65,0x57,0x16,0x94,0x6b,0xfb,0x59,0xd0,0xc8, + 0x22,0x36,0xdb,0xd2,0x63,0x98,0x43,0xa1,0x04,0x87,0x86,0xf7,0xa6,0x26,0xbb,0xd6, + 0x59,0x4d,0xbf,0x6a,0x2e,0xaa,0x2b,0xef,0xe6,0x78,0xb6,0x4e,0xe0,0x2f,0xdc,0x7c, + 0xbe,0x57,0x19,0x32,0x7e,0x2a,0xd0,0xb8,0xba,0x29,0x00,0x3c,0x52,0x7d,0xa8,0x49, + 0x3b,0x2d,0xeb,0x25,0x49,0xfa,0xa3,0xaa,0x39,0xa7,0xc5,0xa7,0x50,0x11,0x36,0xfb, + 0xc6,0x67,0x4a,0xf5,0xa5,0x12,0x65,0x7e,0xb0,0xdf,0xaf,0x4e,0xb3,0x61,0x7f,0x2f } }; + unsigned base=0, offset=0, entries, tag, type, len, save, c; + unsigned ver97=0, serial=0, i; + uchar buf97[324], ci, cj, ck; + static const int size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 }; + short sorder; + char buf[10]; +/* + The MakerNote might have its own TIFF header (possibly with + its own byte-order!), or it might just be a table. + */ + sorder = order; + fread (buf, 1, 10, ifp); + if (!strncmp (buf,"KC" ,2) || /* these aren't TIFF format */ + !strncmp (buf,"MLY",3)) return; + if (!strcmp (buf,"Nikon")) { + base = ftell(ifp); + order = get2(); + if (get2() != 42) goto quit; + offset = get4(); + fseek (ifp, offset-8, SEEK_CUR); + } else if (!strncmp (buf,"FUJIFILM",8) || + !strcmp (buf,"Panasonic")) { + order = 0x4949; + fseek (ifp, 2, SEEK_CUR); + } else if (!strcmp (buf,"OLYMP") || + !strcmp (buf,"LEICA") || + !strcmp (buf,"EPSON")) + fseek (ifp, -2, SEEK_CUR); + else if (!strcmp (buf,"AOC") || + !strcmp (buf,"QVC")) + fseek (ifp, -4, SEEK_CUR); + else fseek (ifp, -10, SEEK_CUR); + + entries = get2(); + while (entries--) { + tag = get2(); + type = get2(); + len = get4(); + save = ftell(ifp); + if (len * size[type < 13 ? type:0] > 4) + fseek (ifp, get4()+base, SEEK_SET); + + if (tag == 8 && type == 4) + shot_order = get4(); + if (tag == 0xc && len == 4) { + camera_red = getrat(); + camera_blue = getrat(); + } + if (tag == 0x14 && len == 2560 && type == 7) { + fseek (ifp, 1248, SEEK_CUR); + goto get2_256; + } + if (strstr(make,"PENTAX")) { + if (tag == 0x1b) tag = 0x1018; + if (tag == 0x1c) tag = 0x1017; + } + if (tag == 0x1d) + while ((c = fgetc(ifp))) + serial = serial*10 + (isdigit(c) ? c - '0' : c % 10); + if (tag == 0x8c) + nikon_curve_offset = ftell(ifp) + 2112; + if (tag == 0x96) + nikon_curve_offset = ftell(ifp) + 2; + if (tag == 0x97) { + for (i=0; i < 4; i++) + ver97 = (ver97 << 4) + fgetc(ifp)-'0'; + switch (ver97) { + case 0x100: + fseek (ifp, 68, SEEK_CUR); + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + break; + case 0x102: + fseek (ifp, 6, SEEK_CUR); + goto get2_rggb; + case 0x103: + fseek (ifp, 16, SEEK_CUR); + FORC4 cam_mul[c] = get2(); + } + if (ver97 >> 8 == 2) { + if (ver97 != 0x205) fseek (ifp, 280, SEEK_CUR); + fread (buf97, 324, 1, ifp); + } + } + if (tag == 0xa7 && ver97 >> 8 == 2) { + ci = xlat[0][serial & 0xff]; + cj = xlat[1][fgetc(ifp)^fgetc(ifp)^fgetc(ifp)^fgetc(ifp)]; + ck = 0x60; + for (i=0; i < 324; i++) + buf97[i] ^= (cj += ci * ck++); + FORC4 cam_mul[c ^ (c >> 1)] = + sget2 (buf97 + (ver97 == 0x205 ? 14:6) + c*2); + } + if (tag == 0xe0 && len == 17) { + get2(); + raw_width = get2(); + raw_height = get2(); + } + if (tag == 0x200 && len == 4) + black = (get2()+get2()+get2()+get2())/4; + if (tag == 0x201 && len == 4) + goto get2_rggb; + if (tag == 0x401 && len == 4) { + black = (get4()+get4()+get4()+get4())/4; + } + if (tag == 0xe01) { /* Nikon Capture Note */ + type = order; + order = 0x4949; + fseek (ifp, 22, SEEK_CUR); + for (offset=22; offset+22 < len; offset += 22+i) { + tag = get4(); + fseek (ifp, 14, SEEK_CUR); + i = get4()-4; + if (tag == 0x76a43207) flip = get2(); + else fseek (ifp, i, SEEK_CUR); + } + order = type; + } + if (tag == 0xe80 && len == 256 && type == 7) { + fseek (ifp, 48, SEEK_CUR); + camera_red = get2() * 508 * 1.078 / 0x10000; + camera_blue = get2() * 382 * 1.173 / 0x10000; + } + if (tag == 0xf00 && len == 614 && type == 7) { + fseek (ifp, 188, SEEK_CUR); + goto get2_256; + } + if (tag == 0x1017) + camera_red = get2() / 256.0; + if (tag == 0x1018) + camera_blue = get2() / 256.0; + if (tag == 0x2011 && len == 2) { +get2_256: + order = 0x4d4d; + camera_red = get2() / 256.0; + camera_blue = get2() / 256.0; + } + if (tag == 0x4001) { + fseek (ifp, strstr(model,"EOS-1D") ? 68 : + strstr(model,"EOS 5D") ? 126 : 50, SEEK_CUR); +get2_rggb: + FORC4 cam_mul[c ^ (c >> 1)] = get2(); + } + fseek (ifp, save+4, SEEK_SET); + } +quit: + order = sorder; +} + +/* + Since the TIFF DateTime string has no timezone information, + assume that the camera's clock was set to Universal Time. + */ +void CLASS get_timestamp (int reversed) +{ + struct tm t; + char str[20]; + int i; + + if (timestamp) return; + str[19] = 0; + if (reversed) + for (i=19; i--; ) str[i] = fgetc(ifp); + else + fread (str, 19, 1, ifp); + if (sscanf (str, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, + &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) != 6) + return; + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); +} + +void CLASS parse_exif (int base) +{ + int entries, tag, type, len, val, save; + + entries = get2(); + while (entries--) { + tag = get2(); + type = get2(); + len = get4(); + val = get4(); + save = ftell(ifp); + fseek (ifp, base+val, SEEK_SET); + if (tag == 0x9003 || tag == 0x9004) + get_timestamp(0); + if (tag == 0x927c) + parse_makernote(); + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_mos (int offset); +void CLASS sony_decrypt (unsigned *data, int len, int start, int key); + +int CLASS parse_tiff_ifd (int base, int level) +{ + unsigned entries, tag, type, len, plen=16, save; + int done=0, use_cm=0, cfa, i, j, c; + static const int size[] = { 1,1,1,2,4,8,1,1,2,4,8,4,8 }; + char software[64], *cbuf, *cp; + static const int flip_map[] = { 0,1,3,2,4,6,7,5 }; + uchar cfa_pat[16], cfa_pc[] = { 0,1,2,3 }, tab[256]; + double dblack, cc[4][4], cm[4][3], cam_xyz[4][3]; + double ab[]={ 1,1,1,1 }, asn[] = { 0,0,0,0 }, xyz[] = { 1,1,1 }; + unsigned *buf, sony_offset=0, sony_length=0, sony_key=0; + FILE *sfp; + + for (j=0; j < 4; j++) + for (i=0; i < 4; i++) + cc[j][i] = i == j; + entries = get2(); + if (entries > 512) return 1; + while (entries--) { + tag = get2(); + type = get2(); + len = get4(); + save = ftell(ifp); + if (tag > 50700 && tag < 50800) done = 1; + if (len * size[type < 13 ? type:0] > 4) + fseek (ifp, get4()+base, SEEK_SET); + switch (tag) { + case 0x11: + case 0x12: + if (type == 3 && len == 1) + cam_mul[(tag-0x11)*2] = get2() / 256.0; + break; + case 0x27: + if (len < 50) break; + fseek (ifp, 12, SEEK_CUR); + FORC3 cam_mul[c] = get2(); + break; + case 0x2: + case 0x100: /* ImageWidth */ + if ((strcmp(make,"Canon") || level) && len == 1) + raw_width = type==3 ? get2() : get4(); + break; + case 0x3: + case 0x101: /* ImageHeight */ + if ((strcmp(make,"Canon") || level) && len == 1) + raw_height = type==3 ? get2() : get4(); + break; + case 0x102: /* Bits per sample */ + fuji_secondary = len == 2; + maximum = (1 << (tiff_bps = get2())) - 1; + break; + case 0x103: /* Compression */ + tiff_data_compression = get2(); + break; + case 0x106: /* Kodak color format */ + kodak_data_compression = get2(); + break; + case 0x10f: /* Make */ + fgets (make, 64, ifp); + break; + case 0x110: /* Model */ + fgets (model, 64, ifp); + break; + case 0x111: /* StripOffset */ + data_offset = get4(); + break; + case 0x112: /* Orientation */ + flip = flip_map[(get2()-1) & 7]; + break; + case 0x115: /* SamplesPerPixel */ + tiff_samples = get2(); + break; + case 0x131: /* Software tag */ + fgets (software, 64, ifp); + if (!strncmp(software,"Adobe",5) || + !strncmp(software,"Bibble",6) || + !strcmp (software,"Digital Photo Professional")) + make[0] = 0; + break; + case 0x132: /* DateTime tag */ + get_timestamp(0); + break; + case 0x144: /* TileOffsets */ + if (level) { + data_offset = ftell(ifp); + } else { + data_offset = get4(); + done = 1; + } + break; + case 0x14a: /* SubIFD tag */ + if (len > 2 && !dng_version && !strcmp(make,"Kodak")) + len = 2; + while (len--) { + i = ftell(ifp); + fseek (ifp, get4()+base, SEEK_SET); + if (parse_tiff_ifd (base, level+1)) break; + fseek (ifp, i+4, SEEK_SET); + } + break; + case 29184: sony_offset = get4(); break; + case 29185: sony_length = get4(); break; + case 29217: sony_key = get4(); break; + case 29443: + FORC4 cam_mul[c ^ (c < 2)] = get2(); + break; + case 33405: /* Model2 */ + fgets (model2, 64, ifp); + break; + case 33422: /* CFAPattern */ + if ((plen=len) > 16) plen = 16; + fread (cfa_pat, 1, plen, ifp); + for (colors=cfa=i=0; i < plen; i++) { + colors += !(cfa & (1 << cfa_pat[i])); + cfa |= 1 << cfa_pat[i]; + } + if (cfa == 070) memcpy (cfa_pc,"\003\004\005",3); /* CMY */ + if (cfa == 072) memcpy (cfa_pc,"\005\003\004\001",4); /* GMCY */ + goto guess_cfa_pc; + case 34310: + parse_mos (ftell(ifp)); + break; + case 34665: /* EXIF tag */ + fseek (ifp, get4()+base, SEEK_SET); + parse_exif (base); + break; + case 37122: /* CompressedBitsPerPixel */ + kodak_cbpp = get4(); + break; + case 37400: + for (raw_color = i=0; i < 3; i++) { + getrat(); + FORC3 rgb_cam[i][c] = getrat(); + } + break; + case 46275: + strcpy (make, "Imacon"); + data_offset = ftell(ifp); + raw_width = 4090; + raw_height = len / raw_width / 2; + done = 1; + break; + case 50454: /* Sinar tag */ + case 50455: + if (!(cbuf = malloc(len))) break; + fread (cbuf, 1, len, ifp); + for (cp = cbuf-1; cp && cp < cbuf+len; cp = strchr(cp,'\n')) + if (!strncmp (++cp,"Neutral ",8)) + sscanf (cp+8, "%f %f %f", cam_mul, cam_mul+1, cam_mul+2); + free (cbuf); + break; + case 50706: /* DNGVersion */ + FORC4 dng_version = (dng_version << 8) + fgetc(ifp); + break; + case 50710: /* CFAPlaneColor */ + if (len > 4) len = 4; + colors = len; + fread (cfa_pc, 1, colors, ifp); +guess_cfa_pc: + FORCC tab[cfa_pc[c]] = c; + for (i=16; i--; ) + filters = filters << 2 | tab[cfa_pat[i % plen]]; + break; + case 50711: /* CFALayout */ + if (get2() == 2) { + fuji_width = (raw_width+1)/2; + filters = 0x49494949; + } + break; + case 0x123: + case 0x90d: + case 50712: /* LinearizationTable */ + if (len > 0x1000) + len = 0x1000; + read_shorts (curve, len); + for (i=len; i < 0x1000; i++) + maximum = curve[i] = curve[i-1]; + break; + case 50714: /* BlackLevel */ + case 50715: /* BlackLevelDeltaH */ + case 50716: /* BlackLevelDeltaV */ + for (dblack=i=0; i < len; i++) + dblack += getrat(); + black += dblack/len + 0.5; + break; + case 50717: /* WhiteLevel */ + maximum = get2(); + break; + case 50718: /* DefaultScale */ + i = get4(); + j = get4() * get4(); + i *= get4(); + if (i > j) xmag = i / j; + else ymag = j / i; + break; + case 50721: /* ColorMatrix1 */ + case 50722: /* ColorMatrix2 */ + FORCC for (j=0; j < 3; j++) + cm[c][j] = getrat(); + use_cm = 1; + break; + case 50723: /* CameraCalibration1 */ + case 50724: /* CameraCalibration2 */ + for (i=0; i < colors; i++) + FORCC cc[i][c] = getrat(); + case 50727: /* AnalogBalance */ + FORCC ab[c] = getrat(); + break; + case 50728: /* AsShotNeutral */ + FORCC asn[c] = getrat(); + break; + case 50729: /* AsShotWhiteXY */ + xyz[0] = getrat(); + xyz[1] = getrat(); + xyz[2] = 1 - xyz[0] - xyz[1]; + break; + case 50740: /* DNGPrivateData */ + if (dng_version) break; + fseek (ifp, get4()+base, SEEK_SET); + parse_tiff_ifd (base, level+1); + break; + case 50829: /* ActiveArea */ + top_margin = get4(); + left_margin = get4(); + height = get4() - top_margin; + width = get4() - left_margin; + } + fseek (ifp, save+4, SEEK_SET); + } + if (sony_length && (buf = malloc(sony_length))) { + fseek (ifp, sony_offset, SEEK_SET); + fread (buf, sony_length, 1, ifp); + sony_decrypt (buf, sony_length/4, 1, sony_key); + sfp = ifp; + if ((ifp = tmpfile())) { + fwrite (buf, sony_length, 1, ifp); + fseek (ifp, 0, SEEK_SET); + parse_tiff_ifd (-sony_offset, level); + fclose (ifp); + } + ifp = sfp; + free (buf); + } + if (!(base | level | dng_version) && + (strstr(make,"Minolta") || strstr(make,"MINOLTA"))) make[0] = 0; + for (i=0; i < colors; i++) + FORCC cc[i][c] *= ab[i]; + if (use_cm) { + FORCC for (i=0; i < 3; i++) + for (cam_xyz[c][i]=j=0; j < colors; j++) + cam_xyz[c][i] += cc[c][j] * cm[j][i] * xyz[i]; + cam_xyz_coeff (cam_xyz); + } + if (asn[0]) + FORCC pre_mul[c] = 1 / asn[c]; + if (!use_cm) + FORCC pre_mul[c] /= cc[c][c]; + return done; +} + +void CLASS parse_tiff (int base) +{ + int doff, maxifd=1000; + + fseek (ifp, base, SEEK_SET); + order = get2(); + if (order != 0x4949 && order != 0x4d4d) return; + get2(); + while ((doff = get4()) && maxifd--) { + fseek (ifp, doff+base, SEEK_SET); + if (parse_tiff_ifd (base, 0)) break; + if (!dng_version && data_offset == 8) make[0] = 0; + } + if (!dng_version && !strncmp(make,"Kodak",5)) { + fseek (ifp, 12+base, SEEK_SET); + parse_tiff_ifd (base, 2); + } +} + +void CLASS parse_minolta() +{ + int save, tag, len, offset, high=0, wide=0, i, c; + + fseek (ifp, 4, SEEK_SET); + offset = get4() + 8; + while ((save=ftell(ifp)) < offset) { + tag = get4(); + len = get4(); + switch (tag) { + case 0x505244: /* PRD */ + fseek (ifp, 8, SEEK_CUR); + high = get2(); + wide = get2(); + break; + case 0x574247: /* WBG */ + get4(); + i = strstr(model,"A200") ? 3:0; + FORC4 cam_mul[c ^ (c >> 1) ^ i] = get2(); + break; + case 0x545457: /* TTW */ + parse_tiff (ftell(ifp)); + } + fseek (ifp, save+len+8, SEEK_SET); + } + raw_height = high; + raw_width = wide; + data_offset = offset; +} + +/* + Many cameras have a "debug mode" that writes JPEG and raw + at the same time. The raw file has no header, so try to + to open the matching JPEG file and read its metadata. + */ +void CLASS parse_external_jpeg() +{ + char *file, *ext, *jname, *jfile, *jext; + FILE *save=ifp; + + ext = strrchr (ifname, '.'); + file = strrchr (ifname, '/'); + if (!file) file = strrchr (ifname, '\\'); + if (!file) file = ifname-1; + file++; + if (strlen(ext) != 4 || ext-file != 8) return; + jname = malloc (strlen(ifname) + 1); + merror (jname, "parse_external()"); + strcpy (jname, ifname); + jfile = file - ifname + jname; + jext = ext - ifname + jname; + if (strcasecmp (ext, ".jpg")) { + strcpy (jext, isupper(ext[1]) ? ".JPG":".jpg"); + memcpy (jfile, file+4, 4); + memcpy (jfile+4, file, 4); + } else + while (isdigit(*--jext)) { + if (*jext != '9') { + (*jext)++; + break; + } + *jext = '0'; + } + if (strcmp (jname, ifname)) { + if ((ifp = fopen (jname, "rb"))) { + if (verbose) + fprintf (stderr, "Reading metadata from %s...\n", jname); + parse_tiff (12); + fclose (ifp); + } + } + if (!timestamp) + fprintf (stderr, "Failed to read metadata from %s\n", jname); + free (jname); + ifp = save; +} + +/* + CIFF block 0x1030 contains an 8x8 white sample. + Load this into white[][] for use in scale_colors(). + */ +void CLASS ciff_block_1030() +{ + static const ushort key[] = { 0x410, 0x45f3 }; + int i, bpp, row, col, vbits=0; + unsigned long bitbuf=0; + + get2(); + if (get4() != 0x80008) return; + if (get4() == 0) return; + bpp = get2(); + if (bpp != 10 && bpp != 12) return; + for (i=row=0; row < 8; row++) + for (col=0; col < 8; col++) { + if (vbits < bpp) { + bitbuf = bitbuf << 16 | (get2() ^ key[i++ & 1]); + vbits += 16; + } + white[row][col] = + bitbuf << (LONG_BIT - vbits) >> (LONG_BIT - bpp); + vbits -= bpp; + } +} + +/* + Parse a CIFF file, better known as Canon CRW format. + */ +void CLASS parse_ciff (int offset, int length) +{ + int tboff, nrecs, i, c, type, len, roff, aoff, save, wbi=-1; + static const int remap[] = { 1,2,3,4,5,1 }; + static const int remap_10d[] = { 0,1,3,4,5,6,0,0,2,8 }; + static const int remap_s70[] = { 0,1,2,9,4,3,6,7,8,9,10,0,0,0,7,0,0,8 }; + ushort key[] = { 0x410, 0x45f3 }; + + if (strcmp(model,"Canon PowerShot G6") && + strcmp(model,"Canon PowerShot S60") && + strcmp(model,"Canon PowerShot S70") && + strcmp(model,"Canon PowerShot Pro1")) + key[0] = key[1] = 0; + fseek (ifp, offset+length-4, SEEK_SET); + tboff = get4() + offset; + fseek (ifp, tboff, SEEK_SET); + nrecs = get2(); + if (nrecs > 100) return; + for (i = 0; i < nrecs; i++) { + type = get2(); + len = get4(); + roff = get4(); + aoff = offset + roff; + save = ftell(ifp); + if (type == 0x080a) { /* Get the camera make and model */ + fseek (ifp, aoff, SEEK_SET); + fread (make, 64, 1, ifp); + fseek (ifp, aoff+strlen(make)+1, SEEK_SET); + fread (model, 64, 1, ifp); + } + if (type == 0x102a) { /* Find the White Balance index */ + fseek (ifp, aoff+14, SEEK_SET); /* 0=auto, 1=daylight, 2=cloudy ... */ + wbi = get2(); + if (((!strcmp(model,"Canon EOS DIGITAL REBEL") || + !strcmp(model,"Canon EOS 300D DIGITAL"))) && wbi == 6) + wbi++; + } + if (type == 0x102c) { /* Get white balance (G2) */ + if (!strcmp(model,"Canon PowerShot G1") || + !strcmp(model,"Canon PowerShot Pro90 IS")) { + fseek (ifp, aoff+120, SEEK_SET); + FORC4 cam_mul[c ^ 2] = get2(); + } else { + fseek (ifp, aoff+100, SEEK_SET); + goto common; + } + } + if (type == 0x0032) { /* Get white balance (D30 & G3) */ + if (!strcmp(model,"Canon EOS D30")) { + fseek (ifp, aoff+72, SEEK_SET); +common: + camera_red = get2() ^ key[0]; + camera_red =(get2() ^ key[1]) / camera_red; + camera_blue = get2() ^ key[0]; + camera_blue /= get2() ^ key[1]; + if (!wbi) camera_red = -1; /* Use my auto WB for this photo */ + } else if (!strcmp(model,"Canon PowerShot G6") || + !strcmp(model,"Canon PowerShot S60") || + !strcmp(model,"Canon PowerShot S70")) { + fseek (ifp, aoff+96 + remap_s70[wbi]*8, SEEK_SET); + goto common; + } else if (!strcmp(model,"Canon PowerShot Pro1")) { + fseek (ifp, aoff+96 + wbi*8, SEEK_SET); + goto common; + } else { + fseek (ifp, aoff+80 + (wbi < 6 ? remap[wbi]*8 : 0), SEEK_SET); + if (!camera_red) + goto common; + } + } + if (type == 0x10a9) { /* Get white balance (D60) */ + if (!strcmp(model,"Canon EOS 10D")) + wbi = remap_10d[wbi]; + fseek (ifp, aoff+2 + wbi*8, SEEK_SET); + camera_red = get2(); + camera_red /= get2(); + camera_blue = get2(); + camera_blue = get2() / camera_blue; + } + if (type == 0x1030 && (wbi == 6 || wbi == 15)) { + fseek (ifp, aoff, SEEK_SET); /* Get white sample */ + ciff_block_1030(); + } + if (type == 0x1031) { /* Get the raw width and height */ + fseek (ifp, aoff+2, SEEK_SET); + raw_width = get2(); + raw_height = get2(); + } + if (type == 0x180e) { /* Get the timestamp */ + fseek (ifp, aoff, SEEK_SET); + timestamp = get4(); + } + if (type == 0x5817) + shot_order = len; + if (type == 0x580e) + timestamp = len; +#ifdef LOCALTIME + if ((type | 0x4000) == 0x580e) + timestamp = mktime (gmtime (×tamp)); +#endif + if (type == 0x5813) + flash_used = int_to_float(len); + if (type == 0x5814) + canon_5814 = int_to_float(len); + if (type == 0x1810) { /* Get the rotation */ + fseek (ifp, aoff+12, SEEK_SET); + flip = get4(); + } + if (type == 0x1835) { /* Get the decoder table */ + fseek (ifp, aoff, SEEK_SET); + crw_init_tables (get4()); + } + if (type >> 8 == 0x28 || type >> 8 == 0x30) /* Get sub-tables */ + parse_ciff(aoff, len); + fseek (ifp, save, SEEK_SET); + } +} + +void CLASS parse_rollei() +{ + char line[128], *val; + int tx=0, ty=0; + struct tm t; + + fseek (ifp, 0, SEEK_SET); + do { + fgets (line, 128, ifp); + if ((val = strchr(line,'='))) + *val++ = 0; + else + val = line + strlen(line); + if (!strcmp(line,"DAT")) + sscanf (val, "%d.%d.%d", &t.tm_mday, &t.tm_mon, &t.tm_year); + if (!strcmp(line,"TIM")) + sscanf (val, "%d:%d:%d", &t.tm_hour, &t.tm_min, &t.tm_sec); + if (!strcmp(line,"HDR")) + data_offset = atoi(val); + if (!strcmp(line,"X ")) + raw_width = atoi(val); + if (!strcmp(line,"Y ")) + raw_height = atoi(val); + if (!strcmp(line,"TX ")) + tx = atoi(val); + if (!strcmp(line,"TY ")) + ty = atoi(val); + } while (strncmp(line,"EOHD",4)); + t.tm_year -= 1900; + t.tm_mon -= 1; + if (mktime(&t) > 0) + timestamp = mktime(&t); + data_offset += tx * ty * 2; + strcpy (make, "Rollei"); + strcpy (model,"d530flex"); +} + +void CLASS parse_mos (int offset) +{ + char data[40]; + int skip, from, i, c, neut[4]; + static const unsigned bayer[] = + { 0x94949494, 0x61616161, 0x16161616, 0x49494949 }; + + fseek (ifp, offset, SEEK_SET); + while (1) { + fread (data, 1, 8, ifp); + if (strcmp(data,"PKTS")) break; + if (!make[0]) strcpy(make,"Leaf"); + fread (data, 1, 40, ifp); + skip = get4(); + from = ftell(ifp); +#ifdef USE_LCMS + if (!strcmp(data,"icc_camera_profile")) { + profile_length = skip; + profile_offset = from; + } +#endif + if (!strcmp(data,"CaptProf_number_of_planes")) { + fscanf (ifp, "%d", &i); + if (i > 1) filters = 0; + } + if (!strcmp(data,"CaptProf_raw_data_rotation") && filters) { + fscanf (ifp, "%d", &i); + filters = bayer[i/90]; + } + if (!strcmp(data,"NeutObj_neutrals")) { + for (i=0; i < 4; i++) + fscanf (ifp, "%d", neut+i); + FORC3 cam_mul[c] = 1.0 / neut[c+1]; + } + parse_mos (from); + fseek (ifp, skip+from, SEEK_SET); + } +} + +void CLASS parse_phase_one (int base) +{ + unsigned entries, tag, type, len, data, save, i, c; + char *cp; + + fseek (ifp, base, SEEK_SET); + order = get4() & 0xffff; + if (get4() >> 8 != 0x526177) return; /* "Raw" */ + fseek (ifp, base+get4(), SEEK_SET); + entries = get4(); + get4(); + while (entries--) { + tag = get4(); + type = get4(); + len = get4(); + data = get4(); + save = ftell(ifp); + fseek (ifp, base+data, SEEK_SET); + switch (tag) { + case 0x106: + for (raw_color = i=0; i < 3; i++) + FORC3 rgb_cam[i][c] = int_to_float(get4()); + break; + case 0x107: + FORC3 cam_mul[c] = pre_mul[c] = int_to_float(get4()); + break; + case 0x108: raw_width = data; break; + case 0x109: raw_height = data; break; + case 0x10a: left_margin = data; break; + case 0x10b: top_margin = data; break; + case 0x10c: width = data; break; + case 0x10d: height = data; break; + case 0x10e: tiff_data_compression = data; break; + case 0x10f: data_offset = data+base; break; + case 0x112: + nikon_curve_offset = save - 4; break; + case 0x301: + fread (model, 64, 1, ifp); + cp = strstr(model," camera"); + if (cp && cp < model+64) *cp = 0; + } + fseek (ifp, save, SEEK_SET); + } + load_raw = tiff_data_compression < 3 ? + phase_one_load_raw:phase_one_load_raw_c; + strcpy (make, "Phase One"); + if (model[0]) return; + sprintf (model, "%dx%d", width, height); + switch (raw_height) { + case 2060: strcpy (model,"LightPhase"); break; + case 2682: strcpy (model,"H 10"); break; + case 4128: strcpy (model,"H 20"); break; + case 5488: strcpy (model,"H 25"); break; + } +} + +void CLASS parse_fuji (int offset) +{ + int entries, tag, len, save, c; + + fseek (ifp, offset, SEEK_SET); + entries = get4(); + if (entries > 255) return; + while (entries--) { + tag = get2(); + len = get2(); + save = ftell(ifp); + if (tag == 0x100) { + raw_height = get2(); + raw_width = get2(); + } else if (tag == 0x121) { + height = get2(); + if ((width = get2()) == 4284) width += 3; + } else if (tag == 0x130) + fuji_layout = fgetc(ifp) >> 7; + if (tag == 0x2ff0) + FORC4 cam_mul[c ^ 1] = get2(); + fseek (ifp, save+len, SEEK_SET); + } + if (fuji_layout) { + height *= 2; + width /= 2; + } +} + +int CLASS parse_jpeg (int offset) +{ + int len, save, hlen; + + fseek (ifp, offset, SEEK_SET); + if (fgetc(ifp) != 0xff || fgetc(ifp) != 0xd8) return 0; + + while (fgetc(ifp) == 0xff && fgetc(ifp) >> 4 != 0xd) { + order = 0x4d4d; + len = get2() - 2; + save = ftell(ifp); + order = get2(); + hlen = get4(); + if (get4() == 0x48454150) /* "HEAP" */ + parse_ciff (save+hlen, len-hlen); + parse_tiff (save+6); + fseek (ifp, save+len, SEEK_SET); + } + return 1; +} + +void CLASS parse_riff() +{ + unsigned i, size, end; + char tag[4], date[64], month[64]; + static const char mon[12][4] = + { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" }; + struct tm t; + + order = 0x4949; + fread (tag, 4, 1, ifp); + size = get4(); + if (!memcmp(tag,"RIFF",4) || !memcmp(tag,"LIST",4)) { + end = ftell(ifp) + size; + get4(); + while (ftell(ifp) < end) + parse_riff(); + } else if (!memcmp(tag,"IDIT",4) && size < 64) { + fread (date, 64, 1, ifp); + date[size] = 0; + if (sscanf (date, "%*s %s %d %d:%d:%d %d", month, &t.tm_mday, + &t.tm_hour, &t.tm_min, &t.tm_sec, &t.tm_year) == 6) { + for (i=0; i < 12 && strcmp(mon[i],month); i++); + t.tm_mon = i; + t.tm_year -= 1900; + if (mktime(&t) > 0) + timestamp = mktime(&t); + } + } else + fseek (ifp, size, SEEK_CUR); +} + +void CLASS parse_smal (int offset, int fsize) +{ + int ver; + + fseek (ifp, offset+2, SEEK_SET); + order = 0x4949; + ver = fgetc(ifp); + if (ver == 6) + fseek (ifp, 5, SEEK_CUR); + if (get4() != fsize) return; + if (ver > 6) data_offset = get4(); + raw_height = height = get2(); + raw_width = width = get2(); + strcpy (make, "SMaL"); + sprintf (model, "v%d %dx%d", ver, width, height); + if (ver == 6) load_raw = smal_v6_load_raw; + if (ver == 9) load_raw = smal_v9_load_raw; +} + +char * CLASS foveon_gets (int offset, char *str, int len) +{ + int i; + fseek (ifp, offset, SEEK_SET); + for (i=0; i < len-1; i++) + if ((str[i] = get2()) == 0) break; + str[i] = 0; + return str; +} + +void CLASS parse_foveon() +{ + int entries, off, len, tag, save, i, wide, high, pent, poff[256][2]; + char name[64]; + + order = 0x4949; /* Little-endian */ + fseek (ifp, 36, SEEK_SET); + flip = get4(); + fseek (ifp, -4, SEEK_END); + fseek (ifp, get4(), SEEK_SET); + if (get4() != 0x64434553) return; /* SECd */ + get4(); + entries = get4(); + while (entries--) { + off = get4(); + len = get4(); + tag = get4(); + save = ftell(ifp); + fseek (ifp, off, SEEK_SET); + if (get4() != (0x20434553 | (tag << 24))) return; + switch (tag) { + case 0x47414d49: /* IMAG */ + case 0x32414d49: /* IMA2 */ + fseek (ifp, 12, SEEK_CUR); + wide = get4(); + high = get4(); + if (wide > raw_width && high > raw_height) { + raw_width = wide; + raw_height = high; + data_offset = off + 24; + } + break; + case 0x464d4143: /* CAMF */ + meta_offset = off + 24; + meta_length = len - 28; + if (meta_length > 0x20000) + meta_length = 0x20000; + break; + case 0x504f5250: /* PROP */ + get4(); + pent = get4(); + fseek (ifp, 12, SEEK_CUR); + off += pent*8 + 24; + if (pent > 256) pent=256; + for (i=0; i < pent*2; i++) + poff[0][i] = off + get4()*2; + for (i=0; i < pent; i++) { + foveon_gets (poff[i][0], name, 64); + if (!strcmp (name, "CAMMANUF")) + foveon_gets (poff[i][1], make, 64); + if (!strcmp (name, "CAMMODEL")) + foveon_gets (poff[i][1], model, 64); + if (!strcmp (name, "WB_DESC")) + foveon_gets (poff[i][1], model2, 64); + if (!strcmp (name, "TIME")) + timestamp = atoi (foveon_gets (poff[i][1], name, 64)); + } +#ifdef LOCALTIME + timestamp = mktime (gmtime (×tamp)); +#endif + } + fseek (ifp, save, SEEK_SET); + } + is_foveon = 1; +} + +/* + Thanks to Adobe for providing these excellent CAM -> XYZ matrices! + */ +void CLASS adobe_coeff() +{ + static const struct { + const char *prefix; + short trans[12]; + } table[] = { + { "Canon EOS D2000", + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Canon EOS D6000", + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Canon EOS D30", + { 9805,-2689,-1312,-5803,13064,3068,-2438,3075,8775 } }, + { "Canon EOS D60", + { 6188,-1341,-890,-7168,14489,2937,-2640,3228,8483 } }, + { "Canon EOS 5D", + { 6228,-404,-967,-8314,16108,2312,-1923,2179,7499 } }, + { "Canon EOS 20D", + { 6599,-537,-891,-8071,15783,2424,-1983,2234,7462 } }, + { "Canon EOS 350D", + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS DIGITAL REBEL XT", + { 6018,-617,-965,-8645,15881,2975,-1530,1719,7642 } }, + { "Canon EOS-1Ds Mark II", + { 6517,-602,-867,-8180,15926,2378,-1618,1771,7633 } }, + { "Canon EOS-1D Mark II", + { 6264,-582,-724,-8312,15948,2504,-1744,1919,8664 } }, + { "Canon EOS-1DS", + { 4374,3631,-1743,-7520,15212,2472,-2892,3632,8161 } }, + { "Canon EOS-1D", + { 6806,-179,-1020,-8097,16415,1687,-3267,4236,7690 } }, + { "Canon EOS", + { 8197,-2000,-1118,-6714,14335,2592,-2536,3178,8266 } }, + { "Canon PowerShot A50", + { -5300,9846,1776,3436,684,3939,-5540,9879,6200,-1404,11175,217 } }, + { "Canon PowerShot A5", + { -4801,9475,1952,2926,1611,4094,-5259,10164,5947,-1554,10883,547 } }, + { "Canon PowerShot G1", + { -4778,9467,2172,4743,-1141,4344,-5146,9908,6077,-1566,11051,557 } }, + { "Canon PowerShot G2", + { 9087,-2693,-1049,-6715,14382,2537,-2291,2819,7790 } }, + { "Canon PowerShot G3", + { 9212,-2781,-1073,-6573,14189,2605,-2300,2844,7664 } }, + { "Canon PowerShot G5", + { 9757,-2872,-933,-5972,13861,2301,-1622,2328,7212 } }, + { "Canon PowerShot G6", + { 9877,-3775,-871,-7613,14807,3072,-1448,1305,7485 } }, + { "Canon PowerShot Pro1", + { 10062,-3522,-999,-7643,15117,2730,-765,817,7323 } }, + { "Canon PowerShot Pro70", + { -4155,9818,1529,3939,-25,4522,-5521,9870,6610,-2238,10873,1342 } }, + { "Canon PowerShot Pro90", + { -4963,9896,2235,4642,-987,4294,-5162,10011,5859,-1770,11230,577 } }, + { "Canon PowerShot S30", + { 10566,-3652,-1129,-6552,14662,2006,-2197,2581,7670 } }, + { "Canon PowerShot S40", + { 8510,-2487,-940,-6869,14231,2900,-2318,2829,9013 } }, + { "Canon PowerShot S45", + { 8163,-2333,-955,-6682,14174,2751,-2077,2597,8041 } }, + { "Canon PowerShot S50", + { 8882,-2571,-863,-6348,14234,2288,-1516,2172,6569 } }, + { "Canon PowerShot S60", + { 8795,-2482,-797,-7804,15403,2573,-1422,1996,7082 } }, + { "Canon PowerShot S70", + { 9976,-3810,-832,-7115,14463,2906,-901,989,7889 } }, + { "Contax N Digital", + { 7777,1285,-1053,-9280,16543,2916,-3677,5679,7060 } }, + { "EPSON R-D1", + { 6827,-1878,-732,-8429,16012,2564,-704,592,7145 } }, + { "FUJIFILM FinePix E550", + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix F8", + { 11044,-3888,-1120,-7248,15168,2208,-1531,2277,8069 } }, + { "FUJIFILM FinePix F7", + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S20Pro", + { 10004,-3219,-1201,-7036,15047,2107,-1863,2565,7736 } }, + { "FUJIFILM FinePix S2Pro", + { 12492,-4690,-1402,-7033,15423,1647,-1507,2111,7697 } }, + { "FUJIFILM FinePix S3Pro", + { 11807,-4612,-1294,-8927,16968,1988,-2120,2741,8006 } }, + { "FUJIFILM FinePix S5000", + { 8754,-2732,-1019,-7204,15069,2276,-1702,2334,6982 } }, + { "FUJIFILM FinePix S5100", + { 11940,-4431,-1255,-6766,14428,2542,-993,1165,7421 } }, + { "FUJIFILM FinePix S7000", + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "FUJIFILM FinePix S9", /* copied from S7000 */ + { 10190,-3506,-1312,-7153,15051,2238,-2003,2399,7505 } }, + { "KODAK NC2000F", /* DJC */ + { 16475,-6903,-1218,-851,10375,477,2505,-7,1020 } }, + { "Kodak DCS315C", + { 17523,-4827,-2510,756,8546,-137,6113,1649,2250 } }, + { "Kodak DCS330C", + { 20620,-7572,-2801,-103,10073,-396,3551,-233,2220 } }, + { "KODAK DCS420", + { 10868,-1852,-644,-1537,11083,484,2343,628,2216 } }, + { "KODAK DCS460", + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS1", + { 10592,-2206,-967,-1944,11685,230,2206,670,1273 } }, + { "KODAK EOSDCS3B", + { 9898,-2700,-940,-2478,12219,206,1985,634,1031 } }, + { "Kodak DCS520C", + { 24542,-10860,-3401,-1490,11370,-297,2858,-605,3225 } }, + { "Kodak DCS560C", + { 20482,-7172,-3125,-1033,10410,-285,2542,226,3136 } }, + { "Kodak DCS620C", + { 23617,-10175,-3149,-2054,11749,-272,2586,-489,3453 } }, + { "Kodak DCS620X", + { 13095,-6231,154,12221,-21,-2137,895,4602,2258 } }, + { "Kodak DCS660C", + { 18244,-6351,-2739,-791,11193,-521,3711,-129,2802 } }, + { "Kodak DCS720X", + { 11775,-5884,950,9556,1846,-1286,-1019,6221,2728 } }, + { "Kodak DCS760C", + { 16623,-6309,-1411,-4344,13923,323,2285,274,2926 } }, + { "Kodak DCS Pro SLR", + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14nx", + { 5494,2393,-232,-6427,13850,2846,-1876,3997,5445 } }, + { "Kodak DCS Pro 14", + { 7791,3128,-776,-8588,16458,2039,-2455,4006,6198 } }, + { "Kodak ProBack645", + { 16414,-6060,-1470,-3555,13037,473,2545,122,4948 } }, + { "Kodak ProBack", + { 21179,-8316,-2918,-915,11019,-165,3477,-180,4210 } }, + { "LEICA DIGILUX 2", + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Leaf Valeo", + { 8236,1746,-1314,-8251,15953,2428,-3673,5786,5771 } }, + { "Minolta DiMAGE 5", + { 8983,-2942,-963,-6556,14476,2237,-2426,2887,8014 } }, + { "Minolta DiMAGE 7Hi", + { 11368,-3894,-1242,-6521,14358,2339,-2475,3056,7285 } }, + { "Minolta DiMAGE 7", + { 9144,-2777,-998,-6676,14556,2281,-2470,3019,7744 } }, + { "Minolta DiMAGE A1", + { 9274,-2547,-1167,-8220,16323,1943,-2273,2720,8340 } }, + { "MINOLTA DiMAGE A200", + { 8560,-2487,-986,-8112,15535,2771,-1209,1324,7743 } }, + { "Minolta DiMAGE A2", + { 9097,-2726,-1053,-8073,15506,2762,-966,981,7763 } }, + { "Minolta DiMAGE Z2", + { 11428,-3512,-1706,-5895,13815,2266,-2382,2719,5651 } }, + { "MINOLTA DYNAX 5", + { 10284,-3283,-1086,-7957,15762,2316,-829,882,6644 } }, + { "MINOLTA DYNAX 7", + { 10239,-3104,-1099,-8037,15727,2451,-927,925,6871 } }, + { "NIKON D100", + { 5902,-933,-782,-8983,16719,2354,-1402,1455,6464 } }, + { "NIKON D1H", + { 7577,-2166,-926,-7454,15592,1934,-2377,2808,8606 } }, + { "NIKON D1X", + { 7702,-2245,-975,-9114,17242,1875,-2679,3055,8521 } }, + { "NIKON D1", + { 7559,-2130,-965,-7611,15713,1972,-2478,3042,8290 } }, + { "NIKON D2H", + { 5710,-901,-615,-8594,16617,2024,-2975,4120,6830 } }, + { "NIKON D2X", + { 10231,-2769,-1255,-8301,15900,2552,-797,680,7148 } }, + { "NIKON D50", + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON D70", + { 7732,-2422,-789,-8238,15884,2498,-859,783,7330 } }, + { "NIKON E995", /* copied from E5000 */ + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E2500", + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E4500", + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5000", + { -5547,11762,2189,5814,-558,3342,-4924,9840,5949,688,9083,96 } }, + { "NIKON E5400", + { 9349,-2987,-1001,-7919,15766,2266,-2098,2680,6839 } }, + { "NIKON E5700", + { -5368,11478,2368,5537,-113,3148,-4969,10021,5782,778,9028,211 } }, + { "NIKON E8400", + { 7842,-2320,-992,-8154,15718,2599,-1098,1342,7560 } }, + { "NIKON E8700", + { 8489,-2583,-1036,-8051,15583,2643,-1307,1407,7354 } }, + { "NIKON E8800", + { 7971,-2314,-913,-8451,15762,2894,-1442,1520,7610 } }, + { "OLYMPUS C5050", + { 10508,-3124,-1273,-6079,14294,1901,-1653,2306,6237 } }, + { "OLYMPUS C5060", + { 10445,-3362,-1307,-7662,15690,2058,-1135,1176,7602 } }, + { "OLYMPUS C70", + { 10793,-3791,-1146,-7498,15177,2488,-1390,1577,7321 } }, + { "OLYMPUS C80", + { 8606,-2509,-1014,-8238,15714,2703,-942,979,7760 } }, + { "OLYMPUS E-10", + { 12745,-4500,-1416,-6062,14542,1580,-1934,2256,6603 } }, + { "OLYMPUS E-1", + { 11846,-4767,-945,-7027,15878,1089,-2699,4122,8311 } }, + { "OLYMPUS E-20", + { 13173,-4732,-1499,-5807,14036,1895,-2045,2452,7142 } }, + { "OLYMPUS E-300", + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "OLYMPUS E-500", /* copied from E-300 */ + { 7828,-1761,-348,-5788,14071,1830,-2853,4518,6557 } }, + { "PENTAX *ist DS", + { 10371,-2333,-1206,-8688,16231,2602,-1230,1116,11282 } }, + { "PENTAX *ist D", + { 9651,-2059,-1189,-8881,16512,2487,-1460,1345,10687 } }, + { "Panasonic DMC-FZ30", + { 10976,-4029,-1141,-7918,15491,2600,-1670,2071,8246 } }, + { "Panasonic DMC-LC1", + { 11340,-4069,-1275,-7555,15266,2448,-2960,3426,7685 } }, + { "Panasonic DMC-LX1", + { 10704,-4187,-1230,-8314,15952,2501,-920,945,8927 } }, + { "SONY DSC-F828", + { 7924,-1910,-777,-8226,15459,2998,-1517,2199,6818,-7242,11401,3481 } }, + { "SONY DSC-R1", /* DJC */ + { 10528,-3695,-517,-2822,10699,2124,406,1240,5342 } }, + { "SONY DSC-V3", + { 7511,-2571,-692,-7894,15088,3060,-948,1111,8128 } } + }; + double cam_xyz[4][3]; + char name[130]; + int i, j; + + sprintf (name, "%s %s", make, model); + for (i=0; i < sizeof table / sizeof *table; i++) + if (!strncmp (name, table[i].prefix, strlen(table[i].prefix))) { + for (j=0; j < 12; j++) + cam_xyz[0][j] = table[i].trans[j]; + cam_xyz_coeff (cam_xyz); + break; + } +} + +void CLASS simple_coeff (int index) +{ + static const float table[][12] = { + /* index 0 -- all Foveon cameras */ + { 1.4032,-0.2231,-0.1016,-0.5263,1.4816,0.017,-0.0112,0.0183,0.9113 }, + /* index 1 -- Kodak DC20 and DC25 */ + { 2.25,0.75,-1.75,-0.25,-0.25,0.75,0.75,-0.25,-0.25,-1.75,0.75,2.25 }, + /* index 2 -- Logitech Fotoman Pixtura */ + { 1.893,-0.418,-0.476,-0.495,1.773,-0.278,-1.017,-0.655,2.672 }, + /* index 3 -- Nikon E700, E800, and E950 */ + { -1.936280, 1.800443, -1.448486, 2.584324, + 1.405365, -0.524955, -0.289090, 0.408680, + -1.204965, 1.082304, 2.941367, -1.818705 } + }; + int i, c; + + for (raw_color = i=0; i < 3; i++) + FORCC rgb_cam[i][c] = table[index][i*colors+c]; +} + +short CLASS guess_byte_order (int words) +{ + uchar test[4][2]; + int t=2, msb; + double diff, sum[2] = {0,0}; + + fread (test[0], 2, 2, ifp); + for (words-=2; words--; ) { + fread (test[t], 2, 1, ifp); + for (msb=0; msb < 2; msb++) { + diff = (test[t^2][msb] << 8 | test[t^2][!msb]) + - (test[t ][msb] << 8 | test[t ][!msb]); + sum[msb] += diff*diff; + } + t = (t+1) & 3; + } + return sum[0] < sum[1] ? 0x4d4d : 0x4949; +} + +/* + Identify which camera created this file, and set global variables + accordingly. Return nonzero if the file cannot be decoded. + */ +int CLASS identify (int no_decode) +{ + char head[32], *cp; + unsigned hlen, fsize, i, c, is_jpeg=0, is_canon; + static const struct { + int fsize; + char make[12], model[15], withjpeg; + } table[] = { + { 62464, "Kodak", "DC20" ,0 }, + { 124928, "Kodak", "DC20" ,0 }, + { 311696, "ST Micro", "STV680 VGA" ,0 }, /* SPYz */ + { 787456, "Creative", "PC-CAM 600" ,0 }, + { 1138688, "Minolta", "RD175" ,0 }, + { 3840000, "Foculus", "531C" ,0 }, + { 1920000, "AVT", "F-201C" ,0 }, + { 5067304, "AVT", "F-510C" ,0 }, + { 10134608, "AVT", "F-510C" ,0 }, + { 16157136, "AVT", "F-810C" ,0 }, + { 6624000, "Pixelink", "A782" ,0 }, + { 13248000, "Pixelink", "A782" ,0 }, + { 6291456, "RoverShot","3320AF" ,0 }, + { 5939200, "OLYMPUS", "C770UZ" ,0 }, + { 1581060, "NIKON", "E900" ,1 }, /* or E900s,E910 */ + { 2465792, "NIKON", "E950" ,1 }, /* or E800,E700 */ + { 2940928, "NIKON", "E2100" ,1 }, /* or E2500 */ + { 4771840, "NIKON", "E990" ,1 }, /* or E995 */ + { 4775936, "NIKON", "E3700" ,1 }, /* or Optio 33WR */ + { 5869568, "NIKON", "E4300" ,1 }, /* or DiMAGE Z2 */ + { 5865472, "NIKON", "E4500" ,1 }, + { 7438336, "NIKON", "E5000" ,1 }, /* or E5700 */ + { 1976352, "CASIO", "QV-2000UX" ,1 }, + { 3217760, "CASIO", "QV-3*00EX" ,1 }, + { 6218368, "CASIO", "QV-5700" ,1 }, + { 7530816, "CASIO", "QV-R51" ,1 }, + { 7684000, "CASIO", "QV-4000" ,1 }, + { 4948608, "CASIO", "EX-S100" ,1 }, + { 7542528, "CASIO", "EX-Z50" ,1 }, + { 7753344, "CASIO", "EX-Z55" ,1 }, + { 7426656, "CASIO", "EX-P505" ,1 }, + { 9313536, "CASIO", "EX-P600" ,1 }, + { 10979200, "CASIO", "EX-P700" ,1 }, + { 3178560, "PENTAX", "Optio S" ,1 }, /* 8-bit */ + { 4841984, "PENTAX", "Optio S" ,1 }, /* 12-bit */ + { 6114240, "PENTAX", "Optio S4" ,1 }, /* or S4i */ + { 12582980, "Sinar", "" ,0 } }; + static const char *corp[] = + { "Canon", "NIKON", "EPSON", "KODAK", "Kodak", "OLYMPUS", "PENTAX", + "MINOLTA", "Minolta", "Konica", "CASIO", "Sinar" }; + +/* What format is this file? Set make[] if we recognize it. */ + + load_raw = NULL; + raw_height = raw_width = fuji_width = flip = 0; + height = width = top_margin = left_margin = 0; + make[0] = model[0] = model2[0] = 0; + memset (white, 0, sizeof white); + data_offset = meta_length = tiff_bps = tiff_data_compression = 0; + kodak_cbpp = zero_after_ff = dng_version = fuji_secondary = 0; + timestamp = shot_order = tiff_samples = black = is_foveon = 0; + raw_color = use_gamma = xmag = ymag = 1; + filters = UINT_MAX; /* 0 = no filters, UINT_MAX = unknown */ + for (i=0; i < 4; i++) { + cam_mul[i] = i == 1; + pre_mul[i] = i < 3; + FORC3 rgb_cam[c][i] = c == i; + } + colors = 3; + for (i=0; i < 0x1000; i++) curve[i] = i; + maximum = 0xfff; +#ifdef USE_LCMS + profile_length = 0; +#endif + + order = get2(); + hlen = get4(); + fseek (ifp, 0, SEEK_SET); + fread (head, 1, 32, ifp); + fseek (ifp, 0, SEEK_END); + fsize = ftell(ifp); + if ((cp = memmem (head, 32, "MMMM", 4)) || + (cp = memmem (head, 32, "IIII", 4))) + parse_phase_one (cp-head); + else if (order == 0x4949 || order == 0x4d4d) { + if (!memcmp (head+6,"HEAPCCDR",8)) { + data_offset = hlen; + parse_ciff (hlen, fsize - hlen); + } else { + parse_tiff(0); + if (!dng_version && !strncmp(make,"NIKON",5) && filters == UINT_MAX) + make[0] = 0; + } + } else if (!memcmp (head,"\xff\xd8\xff\xe1",4) && + !memcmp (head+6,"Exif",4)) { + fseek (ifp, 4, SEEK_SET); + fseek (ifp, 4 + get2(), SEEK_SET); + if (fgetc(ifp) != 0xff) + parse_tiff(12); + } else if (!memcmp (head,"BM",2) && + head[26] == 1 && head[28] == 16 && head[30] == 0) { + data_offset = 0x1000; + order = 0x4949; + fseek (ifp, 38, SEEK_SET); + if (get4() == 2834 && get4() == 2834 && get4() == 0 && get4() == 4096) { + strcpy (model, "BMQ"); + flip = 3; + goto nucore; + } + } else if (!memcmp (head,"BR",2)) { + strcpy (model, "RAW"); +nucore: + strcpy (make, "Nucore"); + order = 0x4949; + fseek (ifp, 10, SEEK_SET); + data_offset += get4(); + get4(); + raw_width = get4(); + raw_height = get4(); + if (model[0] == 'B' && raw_width == 2597) { + raw_width++; + data_offset -= 0x1000; + } + } else if (!memcmp (head+25,"ARECOYK",7)) { + strcpy (make, "Contax"); + strcpy (model,"N Digital"); + fseek (ifp, 33, SEEK_SET); + get_timestamp(1); + fseek (ifp, 60, SEEK_SET); + FORC4 cam_mul[c ^ (c >> 1)] = get4(); + } else if (!strcmp (head, "PXN")) { + strcpy (make, "Logitech"); + strcpy (model,"Fotoman Pixtura"); + } else if (!memcmp (head,"FUJIFILM",8)) { + fseek (ifp, 92, SEEK_SET); + parse_fuji (get4()); + fseek (ifp, 84, SEEK_SET); + if ((hlen = get4()) > 120) { + fseek (ifp, 120, SEEK_SET); + fuji_secondary = (i = get4()) && 1; + if (fuji_secondary && use_secondary) + parse_fuji (i); + } + fseek (ifp, 100, SEEK_SET); + i = get4(); + parse_tiff (hlen+12); + data_offset = i; + } else if (!memcmp (head,"RIFF",4)) { + fseek (ifp, 0, SEEK_SET); + parse_riff(); + } else if (!memcmp (head,"DSC-Image",9)) + parse_rollei(); + else if (!memcmp (head,"\0MRM",4)) + parse_minolta(); + else if (!memcmp (head,"FOVb",4)) + parse_foveon(); + else + for (i=0; i < sizeof table / sizeof *table; i++) + if (fsize == table[i].fsize) { + strcpy (make, table[i].make ); + strcpy (model, table[i].model); + if (table[i].withjpeg) + parse_external_jpeg(); + } + parse_mos(8); + parse_mos(3472); + if (make[0] == 0) parse_smal (0, fsize); + if (make[0] == 0) is_jpeg = parse_jpeg(0); + if (no_decode) return !timestamp; + + for (i=0; i < sizeof corp / sizeof *corp; i++) + if (strstr (make, corp[i])) /* Simplify company names */ + strcpy (make, corp[i]); + if (!strncmp (make,"KODAK",5)) + make[16] = model[16] = 0; + cp = make + strlen(make); /* Remove trailing spaces */ + while (*--cp == ' ') *cp = 0; + cp = model + strlen(model); + while (*--cp == ' ') *cp = 0; + i = strlen(make); /* Remove make from model */ + if (!strncmp (model, make, i) && model[i++] == ' ') + memmove (model, model+i, 64-i); + make[63] = model[63] = model2[63] = 0; + + if (make[0] == 0) { + fprintf (stderr, "%s: unsupported file format.\n", ifname); + return 1; + } + if ((raw_height | raw_width) < 0) + raw_height = raw_width = 0; + if (!height) height = raw_height; + if (!width) width = raw_width; + if (fuji_width) { + width = height + fuji_width; + height = width - 1; + xmag = ymag = 1; + } + if (dng_version) { + strcat (model," DNG"); + if (filters == UINT_MAX) filters = 0; + if (!filters) + colors = tiff_samples; + if (tiff_data_compression == 1) + load_raw = adobe_dng_load_raw_nc; + if (tiff_data_compression == 7) + load_raw = adobe_dng_load_raw_lj; + FORC4 cam_mul[c] = pre_mul[c]; + goto dng_skip; + } + +/* We'll try to decode anything from Canon or Nikon. */ + + if (filters == UINT_MAX) filters = 0x94949494; + if ((is_canon = !strcmp(make,"Canon"))) { + load_raw = memcmp (head+6,"HEAPCCDR",8) ? + lossless_jpeg_load_raw : canon_compressed_load_raw; + maximum = 0xfff; + } + if (!strcmp(make,"NIKON")) + load_raw = nikon_is_compressed() ? + nikon_compressed_load_raw : nikon_load_raw; + if (!strncmp (make,"OLYMPUS",7)) + height += height & 1; + +/* Set parameters based on camera name (for non-DNG files). */ + + if (is_foveon) { + if (height*2 < width) ymag = 2; + if (height > width) xmag = 2; + filters = 0; + load_raw = foveon_load_raw; + simple_coeff(0); + } else if (!strcmp(model,"PowerShot 600")) { + height = 613; + width = 854; + colors = 4; + filters = 0xe1e4e1e4; + load_raw = canon_600_load_raw; + } else if (!strcmp(model,"PowerShot A5") || + !strcmp(model,"PowerShot A5 Zoom")) { + height = 773; + width = 960; + raw_width = 992; + colors = 4; + filters = 0x1e4e1e4e; + load_raw = canon_a5_load_raw; + } else if (!strcmp(model,"PowerShot A50")) { + height = 968; + width = 1290; + raw_width = 1320; + colors = 4; + filters = 0x1b4e4b1e; + load_raw = canon_a5_load_raw; + } else if (!strcmp(model,"PowerShot Pro70")) { + height = 1024; + width = 1552; + colors = 4; + filters = 0x1e4b4e1b; + load_raw = canon_a5_load_raw; + black = 34; + } else if (!strcmp(model,"PowerShot Pro90 IS")) { + width = 1896; + colors = 4; + filters = 0xb4b4b4b4; + } else if (is_canon && raw_width == 2144) { + height = 1550; + width = 2088; + top_margin = 8; + left_margin = 4; + if (!strcmp(model,"PowerShot G1")) { + colors = 4; + filters = 0xb4b4b4b4; + } + } else if (is_canon && raw_width == 2224) { + height = 1448; + width = 2176; + top_margin = 6; + left_margin = 48; + } else if (is_canon && raw_width == 2376) { + height = 1720; + width = 2312; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 2672) { + height = 1960; + width = 2616; + top_margin = 6; + left_margin = 12; + } else if (is_canon && raw_width == 3152) { + height = 2056; + width = 3088; + top_margin = 12; + left_margin = 64; + maximum = 0xfa0; + } else if (is_canon && raw_width == 3160) { + height = 2328; + width = 3112; + top_margin = 12; + left_margin = 44; + } else if (is_canon && raw_width == 3344) { + height = 2472; + width = 3288; + top_margin = 6; + left_margin = 4; + } else if (!strcmp(model,"EOS D2000C")) { + filters = 0x61616161; + black = curve[200]; + } else if (!strcmp(model,"EOS-1D")) { + raw_height = height = 1662; + raw_width = width = 2496; + data_offset = 288912; + filters = 0x61616161; + } else if (!strcmp(model,"EOS-1DS")) { + raw_height = height = 2718; + raw_width = width = 4082; + data_offset = 289168; + filters = 0x61616161; + } else if (is_canon && raw_width == 3516) { + top_margin = 14; + left_margin = 42; + goto canon_cr2; + } else if (is_canon && raw_width == 3596) { + top_margin = 12; + left_margin = 74; + goto canon_cr2; + } else if (is_canon && raw_width == 4476) { + top_margin = 34; + left_margin = 90; + goto canon_cr2; + } else if (is_canon && raw_width == 5108) { + top_margin = 13; + left_margin = 98; + maximum = 0xe80; +canon_cr2: + height = raw_height - top_margin; + width = raw_width - left_margin; + } else if (!strcmp(model,"D1")) { + camera_red *= 256/527.0; + camera_blue *= 256/317.0; + } else if (!strcmp(model,"D1X")) { + width = 4024; + ymag = 2; + } else if (!strcmp(model,"D70")) { + maximum = 0xf53; + } else if (!strcmp(model,"D100")) { + if (tiff_data_compression == 34713 && load_raw == nikon_load_raw) + raw_width = (width += 3) + 3; + maximum = 0xf44; + } else if (!strcmp(model,"D2H")) { + width = 2482; + left_margin = 6; + } else if (!strcmp(model,"D2X")) { + width = 4312; + } else if (fsize == 1581060) { + height = 963; + width = 1287; + raw_width = 1632; + load_raw = nikon_e900_load_raw; + maximum = 0x3f4; + colors = 4; + filters = 0x1e1e1e1e; + simple_coeff(3); + pre_mul[0] = 1.2085; + pre_mul[1] = 1.0943; + pre_mul[3] = 1.1103; + } else if (fsize == 2465792) { + height = 1203; + width = 1616; + raw_width = 2048; + load_raw = nikon_e900_load_raw; + maximum = 0x3dd; + colors = 4; + filters = 0x4b4b4b4b; + simple_coeff(3); + pre_mul[0] = 1.18193; + pre_mul[2] = 1.16452; + pre_mul[3] = 1.17250; + } else if (!strcmp(model,"E880") || + !strcmp(model,"E990")) { + if (!timestamp && !nikon_e990()) goto cp_e995; + height = 1540; + width = 2064; + colors = 4; + filters = 0xb4b4b4b4; + simple_coeff(3); + pre_mul[0] = 1.196; + pre_mul[1] = 1.246; + pre_mul[2] = 1.018; + } else if (!strcmp(model,"E995")) { +cp_e995: + strcpy (model, "E995"); + height = 1540; + width = 2064; + colors = 4; + filters = 0xe1e1e1e1; + } else if (!strcmp(model,"E2100")) { + if (!timestamp && !nikon_e2100()) goto cp_e2500; + height = 1206; + width = 1616; + load_raw = nikon_e2100_load_raw; + pre_mul[0] = 1.945; + pre_mul[2] = 1.040; + } else if (!strcmp(model,"E2500")) { +cp_e2500: + strcpy (model, "E2500"); + height = 1204; + width = 1616; + colors = 4; + filters = 0x4b4b4b4b; + } else if (fsize == 4775936) { + height = 1542; + width = 2064; + load_raw = nikon_e2100_load_raw; + pre_mul[0] = 1.818; + pre_mul[2] = 1.618; + if ((i = nikon_3700()) == 2) { + strcpy (make, "OLYMPUS"); + strcpy (model, "C740UZ"); + } else if (i == 0) { + strcpy (make, "PENTAX"); + strcpy (model,"Optio 33WR"); + flip = 1; + filters = 0x16161616; + pre_mul[0] = 1.331; + pre_mul[2] = 1.820; + } + } else if (!strcmp(model,"E4300")) { + if (!timestamp && minolta_z2()) goto dimage_z2; + height = 1710; + width = 2288; + filters = 0x16161616; + pre_mul[0] = 508; + pre_mul[1] = 256; + pre_mul[2] = 322; + } else if (!strcmp(model,"DiMAGE Z2")) { +dimage_z2: + strcpy (make, "MINOLTA"); + strcpy (model,"DiMAGE Z2"); + height = 1710; + width = 2288; + filters = 0x16161616; + load_raw = nikon_e2100_load_raw; + black = 68; + } else if (!strcmp(model,"E4500")) { + height = 1708; + width = 2288; + colors = 4; + filters = 0xb4b4b4b4; + } else if (fsize == 7438336) { + height = 1924; + width = 2576; + colors = 4; + filters = 0xb4b4b4b4; + } else if (!strcmp(model,"R-D1")) { + tiff_data_compression = 34713; + load_raw = nikon_load_raw; + } else if (!strcmp(model,"FinePix S5100") || + !strcmp(model,"FinePix S5500")) { + load_raw = unpacked_load_raw; + maximum = 0xffff; + } else if (!strncmp(model,"FinePix",7)) { + if (!strcmp(model+7,"S2Pro")) { + strcpy (model+7," S2Pro"); + height = 2144; + width = 2880; + black = 128; + flip = 6; + } else + maximum = 0x3e00; + top_margin = (raw_height - height)/2; + left_margin = (raw_width - width )/2; + data_offset += (top_margin*raw_width + left_margin) * 2; + if (fuji_secondary) + data_offset += use_secondary * ( strcmp(model+7," S3Pro") + ? (raw_width *= 2) : raw_height*raw_width*2 ); + fuji_width = width >> !fuji_layout; + width = (height >> fuji_layout) + fuji_width; + raw_height = height; + height = width - 1; + load_raw = fuji_load_raw; + if (!(fuji_width & 1)) filters = 0x49494949; + } else if (!strcmp(model,"RD175")) { + height = 986; + width = 1534; + data_offset = 513; + filters = 0x61616161; + load_raw = minolta_rd175_load_raw; + } else if (!strcmp(model,"Digital Camera KD-400Z")) { + height = 1712; + width = 2312; + raw_width = 2336; + data_offset = 4034; + fseek (ifp, 2032, SEEK_SET); + goto konica_400z; + } else if (!strcmp(model,"Digital Camera KD-510Z")) { + data_offset = 4032; + pre_mul[0] = 1.297; + pre_mul[2] = 1.438; + fseek (ifp, 2032, SEEK_SET); + goto konica_510z; + } else if (!strcasecmp(make,"MINOLTA")) { + load_raw = unpacked_load_raw; + maximum = 0xf7d; + if (!strncmp(model,"DiMAGE A",8)) { + if (!strcmp(model,"DiMAGE A200")) + filters = 0x49494949; + load_raw = packed_12_load_raw; + maximum = model[8] == '1' ? 0xf8b : 0xfff; + } else if (!strncmp(model,"ALPHA",5) || + !strncmp(model,"DYNAX",5) || + !strncmp(model,"MAXXUM",6)) { + sprintf (model, "DYNAX %s", model+6 + (model[0]=='M')); + load_raw = packed_12_load_raw; + maximum = 0xffb; + } else if (!strncmp(model,"DiMAGE G",8)) { + if (model[8] == '4') { + data_offset = 5056; + pre_mul[0] = 1.602; + pre_mul[2] = 1.441; + fseek (ifp, 2078, SEEK_SET); + height = 1716; + width = 2304; + } else if (model[8] == '5') { + data_offset = 4016; + fseek (ifp, 1936, SEEK_SET); +konica_510z: + height = 1956; + width = 2607; + raw_width = 2624; + } else if (model[8] == '6') { + data_offset = 4032; + fseek (ifp, 2030, SEEK_SET); + height = 2136; + width = 2848; + } + filters = 0x61616161; +konica_400z: + load_raw = unpacked_load_raw; + maximum = 0x3df; + order = 0x4d4d; + FORC4 cam_mul[(c >> 1) | ((c & 1) << 1)] = get2(); + } + if (pre_mul[0] == 1 && pre_mul[2] == 1) { + pre_mul[0] = 1.42; + pre_mul[2] = 1.25; + } + } else if (!strncmp(model,"*ist D",6)) { + load_raw = model[6] ? packed_12_load_raw : unpacked_load_raw; + if (model[6] == 'S') height -= 2; + } else if (!strcmp(model,"Optio S")) { + if (fsize == 3178560) { + height = 1540; + width = 2064; + load_raw = eight_bit_load_raw; + camera_red *= 4; + camera_blue *= 4; + pre_mul[0] = 1.391; + pre_mul[2] = 1.188; + } else { + height = 1544; + width = 2068; + raw_width = 3136; + load_raw = packed_12_load_raw; + maximum = 0xf7c; + pre_mul[0] = 1.137; + pre_mul[2] = 1.453; + } + } else if (!strncmp(model,"Optio S4",8)) { + height = 1737; + width = 2324; + raw_width = 3520; + load_raw = packed_12_load_raw; + maximum = 0xf7a; + pre_mul[0] = 1.980; + pre_mul[2] = 1.570; + } else if (!strcmp(model,"STV680 VGA")) { + height = 484; + width = 644; + load_raw = eight_bit_load_raw; + flip = 2; + filters = 0x16161616; + black = 16; + pre_mul[0] = 1.097; + pre_mul[2] = 1.128; + } else if (!strcmp(model,"531C")) { + height = 1200; + width = 1600; + load_raw = unpacked_load_raw; + filters = 0x49494949; + pre_mul[1] = 1.218; + } else if (!strcmp(model,"F-201C")) { + height = 1200; + width = 1600; + load_raw = eight_bit_load_raw; + } else if (!strcmp(model,"F-510C")) { + height = 1958; + width = 2588; + load_raw = (fsize < 7500000) ? eight_bit_load_raw : unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"F-810C")) { + height = 2469; + width = 3272; + load_raw = unpacked_load_raw; + maximum = 0xfff0; + } else if (!strcmp(model,"A782")) { + height = 3000; + width = 2208; + filters = 0x61616161; + load_raw = (fsize < 10000000) ? eight_bit_load_raw : unpacked_load_raw; + maximum = 0xffc0; + } else if (!strcmp(model,"3320AF")) { + height = 1536; + raw_width = width = 2048; + filters = 0x61616161; + load_raw = unpacked_load_raw; + maximum = 0x3ff; + pre_mul[0] = 1.717; + pre_mul[2] = 1.138; + fseek (ifp, 0x300000, SEEK_SET); + if ((order = guess_byte_order(0x10000)) == 0x4d4d) { + data_offset = (2048 * 16 + 28) * 2; + height -= 16; + width -= 28; + maximum = 0xf5c0; + strcpy (make, "ISG"); + sprintf (model, "%dx%d", width, height); + } + } else if (!strcmp(make,"Imacon")) { + height = raw_height - 6; + width = raw_width - 10; + data_offset += 6 + raw_width*12; + flip = height > width+10 ? 5:3; + sprintf (model, "Ixpress %d-Mp", height*width/1000000); + filters = 0x61616161; + load_raw = unpacked_load_raw; + maximum = 0xffff; + pre_mul[0] = 1.963; + pre_mul[2] = 1.430; + } else if (!strcmp(make,"Sinar")) { + if (!memcmp(head,"8BPS",4)) { + fseek (ifp, 14, SEEK_SET); + height = get4(); + width = get4(); + filters = 0x61616161; + data_offset = 68; + } + load_raw = unpacked_load_raw; + maximum = 0x3fff; + } else if (!strcmp(make,"Leaf")) { + load_raw = unpacked_load_raw; + if (tiff_data_compression == 99) + load_raw = lossless_jpeg_load_raw; + maximum = 0x3fff; + strcpy (model, "Valeo"); + if (filters == 0) { + load_raw = leaf_load_raw; + maximum = 0xffff; + strcpy (model, "Volare"); + } + } else if (!strcmp(make,"LEICA") || !strcmp(make,"Panasonic")) { + if (width == 3880) { + data_offset += 12; + maximum = 0xf7f0; + width -= 22; + } else if (width == 3304) { + maximum = 0xf94c; + width -= 16; + } else maximum = 0xfff0; + load_raw = unpacked_load_raw; + } else if (!strcmp(model,"E-1")) { + filters = 0x61616161; + load_raw = unpacked_load_raw; + maximum = 0xfff0; + black = 1024; + } else if (!strcmp(model,"E-10")) { + load_raw = unpacked_load_raw; + maximum = 0xfff0; + black = 2048; + } else if (!strncmp(model,"E-20",4)) { + load_raw = unpacked_load_raw; + maximum = 0xffc0; + black = 2560; + } else if (!strcmp(model,"E-300") || + !strcmp(model,"E-500")) { + width -= 20; + load_raw = olympus_e300_load_raw; + maximum = 0xfff; + if (fsize > 15728640) { + load_raw = unpacked_load_raw; + maximum = 0xfc30; + } + } else if (!strcmp(model,"C770UZ")) { + height = 1718; + width = 2304; + filters = 0x16161616; + load_raw = nikon_e2100_load_raw; + } else if (!strcmp(make,"OLYMPUS")) { + load_raw = olympus_cseries_load_raw; + if (!strcmp(model,"C5050Z") || + !strcmp(model,"C8080WZ")) + filters = 0x16161616; + } else if (!strcmp(model,"N Digital")) { + height = 2047; + width = 3072; + filters = 0x61616161; + data_offset = 0x1a00; + load_raw = packed_12_load_raw; + maximum = 0xf1e; + } else if (!strcmp(model,"DSC-F828")) { + width = 3288; + left_margin = 5; + data_offset = 862144; + load_raw = sony_load_raw; + filters = 0x9c9c9c9c; + colors = 4; + black = 491; + } else if (!strcmp(model,"DSC-V3")) { + width = 3109; + left_margin = 59; + data_offset = 787392; + load_raw = sony_load_raw; + } else if (!strcmp(model,"DSC-R1")) { + width = 3925; + order = 0x4d4d; + load_raw = unpacked_load_raw; + black = 512; + } else if (!strncmp(model,"P850",4)) { + height = 1950; + width = 2608; + data_offset = 76456; + filters = 0x16161616; + load_raw = packed_12_load_raw; + } else if (!strcasecmp(make,"KODAK")) { + filters = 0x61616161; + if (!strcmp(model,"NC2000F")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS3B")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"EOSDCS1")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS315C")) { + black = 8; + } else if (!strcmp(model,"DCS330C")) { + black = 8; + } else if (!strcmp(model,"DCS420")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460")) { + width -= 4; + left_margin = 2; + } else if (!strcmp(model,"DCS460A")) { + width -= 4; + left_margin = 2; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS520C")) { + black = 180; + } else if (!strcmp(model,"DCS560C")) { + black = 188; + } else if (!strcmp(model,"DCS620C")) { + black = 180; + } else if (!strcmp(model,"DCS620X")) { + black = 185; + } else if (!strcmp(model,"DCS660C")) { + black = 214; + } else if (!strcmp(model,"DCS660M")) { + black = 214; + colors = 1; + filters = 0; + } else if (!strcmp(model,"DCS760M")) { + colors = 1; + filters = 0; + } + switch (tiff_data_compression) { + case 0: /* No compression */ + case 1: + load_raw = kodak_easy_load_raw; + break; + case 7: /* Lossless JPEG */ + load_raw = lossless_jpeg_load_raw; + case 32867: + break; + case 65000: /* Kodak DCR compression */ + if (kodak_data_compression == 32803) + load_raw = kodak_compressed_load_raw; + else { + load_raw = kodak_yuv_load_raw; + height = (height+1) & -2; + width = (width +1) & -2; + filters = 0; + } + break; + default: + fprintf (stderr, "%s: %s %s uses unsupported compression method %d.\n", + ifname, make, model, tiff_data_compression); + return 1; + } + if (strstr(model,"DC25")) { + strcpy (model, "DC25"); + data_offset = 15424; + } + if (!strncmp(model,"DC2",3)) { + height = 242; + if (fsize < 100000) { + raw_width = 256; width = 249; + } else { + raw_width = 512; width = 501; + } + data_offset += raw_width + 1; + colors = 4; + filters = 0x8d8d8d8d; + simple_coeff(1); + pre_mul[1] = 1.179; + pre_mul[2] = 1.209; + pre_mul[3] = 1.036; + load_raw = kodak_easy_load_raw; + } else if (!strcmp(model,"Digital Camera 40")) { + strcpy (model, "DC40"); + height = 512; + width = 768; + data_offset = 1152; + load_raw = kodak_radc_load_raw; + } else if (strstr(model,"DC50")) { + strcpy (model, "DC50"); + height = 512; + width = 768; + data_offset = 19712; + load_raw = kodak_radc_load_raw; + } else if (strstr(model,"DC120")) { + strcpy (model, "DC120"); + height = 976; + width = 848; + if (tiff_data_compression == 7) + load_raw = kodak_jpeg_load_raw; + else + load_raw = kodak_dc120_load_raw; + } + } else if (!strcmp(model,"Fotoman Pixtura")) { + height = 512; + width = 768; + data_offset = 3632; + load_raw = kodak_radc_load_raw; + filters = 0x61616161; + simple_coeff(2); + } else if (!strcmp(make,"Rollei")) { + switch (raw_width) { + case 1316: + height = 1030; + width = 1300; + top_margin = 1; + left_margin = 6; + break; + case 2568: + height = 1960; + width = 2560; + top_margin = 2; + left_margin = 8; + } + filters = 0x16161616; + load_raw = rollei_load_raw; + pre_mul[0] = 1.8; + pre_mul[2] = 1.3; + } else if (!strcmp(model,"PC-CAM 600")) { + height = 768; + data_offset = width = 1024; + filters = 0x49494949; + load_raw = eight_bit_load_raw; + pre_mul[0] = 1.14; + pre_mul[2] = 2.73; + } else if (!strcmp(model,"QV-2000UX")) { + height = 1208; + width = 1632; + data_offset = width * 2; + load_raw = eight_bit_load_raw; + } else if (fsize == 3217760) { + height = 1546; + width = 2070; + raw_width = 2080; + load_raw = eight_bit_load_raw; + } else if (!strcmp(model,"QV-4000")) { + height = 1700; + width = 2260; + load_raw = unpacked_load_raw; + maximum = 0xffff; + } else if (!strcmp(model,"QV-5700")) { + height = 1924; + width = 2576; + load_raw = casio_qv5700_load_raw; + } else if (!strcmp(model,"QV-R51")) { + height = 1926; + width = 2576; + raw_width = 3904; + load_raw = packed_12_load_raw; + pre_mul[0] = 1.340; + pre_mul[2] = 1.672; + } else if (!strcmp(model,"EX-S100")) { + height = 1544; + width = 2058; + raw_width = 3136; + load_raw = packed_12_load_raw; + pre_mul[0] = 1.631; + pre_mul[2] = 1.106; + } else if (!strcmp(model,"EX-Z50")) { + height = 1931; + width = 2570; + raw_width = 3904; + load_raw = packed_12_load_raw; + pre_mul[0] = 2.529; + pre_mul[2] = 1.185; + } else if (!strcmp(model,"EX-Z55")) { + height = 1960; + width = 2570; + raw_width = 3904; + load_raw = packed_12_load_raw; + pre_mul[0] = 1.520; + pre_mul[2] = 1.316; + } else if (!strcmp(model,"EX-P505")) { + height = 1928; + width = 2568; + raw_width = 3852; + load_raw = packed_12_load_raw; + pre_mul[0] = 2.07; + pre_mul[2] = 1.88; + } else if (!strcmp(model,"EX-P600")) { + height = 2142; + width = 2844; + raw_width = 4288; + load_raw = packed_12_load_raw; + pre_mul[0] = 1.797; + pre_mul[2] = 1.219; + } else if (!strcmp(model,"EX-P700")) { + height = 2318; + width = 3082; + raw_width = 4672; + load_raw = packed_12_load_raw; + pre_mul[0] = 1.758; + pre_mul[2] = 1.504; + } else if (!strcmp(make,"Nucore")) { + filters = 0x61616161; + load_raw = unpacked_load_raw; + if (width == 2598) { + filters = 0x16161616; + load_raw = nucore_load_raw; + flip = 2; + } + } + if (raw_color) adobe_coeff(); +dng_skip: + if (!load_raw || !height || is_jpeg) { + fprintf (stderr, "%s: Cannot decode %s %s%s images.\n", + ifname, make, model, is_jpeg ? " JPEG":""); + return 1; + } +#ifdef NO_JPEG + if (load_raw == kodak_jpeg_load_raw) { + fprintf (stderr, "%s: decoder was not linked with libjpeg.\n", ifname); + return 1; + } +#endif + if (!raw_height) raw_height = height; + if (!raw_width ) raw_width = width; + raw_color |= use_camera_rgb && colors == 3; + FORCC { /* Apply user-selected color balance */ + rgb_cam[0][c] *= red_scale; + rgb_cam[2][c] *= blue_scale; + } + if (filters && colors == 3) + for (i=0; i < 32; i+=4) { + if ((filters >> i & 15) == 9) + filters |= 2 << i; + if ((filters >> i & 15) == 6) + filters |= 8 << i; + } + fseek (ifp, data_offset, SEEK_SET); + return 0; +} + +#ifdef USE_LCMS +void CLASS apply_profile (char *pfname) +{ + char *prof; + cmsHPROFILE hInProfile=NULL, hOutProfile; + cmsHTRANSFORM hTransform; + + if (pfname) + hInProfile = cmsOpenProfileFromFile (pfname, "r"); + else if (profile_length) { + prof = malloc (profile_length); + merror (prof, "apply_profile()"); + fseek (ifp, profile_offset, SEEK_SET); + fread (prof, 1, profile_length, ifp); + hInProfile = cmsOpenProfileFromMem (prof, profile_length); + free (prof); + } + if (!hInProfile) return; + if (verbose) + fprintf (stderr, "Applying color profile...\n"); + maximum = 0xffff; + use_gamma = 0; + raw_color = 1; /* Don't use rgb_cam with a profile */ + + hOutProfile = cmsCreate_sRGBProfile(); + hTransform = cmsCreateTransform (hInProfile, TYPE_RGBA_16, + hOutProfile, TYPE_RGBA_16, INTENT_PERCEPTUAL, 0); + cmsDoTransform (hTransform, image, image, width*height); + + cmsDeleteTransform (hTransform); + cmsCloseProfile (hInProfile); + cmsCloseProfile (hOutProfile); +} +#endif + +/* + Convert the entire image to RGB colorspace and build a histogram. + */ +void CLASS convert_to_rgb() +{ + int row, col, c, i, fc=0; + ushort *img; + float rgb[3]; + + if (verbose) + fprintf (stderr, raw_color ? + "Building histograms...\n" : "Converting to sRGB colorspace...\n"); + + if (document_mode) + colors = 1; + memset (histogram, 0, sizeof histogram); + for (row = 0; row < height; row++) + for (col = 0; col < width; col++) { + img = image[row*width+col]; + if (document_mode) + fc = FC(row,col); + if (colors == 4 && raw_color) /* Recombine the greens */ + img[1] = (img[1] + img[3]) >> 1; + if (colors == 1) /* RGB from grayscale */ + FORC3 rgb[c] = img[fc]; + else if (raw_color) /* RGB from RGB (easy) */ + goto norgb; + else FORC3 /* RGB via rgb_cam */ + for (rgb[c]=i=0; i < colors; i++) + rgb[c] += img[i] * rgb_cam[c][i]; + FORC3 img[c] = CLIP((int) rgb[c]); +norgb: + FORC3 histogram[c][img[c] >> 3]++; + } +} + +void CLASS fuji_rotate() +{ + int i, wide, high, row, col; + double step; + float r, c, fr, fc; + unsigned ur, uc; + ushort (*img)[4], (*pix)[4]; + + if (!fuji_width) return; + if (verbose) + fprintf (stderr, "Rotating image 45 degrees...\n"); + fuji_width = (fuji_width - 1 + shrink) >> shrink; + step = sqrt(0.5); + wide = fuji_width / step; + high = (height - fuji_width) / step; + img = calloc (wide*high, sizeof *img); + merror (img, "fuji_rotate()"); + + for (row=0; row < high; row++) + for (col=0; col < wide; col++) { + ur = r = fuji_width + (row-col)*step; + uc = c = (row+col)*step; + if (ur > height-2 || uc > width-2) continue; + fr = r - ur; + fc = c - uc; + pix = image + ur*width + uc; + for (i=0; i < colors; i++) + img[row*wide+col][i] = + (pix[ 0][i]*(1-fc) + pix[ 1][i]*fc) * (1-fr) + + (pix[width][i]*(1-fc) + pix[width+1][i]*fc) * fr; + } + free (image); + width = wide; + height = high; + image = img; + fuji_width = 0; +} + +void CLASS flip_image() +{ + unsigned *flag; + int size, base, dest, next, row, col, temp; + INT64 *img, hold; + + if (verbose) + fprintf (stderr, "Flipping image %c:%c:%c...\n", + flip & 1 ? 'H':'0', flip & 2 ? 'V':'0', flip & 4 ? 'T':'0'); + + img = (INT64 *) image; + size = height * width; + flag = calloc ((size+31) >> 5, sizeof *flag); + merror (flag, "flip_image()"); + for (base = 0; base < size; base++) { + if (flag[base >> 5] & (1 << (base & 31))) + continue; + dest = base; + hold = img[base]; + while (1) { + if (flip & 4) { + row = dest % height; + col = dest / height; + } else { + row = dest / width; + col = dest % width; + } + if (flip & 2) + row = height - 1 - row; + if (flip & 1) + col = width - 1 - col; + next = row * width + col; + if (next == base) break; + flag[next >> 5] |= 1 << (next & 31); + img[dest] = img[next]; + dest = next; + } + img[dest] = hold; + } + free (flag); + if (flip & 4) { + temp = height; + height = width; + width = temp; + temp = ymag; + ymag = xmag; + xmag = temp; + } +} + +/* + Write the image to an 8-bit PPM file. + */ +void CLASS write_ppm (FILE *ofp) +{ + uchar (*ppm)[3], lut[0x10000]; + int perc, c, val, total, i, row, col; + float white=0, r; + + fprintf (ofp, "P6\n%d %d\n255\n", xmag*width, ymag*height); + ppm = calloc (width, 3*xmag); + merror (ppm, "write_ppm()"); + + perc = width * height * 0.01; /* 99th percentile white point */ + if (fuji_width) perc /= 2; + FORC3 { + for (val=0x2000, total=0; --val > 32; ) + if ((total += histogram[c][val]) > perc) break; + if (white < val) white = val; + } + white *= 8 / bright; + for (i=0; i < 0x10000; i++) { + r = i / white; + val = 256 * ( !use_gamma ? r : +#ifdef SRGB_GAMMA + r <= 0.00304 ? r*12.92 : pow(r,2.5/6)*1.055-0.055 ); +#else + r <= 0.018 ? r*4.5 : pow(r,0.45)*1.099-0.099 ); +#endif + if (val > 255) val = 255; + lut[i] = val; + } + for (row=0; row < height; row++) { + for (col=0; col < width; col++) + FORC3 for (i=0; i < xmag; i++) + ppm[xmag*col+i][c] = lut[image[row*width+col][c]]; + for (i=0; i < ymag; i++) + fwrite (ppm, width, 3*xmag, ofp); + } + free (ppm); +} + +/* + Write the image to a 16-bit Photoshop file. + */ +void CLASS write_psd (FILE *ofp) +{ + char head[] = { + '8','B','P','S', /* signature */ + 0,1,0,0,0,0,0,0, /* version and reserved */ + 0,3, /* number of channels */ + 0,0,0,0, /* height, big-endian */ + 0,0,0,0, /* width, big-endian */ + 0,16, /* 16-bit color */ + 0,3, /* mode (1=grey, 3=rgb) */ + 0,0,0,0, /* color mode data */ + 0,0,0,0, /* image resources */ + 0,0,0,0, /* layer/mask info */ + 0,0 /* no compression */ + }; + int hw[2], psize, row, col, c; + ushort *buffer, *pred; + + hw[0] = htonl(height); /* write the header */ + hw[1] = htonl(width); + memcpy (head+14, hw, sizeof hw); + fwrite (head, 40, 1, ofp); + + psize = height*width; + buffer = calloc (6, psize); + merror (buffer, "write_psd()"); + pred = buffer; + + for (row = 0; row < height; row++) + for (col = 0; col < width; col++) { + FORC3 pred[c*psize] = htons(image[row*width+col][c]); + pred++; + } + fwrite(buffer, psize, 6, ofp); + free (buffer); +} + +/* + Write the image to a 16-bit PPM file. + */ +void CLASS write_ppm16 (FILE *ofp) +{ + int row, col, c; + ushort (*ppm)[3]; + + if (maximum < 256) maximum = 256; + fprintf (ofp, "P6\n%d %d\n%d\n", width, height, maximum); + + ppm = calloc (width, 6); + merror (ppm, "write_ppm16()"); + + for (row = 0; row < height; row++) { + for (col = 0; col < width; col++) + FORC3 ppm[col][c] = htons(image[row*width+col][c]); + fwrite (ppm, width, 6, ofp); + } + free (ppm); +} + +int CLASS main (int argc, char **argv) +{ + int arg, status=0, user_flip=-1, user_black=-1, user_qual=-1; + int timestamp_only=0, identify_only=0, write_to_stdout=0; + int half_size=0, use_fuji_rotate=1, quality; + char opt, *ofname, *cp; + struct utimbuf ut; + const char *write_ext = ".ppm"; + FILE *ofp = stdout; +#ifdef USE_LCMS + char *profile = NULL; +#endif + +#ifndef LOCALTIME + putenv ("TZ=UTC"); +#endif + if (argc == 1) + { + fprintf (stderr, + "\nRaw Photo Decoder \"dcraw\" v7.82" + "\nby Dave Coffin, dcoffin a cybercom o net" + "\n\nUsage: %s [options] file1 file2 ...\n" + "\nValid options:" + "\n-v Print verbose messages" + "\n-z Change file dates to camera timestamp" + "\n-i Identify files without decoding them" + "\n-c Write to standard output" + "\n-a Use automatic white balance" + "\n-w Use camera white balance, if possible" + "\n-r Set red multiplier (default = 1.0)" + "\n-l Set blue multiplier (default = 1.0)" + "\n-b Set brightness (default = 1.0)" + "\n-k Set black point" + "\n-n Don't clip colors" + "\n-m Don't convert camera RGB to sRGB" +#ifdef USE_LCMS + "\n-p Apply color profile from file" +#endif + "\n-d Document Mode (no color, no interpolation)" + "\n-q [0-3] Set the interpolation quality" + "\n-h Half-size color image (twice as fast as \"-q 0\")" + "\n-f Interpolate RGGB as four colors" + "\n-B Apply bilateral filter to reduce noise" + "\n-j Show Fuji Super CCD images tilted 45 degrees" + "\n-s Use secondary pixels (Fuji Super CCD SR only)" + "\n-t [0-7] Flip image (0 = none, 3 = 180, 5 = 90CCW, 6 = 90CW)" + "\n-2 Write 8-bit PPM with 0.45 gamma (default)" + "\n-3 Write 16-bit linear PSD (Adobe Photoshop)" + "\n-4 Write 16-bit linear PPM" + "\n\n", argv[0]); + return 1; + } + + argv[argc] = ""; + for (arg=1; argv[arg][0] == '-'; ) { + opt = argv[arg++][1]; + if ((strchr("Bbrlktq", opt) && !isdigit(argv[arg][0])) || + (opt == 'B' && !isdigit(argv[arg+1][0]))) { + fprintf (stderr, "Non-numeric argument to \"-%c\"\n", opt); + return 1; + } + switch (opt) + { + case 'B': sigma_d = atof(argv[arg++]); + sigma_r = atof(argv[arg++]); break; + case 'b': bright = atof(argv[arg++]); break; + case 'r': red_scale = atof(argv[arg++]); break; + case 'l': blue_scale = atof(argv[arg++]); break; + case 'k': user_black = atoi(argv[arg++]); break; + case 't': user_flip = atoi(argv[arg++]); break; + case 'q': user_qual = atoi(argv[arg++]); break; +#ifdef USE_LCMS + case 'p': profile = argv[arg++] ; break; +#endif + case 'z': timestamp_only = 1; break; + case 'i': identify_only = 1; break; + case 'c': write_to_stdout = 1; break; + case 'v': verbose = 1; break; + case 'h': half_size = 1; /* "-h" implies "-f" */ + case 'f': four_color_rgb = 1; break; + case 'd': document_mode = 1; break; + case 'a': use_auto_wb = 1; break; + case 'w': use_camera_wb = 1; break; + case 'j': use_fuji_rotate = 0; break; + case 's': use_secondary = 1; break; + case 'n': clip_color = 0; break; + case 'm': use_camera_rgb = 1; break; + + case '2': write_fun = write_ppm; write_ext = ".ppm"; break; + case '3': write_fun = write_psd; write_ext = ".psd"; break; + case '4': write_fun = write_ppm16; write_ext = ".ppm"; break; + + default: + fprintf (stderr, "Unknown option \"-%c\".\n", opt); + return 1; + } + } + if (arg == argc) { + fprintf (stderr, "No files to process.\n"); + return 1; + } + if (write_to_stdout) { + if (isatty(1)) { + fprintf (stderr, "Will not write an image to the terminal!\n"); + return 1; + } +#if defined(WIN32) || defined(DJGPP) || defined(__CYGWIN__) + if (setmode(1,O_BINARY) < 0) { + perror("setmode()"); + return 1; + } +#endif + } + for ( ; arg < argc; arg++) { + status = 1; + image = NULL; + if (setjmp (failure)) { + if (fileno(ifp) > 2) fclose(ifp); + if (fileno(ofp) > 2) fclose(ofp); + if (image) free (image); + status = 1; + continue; + } + ifname = argv[arg]; + if (!(ifp = fopen (ifname, "rb"))) { + perror (ifname); + continue; + } + if (timestamp_only) { + if ((status = identify(1))) + fprintf (stderr, "%s has no timestamp.\n", ifname); + else if (identify_only) + printf ("%10ld%10d %s\n", timestamp, shot_order, ifname); + else { + if (verbose) + fprintf (stderr, "%s time set to %d.\n", ifname, (int) timestamp); + ut.actime = ut.modtime = timestamp; + utime (ifname, &ut); + } + goto next; + } + if ((status = identify(0))) goto next; + if (user_flip >= 0) + flip = user_flip; + switch ((flip+3600) % 360) { + case 270: flip = 5; break; + case 180: flip = 3; break; + case 90: flip = 6; + } + if (identify_only) { + fprintf (stderr, "%s is a %s %s image.\n", ifname, make, model); +next: + fclose(ifp); + continue; + } + shrink = half_size && filters; + iheight = (height + shrink) >> shrink; + iwidth = (width + shrink) >> shrink; + image = calloc (iheight*iwidth*sizeof *image + meta_length, 1); + merror (image, "main()"); + meta_data = (char *) (image + iheight*iwidth); + if (verbose) + fprintf (stderr, + "Loading %s %s image from %s...\n", make, model, ifname); + (*load_raw)(); + bad_pixels(); + height = iheight; + width = iwidth; +#ifdef COLORCHECK + colorcheck(); +#endif + quality = 2 + !fuji_width; + if (user_qual >= 0) quality = user_qual; + if (user_black >= 0) black = user_black; + if (is_foveon) foveon_interpolate(); + else scale_colors(); + if (shrink) filters = 0; + cam_to_cielab (NULL,NULL); + if (filters && !document_mode) { + if (quality == 0) + lin_interpolate(); + else if (quality < 3 || colors > 3) + vng_interpolate(); + else ahd_interpolate(); + } + if (sigma_d > 0 && sigma_r > 0) bilateral_filter(); + if (use_fuji_rotate) fuji_rotate(); +#ifdef USE_LCMS + apply_profile (profile); +#endif + convert_to_rgb(); + if (flip) flip_image(); + fclose(ifp); + ofname = malloc (strlen(ifname) + 16); + merror (ofname, "main()"); + if (write_to_stdout) + strcpy (ofname, "standard output"); + else { + strcpy (ofname, ifname); + if ((cp = strrchr (ofname, '.'))) *cp = 0; + strcat (ofname, write_ext); + ofp = fopen (ofname, "wb"); + if (!ofp) { + status = 1; + perror(ofname); + goto cleanup; + } + } + if (verbose) + fprintf (stderr, "Writing data to %s...\n", ofname); + (*write_fun)(ofp); + if (ofp != stdout) + fclose(ofp); +cleanup: + free (ofname); + free (image); + } + return status; +} diff --git a/filters/krita/raw/kis_raw_import.cpp b/filters/krita/raw/kis_raw_import.cpp new file mode 100644 index 000000000..f9c1f5ea2 --- /dev/null +++ b/filters/krita/raw/kis_raw_import.cpp @@ -0,0 +1,630 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#include "config.h" + +#ifdef HAVE_SYS_TYPES_H + #include +#endif + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "imageviewer.h" +#include "kis_config.h" +#include "kis_cmb_idlist.h" +#include "kis_types.h" +#include "kis_raw_import.h" +#include "kis_doc.h" +#include "kis_image.h" +#include "kis_meta_registry.h" +#include "kis_layer.h" +#include "kis_annotation.h" +#include "kis_profile.h" +#include "kis_colorspace_factory_registry.h" +#include "kis_iterators_pixel.h" +#include "kis_abstract_colorspace.h" +#include "kis_paint_device.h" +#include "kis_paint_layer.h" +#include "wdgrawimport.h" + +typedef KGenericFactory KisRawImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkrita_raw_import, KisRawImportFactory("kofficefilters")) + +KisRawImport::KisRawImport(KoFilter *, const char *, const QStringList&) + : KoFilter() + , m_data(0) + , m_process(0) + , m_progress(0) + , m_err(false) +{ + m_dialog = new KDialogBase(); + m_dialog->enableButtonApply(false); + m_page = new WdgRawImport(m_dialog); + m_dialog -> setMainWidget(m_page); + + connect(m_page->bnPreview, SIGNAL(clicked()), this, SLOT(slotUpdatePreview())); + connect(m_page->grpColorSpace, SIGNAL(clicked( int )), this, SLOT(slotFillCmbProfiles())); + connect(m_page->grpChannelDepth, SIGNAL(clicked( int )), this, SLOT(slotFillCmbProfiles())); + + KisConfig cfg; + QString monitorProfileName = cfg.monitorProfile(); + m_monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + + slotFillCmbProfiles(); +} + +KisRawImport::~KisRawImport() +{ + delete m_dialog; + delete m_process; +} + +KoFilter::ConversionStatus KisRawImport::convert(const QCString& from, const QCString& to) +{ + if (from != "image/x-raw" || to != "application/x-krita") { + return KoFilter::NotImplemented; + } + + if (m_err) { + return KoFilter::CreationError; + } + + kdDebug(41008) << "Krita importing from Raw\n"; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + if (!doc) { + return KoFilter::CreationError; + } + + doc -> prepareForImport(); + + QString filename = m_chain -> inputFile(); + + if (filename.isEmpty()) { + return KoFilter::FileNotFound; + } + + slotUpdatePreview(); + + // Show dialog + m_dialog->setCursor(Qt::ArrowCursor); + QApplication::setOverrideCursor(Qt::ArrowCursor); + + KConfig * cfg = KGlobal::config(); + cfg->setGroup("rawimport"); + + m_page->radioGray->setChecked(cfg->readBoolEntry("gray", false)); + m_page->radioRGB->setChecked(cfg->readBoolEntry("rgb", true)); + m_page->radio8->setChecked(cfg->readBoolEntry("8bit", false)); + m_page->radio16->setChecked(cfg->readBoolEntry("16bit", true)); + m_page->chkFourColorRGB->setChecked( cfg->readBoolEntry("four_color_rgb", false)); + m_page->chkCameraColors->setChecked( cfg->readBoolEntry("camera_colors", false)); + m_page->chkBrightness->setChecked( cfg->readBoolEntry("do_brightness", false)); + m_page->chkBlackpoint->setChecked( cfg->readBoolEntry("do_blackpoint", false)); + m_page->chkRed->setChecked( cfg->readBoolEntry("do_red", false)); + m_page->chkBlue->setChecked( cfg->readBoolEntry("do_blue", false)); + m_page->radioFixed->setChecked( cfg->readBoolEntry("fixed_wb", true)); + m_page->radioAutomatic->setChecked( cfg->readBoolEntry("automatic_wb", false)); + m_page->radioCamera->setChecked( cfg->readBoolEntry("camera_wb", false)); + m_page->chkClip->setChecked( cfg->readBoolEntry("clip", true)); + m_page->chkProfile->setChecked(cfg->readBoolEntry("useprofile", false)); + m_page->dblBrightness->setValue(cfg->readDoubleNumEntry("brightness", 1.0)); + m_page->dblBlackpoint->setValue(cfg->readDoubleNumEntry("blackpoint", 0)); + m_page->dblRed->setValue(cfg->readDoubleNumEntry("red", 1.0)); + m_page->dblBlue->setValue(cfg->readDoubleNumEntry("blue", 1.0)); + + if (m_dialog->exec() == QDialog::Accepted) { + + cfg->writeEntry("gray", m_page->radioGray->isChecked()); + cfg->writeEntry("rgb", m_page->radioRGB->isChecked()); + cfg->writeEntry("8bit", m_page->radio8->isChecked()); + cfg->writeEntry("16bit", m_page->radio16->isChecked()); + cfg->writeEntry("four_color_rgb", m_page->chkFourColorRGB -> isChecked()); + cfg->writeEntry("camera_colors", m_page->chkCameraColors -> isChecked()); + cfg->writeEntry("do_brightness", m_page->chkBrightness -> isChecked()); + cfg->writeEntry("do_blackpoint", m_page->chkBlackpoint -> isChecked()); + cfg->writeEntry("do_red", m_page->chkRed -> isChecked()); + cfg->writeEntry("do_blue", m_page->chkBlue -> isChecked()); + cfg->writeEntry("fixed_wb", m_page->radioFixed -> isChecked()); + cfg->writeEntry("automatic_wb", m_page->radioAutomatic -> isChecked()); + cfg->writeEntry("camera_wb", m_page->radioCamera -> isChecked()); + cfg->writeEntry("clip", m_page->chkClip->isChecked()); + cfg->writeEntry("useprofile", m_page->chkProfile->isChecked()); + cfg->writeEntry("brightness", m_page->dblBrightness->value()); + cfg->writeEntry("blackpoint", m_page->dblBlackpoint->value()); + cfg->writeEntry("red", m_page->dblRed->value()); + cfg->writeEntry("blue", m_page->dblBlue->value()); + + QApplication::setOverrideCursor(Qt::waitCursor); + // Create a busy indicator to show that we didn't die or so + m_progress = new QProgressDialog(); + m_progress -> setTotalSteps(0); + m_progress -> setCancelButton(0); + QTimer timer; + connect(&timer, SIGNAL(timeout()), this, SLOT(incrementProgress())); + timer.start(200); + + doc -> undoAdapter() -> setUndo(false); + + getImageData(createArgumentList(false)); + + KisImageSP image = 0; + KisPaintLayerSP layer = 0; + KisPaintDeviceSP device = 0; + + QApplication::restoreOverrideCursor(); + + delete m_progress; + m_progress = 0; + + if (m_page->radio8->isChecked()) { + // 8 bits + + QImage img; + img.loadFromData(*m_data); + + KisColorSpace * cs = 0; + if (m_page->radioGray->isChecked()) { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("GRAYA"), profile() ); + } + else { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("RGBA"), profile() ); + } + if (cs == 0) { kdDebug() << "No CS\n"; return KoFilter::InternalError; } + + image = new KisImage(doc->undoAdapter(), img.width(), img.height(), cs, filename); + if (image == 0) return KoFilter::CreationError; + image->blockSignals(true); // Don't send out signals while we're building the image + + layer = dynamic_cast( image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data() ); + if (layer == 0) return KoFilter::CreationError; + + device = layer->paintDevice(); + if (device == 0) return KoFilter::CreationError; + + device->convertFromQImage(img, ""); + + } else { + // 16 bits + + Q_UINT32 startOfImagedata = 0; + QSize sz = determineSize(startOfImagedata); + + kdDebug(41008) << "Total bytes: " << m_data->size() + << "\n start of image data: " << startOfImagedata + << "\n bytes for pixels left: " << m_data->size() - startOfImagedata + << "\n total pixels: " << sz.width() * sz.height() + << "\n total pixel bytes: " << sz.width() * sz.height() * 6 + << "\n total necessary bytes: " << (sz.width() * sz.height() * 6) + startOfImagedata + << "\n"; + + + char * data = m_data->data() + startOfImagedata; + + KisColorSpace * cs = 0; + if (m_page->radioGray->isChecked()) { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("GRAYA16"), profile() ); + } + else { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("RGBA16"), profile() ); + } + if (cs == 0) return KoFilter::InternalError; + + image = new KisImage( doc->undoAdapter(), sz.width(), sz.height(), cs, filename); + if (image == 0)return KoFilter::CreationError; + + layer = dynamic_cast (image->newLayer(image -> nextLayerName(), OPACITY_OPAQUE).data()); + if (layer == 0) return KoFilter::CreationError; + + device = layer->paintDevice(); + if (device == 0) return KoFilter::CreationError; + + // Copy the colordata to the pixels + int pos = 0; + + for (int line = 0; line < sz.height(); ++line) { + KisHLineIterator it = device->createHLineIterator(0, line, sz.width(), true); + + while (!it.isDone()) { + if (m_page->radioGray->isChecked()) { + Q_UINT16 d = (Q_INT16)*(data + pos); + d = ntohs(d); + memcpy(it.rawData(), &d, 2); + pos += 2; + } + else { + // Red + Q_UINT16 d = (Q_INT16)*(data + pos); + d = ntohs(d); + memcpy(it.rawData() + 4, &d, 2); + + // Green + pos += 2; + d = (Q_INT16)*(data + pos ); + d = ntohs(d); + memcpy(it.rawData() + 2, &d, 2); + + // Blue + pos += 2; + d = (Q_INT16)*(data + pos ); + d = ntohs(d); + memcpy(it.rawData(), &d, 2); + + pos += 2; + } + cs->setAlpha(it.rawData(), OPACITY_OPAQUE, 1); + ++it; + } + } + } + layer->setDirty(); + kdDebug() << "going to set image\n"; + doc -> setCurrentImage(image); + doc -> undoAdapter() -> setUndo(true); + doc -> setModified(false); + kdDebug() << "everything ok\n"; + + QApplication::restoreOverrideCursor(); + return KoFilter::OK; + } + + QApplication::restoreOverrideCursor(); + return KoFilter::UserCancelled; +} + +void KisRawImport::incrementProgress() +{ + m_progress -> setProgress(m_progress -> progress() + 10); +} + + +void KisRawImport::slotUpdatePreview() +{ + QApplication::setOverrideCursor(Qt::waitCursor); + getImageData(createArgumentList(true)); + + kdDebug(41008) << "Retrieved " << m_data->size() << " bytes of image data\n"; + + if (m_data->isNull()) return; + + QImage img; + + if (m_page->radio8->isChecked()) { + // 8 bits + img.loadFromData(*m_data); + + } else { + // 16 bits + + Q_UINT32 startOfImagedata = 0; + QSize sz = determineSize(startOfImagedata); + + kdDebug(41008) << "Total bytes: " << m_data->size() + << "\n start of image data: " << startOfImagedata + << "\n bytes for pixels left: " << m_data->size() - startOfImagedata + << "\n total pixels: " << sz.width() * sz.height() + << "\n total pixel bytes: " << sz.width() * sz.height() * 6 + << "\n total necessary bytes: " << (sz.width() * sz.height() * 6) + startOfImagedata + << "\n"; + + char * data = m_data->data() + startOfImagedata; + + KisColorSpace * cs = 0; + if (m_page->radioGray->isChecked()) { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("GRAYA16"), profile() ); + } + else { + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace( KisID("RGBA16"), profile() ); + } + KisPaintDevice * dev = new KisPaintDevice(cs, "preview"); + // Copy the colordata to the pixels + int pos = 0; + + for (int line = 0; line < sz.height(); ++line) { + KisHLineIterator it = dev->createHLineIterator(0, line, sz.width(), true); + + while (!it.isDone()) { + if (m_page->radioGray->isChecked()) { + Q_UINT16 d = (Q_INT16)*(data + pos); + d = ntohs(d); + memcpy(it.rawData(), &d, 2); + pos += 2; + } + else { + // Red + Q_UINT16 d = (Q_INT16)*(data + pos); + d = ntohs(d); + memcpy(it.rawData() + 4, &d, 2); + + // Green + pos += 2; + d = (Q_INT16)*(data + pos ); + d = ntohs(d); + memcpy(it.rawData() + 2, &d, 2); + + // Blue + pos += 2; + d = (Q_INT16)*(data + pos ); + d = ntohs(d); + memcpy(it.rawData(), &d, 2); + + pos += 2; + } + cs->setAlpha(it.rawData(), OPACITY_OPAQUE, 1); + ++it; + } + } + + img = dev->convertToQImage(m_monitorProfile); + } + + m_page->lblPreview->setImage(img); + QApplication::restoreOverrideCursor(); +} + + +void KisRawImport::getImageData( QStringList arguments ) +{ + // delete m_process; + delete m_data; + + kdDebug(41008) << "getImageData " << arguments.join(" ") << "\n"; + KProcess process (this); + m_data = new QByteArray(0); + + for (QStringList::iterator it = arguments.begin(); it != arguments.end(); ++it) { + process << *it; + } + + process.setUseShell(true); + connect(&process, SIGNAL(receivedStdout(KProcess *, char *, int)), this, SLOT(slotReceivedStdout(KProcess *, char *, int))); + connect(&process, SIGNAL(receivedStderr(KProcess *, char *, int)), this, SLOT(slotReceivedStderr(KProcess *, char *, int))); + connect(&process, SIGNAL(processExited(KProcess *)), this, SLOT(slotProcessDone())); + + + kdDebug(41008) << "Starting process\n"; + + if (!process.start(KProcess::NotifyOnExit, KProcess::AllOutput)) { + KMessageBox::error( 0, i18n("Cannot convert RAW files because the dcraw executable could not be started.")); + } + while (process.isRunning()) { + //kdDebug(41008) << "Waiting...\n"; + qApp->eventLoop()->processEvents(QEventLoop::ExcludeUserInput); + //process.wait(2); + } + + if (process.normalExit()) { + kdDebug(41008) << "Return value of process: " << process.exitStatus() << "\n"; + } + else { + kdDebug(41008) << "Process did not exit normally. Exit signal: " << process.exitSignal() << "\n"; + m_err = true; + } + +} + + +void KisRawImport::slotProcessDone() +{ + kdDebug(41008) << "process done!\n"; +} + +void KisRawImport::slotReceivedStdout(KProcess *, char *buffer, int buflen) +{ + //kdDebug(41008) << "stdout received " << buflen << " bytes on stdout.\n"; + //kdDebug(41008) << QString::fromAscii(buffer, buflen) << "\n"; + int oldSize = m_data->size(); + m_data->resize(oldSize + buflen, QGArray::SpeedOptim); + memcpy(m_data->data() + oldSize, buffer, buflen); +} + +void KisRawImport::slotReceivedStderr(KProcess *, char *buffer, int buflen) +{ + QByteArray b(buflen); + memcpy(b.data(), buffer, buflen); + kdDebug(41008) << QString(b) << "\n"; + KMessageBox::error(0, i18n("Error: Dcraw cannot load this image. Message: ") + QString(b)); + m_err = true; +} + + +QStringList KisRawImport::createArgumentList(bool forPreview) +{ + QStringList args; + + args.append("dcraw"); // XXX: Create a kritadcraw so we can count on it being available + + //args.append("-v"); // Verbose + + args.append("-c"); // Write to stdout + + if (forPreview) { + args.append("-h"); // Fast, half size image + } + + if (m_page->radio8->isChecked()) { + args.append("-2"); // 8 bits + } + else { + args.append("-4"); // 16 bits + } + + if (m_page->radioGray->isChecked()) { + args.append("-d"); // Create grayscale image + } + + if (m_page->chkCameraColors->isChecked()) { + args.append("-m"); // Use camera raw colors instead of sRGB + } + + if (m_page->radioAutomatic->isChecked()) { + args.append("-a"); // Automatic white balancing + } + + if (m_page->radioCamera->isChecked()) { + args.append("-w"); // Use camera white balance, if present + } + + if (m_page->chkFourColorRGB->isChecked()) { + args.append("-f"); // Interpolate RGB as four colors + } + + if (!m_page->chkClip->isChecked()) { + args.append("-n"); // Do not clip colors + } + + if (m_page->chkBrightness->isChecked()) { + args.append("-b " + QString::number(m_page->dblBrightness->value())); + } + + if (m_page->chkBlackpoint->isChecked()) { + args.append("-k " + QString::number(m_page->dblBlackpoint->value())); + } + + if (m_page->chkRed->isChecked()) { + args.append("-r " + QString::number(m_page->dblRed->value())); + } + + if (m_page->chkBlue->isChecked()) { + args.append("-l " + QString::number(m_page->dblBlue->value())); + } + + + KisProfile * pf = profile(); + if (m_page->chkProfile->isChecked()) { + if (!pf->filename().isNull()) { + // Use the user-set profile, if it's not an lcms internal + // profile. This does not add the profile to the image, we + // need to do that later. + args.append("-p \"" + pf->filename() + "\""); + } + } + + // Don't forget the filename + args.append("\"" + m_chain -> inputFile() + "\""); + + return args; +} + +QSize KisRawImport::determineSize(Q_UINT32& startOfImageData) +{ + if (m_data->isNull() || m_data->size() < 2048) { + startOfImageData = 0; + return QSize(0,0); + } + + QString magick = QString::fromAscii(m_data->data(), 2); + if (magick != "P6") { + kdDebug(41008) << " Bad magick! " << magick << "\n"; + startOfImageData = 0; + return QSize(0,0); + } + + // Find the third newline that marks the header end in a dcraw generated ppm. + Q_UINT32 i = 0; + Q_UINT32 counter = 0; + + while (true) { + if (counter == 3) break; + if (m_data->data()[i] == '\n') { + counter++; + } + ++i; + } + + QString size = QStringList::split("\n", QString::fromAscii(m_data->data(), i))[1]; + kdDebug(41008) << "Header: " << QString::fromAscii(m_data->data(), i) << "\n"; + QStringList sizelist = QStringList::split(" ", size); + Q_INT32 w = sizelist[0].toInt(); + Q_INT32 h = sizelist[1].toInt(); + + startOfImageData = i; + return QSize(w, h); + +} + +KisProfile * KisRawImport::profile() +{ + if (m_page->chkProfile->isChecked()) { + return KisMetaRegistry::instance()->csRegistry()->getProfileByName(m_page->cmbProfile->currentText()); + } + else + return 0; +} + +void KisRawImport::slotFillCmbProfiles() +{ + KisID s = getColorSpace(); + + KisColorSpaceFactory * csf = KisMetaRegistry::instance()->csRegistry() -> get(s); + m_page -> cmbProfile -> clear(); + QValueVector profileList = KisMetaRegistry::instance()->csRegistry()->profilesFor( csf ); + QValueVector ::iterator it; + for ( it = profileList.begin(); it != profileList.end(); ++it ) { + m_page -> cmbProfile -> insertItem((*it) -> productName()); + } +} + +KisID KisRawImport::getColorSpace() +{ + if (m_page->radioRGB->isChecked()) { + if (m_page->radio16->isChecked()) { + return KisID( "RGBA16" ); + } + } + else { + if (m_page->radio16->isChecked()) { + return KisID( "GRAYA16" ); + } + else { + return KisID( "GRAYA" ); + } + } + return KisID("RGBA"); +} + +#include "kis_raw_import.moc" diff --git a/filters/krita/raw/kis_raw_import.h b/filters/krita/raw/kis_raw_import.h new file mode 100644 index 000000000..cff059f7e --- /dev/null +++ b/filters/krita/raw/kis_raw_import.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2005 Boudewijn Rempt + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_RAW_IMPORT_H_ +#define KIS_RAW_IMPORT_H_ + +#include + +class KProcess; +class KDialogBase; +class WdgRawImport; +class KisProfile; +class QProgressDialog; + +class KisRawImport : public KoFilter { + Q_OBJECT + +public: + KisRawImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisRawImport(); + +public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); + + +private slots: + + void slotUpdatePreview(); + void slotFillCmbProfiles(); + void slotProcessDone(); + void slotReceivedStdout(KProcess *proc, char *buffer, int buflen); + void slotReceivedStderr(KProcess *proc, char *buffer, int buflen); + void incrementProgress(); + +private: + + QStringList createArgumentList(bool forPreview = false); + QSize determineSize(Q_UINT32& startOfImageData); + void getImageData(QStringList arguments); + KisProfile * profile(); + KisID getColorSpace(); + +private: + QByteArray * m_data; + KDialogBase * m_dialog; + WdgRawImport * m_page; + KisProfile * m_monitorProfile; + KProcess * m_process; + QProgressDialog* m_progress; + bool m_err; // Set to true when slotReceivedStderr is called +}; + +#endif // KIS_RAW_IMPORT_H_ + diff --git a/filters/krita/raw/krita_raw.desktop b/filters/krita/raw/krita_raw.desktop new file mode 100644 index 000000000..4b4fd1fc8 --- /dev/null +++ b/filters/krita/raw/krita_raw.desktop @@ -0,0 +1,57 @@ +[Desktop Entry] +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +MimeType=image/x-raw +Type=Application +Icon=krita +Categories= +X-KDE-StartupNotify=true +X-DCOP-ServiceType=Multi diff --git a/filters/krita/raw/krita_raw_import.desktop b/filters/krita/raw/krita_raw_import.desktop new file mode 100644 index 000000000..61cb4da17 --- /dev/null +++ b/filters/krita/raw/krita_raw_import.desktop @@ -0,0 +1,51 @@ +[Desktop Entry] +Type=Service +Name=Krita RAW Import Filter +Name[bg]=Филтър за импортиране на RAW в Krita +Name[br]=Sil enporzh RAW evit Krita +Name[ca]=Filtre d'importació RAW per a Krita +Name[da]=Krita RAW-importfilter +Name[de]=Krita RAW-Importfilter +Name[el]=Φίλτρο εισαγωγής RAW του Krita +Name[eo]=Krita RAW-importfiltrilo +Name[es]=Filtro de importación a RAW de Krita +Name[et]=Krita toorpiltide impordifilter +Name[fa]=پالایۀ واردات Krita RAW +Name[fi]=Krita RAW -tuontisuodin +Name[fr]=Filtre d'importation RAW de Krita +Name[fy]=Krita RAW Ymportfilter +Name[ga]=Scagaire Iompórtála RAW Krita +Name[gl]=Filtro de Importación RAW para Krita +Name[he]=Krita RAW מסנן יבוא +Name[hr]=Krita RAW filtar uvoza +Name[hu]=Krita RAW importszűrő +Name[is]=Krita RAW innflutningssía +Name[it]=Filtro di importazione di formati grezzi per Krita +Name[ja]=Krita RAW インポートフィルタ +Name[km]=តម្រង​នាំចូល RAW សម្រាប់ Krita +Name[lt]=Krita RAW importavimo filtras +Name[lv]=Krita RAW importa filtrs +Name[nb]=RAW importfilter for Krita +Name[nds]=RAW-Importfilter för Krita +Name[ne]=क्रिता RAW आयात फिल्टर +Name[nl]=Krita RAW Importfilter +Name[pl]=Filtr importu formatu RAW dla Krita +Name[pt]=Filtro de Importação RAW para o Krita +Name[pt_BR]=Filtro de Importação RAW para o Krita +Name[ru]=Фильтр импорта рисунков RAW в Krita +Name[se]=Krita RAW-sisafievrridansilli +Name[sk]=RAW filter pre import do Krita +Name[sl]=Uvozni filter RAW za Krito +Name[sr]=Krita-ин филтер за увоз из RAW-а +Name[sr@Latn]=Krita-in filter za uvoz iz RAW-a +Name[sv]=Krita RAW-importfilter +Name[uk]=Фільтр імпорту RAW для Krita +Name[uz]=Krita RAW import filteri +Name[uz@cyrillic]=Krita RAW импорт филтери +Name[zh_CN]=Krita RAW 导入过滤器 +Name[zh_TW]=Krita RAW 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-raw +X-KDE-Weight=1 +X-KDE-Library=libkrita_raw_import +ServiceTypes=KOfficeFilter diff --git a/filters/krita/raw/wdgrawimport.ui b/filters/krita/raw/wdgrawimport.ui new file mode 100644 index 000000000..af2163adc --- /dev/null +++ b/filters/krita/raw/wdgrawimport.ui @@ -0,0 +1,496 @@ + +WdgRawImport + + + WdgRawImport + + + + 0 + 0 + 835 + 596 + + + + + unnamed + + + + bnPreview + + + &Update Preview + + + + + lblPreview + + + + 7 + 7 + 0 + 0 + + + + + 200 + 150 + + + + + + layout2 + + + + unnamed + + + + grpColorSettings + + + Color Settings + + + + unnamed + + + + chkBlackpoint + + + Blackpoint: + + + + + chkRed + + + Red multiplier: + + + + + dblRed + + + 0.1 + + + 1 + + + + + chkBlue + + + Blue multiplier: + + + + + dblBlue + + + 0.1 + + + 1 + + + + + dblBlackpoint + + + + + dblBrightness + + + 0.1 + + + 2 + + + Brightness. 1.0 is default + + + + + grpWhiteBalance + + + &White Balance + + + true + + + + unnamed + + + + radioFixed + + + White card in sunlight + + + true + + + + + radioAutomatic + + + Automatic + + + + + + false + + + Automatic color balance. The default is to use a fixed color balance based on a white card photographed in sunlight. + + + + + radioCamera + + + From camera + + + + + + + Use the color balance specified by the camera. If this cannot be found, dcraw prints a warning and reverts to the default. + + + + + + + chkBrightness + + + Brightness: + + + + + + + grpColorSpace + + + Colorspace + + + true + + + + unnamed + + + + radioGray + + + &Document mode + + + + + radioRGB + + + &RGB + + + true + + + + + + + grpChannelDepth + + + Channel Depth + + + false + + + true + + + 0 + + + + unnamed + + + + radio16 + + + &16 bits per channel + + + Alt+1 + + + true + + + + + radio8 + + + &8 bits per channel + + + Alt+8 + + + false + + + + + + + chkFourColorRGB + + + &Interpolate RGB as four colors + + + Interpolate RGB as four colors. This blurs the image a little, but it eliminates false 2x2 mesh patterns. + + + + + + + spacer3 + + + Horizontal + + + Expanding + + + + 500 + 20 + + + + + + spacer3_2 + + + Vertical + + + Expanding + + + + 20 + 120 + + + + + + layout4 + + + + unnamed + + + + chkClip + + + Clip colors to prevent pink highlights + + + + + + true + + + By default, dcraw clips all colors to prevent pink hues in the highlights. Combine this option with -b 0.25 to leave the image data completely unclipped. + + + + + layout10 + + + + unnamed + + + + chkProfile + + + + + + + + + + + cmbProfile + + + true + + + + 3 + 0 + 0 + 0 + + + + + + + + chkCameraColors + + + Use camera raw colors, not sRGB + + + + + spacer4 + + + Horizontal + + + Expanding + + + + 41 + 20 + + + + + + + + + + KisCmbIDList +
    kis_cmb_idlist.h
    + + 1 + 24 + + 0 + + 5 + 5 + 0 + 0 + + image0 +
    + + ImageViewer +
    imageviewer.h
    + + -1 + -1 + + 0 + + 5 + 5 + 0 + 0 + + image1 + moved(QPoint) + moving(QPoint) + startMoving(QPoint) + zoomIn() + slot() + zoomOut() + slot() + slot() + slotMoving(QPoint) + slotMoved(QPoint) + slot() + slotStartMoving(QPoint) +
    +
    + + + 89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154388dad945f4c5b551cc73fe7dc4b7b4bcba0762d45c43114323599ee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d2a2f1af664b6f1e0fe3863a0718969700eb0c52142da0242a1bd6d696f7bcff101585203ceb8fd9ece39f99dcff9fe7edf939f88c562ec465f5f9fe609442c161362173c3e3eae7b7a7ac8e7f36432196cdbfe4f907c3e4f2291201e8fe338cec3737357e9e8e828aded1e229d650e1f2d51754b082110124c13a4dc5ea341eb9dc284c0558a853f3ce8cb0677ef500fde7d39d2596679e326597b8e9abb85d7a770ab16ab6983ec5a05b487a70e36f0f4e10afe408d6a558310980108478dba4a1e8233990c5d474b64ed39aa3a8fe5f3317fbf81dbd70bccfeb205947632fd74f6589c1c6ea2f70d03a58ba0c1f2c9bdc1b66de3b8256a6e11cbe7e3ee1d181b590124fe2693aeee08d223c82c3a2c24b7b874bec8f26288774f7bd054504aef0dde6e99c0eb83f9fb266323cb80a27fb0958141836044605a2ee5523393371cc646fee2da37195aa35d0c0c5b4859ac03d7e91712dcaac5adab3650a3ff9d08ef7dd8404bb48869e5d958b5b87dadc4c9a1464e9f0d0326df7ebd86bd2e310cb1bf62d384d59441f2d70a070e1c60e09489929b988681bdd9cc97170bcc4c65595f71f8e0e3301337fc24a7732467831875a47f289652b0be5e4151e6d07316c1b0c0340d8ab92023e76d66a6b2840e36d2fb7a13fee632475e6edc367ea98a90fb98b7dd6310ca0328a44761582e1bab41befabcc0ec940d28bc5e93b68e064cab84e1d9beaeb48934eac1f53b01c1b000fca496aa54b61a99fcde61662a4b4b4b23d1680be9d426173e4df3602a48ea411989a4fd590f52a8fd156b05ed9d350e3defe3cfdf4b4c7ce770ea7d3fb9f520afbe1620daeee5c26735d20b9b9cfb6811a754a439e4e5c5639a4caa1e5caf586bfc0197b78702005cb9b4cae4cd3267ce8638fe964bd72b393e39d74928d242617303a756a37f284447770dcdbffc6384a05a85de1306e9a52057c7527c7131c3c42d3f475eb2303c82d4fc3276d6811db37efeb148723082d9b08f79f97c1e5729109a9a28307cc622d2d6cdf52b2b24efe548dedb00142009862cfa879ee1a71f6cec928353511472fbf4389148b0b0e0c108081412458dfe21c9f11351e67e7358595468246d1d1e5e38a6e9e851bc39d84ab502a669331dafec0d8ec7e3e8cb06e1a881d727d1ae40180a434a8c9db129a54126ad48a7358c2b4c5352c8c374bcccdab2bb37d8719cba79fab8211f9df218e0582c261e95f8bfc04f1a1e8bc5c4dfe0a190172af6a9690000000049454e44ae426082 + + + 789c534e494dcbcc4b554829cdcdad8c2fcf4c29c95030e0524611cd48cd4ccf28010a1797249664262b2467241641a592324b8aa363156c15aab914146aadb90067111b1f + + + + radioRGB + radio16 + chkBrightness + dblBrightness + chkBlackpoint + dblBlackpoint + chkRed + dblRed + chkBlue + dblBlue + radioFixed + chkFourColorRGB + chkClip + chkProfile + chkCameraColors + bnPreview + radioAutomatic + + +
    diff --git a/filters/krita/tiff/Makefile.am b/filters/krita/tiff/Makefile.am new file mode 100644 index 000000000..13eb58100 --- /dev/null +++ b/filters/krita/tiff/Makefile.am @@ -0,0 +1,49 @@ +kde_module_LTLIBRARIES = libkritatiffimport.la libkritatiffexport.la + +libkritatiffexport_la_LDFLAGS = -avoid-version -module -no-undefined \ + $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) +libkritatiffexport_la_LIBADD = $(top_builddir)/krita/libkritacommon.la \ + libkritatiffconverter.la $(KOFFICE_LIBS) -ltiff + +libkritatiffimport_la_LDFLAGS = -avoid-version -module -no-undefined \ + $(KDE_PLUGIN) $(KDE_RPATH) $(all_libraries) +libkritatiffimport_la_LIBADD = $(top_builddir)/krita/libkritacommon.la \ + libkritatiffconverter.la $(KOFFICE_LIBS) -ltiff + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) \ + $(all_includes) + + +servicedir = $(kde_servicesdir) + + +kdelnkdir = $(kde_appsdir)/.hidden + + + + +METASOURCES = AUTO + + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +libkritatiffimport_la_SOURCES = kis_tiff_import.cc +libkritatiffexport_la_SOURCES = kis_tiff_export.cc kis_wdg_options_tiff.ui \ + kis_dlg_options_tiff.cpp +service_DATA = krita_tiff_export.desktop krita_tiff_import.desktop +kdelnk_DATA = krita_tiff.desktop +noinst_HEADERS = kis_dlg_options_tiff.h kis_tiff_writer_visitor.h \ + kis_tiff_ycbcr_reader.h +libkritatiffconverter_la_LDFLAGS = -no-undefined $(all_libraries) +noinst_LTLIBRARIES = libkritatiffconverter.la +libkritatiffconverter_la_SOURCES = kis_tiff_converter.cc kis_tiff_stream.cc \ + kis_tiff_writer_visitor.cpp kis_tiff_reader.cc kis_tiff_ycbcr_reader.cc diff --git a/filters/krita/tiff/configure.in.bot b/filters/krita/tiff/configure.in.bot new file mode 100644 index 000000000..aea71e8ce --- /dev/null +++ b/filters/krita/tiff/configure.in.bot @@ -0,0 +1,7 @@ +if test -z "$LIBTIFF"; then + echo "" + echo "You're missing libtiff (binaries and/or headers), krita won't be able" + echo "to import/export tiff" + echo "" + all_tests=bad +fi diff --git a/filters/krita/tiff/kis_dlg_options_tiff.cpp b/filters/krita/tiff/kis_dlg_options_tiff.cpp new file mode 100644 index 000000000..6b9f30270 --- /dev/null +++ b/filters/krita/tiff/kis_dlg_options_tiff.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_dlg_options_tiff.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "kis_wdg_options_tiff.h" + +KisDlgOptionsTIFF::KisDlgOptionsTIFF(QWidget *parent, const char *name) + : KDialogBase(parent, name, false, i18n("TIFF Export Options"), KDialogBase::Ok | KDialogBase::Cancel) +{ + optionswdg = new KisWdgOptionsTIFF(this); + activated(0); + connect(optionswdg->kComboBoxCompressionType, SIGNAL(activated ( int )), this, SLOT(activated ( int ) )); + connect(optionswdg->flatten, SIGNAL(toggled(bool)), this, SLOT(flattenToggled( bool) ) ); + setMainWidget(optionswdg); + kapp->restoreOverrideCursor(); + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum) ); +} + +KisDlgOptionsTIFF::~KisDlgOptionsTIFF() +{ +} + +void KisDlgOptionsTIFF::activated ( int index ) +{ +/* optionswdg->groupBoxJPEG->hide(); + optionswdg->groupBoxDeflate->hide(); + optionswdg->groupBoxCCITGroupCCITG3->hide(); + optionswdg->groupBoxPixarLog->hide();*/ + switch(index) + { + case 1: + optionswdg->codecsOptionsStack->raiseWidget(1); +// optionswdg->groupBoxJPEG->show(); + break; + case 2: + optionswdg->codecsOptionsStack->raiseWidget(2); +// optionswdg->groupBoxDeflate->show(); + break; + case 6: + optionswdg->codecsOptionsStack->raiseWidget(3); +// optionswdg->groupBoxCCITGroupCCITG3->show(); + break; + case 8: + optionswdg->codecsOptionsStack->raiseWidget(4); +// optionswdg->groupBoxPixarLog->show(); + break; + default: + optionswdg->codecsOptionsStack->raiseWidget(0); + } +} + +void KisDlgOptionsTIFF::flattenToggled(bool t) +{ + optionswdg->alpha->setEnabled(t); + if(!t) + { + optionswdg->alpha->setChecked(true); + } +} + + +KisTIFFOptions KisDlgOptionsTIFF::options() +{ + KisTIFFOptions options; + switch(optionswdg->kComboBoxCompressionType->currentItem ()) + { + case 0: + options.compressionType = COMPRESSION_NONE; + break; + case 1: + options.compressionType = COMPRESSION_JPEG; + break; + case 2: + options.compressionType = COMPRESSION_DEFLATE; + break; + case 3: + options.compressionType = COMPRESSION_LZW; + break; +#ifdef COMPRESSION_JP2000 + case 4: + options.compressionType = COMPRESSION_JP2000; + break; +#endif + case 5: + options.compressionType = COMPRESSION_CCITTRLE; + break; + case 6: + options.compressionType = COMPRESSION_CCITTFAX3; + break; + case 7: + options.compressionType = COMPRESSION_CCITTFAX4; + break; + case 8: + options.compressionType = COMPRESSION_PIXARLOG; + break; + } + options.predictor = optionswdg->kComboBoxPredictor->currentItem() + 1; + options.alpha = optionswdg->alpha->isChecked(); + options.flatten = optionswdg->flatten->isChecked(); + options.jpegQuality = optionswdg->qualityLevel->value(); + options.deflateCompress = optionswdg->compressionLevelDeflate->value(); + options.faxMode = optionswdg->kComboBoxFaxMode->currentItem() + 1; + options.pixarLogCompress = optionswdg->compressionLevelPixarLog->value(); + + return options; +} + +#include "kis_dlg_options_tiff.moc" diff --git a/filters/krita/tiff/kis_dlg_options_tiff.h b/filters/krita/tiff/kis_dlg_options_tiff.h new file mode 100644 index 000000000..a81bd65f8 --- /dev/null +++ b/filters/krita/tiff/kis_dlg_options_tiff.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_DLG_OPTIONS_TIFF_H +#define KIS_DLG_OPTIONS_TIFF_H + +#include +#include + +class KisWdgOptionsTIFF; +/** + @author Cyrille Berger +*/ +class KisDlgOptionsTIFF : public KDialogBase +{ + Q_OBJECT + public: + KisDlgOptionsTIFF(QWidget *parent=0, const char *name=0); + ~KisDlgOptionsTIFF(); + public slots: + void activated ( int index ); + void flattenToggled(bool); + KisTIFFOptions options(); + public: + KisWdgOptionsTIFF* optionswdg; +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_converter.cc b/filters/krita/tiff/kis_tiff_converter.cc new file mode 100644 index 000000000..955ab9ef5 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_converter.cc @@ -0,0 +1,677 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_converter.h" + +#include + +#include +#include LCMS_HEADER + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "kis_tiff_reader.h" +#include "kis_tiff_ycbcr_reader.h" +#include "kis_tiff_stream.h" +#include "kis_tiff_writer_visitor.h" + +namespace { + + QString getColorSpaceForColorType(uint16 color_type, uint16 color_nb_bits, TIFF *image, uint16 &nbchannels, uint16 &extrasamplescount, uint8 &destDepth, uint16 sampletype) { + if(color_type == PHOTOMETRIC_MINISWHITE || color_type == PHOTOMETRIC_MINISBLACK) + { + if(nbchannels == 0) nbchannels = 1; + extrasamplescount = nbchannels - 1; // FIX the extrasamples count in case of + if(color_nb_bits <= 8) + { + destDepth = 8; + return "GRAYA"; + } else { + destDepth = 16; + return "GRAYA16"; + } + } else if(color_type == PHOTOMETRIC_RGB /*|| color_type == */ ) { + if(nbchannels == 0) nbchannels = 3; + extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of + if(sampletype == SAMPLEFORMAT_IEEEFP) + { + if(color_nb_bits == 16) + { + destDepth = 16; + return "RGBAF16HALF"; + } else if( color_nb_bits == 32) { + destDepth = 32; + return "RGBAF32"; + } + return ""; + } else { + if(color_nb_bits <= 8) + { + destDepth = 8; + return "RGBA"; + } else { + destDepth = 16; + return "RGBA16"; + } + } + } else if(color_type == PHOTOMETRIC_YCBCR ) { + if(nbchannels == 0) nbchannels = 3; + extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of + if(color_nb_bits <= 8) + { + destDepth = 8; + return "YCbCrAU8"; + } else { + destDepth = 16; + return "YCbCrAU16"; + } + } else if(color_type == PHOTOMETRIC_SEPARATED ) { + if(nbchannels == 0) nbchannels = 4; + // SEPARATED is in general CMYK but not allways, so we check + uint16 inkset; + if((TIFFGetField(image, TIFFTAG_INKSET, &inkset) == 0)){ + kdDebug(41008) << "Image does not define the inkset." << endl; + inkset = 2; + } + if(inkset != INKSET_CMYK) + { + kdDebug(41008) << "Unsupported inkset (right now, only CMYK is supported)" << endl; + char** ink_names; + uint16 numberofinks; + if( TIFFGetField(image, TIFFTAG_INKNAMES, &ink_names) && TIFFGetField(image, TIFFTAG_NUMBEROFINKS, &numberofinks) ) + { + kdDebug(41008) << "Inks are : " << endl; + for(uint i = 0; i < numberofinks; i++) + { + kdDebug(41008) << ink_names[i] << endl; + } + } else { + kdDebug(41008) << "inknames aren't defined !" << endl; + // To be able to read stupid adobe files, if there are no information about inks and four channels, then it's a CMYK file : + if( nbchannels - extrasamplescount != 4) + { + return ""; + } + } + } + if(color_nb_bits <= 8) + { + destDepth = 8; + return "CMYK"; + } else { + destDepth = 16; + return "CMYKA16"; + } + } else if(color_type == PHOTOMETRIC_CIELAB +#ifdef PHOTOMETRIC_ICCLAB + || color_type == PHOTOMETRIC_ICCLAB +#endif + ) { + destDepth = 16; + if(nbchannels == 0) nbchannels = 3; + extrasamplescount = nbchannels - 3; // FIX the extrasamples count in case of + return "LABA"; // TODO add support for a 8bit LAB colorspace when it is written + } else if(color_type == PHOTOMETRIC_PALETTE) { + destDepth = 16; + if(nbchannels == 0) nbchannels = 2; + extrasamplescount = nbchannels - 2; // FIX the extrasamples count in case of + // <-- we will convert the index image to RGBA16 as the palette is allways on 16bits colors + return "RGBA16"; + } + return ""; + } +} + +KisTIFFConverter::KisTIFFConverter(KisDoc *doc, KisUndoAdapter *adapter) +{ + m_doc = doc; + m_adapter = adapter; + m_job = 0; + m_stop = false; +} + +KisTIFFConverter::~KisTIFFConverter() +{ +} + +KisImageBuilder_Result KisTIFFConverter::decode(const KURL& uri) +{ + kdDebug(41008) << "Start decoding TIFF File" << endl; + // Opent the TIFF file + TIFF *image = 0; + if((image = TIFFOpen(QFile::encodeName(uri.path()), "r")) == NULL){ + kdDebug(41008) << "Could not open the file, either it doesn't exist, either it is not a TIFF : " << uri.path() << endl; + + return (KisImageBuilder_RESULT_BAD_FETCH); + } + do { + kdDebug(41008) << "Read new sub-image" << endl; + KisImageBuilder_Result result = readTIFFDirectory(image); + if(result != KisImageBuilder_RESULT_OK){ + return result; + } + } while (TIFFReadDirectory(image)); + // Freeing memory + TIFFClose(image); + return KisImageBuilder_RESULT_OK; +} + +KisImageBuilder_Result KisTIFFConverter::readTIFFDirectory( TIFF* image) +{ + // Read information about the tiff + uint32 width, height; + if(TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width) == 0){ + kdDebug(41008) << "Image does not define its width" << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_INVALID_ARG; + } + if(TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height) == 0){ + kdDebug(41008) << "Image does not define its height" << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_INVALID_ARG; + } + uint16 depth; + if((TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &depth) == 0)){ + kdDebug(41008) << "Image does not define its depth" << endl; + depth = 1; + } + uint16 sampletype; + if((TIFFGetField(image, TIFFTAG_SAMPLEFORMAT, &sampletype) == 0)){ + kdDebug(41008) << "Image does not define its sample type" << endl; + sampletype = SAMPLEFORMAT_UINT; + } + // Determine the number of channels (usefull to know if a file has an alpha or not + uint16 nbchannels; + if(TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &nbchannels) == 0){ + kdDebug(41008) << "Image has an undefined number of samples per pixel" << endl; + nbchannels = 0; + } + // Get the number of extrasamples and information about them + uint16 *sampleinfo, extrasamplescount; + if(TIFFGetField(image, TIFFTAG_EXTRASAMPLES, &extrasamplescount, &sampleinfo) == 0) + { + extrasamplescount = 0; + } + // Determine the colorspace + uint16 color_type; + if(TIFFGetField(image, TIFFTAG_PHOTOMETRIC, &color_type) == 0){ + kdDebug(41008) << "Image has an undefined photometric interpretation" << endl; + color_type = PHOTOMETRIC_MINISWHITE; + } + uint8 dstDepth; + QString csName = getColorSpaceForColorType(color_type, depth, image, nbchannels, extrasamplescount, dstDepth,sampletype); + if(csName.isEmpty()) { + kdDebug(41008) << "Image has an unsupported colorspace : " << color_type << " for this depth : "<< depth << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + kdDebug(41008) << "Colorspace is : " << csName << " with a depth of " << depth << " and with a nb of channels of " << nbchannels << endl; + + // Read image profile + kdDebug() << "Reading profile" << endl; + KisProfile* profile = 0; + DWORD EmbedLen; + LPBYTE EmbedBuffer; + + if (TIFFGetField(image, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) { + kdDebug(41008) << "Profile found" << endl; + QByteArray rawdata; + rawdata.resize(EmbedLen); + memcpy(rawdata.data(), EmbedBuffer, EmbedLen); + profile = new KisProfile(rawdata); + } else { + kdDebug(41008) << "No Profile found" << endl; + } + + // Retrieve a pointer to the colorspace + KisColorSpace* cs = 0; + if (profile && profile->isSuitableForOutput()) + { + kdDebug(41008) << "image has embedded profile: " << profile -> productName() << "\n"; + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(csName, profile); + } + else + cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName,""),""); + + if(cs == 0) { + kdDebug(41008) << "Colorspace " << csName << " is not available, please check your installation." << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE; + } + + // Create the cmsTransform if needed + cmsHTRANSFORM transform = 0; + if(profile && !profile->isSuitableForOutput()) + { + kdDebug(41008) << "The profile can't be used in krita, need conversion" << endl; + transform = cmsCreateTransform(profile->profile(), cs->colorSpaceType(), + cs->getProfile()->profile() , cs->colorSpaceType(), + INTENT_PERCEPTUAL, 0); + } + + + // Check if there is an alpha channel + int8 alphapos = -1; // <- no alpha + // Check which extra is alpha if any + kdDebug(41008) << "There are " << nbchannels << " channels and " << extrasamplescount << " extra channels" << endl; + if(sampleinfo) // index images don't have any sampleinfo, and therefor sampleinfo == 0 + { + for(int i = 0; i < extrasamplescount; i ++) + { + kdDebug(41008) << i << " " << extrasamplescount << " " << (cs->nColorChannels()) << nbchannels << " " << sampleinfo[i] << endl; + if(sampleinfo[i] == EXTRASAMPLE_ASSOCALPHA) + { + // XXX: dangelo: the color values are already multiplied with + // the alpha value. This needs to be reversed later (postprocessor?) + alphapos = i; + } + + if (sampleinfo[i] == EXTRASAMPLE_UNASSALPHA) + { + // color values are not premultiplied with alpha, and can be used as they are. + alphapos = i; + } + } + } + + // Read META Information + KoDocumentInfo * info = m_doc->documentInfo(); + KoDocumentInfoAbout * aboutPage = static_cast(info->page( "about" )); + KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author")); + char* text; + if (TIFFGetField(image, TIFFTAG_ARTIST, &text)) { + authorPage->setFullName(text); + } + if (TIFFGetField(image, TIFFTAG_DOCUMENTNAME, &text)) { + aboutPage->setTitle(text); + } + if (TIFFGetField(image,TIFFTAG_IMAGEDESCRIPTION,&text) ) { + aboutPage->setAbstract( text ); + } + + + // Get the planar configuration + uint16 planarconfig; + if(TIFFGetField(image, TIFFTAG_PLANARCONFIG, &planarconfig) == 0) + { + kdDebug(41008) << "Plannar configuration is not define" << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_INVALID_ARG; + } + // Creating the KisImageSP + if( ! m_img ) { + m_img = new KisImage(m_doc->undoAdapter(), width, height, cs, "built image"); + Q_CHECK_PTR(m_img); + m_img->blockSignals(true); // Don't send out signals while we're building the image + if(profile) + { + m_img -> addAnnotation( profile->annotation() ); + } + } else { + if( m_img->width() < (Q_INT32)width || m_img->height() < (Q_INT32)height) + { + Q_UINT32 newwidth = (m_img->width() < (Q_INT32)width) ? width : m_img->width(); + Q_UINT32 newheight = (m_img->height() < (Q_INT32)height) ? height : m_img->height(); + m_img->resize(newwidth, newheight, false); + } + } + KisPaintLayer* layer = new KisPaintLayer(m_img, m_img -> nextLayerName(), Q_UINT8_MAX); + tdata_t buf = 0; + tdata_t* ps_buf = 0; // used only for planar configuration seperated + TIFFStreamBase* tiffstream; + + KisTIFFReaderBase* tiffReader = 0; + + Q_UINT8 poses[5]; + KisTIFFPostProcessor* postprocessor = 0; + + // Configure poses + uint8 nbcolorsamples = nbchannels - extrasamplescount; + switch(color_type) + { + case PHOTOMETRIC_MINISWHITE: + { + poses[0] = 0; poses[1] = 1; + postprocessor = new KisTIFFPostProcessorInvert(nbcolorsamples); + } + break; + case PHOTOMETRIC_MINISBLACK: + { + poses[0] = 0; poses[1] = 1; + postprocessor = new KisTIFFPostProcessor(nbcolorsamples); + } + break; + case PHOTOMETRIC_CIELAB: + { + poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3; + postprocessor = new KisTIFFPostProcessorICCLABtoCIELAB(nbcolorsamples); + } + break; +#ifdef PHOTOMETRIC_ICCLAB + case PHOTOMETRIC_ICCLAB: + { + poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3; + postprocessor = new KisTIFFPostProcessor(nbcolorsamples); + } + break; +#endif + case PHOTOMETRIC_RGB: + { + poses[0] = 2; poses[1] = 1; poses[2] = 0; poses[3] = 3; + postprocessor = new KisTIFFPostProcessor(nbcolorsamples); + } + break; + case PHOTOMETRIC_SEPARATED: + { + poses[0] = 0; poses[1] = 1; poses[2] = 2; poses[3] = 3; poses[4] = 4; + postprocessor = new KisTIFFPostProcessor(nbcolorsamples); + } + break; + default: + break; + } + + + // Initisalize tiffReader + uint16 * lineSizeCoeffs = new uint16[nbchannels]; + uint16 vsubsampling = 1; + uint16 hsubsampling = 1; + for(uint i = 0; i < nbchannels; i++) + { + lineSizeCoeffs[i] = 1; + } + if( color_type == PHOTOMETRIC_PALETTE) + { + uint16 *red; // No need to free them they are free by libtiff + uint16 *green; + uint16 *blue; + if ((TIFFGetField(image, TIFFTAG_COLORMAP, &red, &green, &blue)) == 0) + { + kdDebug(41008) << "Indexed image does not define a palette" << endl; + TIFFClose(image); + return KisImageBuilder_RESULT_INVALID_ARG; + } + + tiffReader = new KisTIFFReaderFromPalette( layer->paintDevice(), red, green, blue, poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor); + } else if(color_type == PHOTOMETRIC_YCBCR ) { + TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRSUBSAMPLING, &hsubsampling, &vsubsampling ); + lineSizeCoeffs[1] = hsubsampling; + lineSizeCoeffs[2] = hsubsampling; + uint16 position; + TIFFGetFieldDefaulted( image, TIFFTAG_YCBCRPOSITIONING, &position ); + if( dstDepth == 8 ) + { + tiffReader = new KisTIFFYCbCrReaderTarget8Bit(layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position); + } else if( dstDepth == 16 ) + { + tiffReader = new KisTIFFYCbCrReaderTarget16Bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor, hsubsampling, vsubsampling, (KisTIFFYCbCr::Position)position); + } + } else if(dstDepth == 8) + { + tiffReader = new KisTIFFReaderTarget8bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor); + } else if(dstDepth == 16) { + tiffReader = new KisTIFFReaderTarget16bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor); + } else if(dstDepth == 32) { + tiffReader = new KisTIFFReaderTarget32bit( layer->paintDevice(), poses, alphapos, depth, nbcolorsamples, extrasamplescount, transform, postprocessor); + } + + if(TIFFIsTiled(image)) + { + kdDebug(41008) << "tiled image" << endl; + uint32 tileWidth, tileHeight; + uint32 x, y; + TIFFGetField(image, TIFFTAG_TILEWIDTH, &tileWidth); + TIFFGetField(image, TIFFTAG_TILELENGTH, &tileHeight); + uint32 linewidth = (tileWidth * depth * nbchannels) / 8; + if(planarconfig == PLANARCONFIG_CONTIG) + { + buf = _TIFFmalloc(TIFFTileSize(image)); + if(depth < 16) + { + tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, linewidth); + } else if(depth < 32) + { + tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, linewidth); + } else { + tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, linewidth); + } + } else { + ps_buf = new tdata_t[nbchannels]; + uint32 * lineSizes = new uint32[nbchannels]; + uint16 baseSize = TIFFTileSize(image)/nbchannels; + for(uint i = 0; i < nbchannels; i++) + { + ps_buf[i] = _TIFFmalloc(baseSize); + lineSizes[i] = baseSize / lineSizeCoeffs[i]; + } + tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes); + delete [] lineSizes; + } + kdDebug(41008) << linewidth << " " << nbchannels << " " << layer->paintDevice()->colorSpace()->nColorChannels() << endl; + for (y = 0; y < height; y+= tileHeight) + { + for (x = 0; x < width; x += tileWidth) + { + kdDebug(41008) << "Reading tile x = " << x << " y = " << y << endl; + if( planarconfig == PLANARCONFIG_CONTIG ) + { + TIFFReadTile(image, buf, x, y, 0, (tsample_t) -1); + } else { + for(uint i = 0; i < nbchannels; i++) + { + TIFFReadTile(image, ps_buf[i], x, y, 0, i); + } + } + uint32 realTileWidth = (x + tileWidth) < width ? tileWidth : width - x; + for (uint yintile = 0; y + yintile < height && yintile < tileHeight/vsubsampling; ) { + tiffReader->copyDataToChannels( x, y + yintile , realTileWidth, tiffstream); + yintile += 1; + tiffstream->moveToLine( yintile ); + } + tiffstream->restart(); + } + } + } else { + kdDebug(41008) << "striped image" << endl; + tsize_t stripsize = TIFFStripSize(image); + uint32 rowsPerStrip; + TIFFGetFieldDefaulted(image, TIFFTAG_ROWSPERSTRIP, &rowsPerStrip); + kdDebug() << rowsPerStrip << " " << height << endl; + rowsPerStrip = QMIN(rowsPerStrip, height); // when TIFFNumberOfStrips(image) == 1 it might happen that rowsPerStrip is incorrectly set + if(planarconfig == PLANARCONFIG_CONTIG) + { + buf = _TIFFmalloc(stripsize); + if(depth < 16) + { + tiffstream = new TIFFStreamContigBelow16((uint8*)buf, depth, stripsize/rowsPerStrip); + } else if(depth < 32) + { + tiffstream = new TIFFStreamContigBelow32((uint8*)buf, depth, stripsize/rowsPerStrip); + } else { + tiffstream = new TIFFStreamContigAbove32((uint8*)buf, depth, stripsize/rowsPerStrip); + } + } else { + ps_buf = new tdata_t[nbchannels]; + uint32 scanLineSize = stripsize/rowsPerStrip; + kdDebug(41008) << " scanLineSize for each plan = " << scanLineSize << endl; + uint32 * lineSizes = new uint32[nbchannels]; + for(uint i = 0; i < nbchannels; i++) + { + ps_buf[i] = _TIFFmalloc(stripsize); + lineSizes[i] = scanLineSize / lineSizeCoeffs[i]; + } + tiffstream = new TIFFStreamSeperate( (uint8**) ps_buf, nbchannels, depth, lineSizes); + delete [] lineSizes; + } + + kdDebug(41008) << "Scanline size = " << TIFFRasterScanlineSize(image) << " / strip size = " << TIFFStripSize(image) << " / rowsPerStrip = " << rowsPerStrip << " stripsize/rowsPerStrip = " << stripsize/rowsPerStrip << endl; + uint32 y = 0; + kdDebug(41008) << " NbOfStrips = " << TIFFNumberOfStrips(image) << " rowsPerStrip = " << rowsPerStrip << " stripsize = " << stripsize << endl; + for (uint32 strip = 0; y < height; strip++) + { + if( planarconfig == PLANARCONFIG_CONTIG ) + { + TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, 0 ) , buf, (tsize_t) -1); + } else { + for(uint i = 0; i < nbchannels; i++) + { + TIFFReadEncodedStrip(image, TIFFComputeStrip( image, y, i ), ps_buf[i], (tsize_t) -1); + } + } + for( uint32 yinstrip = 0 ; yinstrip < rowsPerStrip && y < height ; ) + { + uint linesread = tiffReader->copyDataToChannels( 0, y, width, tiffstream); + y += linesread; + yinstrip += linesread; + tiffstream->moveToLine( yinstrip ); + } + tiffstream->restart(); + } + } + tiffReader->finalize(); + delete lineSizeCoeffs; + delete tiffReader; + delete tiffstream; + if( planarconfig == PLANARCONFIG_CONTIG ) + { + _TIFFfree(buf); + } else { + for(uint i = 0; i < nbchannels; i++) + { + _TIFFfree(ps_buf[i]); + } + delete[] ps_buf; + } + + m_img->addLayer(layer, m_img->rootLayer(), 0); + return KisImageBuilder_RESULT_OK; +} + +KisImageBuilder_Result KisTIFFConverter::buildImage(const KURL& uri) +{ + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!KIO::NetAccess::exists(uri, false, qApp -> mainWidget())) { + return KisImageBuilder_RESULT_NOT_EXIST; + } + + // We're not set up to handle asynchronous loading at the moment. + KisImageBuilder_Result result = KisImageBuilder_RESULT_FAILURE; + QString tmpFile; + + if (KIO::NetAccess::download(uri, tmpFile, qApp -> mainWidget())) { + KURL uriTF; + uriTF.setPath( tmpFile ); + result = decode(uriTF); + KIO::NetAccess::removeTempFile(tmpFile); + } + + return result; +} + + +KisImageSP KisTIFFConverter::image() +{ + return m_img; +} + + +KisImageBuilder_Result KisTIFFConverter::buildFile(const KURL& uri, KisImageSP img, KisTIFFOptions options) +{ + kdDebug(41008) << "Start writing TIFF File" << endl; + if (!img) + return KisImageBuilder_RESULT_EMPTY; + + if (uri.isEmpty()) + return KisImageBuilder_RESULT_NO_URI; + + if (!uri.isLocalFile()) + return KisImageBuilder_RESULT_NOT_LOCAL; + + // Open file for writing + TIFF *image; + if((image = TIFFOpen(QFile::encodeName(uri.path()), "w")) == NULL){ + kdDebug(41008) << "Could not open the file for writting " << uri.path() << endl; + TIFFClose(image); + return (KisImageBuilder_RESULT_FAILURE); + } + + // Set the document informations + KoDocumentInfo * info = m_doc->documentInfo(); + KoDocumentInfoAbout * aboutPage = static_cast(info->page( "about" )); + QString title = aboutPage->title(); + if(!title.isEmpty()) + { + TIFFSetField(image, TIFFTAG_DOCUMENTNAME, title.ascii()); + } + QString abstract = aboutPage->abstract(); + if(!abstract.isEmpty()) + { + TIFFSetField(image, TIFFTAG_IMAGEDESCRIPTION, abstract.ascii()); + } + KoDocumentInfoAuthor * authorPage = static_cast(info->page( "author" )); + QString author = authorPage->fullName(); + if(!author.isEmpty()) + { + TIFFSetField(image, TIFFTAG_ARTIST, author.ascii()); + } + + KisTIFFWriterVisitor* visitor = new KisTIFFWriterVisitor(image, &options); + KisGroupLayer* root = dynamic_cast(img->rootLayer().data()); + if(root == 0) + { + KIO::del(uri); + TIFFClose(image); + return KisImageBuilder_RESULT_FAILURE; + } + if(!visitor->visit( root )) + { + KIO::del(uri); + TIFFClose(image); + return KisImageBuilder_RESULT_FAILURE; + } + + TIFFClose(image); + return KisImageBuilder_RESULT_OK; +} + + +void KisTIFFConverter::cancel() +{ + m_stop = true; +} + +#include "kis_tiff_converter.moc" diff --git a/filters/krita/tiff/kis_tiff_converter.h b/filters/krita/tiff/kis_tiff_converter.h new file mode 100644 index 000000000..fbda4abdc --- /dev/null +++ b/filters/krita/tiff/kis_tiff_converter.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_TIFF_CONVERTER_H_ +#define _KIS_TIFF_CONVERTER_H_ + +#include +#include + +#include + +#include + +#include + +#include "kis_types.h" +#include "kis_global.h" +#include "kis_annotation.h" +class KisDoc; +class KisUndoAdapter; + +/** + * Image import/export plugins can use these results to report about success or failure. + */ +enum KisImageBuilder_Result { + KisImageBuilder_RESULT_FAILURE = -400, + KisImageBuilder_RESULT_NOT_EXIST = -300, + KisImageBuilder_RESULT_NOT_LOCAL = -200, + KisImageBuilder_RESULT_BAD_FETCH = -100, + KisImageBuilder_RESULT_INVALID_ARG = -50, + KisImageBuilder_RESULT_OK = 0, + KisImageBuilder_RESULT_PROGRESS = 1, + KisImageBuilder_RESULT_EMPTY = 100, + KisImageBuilder_RESULT_BUSY = 150, + KisImageBuilder_RESULT_NO_URI = 200, + KisImageBuilder_RESULT_UNSUPPORTED = 300, + KisImageBuilder_RESULT_INTR = 400, + KisImageBuilder_RESULT_PATH = 500, + KisImageBuilder_RESULT_UNSUPPORTED_COLORSPACE = 600 +}; + +struct KisTIFFOptions { + Q_UINT16 compressionType; + Q_UINT16 predictor; + bool alpha; + bool flatten; + Q_UINT16 jpegQuality; + Q_UINT16 deflateCompress; + Q_UINT16 faxMode; + Q_UINT16 pixarLogCompress; +}; + +class KisTIFFConverter : public KisProgressSubject { + Q_OBJECT + public: + KisTIFFConverter(KisDoc *doc, KisUndoAdapter *adapter); + virtual ~KisTIFFConverter(); + public: + KisImageBuilder_Result buildImage(const KURL& uri); + KisImageBuilder_Result buildFile(const KURL& uri, KisImageSP layer, KisTIFFOptions); + /** Retrieve the constructed image + */ + KisImageSP image(); + public slots: + virtual void cancel(); + private: + KisImageBuilder_Result decode(const KURL& uri); + KisImageBuilder_Result readTIFFDirectory( TIFF* image); + private: + KisImageSP m_img; + KisDoc *m_doc; + KisUndoAdapter *m_adapter; + bool m_stop; + KIO::TransferJob *m_job; +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_export.cc b/filters/krita/tiff/kis_tiff_export.cc new file mode 100644 index 000000000..ee715c6a1 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_export.cc @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_export.h" + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "kis_tiff_converter.h" +#include "kis_dlg_options_tiff.h" +#include "kis_wdg_options_tiff.h" + +typedef KGenericFactory KisTIFFExportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritatiffexport, KisTIFFExportFactory("kofficefilters")) + +KisTIFFExport::KisTIFFExport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisTIFFExport::~KisTIFFExport() +{ +} + +KoFilter::ConversionStatus KisTIFFExport::convert(const QCString& from, const QCString& to) +{ + kdDebug(41008) << "Tiff export! From: " << from << ", To: " << to << "\n"; + + if (from != "application/x-krita") + return KoFilter::NotImplemented; + + + KisDlgOptionsTIFF* kdb = new KisDlgOptionsTIFF(0, "options dialog for tiff"); + + KisDoc *output = dynamic_cast(m_chain->inputDocument()); + + KisColorSpace* cs = output->currentImage()->colorSpace(); + KisChannelInfo::enumChannelValueType type = cs->channels()[0]->channelValueType(); + if( type == KisChannelInfo::FLOAT16 || type == KisChannelInfo::FLOAT32) + { + kdb->optionswdg->kComboBoxPredictor->removeItem(1); + } else { + kdb->optionswdg->kComboBoxPredictor->removeItem(2); + } + + if(kdb->exec() == QDialog::Rejected) + { + return KoFilter::OK; // FIXME Cancel doesn't exist :( + } + + KisTIFFOptions options = kdb->options(); + + if( ( type == KisChannelInfo::FLOAT16 || type == KisChannelInfo::FLOAT32) && options.predictor == 2 ) + { // FIXME THIS IS AN HACK FIX THAT IN 2.0 !! + options.predictor = 3; + } + delete kdb; + + QString filename = m_chain->outputFile(); + + if (!output) + return KoFilter::CreationError; + + if (filename.isEmpty()) return KoFilter::FileNotFound; + + KURL url; + url.setPath(filename); + + KisImageSP img; + + if(options.flatten) + { + img = new KisImage(0, output->currentImage()->width(), output->currentImage()->height(), output->currentImage()->colorSpace(), ""); + KisPaintDeviceSP pd = new KisPaintDevice(*output->currentImage()->projection()); + KisPaintLayerSP l = new KisPaintLayer(img, "projection", OPACITY_OPAQUE, pd); + img->addLayer(l.data(), img->rootLayer(), 0); + } else { + img = output->currentImage(); + } + + + KisTIFFConverter ktc(output, output->undoAdapter()); +/* vKisAnnotationSP_it beginIt = img->beginAnnotations(); + vKisAnnotationSP_it endIt = img->endAnnotations();*/ + KisImageBuilder_Result res; + if ( (res = ktc.buildFile(url, img, options)) == KisImageBuilder_RESULT_OK) { + kdDebug(41008) << "success !" << endl; + return KoFilter::OK; + } + kdDebug(41008) << " Result = " << res << endl; + return KoFilter::InternalError; +} + +#include + diff --git a/filters/krita/tiff/kis_tiff_export.h b/filters/krita/tiff/kis_tiff_export.h new file mode 100644 index 000000000..586c2390e --- /dev/null +++ b/filters/krita/tiff/kis_tiff_export.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_TIFF_EXPORT_H_ +#define _KIS_TIFF_EXPORT_H_ + +#include + +class KisTIFFExport : public KoFilter { + Q_OBJECT + public: + KisTIFFExport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisTIFFExport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_import.cc b/filters/krita/tiff/kis_tiff_import.cc new file mode 100644 index 000000000..155cf67d6 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_import.cc @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_import.h" + +#include + +#include + +#include +#include +#include +#include + +#include "kis_tiff_converter.h" + +typedef KGenericFactory TIFFImportFactory; +K_EXPORT_COMPONENT_FACTORY(libkritatiffimport, TIFFImportFactory("kofficefilters")) + +KisTIFFImport::KisTIFFImport(KoFilter *, const char *, const QStringList&) : KoFilter() +{ +} + +KisTIFFImport::~KisTIFFImport() +{ +} + +KoFilter::ConversionStatus KisTIFFImport::convert(const QCString&, const QCString& to) +{ + kdDebug(41008) << "Importing using TIFFImport!\n"; + + if (to != "application/x-krita") + return KoFilter::BadMimeType; + + KisDoc * doc = dynamic_cast(m_chain -> outputDocument()); + KisView * view = static_cast(doc -> views().getFirst()); + + QString filename = m_chain -> inputFile(); + + if (!doc) + return KoFilter::CreationError; + + doc -> prepareForImport(); + + + if (!filename.isEmpty()) { + + KURL url; + url.setPath(filename); + + if (url.isEmpty()) + return KoFilter::FileNotFound; + + KisTIFFConverter ib(doc, doc -> undoAdapter()); + + if (view != 0) + view -> canvasSubject() -> progressDisplay() -> setSubject(&ib, false, true); + + switch (ib.buildImage(url)) { + case KisImageBuilder_RESULT_UNSUPPORTED: + return KoFilter::NotImplemented; + break; + case KisImageBuilder_RESULT_INVALID_ARG: + return KoFilter::BadMimeType; + break; + case KisImageBuilder_RESULT_NO_URI: + case KisImageBuilder_RESULT_NOT_LOCAL: + return KoFilter::FileNotFound; + break; + case KisImageBuilder_RESULT_BAD_FETCH: + case KisImageBuilder_RESULT_EMPTY: + return KoFilter::ParsingError; + break; + case KisImageBuilder_RESULT_FAILURE: + return KoFilter::InternalError; + break; + case KisImageBuilder_RESULT_OK: + doc -> setCurrentImage( ib.image()); + return KoFilter::OK; + default: + break; + } + + } + return KoFilter::StorageCreationError; +} + +#include + diff --git a/filters/krita/tiff/kis_tiff_import.h b/filters/krita/tiff/kis_tiff_import.h new file mode 100644 index 000000000..75953edce --- /dev/null +++ b/filters/krita/tiff/kis_tiff_import.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ +#ifndef _KIS_TIFF_IMPORT_H_ +#define _KIS_TIFF_IMPORT_H_ + +#include + +class KisTIFFImport : public KoFilter { + Q_OBJECT + public: + KisTIFFImport(KoFilter *parent, const char *name, const QStringList&); + virtual ~KisTIFFImport(); + public: + virtual KoFilter::ConversionStatus convert(const QCString& from, const QCString& to); +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_reader.cc b/filters/krita/tiff/kis_tiff_reader.cc new file mode 100644 index 000000000..bec7f1849 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_reader.cc @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_reader.h" + +#include + +#include +#include + +#include "kis_tiff_stream.h" + + uint KisTIFFReaderTarget8bit::copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x, y, dataWidth, true); + double coeff = Q_UINT8_MAX / (double)( pow(2, sourceDepth() ) - 1 ); +// kdDebug(41008) << " depth expension coefficient : " << coeff << endl; + while (!it.isDone()) { + Q_UINT8 *d = it.rawData(); + Q_UINT8 i; + for(i = 0; i < nbColorsSamples() ; i++) + { + d[poses()[i]] = (Q_UINT8)( tiffstream->nextValue() * coeff ); + } + postProcessor()->postProcess8bit( d); + if(transform()) cmsDoTransform(transform(), d, d, 1); + d[poses()[i]] = Q_UINT8_MAX; + for(int k = 0; k < nbExtraSamples(); k++) + { + if(k == alphaPos()) + d[poses()[i]] = (Q_UINT32) ( tiffstream->nextValue() * coeff ); + else + tiffstream->nextValue(); + } + ++it; + } + return 1; + } + uint KisTIFFReaderTarget16bit::copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x, y, dataWidth, true); + double coeff = Q_UINT16_MAX / (double)( pow(2, sourceDepth() ) - 1 ); +// kdDebug(41008) << " depth expension coefficient : " << coeff << endl; + while (!it.isDone()) { + Q_UINT16 *d = reinterpret_cast(it.rawData()); + Q_UINT8 i; + for(i = 0; i < nbColorsSamples(); i++) + { + d[poses()[i]] = (Q_UINT16)( tiffstream->nextValue() * coeff ); + } + postProcessor()->postProcess16bit( d); + if(transform()) cmsDoTransform(transform(), d, d, 1); + d[poses()[i]] = Q_UINT16_MAX; + for(int k = 0; k < nbExtraSamples(); k++) + { + if(k == alphaPos()) + d[poses()[i]] = (Q_UINT16) ( tiffstream->nextValue() * coeff ); + else + tiffstream->nextValue(); + } + ++it; + } + return 1; + } + + uint KisTIFFReaderTarget32bit::copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x, y, dataWidth, true); + double coeff = Q_UINT32_MAX / (double)( pow(2, sourceDepth() ) - 1 ); +// kdDebug(41008) << " depth expension coefficient : " << coeff << endl; + while (!it.isDone()) { + Q_UINT32 *d = reinterpret_cast(it.rawData()); + Q_UINT8 i; + for(i = 0; i < nbColorsSamples(); i++) + { + d[poses()[i]] = (Q_UINT32)( tiffstream->nextValue() * coeff ); + } + postProcessor()->postProcess32bit( d); + if(transform()) cmsDoTransform(transform(), d, d, 1); + d[poses()[i]] = Q_UINT32_MAX; + for(int k = 0; k < nbExtraSamples(); k++) + { + if(k == alphaPos()) + d[poses()[i]] = (Q_UINT32) ( tiffstream->nextValue() * coeff ); + else + tiffstream->nextValue(); + } + ++it; + } + return 1; + } + uint KisTIFFReaderFromPalette::copyDataToChannels(Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x, y, dataWidth, true); + while (!it.isDone()) { + Q_UINT16* d = reinterpret_cast(it.rawData()); + uint32 index = tiffstream->nextValue(); + d[2] = m_red[index]; + d[1] = m_green[index]; + d[0] = m_blue[index]; + d[3] = Q_UINT16_MAX; + ++it; + } + return 1; + } diff --git a/filters/krita/tiff/kis_tiff_reader.h b/filters/krita/tiff/kis_tiff_reader.h new file mode 100644 index 000000000..d107d21ed --- /dev/null +++ b/filters/krita/tiff/kis_tiff_reader.h @@ -0,0 +1,206 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_TIFF_READER_H_ +#define _KIS_TIFF_READER_H_ + +// On some platforms, tiffio.h #defines NULL in a bad +// way for C++, as (void *)0 instead of using the correct +// C++ value 0. Include stdio.h first to get the right one. +#include +#include + +// #include +// #include +// #include + +#include + +#include "kis_types.h" +#include "kis_global.h" +// #include "kis_annotation.h" + +#include +#include + +#define Q_UINT32_MAX 4294967295u + +class TIFFStreamBase; + +class KisTIFFPostProcessor { + public: + KisTIFFPostProcessor(uint8 nbcolorssamples) : m_nbcolorssamples(nbcolorssamples) { } + public: + virtual void postProcess8bit( Q_UINT8* ) { }; + virtual void postProcess16bit( Q_UINT16* ) { }; + virtual void postProcess32bit( Q_UINT32* ) { }; + protected: + inline uint8 nbColorsSamples() { return m_nbcolorssamples; } + private: + uint8 m_nbcolorssamples; +}; + +class KisTIFFPostProcessorInvert : public KisTIFFPostProcessor { + public: + KisTIFFPostProcessorInvert(uint8 nbcolorssamples) : KisTIFFPostProcessor(nbcolorssamples) {} + public: + virtual void postProcess8bit( Q_UINT8* data ) + { + for(int i = 0; i < nbColorsSamples(); i++) + { + data[i] = Q_UINT8_MAX - data[i]; + } + } + virtual void postProcess16bit( Q_UINT16* data ) + { + Q_UINT16* d = (Q_UINT16*) data; + for(int i = 0; i < nbColorsSamples(); i++) + { + d[i] = Q_UINT16_MAX - d[i]; + } + } + virtual void postProcess32bit( Q_UINT32* data ) + { + Q_UINT32* d = (Q_UINT32*) data; + for(int i = 0; i < nbColorsSamples(); i++) + { + d[i] = Q_UINT32_MAX - d[i]; + } + } +}; + +class KisTIFFPostProcessorICCLABtoCIELAB : public KisTIFFPostProcessor { + public: + KisTIFFPostProcessorICCLABtoCIELAB(uint8 nbcolorssamples) : KisTIFFPostProcessor(nbcolorssamples) {} + public: + void postProcess8bit(Q_UINT8* data) + { + Q_INT8* ds = (Q_INT8*) data; + for(int i = 1; i < nbColorsSamples(); i++) + { + ds[i] = data[i] - Q_UINT8_MAX/2; + } + } + void postProcess16bit(Q_UINT16* data) + { + Q_UINT16* d = (Q_UINT16*) data; + Q_INT16* ds = (Q_INT16*) data; + for(int i = 1; i < nbColorsSamples(); i++) + { + ds[i] = d[i] - Q_UINT16_MAX /2; + } + } + void postProcess32bit(Q_UINT32* data) + { + Q_UINT32* d = (Q_UINT32*) data; + Q_INT32* ds = (Q_INT32*) data; + for(int i = 1; i < nbColorsSamples(); i++) + { + ds[i] = d[i] - Q_UINT32_MAX /2; + } + } +}; + + +class KisTIFFReaderBase { + public: + KisTIFFReaderBase( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor) : m_device(device), m_alphapos(alphapos), m_sourceDepth(sourceDepth), m_nbcolorssamples(nbcolorssamples), m_nbextrasamples(extrasamplescount), m_poses(poses), m_transformProfile(transformProfile), m_postprocess(postprocessor) + { + + } + public: + /** + * This function copy data from the tiff stream to the paint device starting at the given position. + * @param x horizontal start position + * @param y vertical start position + * @param dataWidth width of the data to copy + * @param tiffstream source of data + * + * @return the number of line which were copied + */ + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) =0; + /** + * This function is called when all data has been read and should be used for any postprocessing. + */ + virtual void finalize() { }; + protected: + inline KisPaintDeviceSP paintDevice() { return m_device; } + inline Q_UINT8 alphaPos() { return m_alphapos; } + inline Q_UINT8 sourceDepth() { return m_sourceDepth; } + inline Q_UINT8 nbColorsSamples() { return m_nbcolorssamples; } + inline Q_UINT8 nbExtraSamples() { return m_nbextrasamples; } + inline Q_UINT8* poses() { return m_poses; } + inline cmsHTRANSFORM transform() { return m_transformProfile; } + inline KisTIFFPostProcessor* postProcessor() { return m_postprocess; } + private: + KisPaintDeviceSP m_device; + Q_UINT8 m_alphapos; + Q_UINT8 m_sourceDepth; + Q_UINT8 m_nbcolorssamples; + Q_UINT8 m_nbextrasamples; + Q_UINT8* m_poses; + cmsHTRANSFORM m_transformProfile; + KisTIFFPostProcessor* m_postprocess; + Q_UINT32 m_tiffDataWidth; +}; + +class KisTIFFReaderTarget8bit : public KisTIFFReaderBase { + public: + KisTIFFReaderTarget8bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor ) + { + + } + public: + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream); +}; + + +class KisTIFFReaderTarget16bit : public KisTIFFReaderBase { + public: + KisTIFFReaderTarget16bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor ) + { + + } + public: + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) ; +}; + +class KisTIFFReaderTarget32bit : public KisTIFFReaderBase { + public: + KisTIFFReaderTarget32bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor ) + { + + } + public: + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) ; +}; + +class KisTIFFReaderFromPalette : public KisTIFFReaderBase { + public: + KisTIFFReaderFromPalette( KisPaintDeviceSP device, uint16 *red, uint16 *green, uint16 *blue, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor ), m_red(red), m_green(green), m_blue(blue) + { + + } + public: + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) ; + private: + uint16 *m_red, *m_green, *m_blue; +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_stream.cc b/filters/krita/tiff/kis_tiff_stream.cc new file mode 100644 index 000000000..3d52d4dc7 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_stream.cc @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_stream.h" + +TIFFStreamContigBase::TIFFStreamContigBase( uint8* src, uint16 depth, uint32 lineSize ) : TIFFStreamBase(depth), m_src(src), m_lineSize(lineSize) { restart(); } + +void TIFFStreamContigBase::restart() +{ + m_srcit = m_src; + m_posinc = 8; +} + +void TIFFStreamContigBase::moveToLine(uint32 lineNumber) +{ + m_srcit = m_src + lineNumber * m_lineSize; + m_posinc = 8; +} + +uint32 TIFFStreamContigBelow16::nextValue() +{ + register uint8 remain; + register uint32 value; + remain = m_depth; + value = 0; + while (remain > 0) + { + register uint8 toread; + toread = remain; + if (toread > m_posinc) toread = m_posinc; + remain -= toread; + m_posinc -= toread; + value = (value << toread) | (( (*m_srcit) >> (m_posinc) ) & ( ( 1 << toread ) - 1 ) ); + if (m_posinc == 0) + { + m_srcit++; + m_posinc=8; + } + } + return value; +} + +uint32 TIFFStreamContigBelow32::nextValue() +{ + register uint8 remain; + register uint32 value; + remain = m_depth; + value = 0; + while (remain > 0) + { + register uint8 toread; + toread = remain; + if (toread > m_posinc) toread = m_posinc; + remain -= toread; + m_posinc -= toread; + value = (value) | ( (( (*m_srcit) >> (m_posinc) ) & ( ( 1 << toread ) - 1 ) ) << ( m_depth - 8 - remain ) ); + if (m_posinc == 0) + { + m_srcit++; + m_posinc=8; + } + } + return value; +} + +uint32 TIFFStreamContigAbove32::nextValue() +{ + register uint8 remain; + register uint32 value; + remain = m_depth; + value = 0; + while (remain > 0) + { + register uint8 toread; + toread = remain; + if (toread > m_posinc) toread = m_posinc; + remain -= toread; + m_posinc -= toread; + if(remain < 32 ) + { + value = (value) | ( (( (*m_srcit) >> (m_posinc) ) & ( ( 1 << toread ) - 1 ) ) << ( 24 - remain ) ); + } + if (m_posinc == 0) + { + m_srcit++; + m_posinc=8; + } + } + return value; +} + +TIFFStreamSeperate::TIFFStreamSeperate( uint8** srcs, uint8 nb_samples ,uint16 depth, uint32* lineSize) : TIFFStreamBase(depth), m_nb_samples(nb_samples) +{ + streams = new TIFFStreamContigBase*[nb_samples]; + if(depth < 16) + { + for(uint8 i = 0; i < m_nb_samples; i++) + { + streams[i] = new TIFFStreamContigBelow16(srcs[i], depth, lineSize[i]); + } + } else if( depth < 32 ) + { + for(uint8 i = 0; i < m_nb_samples; i++) + { + streams[i] = new TIFFStreamContigBelow32(srcs[i], depth, lineSize[i]); + } + } else { + for(uint8 i = 0; i < m_nb_samples; i++) + { + streams[i] = new TIFFStreamContigAbove32(srcs[i], depth, lineSize[i]); + } + } + restart(); +} + +TIFFStreamSeperate::~TIFFStreamSeperate() +{ + for(uint8 i = 0; i < m_nb_samples; i++) + { + delete streams[i]; + } + delete[] streams; +} + +uint32 TIFFStreamSeperate::nextValue() +{ + uint32 value = streams[ m_current_sample ]->nextValue(); + if( (++m_current_sample) >= m_nb_samples) + m_current_sample = 0; + return value; +} + +void TIFFStreamSeperate::restart() +{ + m_current_sample = 0; + for(uint8 i = 0; i < m_nb_samples; i++) + { + streams[i]->restart(); + } +} + +void TIFFStreamSeperate::moveToLine(uint32 lineNumber) +{ + for(uint8 i = 0; i < m_nb_samples; i++) + { + streams[i]->moveToLine(lineNumber); + } +} diff --git a/filters/krita/tiff/kis_tiff_stream.h b/filters/krita/tiff/kis_tiff_stream.h new file mode 100644 index 000000000..f203568e8 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_stream.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2005-2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef TIFFSTREAM_H_ +#define TIFFSTREAM_H_ + +#include + +class TIFFStreamBase { + public: + TIFFStreamBase( uint16 depth ) : m_depth(depth) {}; + virtual uint32 nextValue() =0; + virtual void restart() =0; + virtual void moveToLine(uint32 lineNumber) =0; + protected: + uint16 m_depth; +}; + +class TIFFStreamContigBase : public TIFFStreamBase { + public: + TIFFStreamContigBase( uint8* src, uint16 depth, uint32 lineSize ); + virtual void restart(); + virtual void moveToLine(uint32 lineNumber); + protected: + uint8* m_src; + uint8* m_srcit; + uint8 m_posinc; + uint32 m_lineSize; +}; + +class TIFFStreamContigBelow16 : public TIFFStreamContigBase { + public: + TIFFStreamContigBelow16( uint8* src, uint16 depth, uint32 lineSize ) : TIFFStreamContigBase(src, depth, lineSize) { } + public: + virtual uint32 nextValue(); +}; + +class TIFFStreamContigBelow32 : public TIFFStreamContigBase { + public: + TIFFStreamContigBelow32( uint8* src, uint16 depth, uint32 lineSize ) : TIFFStreamContigBase(src, depth, lineSize) { } + public: + virtual uint32 nextValue(); +}; + +class TIFFStreamContigAbove32 : public TIFFStreamContigBase { + public: + TIFFStreamContigAbove32( uint8* src, uint16 depth, uint32 lineSize ) : TIFFStreamContigBase(src, depth, lineSize) { } + public: + virtual uint32 nextValue(); +}; + + +class TIFFStreamSeperate : public TIFFStreamBase { + public: + TIFFStreamSeperate( uint8** srcs, uint8 nb_samples ,uint16 depth, uint32* lineSize); + ~TIFFStreamSeperate(); + virtual uint32 nextValue(); + virtual void restart(); + virtual void moveToLine(uint32 lineNumber); + private: + TIFFStreamContigBase** streams; + uint8 m_current_sample, m_nb_samples; +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_writer_visitor.cpp b/filters/krita/tiff/kis_tiff_writer_visitor.cpp new file mode 100644 index 000000000..64f7e2525 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_writer_visitor.cpp @@ -0,0 +1,237 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_writer_visitor.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "kis_tiff_converter.h" + +namespace { + bool writeColorSpaceInformation( TIFF* image, KisColorSpace * cs, uint16& color_type, uint16& sample_format ) + { + sample_format = SAMPLEFORMAT_UINT; + if ( cs->id() == KisID("GRAYA") || cs->id() == KisID("GRAYA16") ) + { + color_type = PHOTOMETRIC_MINISBLACK; + return true; + } + if ( cs->id() == KisID("RGBA") || cs->id() == KisID("RGBA16") ) + { + color_type = PHOTOMETRIC_RGB; + return true; + } + if ( cs->id() == KisID("RGBAF16HALF") || cs->id() == KisID("RGBAF32") ) + { + color_type = PHOTOMETRIC_RGB; + sample_format = SAMPLEFORMAT_IEEEFP; + return true; + } + if ( cs->id() == KisID("CMYK") || cs->id() == KisID("CMYKA16") ) + { + color_type = PHOTOMETRIC_SEPARATED; + TIFFSetField(image, TIFFTAG_INKSET, INKSET_CMYK); + return true; + } + if ( cs->id() == KisID("LABA") ) + { + color_type = PHOTOMETRIC_CIELAB; + return true; + } + + KMessageBox::error(0, i18n("Cannot export images in %1.\n").arg(cs->id().name()) ) ; + return false; + + } +} + +KisTIFFWriterVisitor::KisTIFFWriterVisitor(TIFF*img, KisTIFFOptions* options) : m_image(img), m_options(options) +{ +} + +KisTIFFWriterVisitor::~KisTIFFWriterVisitor() +{ +} + +bool KisTIFFWriterVisitor::saveAlpha() { return m_options->alpha; } + +bool KisTIFFWriterVisitor::copyDataToStrips( KisHLineIterator it, tdata_t buff, uint8 depth, uint8 nbcolorssamples, Q_UINT8* poses) +{ + if(depth == 32) + { + Q_UINT32 *dst = reinterpret_cast(buff); + while (!it.isDone()) { + const Q_UINT32 *d = reinterpret_cast(it.rawData()); + int i; + for(i = 0; i < nbcolorssamples; i++) + { + *(dst++) = d[poses[i]]; + } + if(saveAlpha()) *(dst++) = d[poses[i]]; + ++it; + } + return true; + } else if(depth == 16) + { + Q_UINT16 *dst = reinterpret_cast(buff); + while (!it.isDone()) { + const Q_UINT16 *d = reinterpret_cast(it.rawData()); + int i; + for(i = 0; i < nbcolorssamples; i++) + { + *(dst++) = d[poses[i]]; + } + if(saveAlpha()) *(dst++) = d[poses[i]]; + ++it; + } + return true; + } else if(depth == 8) { + Q_UINT8 *dst = reinterpret_cast(buff); + while (!it.isDone()) { + const Q_UINT8 *d = it.rawData(); + int i; + for(i = 0; i < nbcolorssamples; i++) + { + *(dst++) = d[poses[i]]; + } + if(saveAlpha()) *(dst++) = d[poses[i]]; + ++it; + } + return true; + } + return false; +} + + +bool KisTIFFWriterVisitor::visit(KisPaintLayer *layer) +{ + kdDebug(41008) << "visiting on paint layer " << layer->name() << "\n"; + KisPaintDeviceSP pd = layer->paintDevice(); + // Save depth + int depth = 8 * pd->pixelSize() / pd->nChannels(); + TIFFSetField(image(), TIFFTAG_BITSPERSAMPLE, depth); + // Save number of samples + if(saveAlpha()) + { + TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->nChannels()); + uint16 sampleinfo[1] = { EXTRASAMPLE_UNASSALPHA }; + TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 1, sampleinfo); + } else { + TIFFSetField(image(), TIFFTAG_SAMPLESPERPIXEL, pd->nChannels() - 1); + TIFFSetField(image(), TIFFTAG_EXTRASAMPLES, 0); + } + // Save colorspace information + uint16 color_type; + uint16 sample_format; + if(!writeColorSpaceInformation(image(), pd->colorSpace(), color_type, sample_format)) + { // unsupported colorspace + return false; + } + TIFFSetField(image(), TIFFTAG_PHOTOMETRIC, color_type); + TIFFSetField(image(), TIFFTAG_SAMPLEFORMAT, sample_format); + TIFFSetField(image(), TIFFTAG_IMAGEWIDTH, layer->image()->width()); + TIFFSetField(image(), TIFFTAG_IMAGELENGTH, layer->image()->height()); + + // Set the compression options + TIFFSetField(image(), TIFFTAG_COMPRESSION, m_options->compressionType); + TIFFSetField(image(), TIFFTAG_FAXMODE, m_options->faxMode); + TIFFSetField(image(), TIFFTAG_JPEGQUALITY, m_options->jpegQuality); + TIFFSetField(image(), TIFFTAG_ZIPQUALITY, m_options->deflateCompress); + TIFFSetField(image(), TIFFTAG_PIXARLOGQUALITY, m_options->pixarLogCompress); + + // Set the predictor + TIFFSetField(image(), TIFFTAG_PREDICTOR, m_options->predictor); + + // Use contiguous configuration + TIFFSetField(image(), TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + // Use 8 rows per strip + TIFFSetField(image(), TIFFTAG_ROWSPERSTRIP, 8); + + // Save profile + KisProfile* profile = pd->colorSpace()->getProfile(); + if(profile) + { + QByteArray ba = profile->annotation()->annotation(); + TIFFSetField(image(), TIFFTAG_ICCPROFILE, ba.size(),ba.data()); + } + tsize_t stripsize = TIFFStripSize(image()); + tdata_t buff = _TIFFmalloc(stripsize); + Q_INT32 height = layer->image()->height(); + Q_INT32 width = layer->image()->width(); + bool r = true; + for (int y = 0; y < height; y++) { + KisHLineIterator it = layer->paintDevice()->createHLineIterator(0, y, width, false); + switch(color_type) + { + case PHOTOMETRIC_MINISBLACK: + { + Q_UINT8 poses[]={ 0,1 }; + r = copyDataToStrips(it, buff, depth, 1, poses); + } + break; + case PHOTOMETRIC_RGB: + { + Q_UINT8 poses[]={ 2, 1, 0, 3}; + r = copyDataToStrips(it, buff, depth, 3, poses); + } + break; + case PHOTOMETRIC_SEPARATED: + { + Q_UINT8 poses[]={ 0, 1, 2, 3, 4 }; + r = copyDataToStrips(it, buff, depth, 4, poses); + } + break; + case PHOTOMETRIC_CIELAB: + { + Q_UINT8 poses[]={ 0, 1, 2, 3 }; + r = copyDataToStrips(it, buff, depth, 3, poses); + } + break; + return false; + } + if(!r) return false; + TIFFWriteScanline(image(), buff, y, (tsample_t) -1); + } + _TIFFfree(buff); + TIFFWriteDirectory(image()); + return true; +} +bool KisTIFFWriterVisitor::visit(KisGroupLayer *layer) +{ + kdDebug(41008) << "Visiting on grouplayer " << layer->name() << "\n"; + KisLayerSP child = layer->firstChild(); + while (child) { + child->accept(*this); + child = child->nextSibling(); + } + return true; +} + +bool KisTIFFWriterVisitor::visit(KisPartLayer *) +{ + return true; +} diff --git a/filters/krita/tiff/kis_tiff_writer_visitor.h b/filters/krita/tiff/kis_tiff_writer_visitor.h new file mode 100644 index 000000000..c05c8d785 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_writer_visitor.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_TIFF_WRITER_VISITOR_H +#define KIS_TIFF_WRITER_VISITOR_H + +#include + +#include + +#include + +class KisTIFFOptions; + +/** + @author Cyrille Berger +*/ +class KisTIFFWriterVisitor : public KisLayerVisitor +{ + public: + KisTIFFWriterVisitor(TIFF*img, KisTIFFOptions* options); + ~KisTIFFWriterVisitor(); + public: + virtual bool visit(KisPaintLayer *layer); + virtual bool visit(KisGroupLayer *layer); + virtual bool visit(KisPartLayer *layer); + virtual bool visit(KisAdjustmentLayer* ) { return true; } + private: + inline TIFF* image() { return m_image; } + inline bool saveAlpha(); + bool copyDataToStrips( KisHLineIterator it, tdata_t buff, uint8 depth, uint8 nbcolorssamples, Q_UINT8* poses); + private: + TIFF* m_image; + KisTIFFOptions* m_options; +}; + +#endif diff --git a/filters/krita/tiff/kis_tiff_ycbcr_reader.cc b/filters/krita/tiff/kis_tiff_ycbcr_reader.cc new file mode 100644 index 000000000..5609f8878 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_ycbcr_reader.cc @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "kis_tiff_ycbcr_reader.h" + +#include +#include + +#include "kis_tiff_stream.h" + + +KisTIFFYCbCrReaderTarget8Bit::KisTIFFYCbCrReaderTarget8Bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor), m_hsub(hsub), m_vsub(vsub), m_position(position) +{ + // Initialize the buffer + Q_INT32 imagewidth = device->image()->width(); + if(2*(imagewidth / 2) != imagewidth) imagewidth++; + m_bufferWidth = imagewidth / m_hsub; + Q_INT32 imageheight = device->image()->height(); + if(2*(imageheight / 2) != imageheight) imageheight++; + m_bufferHeight = imageheight / m_vsub; + m_bufferCb = new Q_UINT8[ m_bufferWidth * m_bufferHeight ]; + m_bufferCr = new Q_UINT8[ m_bufferWidth * m_bufferHeight ]; +} + +KisTIFFYCbCrReaderTarget8Bit::~KisTIFFYCbCrReaderTarget8Bit() +{ + delete[] m_bufferCb; + delete[] m_bufferCr; +} + +uint KisTIFFYCbCrReaderTarget8Bit::copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) +{ + int numcols = dataWidth / m_hsub; + double coeff = Q_UINT8_MAX / (double)( pow(2, sourceDepth() ) - 1 ); +// kdDebug(41008) << " depth expension coefficient : " << coeff << endl; +// kdDebug(41008) << " y = " << y << endl; + uint buffPos = y / m_vsub * m_bufferWidth + x / m_hsub ; + for(int index = 0; index < numcols; index++) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x + m_hsub * index, y, m_hsub, true); + for( int vindex = 0; vindex < m_vsub; vindex++) + { + while( !it.isDone() ) + { + Q_UINT8 *d = it.rawData(); + d[0] = (Q_UINT8)( tiffstream->nextValue() * coeff ); + d[3] = Q_UINT8_MAX; + for(int k = 0; k < nbExtraSamples(); k++) + { + if(k == alphaPos()) + d[3] = (Q_UINT32) ( tiffstream->nextValue() * coeff ); + else + tiffstream->nextValue(); + } + ++it; + } + it.nextRow(); + } + m_bufferCb[ buffPos ] = (Q_UINT8)(tiffstream->nextValue() * coeff); + m_bufferCr[ buffPos ] = (Q_UINT8)(tiffstream->nextValue() * coeff); + buffPos ++; + } + return m_vsub; +} + +void KisTIFFYCbCrReaderTarget8Bit::finalize() +{ + KisHLineIterator it = paintDevice() -> createHLineIterator(0, 0, paintDevice()->image()->width(), true); + for(int y = 0; y < paintDevice()->image()->height(); y++) + { + int x = 0; + while(!it.isDone()) + { + Q_UINT8 *d = it.rawData(); + int index = x/m_hsub + y/m_vsub * m_bufferWidth; + d[1] = m_bufferCb[ index ]; + d[2] = m_bufferCr[ index ]; + ++it; ++x; + } + it.nextRow(); + } +} + +KisTIFFYCbCrReaderTarget16Bit::KisTIFFYCbCrReaderTarget16Bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ) : KisTIFFReaderBase(device, poses, alphapos, sourceDepth, nbcolorssamples, extrasamplescount, transformProfile, postprocessor), m_hsub(hsub), m_vsub(vsub), m_position(position) +{ + // Initialize the buffer + Q_INT32 imagewidth = device->image()->width(); + if(2*(imagewidth / 2) != imagewidth) imagewidth++; + m_bufferWidth = imagewidth / m_hsub; + Q_INT32 imageheight = device->image()->height(); + if(2*(imageheight / 2) != imageheight) imageheight++; + m_bufferHeight = imageheight / m_vsub; + m_bufferCb = new Q_UINT16[ m_bufferWidth * m_bufferHeight ]; + m_bufferCr = new Q_UINT16[ m_bufferWidth * m_bufferHeight ]; +} + +KisTIFFYCbCrReaderTarget16Bit::~KisTIFFYCbCrReaderTarget16Bit() +{ + delete[] m_bufferCb; + delete[] m_bufferCr; +} + +uint KisTIFFYCbCrReaderTarget16Bit::copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream) +{ + int numcols = dataWidth / m_hsub; + double coeff = Q_UINT16_MAX / (double)( pow(2, sourceDepth() ) - 1 ); +// kdDebug(41008) << " depth expension coefficient : " << coeff << endl; +// kdDebug(41008) << " y = " << y << endl; + uint buffPos = y / m_vsub * m_bufferWidth + x / m_hsub ; + for(int index = 0; index < numcols; index++) + { + KisHLineIterator it = paintDevice() -> createHLineIterator(x + m_hsub * index, y, m_hsub, true); + for( int vindex = 0; vindex < m_vsub; vindex++) + { + while( !it.isDone() ) + { + Q_UINT16 *d = reinterpret_cast(it.rawData()); + d[0] = (Q_UINT16)( tiffstream->nextValue() * coeff ); + d[3] = Q_UINT16_MAX; + for(int k = 0; k < nbExtraSamples(); k++) + { + if(k == alphaPos()) + d[3] = (Q_UINT32) ( tiffstream->nextValue() * coeff ); + else + tiffstream->nextValue(); + } + ++it; + } + it.nextRow(); + } + m_bufferCb[ buffPos ] = (Q_UINT16)(tiffstream->nextValue() * coeff); + m_bufferCr[ buffPos ] = (Q_UINT16)(tiffstream->nextValue() * coeff); + buffPos ++; + } + return m_vsub; +} + +void KisTIFFYCbCrReaderTarget16Bit::finalize() +{ + KisHLineIterator it = paintDevice() -> createHLineIterator(0, 0, paintDevice()->image()->width(), true); + for(int y = 0; y < paintDevice()->image()->height(); y++) + { + int x = 0; + while(!it.isDone()) + { + Q_UINT16 *d = reinterpret_cast(it.rawData()); + int index = x/m_hsub + y/m_vsub * m_bufferWidth; + d[1] = m_bufferCb[ index ]; + d[2] = m_bufferCr[ index ]; + ++it; ++x; + } + it.nextRow(); + } +} diff --git a/filters/krita/tiff/kis_tiff_ycbcr_reader.h b/filters/krita/tiff/kis_tiff_ycbcr_reader.h new file mode 100644 index 000000000..b640228c6 --- /dev/null +++ b/filters/krita/tiff/kis_tiff_ycbcr_reader.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_TIFF_YCBCR_READER_H_ +#define _KIS_TIFF_YCBCR_READER_H_ + +#include "kis_tiff_reader.h" + +namespace KisTIFFYCbCr { + enum Position { + POSITION_CENTERED = 1, + POSITION_COSITED = 2 + }; +} + +class KisTIFFYCbCrReaderTarget8Bit : public KisTIFFReaderBase { + public: + /** + * @param hsub horizontal subsampling of Cb and Cr + * @param hsub vertical subsampling of Cb and Cr + */ + KisTIFFYCbCrReaderTarget8Bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ); + ~KisTIFFYCbCrReaderTarget8Bit(); + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream); + virtual void finalize(); + private: + Q_UINT8* m_bufferCb; + Q_UINT8* m_bufferCr; + Q_UINT32 m_bufferWidth, m_bufferHeight; + uint16 m_hsub; + uint16 m_vsub; + KisTIFFYCbCr::Position m_position; + +}; + +class KisTIFFYCbCrReaderTarget16Bit : public KisTIFFReaderBase { + public: + /** + * @param hsub horizontal subsampling of Cb and Cr + * @param hsub vertical subsampling of Cb and Cr + */ + KisTIFFYCbCrReaderTarget16Bit( KisPaintDeviceSP device, Q_UINT8* poses, int8 alphapos, uint8 sourceDepth, uint8 nbcolorssamples, uint8 extrasamplescount, cmsHTRANSFORM transformProfile, KisTIFFPostProcessor* postprocessor, uint16 hsub, uint16 vsub, KisTIFFYCbCr::Position position ); + ~KisTIFFYCbCrReaderTarget16Bit(); + virtual uint copyDataToChannels( Q_UINT32 x, Q_UINT32 y, Q_UINT32 dataWidth, TIFFStreamBase* tiffstream); + virtual void finalize(); + private: + Q_UINT16* m_bufferCb; + Q_UINT16* m_bufferCr; + Q_UINT32 m_bufferWidth, m_bufferHeight; + uint16 m_hsub; + uint16 m_vsub; + KisTIFFYCbCr::Position m_position; + +}; + + +#endif diff --git a/filters/krita/tiff/kis_wdg_options_tiff.ui b/filters/krita/tiff/kis_wdg_options_tiff.ui new file mode 100644 index 000000000..2e1f1c80c --- /dev/null +++ b/filters/krita/tiff/kis_wdg_options_tiff.ui @@ -0,0 +1,741 @@ + +KisWdgOptionsTIFF + + + KisWdgOptionsTIFF + + + + 0 + 0 + 452 + 267 + + + + + 1 + 1 + 0 + 0 + + + + Options of Your TIFF + + + + unnamed + + + 0 + + + + groupBox1 + + + + 1 + 1 + 0 + 0 + + + + TIFF Options + + + + unnamed + + + + layout10 + + + + unnamed + + + + textLabel1 + + + Compression type: + + + + + + None + + + + + JPEG DCT Compression + + + + + Deflate (ZIP) + + + + + Lempel-Ziv & Welch (LZW) + + + + + Leadtools JPEG2000 + + + + + CCITT Modified Huffman RLE + + + + + CCITT Group 3 Fax Encoding + + + + + CCITT Group 4 Fax Encoding + + + + + Pixar Log + + + + kComboBoxCompressionType + + + + + + + layout7 + + + + unnamed + + + + textLabel1_3 + + + Predictor: + + + + + + None + + + + + Horizontal Differencing + + + + + Floating Point Horizontal Differencing + + + + kComboBoxPredictor + + + 0 + + + Using a predictor can improve the compression (mostly for LZW and deflate) + + + + + + + alpha + + + Store alpha &channel (transparency) + + + true + + + Disable to get smaller files if your image has no transparancy + + + <p>The Portable Network Graphics (PNG) file format allows transparancy in your image to be stored by saving an alpha channel. +You can uncheck the box if you are not using transparancy and you want to make the resulting file smaller .<br>Always saving the alpha channel is recommended.</p> + + + + + flatten + + + + 3 + 3 + 0 + 0 + + + + Flatten the &image + + + true + + + This option will merge all layers. It is advisable to check this option, otherwise other applications might not be able to read your file correctly. + + + + + + + codecsOptionsStack + + + NoFrame + + + + WStackPage + + + 0 + + + + unnamed + + + 0 + + + 0 + + + + frame4 + + + NoFrame + + + Plain + + + + + + + WStackPage + + + 1 + + + + unnamed + + + 0 + + + 0 + + + + groupBoxJPEG + + + + 1 + 1 + 0 + 0 + + + + JPEG Compression Options + + + + unnamed + + + + textLabel1_2 + + + Quality: + + + AlignTop + + + + + layout5 + + + + unnamed + + + + qualityLevel + + + 0 + + + 100 + + + 1 + + + 1 + + + 80 + + + Horizontal + + + Both + + + 10 + + + These settings determine how much information is lost during compression + + + + + layout4_2 + + + + unnamed + + + + textLabel3 + + + Smallest + + + + + textLabel4 + + + Best + + + AlignVCenter|AlignRight + + + + + + + + + + + + + WStackPage + + + 2 + + + + unnamed + + + 0 + + + 0 + + + + groupBoxDeflate + + + + 1 + 1 + 0 + 0 + + + + Deflate Compression Options + + + + unnamed + + + + textLabel1_4 + + + Compress: + + + AlignTop + + + Note: the compression level does not change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level does not change the quality of the result.</p> + + + + + layout5_2 + + + + unnamed + + + + compressionLevelDeflate + + + 1 + + + 9 + + + 1 + + + 6 + + + Horizontal + + + Both + + + Note: the compression level doesn't change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + layout4 + + + + unnamed + + + + textLabel3_2 + + + Fast + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + textLabel4_2 + + + Small + + + AlignVCenter|AlignRight + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + + + + + + + + + WStackPage + + + 3 + + + + unnamed + + + 0 + + + 0 + + + + groupBoxCCITGroupCCITG3 + + + + 1 + 1 + 0 + 0 + + + + CCITT Group 3 fax encoding Options + + + + unnamed + + + + textLabel2 + + + Fax mode: + + + + + + Classic + + + + + No RTC + + + + + No EOL + + + + kComboBoxFaxMode + + + + + + + + + WStackPage + + + 4 + + + + unnamed + + + 0 + + + 0 + + + + groupBoxPixarLog + + + + 1 + 1 + 0 + 0 + + + + Pixar Log Compression Options + + + + unnamed + + + + textLabel1_4_2 + + + Compress: + + + AlignTop + + + Note: the compression level does not change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level does not change the quality of the result.</p> + + + + + layout5_2_2 + + + + unnamed + + + + compressionLevelPixarLog + + + 1 + + + 9 + + + 1 + + + 6 + + + Horizontal + + + Both + + + Note: the compression level doesn't change the quality of the result + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + layout4_3 + + + + unnamed + + + + textLabel3_2_2 + + + Fast + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + textLabel4_2_2 + + + Small + + + AlignVCenter|AlignRight + + + <p>Adjust the compression time. Better compression takes longer. +<br>Note: the compression level doesn't change the quality of the result.</p> + + + + + + + + + + + + + + spacer3 + + + Vertical + + + Expanding + + + + 20 + 16 + + + + + + + + + kComboBoxCompressionType + kComboBoxPredictor + alpha + flatten + qualityLevel + compressionLevelDeflate + kComboBoxFaxMode + compressionLevelPixarLog + + + + kcombobox.h + kcombobox.h + kcombobox.h + + diff --git a/filters/krita/tiff/kis_ycbcr_colorspace.h b/filters/krita/tiff/kis_ycbcr_colorspace.h new file mode 100644 index 000000000..0b4ece872 --- /dev/null +++ b/filters/krita/tiff/kis_ycbcr_colorspace.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2006 Cyrille Berger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#ifndef KIS_YCBCR_COLORSPACE_H +#define KIS_YCBCR_COLORSPACE_H +namespace { + const Q_INT32 MAX_CHANNEL_YCbCr = 3; + const Q_INT32 MAX_CHANNEL_YCbCrA = 4; +} +#endif + diff --git a/filters/krita/tiff/krita_tiff.desktop b/filters/krita/tiff/krita_tiff.desktop new file mode 100644 index 000000000..455f6caa2 --- /dev/null +++ b/filters/krita/tiff/krita_tiff.desktop @@ -0,0 +1,63 @@ +[Desktop Entry] +Categories= +Exec=krita %u +GenericName=Painting and Image Editing Application +GenericName[bg]=Редактор на графични изображения +GenericName[ca]=Programa de dibuix i manipulació d'imatges +GenericName[cs]=Malování a úpravy obrázků +GenericName[cy]=Cymhwysiad Peintio Golygu Delweddau +GenericName[da]=Male- og billedredigeringsprogram +GenericName[de]=Mal- und Bildbearbeitungsprogramm +GenericName[el]=Εφαρμογή επεξεργασίας εικόνων +GenericName[eo]=Aplikaĵo por Pentrado kaj Bildredaktado +GenericName[es]=Aplicación de pintura y de edición de imágenes +GenericName[et]=Joonistamise ja pilditöötluse rakendus +GenericName[eu]=Irudien marrazketa eta ediziorako aplikazioa +GenericName[fa]=کاربرد ویرایش تصویر و نقاشی +GenericName[fi]=Maalaus- ja kuvankäsitelyohjelma +GenericName[fr]=Application de dessin et de manipulation d'images +GenericName[fy]=Ofbyldingsmanipulaasje +GenericName[gl]=Aplicación de Pintura e Manipulación de Imaxes +GenericName[he]=יישום לציור ועריכת תמונות +GenericName[hr]=Aplikacija za obradu slika i fotografija +GenericName[hu]=Képszerkesztő +GenericName[is]=Málun og myndritill +GenericName[it]=Applicazione di disegno e di modifica delle immagini +GenericName[ja]=描画と画像編集のためのアプリケーション +GenericName[km]=កម្មវិធី​គូរ​គំនូរ និង​កែសម្រួល​រូបភាព +GenericName[lv]=Zīmēšanas un attēlu apstrādes programma +GenericName[nb]=Program for tegning og bilderedigering +GenericName[nds]=Programm för't Malen un Bildbewerken +GenericName[ne]=पेन्टीङ्ग र छवि सम्पादन अनुप्रयोग +GenericName[nl]=Afbeeldingsmanipulatie +GenericName[pl]=Program do edycji zdjęć oraz rysunków +GenericName[pt]=Aplicação de Pintura e Edição de Imagens +GenericName[pt_BR]=Aplicação de Pintura e Edição de Imagens +GenericName[ru]=Растровые изображения +GenericName[se]=Málen- ja govvagieđahallanprográmma +GenericName[sk]=Program pre tvorbu a úpravu obrázkov +GenericName[sl]=Program za risanje in obdelavo slik +GenericName[sr]=Програм за цртање и уређивање слика +GenericName[sr@Latn]=Program za crtanje i uređivanje slika +GenericName[sv]=Målnings- och bildredigeringsprogram +GenericName[uk]=Програма для малювання і редагування зображень +GenericName[uz]=Rasmlar bilan ishlaydigan dastur +GenericName[uz@cyrillic]=Расмлар билан ишлайдиган дастур +GenericName[zh_CN]=绘图和图像编辑应用程序 +GenericName[zh_TW]=繪圖與影像處理程式 +Icon=krita +MimeType=image/tiff +Name=Krita +Name[hi]=के-रिता +Name[km]= Krita +Name[lo]=ກຣິຕາ +Name[ne]=क्रिता +Path= +StartupNotify=true +Terminal=false +TerminalOptions= +Type=Application +X-DCOP-ServiceType=multi +X-KDE-StartupNotify=true +X-KDE-SubstituteUID=false +X-KDE-Username= diff --git a/filters/krita/tiff/krita_tiff_export.desktop b/filters/krita/tiff/krita_tiff_export.desktop new file mode 100644 index 000000000..e696cd5a6 --- /dev/null +++ b/filters/krita/tiff/krita_tiff_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Icon= +Name=Krita TIFF Export Filter +Name[bg]=Филтър за експортиране от Krita в TIFF +Name[br]=Sil ezporzh TIFF evit Krita +Name[ca]=Filtre d'exportació TIFF per a Krita +Name[da]=Krita TIFF-eksportfilter +Name[de]=Krita TIFF-Exportfilter +Name[el]=Φίλτρο εξαγωγής TIFF του Krita +Name[eo]=Krita TIFF-eksportfiltrilo +Name[es]=Filtro de exportación a TIFF de Krita +Name[et]=Krita TIFF-i ekspordifilter +Name[fa]=پالایۀ صادرات Krita TIFF +Name[fi]=Krita TIFF -vientisuodin +Name[fr]=Filtre d'exportation TIFF de Krita +Name[fy]=Krita TIFF Eksportfilter +Name[ga]=Scagaire Easpórtála TIFF Krita +Name[gl]=Filtro de Exportación de TIFF para Krita +Name[he]=Krita TIFF מסנן יצוא +Name[hr]=Krita TIFF filtar izvoza +Name[hu]=Krita TIFF exportszűrő +Name[is]=Krita TIFF útflutningssía +Name[it]=Filtro di esportazione TIFF per Krita +Name[ja]=Krita TIFF エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ TIFF សម្រាប់ Krita +Name[lt]=Krita TIFF eksportavimo filtras +Name[lv]=Krita TIFF eksporta filtrs +Name[nb]=TIFF-eksportfilter for Krita +Name[nds]=TIFF-Exportfilter för Krita +Name[ne]=क्रिता TIFF निर्यात फिल्टर +Name[nl]=Krita TIFF Exportfilter +Name[pl]=Filtr eksportu do formatu TIFF dla Krita +Name[pt]=Filtro de Exportação de TIFF para o Krita +Name[pt_BR]=Filtro de Exportação de TIFF para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в TIFF +Name[se]=Krita Tiff-olggosfievrridansilli +Name[sk]=Exportný filter Krita TIFF +Name[sl]=Izvozni filter TIFF za Krito +Name[sr]=Krita-ин филтер за извоз у TIFF +Name[sr@Latn]=Krita-in filter za izvoz u TIFF +Name[sv]=Krita TIFF-exportfilter +Name[uk]=Фільтр експорту TIFF для Krita +Name[uz]=Krita TIFF eksport filteri +Name[uz@cyrillic]=Krita TIFF экспорт филтери +Name[zh_CN]=Krita TIFF 导出过滤器 +Name[zh_TW]=Krita TIFF 匯出過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=image/tiff +X-KDE-Import=application/x-krita +X-KDE-Library=libkritatiffexport +X-KDE-Weight=1 diff --git a/filters/krita/tiff/krita_tiff_import.desktop b/filters/krita/tiff/krita_tiff_import.desktop new file mode 100644 index 000000000..65e7ae6c2 --- /dev/null +++ b/filters/krita/tiff/krita_tiff_import.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Icon= +Name=Krita TIFF Import Filter +Name[bg]=Филтър за импортиране от TIFF в Krita +Name[br]=Sil enporzh TIFF evit Krita +Name[ca]=Filtre d'importació TIFF per a Krita +Name[da]=Krita TIFF-importfilter +Name[de]=Krita TIFF-Importfilter +Name[el]=Φίλτρο εισαγωγής TIFF του Krita +Name[eo]=Krita TIFF-importfiltrilo +Name[es]=Filtro de importación desde TIFF de Krita +Name[et]=Krita TIFF-i impordifilter +Name[fa]=پالایۀ واردات Krita TIFF +Name[fi]=Krita TIFF -tuontisuodin +Name[fr]=Filtre d'importation TIFF de Krita +Name[fy]=Krita TIFF Ymportfilter +Name[ga]=Scagaire Iompórtála TIFF Krita +Name[gl]=Filtro de Importación de TIFF para Krita +Name[he]=Krita TIFF מסנן יבוא +Name[hr]=Krita TIFF filtar uvoza +Name[hu]=Krita TIFF importszűrő +Name[is]=Krita TIFF innflutningssía +Name[it]=Filtro di importazione TIFF per Krita +Name[ja]=Krita TIFF インポートフィルタ +Name[km]=តម្រង​នាំចូល TIFF សម្រាប់ Krita +Name[lt]=Krita TIFF importavimo filtras +Name[lv]=Krita TIFF importa filtrs +Name[nb]=TIFF-importfilter for Krita +Name[nds]=TIFF-Importfilter för Krita +Name[ne]=क्रिता TIFF आयात फिल्टर +Name[nl]=Krita TIFF Importfilter +Name[pl]=Filtr importu formatu TIFF dla Krita +Name[pt]=Filtro de Importação de TIFF para o Krita +Name[pt_BR]=Filtro de Importação de TIFF para o Krita +Name[ru]=Фильтр импорта рисунков TIFF в Krita +Name[se]=Krita TIFF-sisafievrridansilli +Name[sk]=TIFF filter pre import do Krita +Name[sl]=Uvozni filter TIFF za Krito +Name[sr]=Krita-ин филтер за увоз из TIFF-а +Name[sr@Latn]=Krita-in filter za uvoz iz TIFF-a +Name[sv]=Krita TIFF-importfilter +Name[uk]=Фільтр імпорту TIFF для Krita +Name[uz]=Krita TIFF import filteri +Name[uz@cyrillic]=Krita TIFF импорт филтери +Name[zh_CN]=Krita TIFF 导入过滤器 +Name[zh_TW]=Krita TIFF 匯入過濾程式 +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Export=application/x-krita +X-KDE-Import=image/tiff +X-KDE-Library=libkritatiffimport +X-KDE-Weight=1 diff --git a/filters/krita/xcf/Makefile.am b/filters/krita/xcf/Makefile.am new file mode 100644 index 000000000..7443abb3b --- /dev/null +++ b/filters/krita/xcf/Makefile.am @@ -0,0 +1,38 @@ +kde_module_LTLIBRARIES = libkritaxcfimport.la libkritaxcfexport.la + +libkritaxcfexport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritaxcfexport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +libkritaxcfimport_la_LDFLAGS = $(KDE_PLUGIN) $(LIBMAGICK_LDFLAGS) $(KDE_RPATH) $(LIBMAGICK_RPATH) $(all_libraries) -module -avoid-version -no-undefined +libkritaxcfimport_la_LIBADD = \ + $(KOFFICE_LIBS) \ + $(LIBMAGICK_LIBS) \ + $(top_builddir)/krita/libkritacommon.la + +INCLUDES= \ + -I$(srcdir) \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/krita \ + -I$(top_srcdir)/krita/core \ + -I$(top_srcdir)/krita/sdk \ + -I$(top_srcdir)/krita/core/tiles \ + -I$(top_srcdir)/krita/kritacolor \ + -I$(top_srcdir)/krita/ui \ + $(KOFFICE_INCLUDES) -I$(interfacedir) \ + $(KOPAINTER_INCLUDES) $(LIBMAGICK_CPPFLAGS) \ + $(all_includes) + +service_DATA = krita_xcf_import.desktop krita_xcf_export.desktop +servicedir = $(kde_servicesdir) + +libkritaxcfimport_la_SOURCES = xcfimport.cpp +libkritaxcfexport_la_SOURCES = xcfexport.cpp + +METASOURCES = AUTO + +SUBDIRS=xcf + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) diff --git a/filters/krita/xcf/krita_xcf_export.desktop b/filters/krita/xcf/krita_xcf_export.desktop new file mode 100644 index 000000000..f4cde2ecf --- /dev/null +++ b/filters/krita/xcf/krita_xcf_export.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Name=Krita XCF Export Filter +Name[bg]=Филтър за експортиране от Krita в XCF +Name[br]=Sil ezporzh XCF evit Krita +Name[ca]=Filtre d'exportació XCF per a Krita +Name[cy]=Hidl Allforio XCF Krita +Name[da]=Krita XCF-eksportfilter +Name[de]=Krita XCF-Exportfilter +Name[el]=Φίλτρο εξαγωγής XCF του Krita +Name[eo]=Krita XCF-importfiltrilo +Name[es]=Filtro de exportación a XCF de Krita +Name[et]=Krita XCF-i ekspordifilter +Name[fa]=پالایۀ صادرات Krita XCF +Name[fi]=Krita XCF -vientisuodin +Name[fr]=Filtre d'exportation XCF de Krita +Name[fy]=Krita XCF Eksportfilter +Name[ga]=Scagaire Easpórtála XCF Krita +Name[gl]=Filtro de Exportación de XCF para Krita +Name[he]=Krita XCF מסנן יצוא +Name[hr]=Krita XCF filtar izvoza +Name[hu]=Krita XCF exportszűrő +Name[is]=Krita XCF útflutningssía +Name[it]=Filtro di esportazione XCF per Krita +Name[ja]=Krita XCF エクスポートフィルタ +Name[km]=តម្រង​នាំចេញ XCF សម្រាប់ Krita +Name[lt]=Krita XCF eksportavimo filtras +Name[lv]=Krita XCF eksporta filtrs +Name[nb]=XCF-eksportfilter for Krita +Name[nds]=XCF-Exportfilter för Krita +Name[ne]=क्रिता XFC निर्यात फिल्टर +Name[nl]=Krita XCF Exportfilter +Name[pl]=Filtr eksportu do formatu XCF dla Krita +Name[pt]=Filtro de Exportação de XCF para o Krita +Name[pt_BR]=Filtro de Exportação de XCF para o Krita +Name[ru]=Фильтр экспорта рисунков Krita в XCF +Name[se]=Krita XCF-olggosfievrridansilli +Name[sk]=Exportný filter Krita XCF +Name[sl]=Izvozni filter XCF za Krito +Name[sr]=Krita-ин филтер за извоз у XCF +Name[sr@Latn]=Krita-in filter za izvoz u XCF +Name[sv]=Krita XCF-exportfilter +Name[uk]=Фільтр експорту XCF для Krita +Name[uz]=Krita XCF eksport filteri +Name[uz@cyrillic]=Krita XCF экспорт филтери +Name[zh_CN]=Krita XCF 导出过滤器 +Name[zh_TW]=Krita XCF 匯出過濾程式 +X-KDE-Export=image/x-xcf-gimp +ServiceTypes=KOfficeFilter +Type=Service +X-KDE-Import=application/x-krita +X-KDE-Weight=1 +X-KDE-Library=libkritaxcfexport diff --git a/filters/krita/xcf/krita_xcf_import.desktop b/filters/krita/xcf/krita_xcf_import.desktop new file mode 100644 index 000000000..7edbcf2c9 --- /dev/null +++ b/filters/krita/xcf/krita_xcf_import.desktop @@ -0,0 +1,52 @@ +[Desktop Entry] +Type=Service +Name=Krita XCF Import Filter +Name[bg]=Филтър за импортиране от XCF в Krita +Name[br]=Sil enporzh XCF evit Krita +Name[ca]=Filtre d'importació XCF per a Krita +Name[cy]=Hidl Mewnforio XCF Krita +Name[da]=Krita XCF-importfilter +Name[de]=Krita XCF-Importfilter +Name[el]=Φίλτρο εισαγωγής XCF του Krita +Name[eo]=Krita XCF-importfiltrilo +Name[es]=Filtro de importación a XCF de Krita +Name[et]=Krita XCF-i impordifilter +Name[fa]=پالایۀ واردات Krita XCF +Name[fi]=Krita XCF -tuontisuodin +Name[fr]=Filtre d'importation XCF de Krita +Name[fy]=Krita XCF Ymportfilter +Name[ga]=Scagaire Iompórtála XCF Krita +Name[gl]=Filtro de Importación de XCF para Krita +Name[he]=Krita XCF מסנן יבוא +Name[hr]=Krita XCF filtar uvoza +Name[hu]=Krita XCF importszűrő +Name[is]=Krita XCF innflutningssía +Name[it]=Filtro di importazione XCF per Krita +Name[ja]=Krita XCF インポートフィルタ +Name[km]=តម្រង​នាំចូល XCF សម្រាប់ Krita +Name[lt]=Krita XCF importavimo filtras +Name[lv]=Krita XCF importa filtrs +Name[nb]=XCF-importfilter for Krita +Name[nds]=XCF-Importfilter för Krita +Name[ne]=क्रिता XCF आयात फिल्टर +Name[nl]=Krita XCF Importfilter +Name[pl]=Filtr importu formatu XCF dla Krita +Name[pt]=Filtro de Importação de XCF para o Krita +Name[pt_BR]=Filtro de Importação de XCF para o Krita +Name[ru]=Фильтр импорта рисунков XCF в Krita +Name[se]=Krita XCF-sisafievrridansilli +Name[sk]=XCF filter pre import do Krita +Name[sl]=Uvozni filter XCF za Krito +Name[sr]=Krita-ин филтер за увоз из XCF-а +Name[sr@Latn]=Krita-in filter za uvoz iz XCF-a +Name[sv]=Krita XCF-importfilter +Name[uk]=Фільтр імпорту XCF для Krita +Name[uz]=Krita XCF import filteri +Name[uz@cyrillic]=Krita XCF импорт филтери +Name[zh_CN]=Krita XCF 导入过滤器 +Name[zh_TW]=Krita XCF 匯入過濾程式 +X-KDE-Export=application/x-krita +X-KDE-Import=image/x-xcf-gimp +X-KDE-Weight=1 +X-KDE-Library=libkritaxcfimport +ServiceTypes=KOfficeFilter diff --git a/filters/krita/xcf/xcf/README b/filters/krita/xcf/xcf/README new file mode 100644 index 000000000..567d2ab1b --- /dev/null +++ b/filters/krita/xcf/xcf/README @@ -0,0 +1,2 @@ +Note: this is source copy of 6 feb. 2006; when updated, use a diff from the gimp cvs +to check for changes in their file format. diff --git a/filters/krita/xcf/xcf/xcf-load.cc b/filters/krita/xcf/xcf/xcf-load.cc new file mode 100644 index 000000000..dded68833 --- /dev/null +++ b/filters/krita/xcf/xcf/xcf-load.cc @@ -0,0 +1,1740 @@ +/* The GIMP -- an image manipulation program + * Copyright (C) 1995 Spencer Kimball and Peter Mattis + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "config.h" + +#include +#include /* strcmp, memcmp */ + +//#include + +//#include "libgimpbase/gimpbase.h" +//#include "libgimpcolor/gimpcolor.h" + +//#include "core/core-types.h" + +//#include "base/tile.h" +//#include "base/tile-manager.h" +//#include "base/tile-manager-private.h" + +//#include "config/gimpcoreconfig.h" + +//#include "core/gimp.h" +//#include "core/gimpcontainer.h" +//#include "core/gimpdrawable.h" +//#include "core/gimpgrid.h" +//#include "core/gimpimage.h" +//#include "core/gimpimage-grid.h" +//#include "core/gimpimage-guides.h" +//#include "core/gimplayer.h" +//#include "core/gimplayer-floating-sel.h" +//#include "core/gimplayermask.h" +//#include "core/gimpparasitelist.h" +//#include "core/gimpselection.h" +//#include "core/gimptemplate.h" +//#include "core/gimpunit.h" + +//#include "text/gimptextlayer.h" +//#include "text/gimptextlayer-xcf.h" + +//#include "vectors/gimpanchor.h" +//#include "vectors/gimpstroke.h" +//#include "vectors/gimpbezierstroke.h" +//#include "vectors/gimpvectors.h" +//#include "vectors/gimpvectors-compat.h" + +#include "xcf-private.h" +#include "xcf-load.h" +#include "xcf-read.h" +#include "xcf-seek.h" + +//#include "gimp-intl.h" + +static bool xcf_load_image_props (XcfInfo * info, KisImage * gimage); +static bool xcf_load_layer_props (XcfInfo * info, + KisImage * gimage, + KisLayer * layer, + bool * apply_mask, + bool * edit_mask, + bool * show_mask, + Q_INT32 * text_layer_flags); +static bool xcf_load_channel_props (XcfInfo * info, + KisImage * gimage, + GimpChannel ** channel); +static bool xcf_load_prop (XcfInfo * info, + PropType * prop_type, Q_INT32 * prop_size); +static KisLayer *xcf_load_layer (XcfInfo * info, KisImage * gimage); +//static GimpChannel * xcf_load_channel (XcfInfo *info, +// KisImage *gimage); +//static GimpLayerMask * xcf_load_layer_mask (XcfInfo *info, +// KisImage *gimage); +static bool xcf_load_hierarchy (XcfInfo * info, TileManager * tiles); +static bool xcf_load_level (XcfInfo * info, TileManager * tiles); +static bool xcf_load_tile (XcfInfo * info, Tile * tile); +static bool xcf_load_tile_rle (XcfInfo * info, + Tile * tile, Q_INT32 data_length); +//static GimpParasite * xcf_load_parasite (XcfInfo *info); +static bool xcf_load_old_paths (XcfInfo * info, KisImage * gimage); +static bool xcf_load_old_path (XcfInfo * info, KisImage * gimage); +static bool xcf_load_vectors (XcfInfo * info, KisImage * gimage); +static bool xcf_load_vector (XcfInfo * info, KisImage * gimage); + +#ifdef SWAP_FROM_FILE +static bool xcf_swap_func (Q_INT32 fd, + Tile * tile, Q_INT32 cmd, gpointer user_data); +#endif + + +KisImage * +xcf_load_image (XcfInfo * info) +{ + KisImage *gimage; + KisLayer *layer; + //GimpChannel *channel; + //KisAnnotation *parasite; + Q_INT32 saved_pos; + Q_INT32 offset; + Q_INT32 width; + Q_INT32 height; + Q_INT32 image_type; + Q_INT32 num_successful_elements = 0; + + /* read in the image width, height and type */ + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & width, 1); + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & height, 1); + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & image_type, 1); + + gimage = gimp_create_image (gimp, width, height, image_type, FALSE); + + gimp_image_undo_disable (gimage); + + /* read the image properties */ + if (!xcf_load_image_props (info, gimage)) + goto hard_error; + + /* check for a GimpGrid parasite */ + parasite = gimp_image_parasite_find (GIMP_IMAGE (gimage), + gimp_grid_parasite_name ()); + if (parasite) + { + GimpGrid *grid = gimp_grid_from_parasite (parasite); + + if (grid) + { + gimp_parasite_list_remove (GIMP_IMAGE (gimage)->parasites, + gimp_parasite_name (parasite)); + + gimp_image_set_grid (GIMP_IMAGE (gimage), grid, FALSE); + } + } + + while (TRUE) + { + /* read in the offset of the next layer */ + info->cp += xcf_read_int32 (info->fp, &offset, 1); + + /* if the offset is 0 then we are at the end + * of the layer list. + */ + if (offset == 0) + break; + + /* save the current position as it is where the + * next layer offset is stored. + */ + saved_pos = info->cp; + + /* seek to the layer offset */ + if (!xcf_seek_pos (info, offset, NULL)) + goto error; + + /* read in the layer */ + layer = xcf_load_layer (info, gimage); + if (!layer) + goto error; + + num_successful_elements++; + + /* add the layer to the image if its not the floating selection */ + if (layer != info->floating_sel) + gimp_image_add_layer (gimage, layer, + gimp_container_num_children (gimage->layers)); + + /* restore the saved position so we'll be ready to + * read the next offset. + */ + if (!xcf_seek_pos (info, saved_pos, NULL)) + goto error; + } + + while (TRUE) + { + /* read in the offset of the next channel */ + info->cp += xcf_read_int32 (info->fp, &offset, 1); + + /* if the offset is 0 then we are at the end + * of the channel list. + */ + if (offset == 0) + break; + + /* save the current position as it is where the + * next channel offset is stored. + */ + saved_pos = info->cp; + + /* seek to the channel offset */ + if (!xcf_seek_pos (info, offset, NULL)) + goto error; + + /* read in the layer */ + channel = xcf_load_channel (info, gimage); + if (!channel) + goto error; + + num_successful_elements++; + + /* add the channel to the image if its not the selection */ + if (channel != gimage->selection_mask) + gimp_image_add_channel (gimage, channel, -1); + + /* restore the saved position so we'll be ready to + * read the next offset. + */ + if (!xcf_seek_pos (info, saved_pos, NULL)) + goto error; + } + + if (info->floating_sel && info->floating_sel_drawable) + floating_sel_attach (info->floating_sel, info->floating_sel_drawable); + + if (info->active_layer) + gimp_image_set_active_layer (gimage, info->active_layer); + + if (info->active_channel) + gimp_image_set_active_channel (gimage, info->active_channel); + + gimp_image_set_filename (gimage, info->filename); + + if (info->tattoo_state > 0) + gimp_image_set_tattoo_state (gimage, info->tattoo_state); + + gimp_image_undo_enable (gimage); + + return gimage; + +error: + if (num_successful_elements == 0) + goto hard_error; + + g_message ("XCF: This file is corrupt! I have loaded as much\n" + "of it as I can, but it is incomplete."); + + gimp_image_undo_enable (gimage); + + return gimage; + +hard_error: + g_message ("XCF: This file is corrupt! I could not even\n" + "salvage any partial image data from it."); + + g_object_unref (gimage); + + return NULL; +} + +static bool +xcf_load_image_props (XcfInfo * info, KisImage * gimage) +{ + PropType prop_type; + Q_INT32 prop_size; + + while (TRUE) + { + if (!xcf_load_prop (info, &prop_type, &prop_size)) + return FALSE; + + switch (prop_type) + { + case PROP_END: + return TRUE; + + case PROP_COLORMAP: + if (info->file_version == 0) + { + Q_INT32 i; + + g_message (_("XCF warning: version 0 of XCF file format\n" + "did not save indexed colormaps correctly.\n" + "Substituting grayscale map.")); + info->cp += + xcf_read_int32 (info->fp, (Q_INT32 *) & gimage->num_cols, 1); + gimage->cmap = g_new (guchar, gimage->num_cols * 3); + if (!xcf_seek_pos (info, info->cp + gimage->num_cols, NULL)) + return FALSE; + + for (i = 0; i < gimage->num_cols; i++) + { + gimage->cmap[i * 3 + 0] = i; + gimage->cmap[i * 3 + 1] = i; + gimage->cmap[i * 3 + 2] = i; + } + } + else + { + info->cp += + xcf_read_int32 (info->fp, (Q_INT32 *) & gimage->num_cols, 1); + gimage->cmap = g_new (guchar, gimage->num_cols * 3); + info->cp += + xcf_read_int8 (info->fp, + (Q_UINT8 *) gimage->cmap, + gimage->num_cols * 3); + } + + /* discard color map, if image is not indexed, this is just + * sanity checking to make sure gimp doesn't end up with an + * image state that is impossible. + */ + if (gimp_image_base_type (gimage) != GIMP_INDEXED) + { + g_free (gimage->cmap); + gimage->cmap = NULL; + gimage->num_cols = 0; + } + break; + + case PROP_COMPRESSION: + { + Q_UINT8 compression; + + info->cp += + xcf_read_int8 (info->fp, (Q_UINT8 *) & compression, 1); + + if ((compression != COMPRESS_NONE) && + (compression != COMPRESS_RLE) && + (compression != COMPRESS_ZLIB) && + (compression != COMPRESS_FRACTAL)) + { + g_message ("unknown compression type: %d", (int) compression); + return FALSE; + } + + info->compression = compression; + } + break; + + case PROP_GUIDES: + { + Q_INT3232 position; + Q_INT328 orientation; + Q_INT32 i, nguides; + + nguides = prop_size / (4 + 1); + for (i = 0; i < nguides; i++) + { + info->cp += + xcf_read_int32 (info->fp, (Q_INT32 *) & position, 1); + info->cp += + xcf_read_int8 (info->fp, (Q_UINT8 *) & orientation, 1); + + /* skip -1 guides from old XCFs */ + if (position < 0) + continue; + + switch (orientation) + { + case XCF_ORIENTATION_HORIZONTAL: + gimp_image_add_hguide (gimage, position, FALSE); + break; + + case XCF_ORIENTATION_VERTICAL: + gimp_image_add_vguide (gimage, position, FALSE); + break; + + default: + g_message ("guide orientation out of range in XCF file"); + continue; + } + } + + /* this is silly as the order of guides doesn't really matter, + * but it restores the list to it's original order, which + * cannot be wrong --Mitch + */ + gimage->guides = g_list_reverse (gimage->guides); + } + break; + + case PROP_RESOLUTION: + { + float xres, yres; + + info->cp += xcf_read_float (info->fp, &xres, 1); + info->cp += xcf_read_float (info->fp, &yres, 1); + if (xres < GIMP_MIN_RESOLUTION || xres > GIMP_MAX_RESOLUTION || + yres < GIMP_MIN_RESOLUTION || yres > GIMP_MAX_RESOLUTION) + { + g_message ("Warning, resolution out of range in XCF file"); + xres = gimage->gimp->config->default_image->xresolution; + yres = gimage->gimp->config->default_image->yresolution; + } + gimage->xresolution = xres; + gimage->yresolution = yres; + } + break; + + case PROP_TATTOO: + { + info->cp += xcf_read_int32 (info->fp, &info->tattoo_state, 1); + } + break; + + case PROP_PARASITES: + { + glong base = info->cp; + KisAnnotation *p; + + while (info->cp - base < prop_size) + { + p = xcf_load_parasite (info); + gimp_image_parasite_attach (gimage, p); + gimp_parasite_free (p); + } + if (info->cp - base != prop_size) + g_message ("Error while loading an image's parasites"); + } + break; + + case PROP_UNIT: + { + Q_INT32 unit; + + info->cp += xcf_read_int32 (info->fp, &unit, 1); + + if ((unit <= GIMP_UNIT_PIXEL) || + (unit >= + _gimp_unit_get_number_of_built_in_units (gimage->gimp))) + { + g_message ("Warning, unit out of range in XCF file, " + "falling back to inches"); + unit = GIMP_UNIT_INCH; + } + + gimage->resolution_unit = unit; + } + break; + + case PROP_PATHS: + xcf_load_old_paths (info, gimage); + break; + + case PROP_USER_UNIT: + { + QCString *unit_strings[5]; + float factor; + Q_INT32 digits; + GimpUnit unit; + Q_INT32 num_units; + Q_INT32 i; + + info->cp += xcf_read_float (info->fp, &factor, 1); + info->cp += xcf_read_int32 (info->fp, &digits, 1); + info->cp += xcf_read_string (info->fp, unit_strings, 5); + + for (i = 0; i < 5; i++) + if (unit_strings[i] == NULL) + unit_strings[i] = g_strdup (""); + + num_units = _gimp_unit_get_number_of_units (gimage->gimp); + + for (unit = + _gimp_unit_get_number_of_built_in_units (gimage->gimp); + unit < num_units; unit++) + { + /* if the factor and the identifier match some unit + * in unitrc, use the unitrc unit + */ + if ((ABS (_gimp_unit_get_factor (gimage->gimp, + unit) - factor) < 1e-5) && + (strcmp (unit_strings[0], + _gimp_unit_get_identifier (gimage->gimp, + unit)) == 0)) + { + break; + } + } + + /* no match */ + if (unit == num_units) + unit = _gimp_unit_new (gimage->gimp, + unit_strings[0], + factor, + digits, + unit_strings[1], + unit_strings[2], + unit_strings[3], unit_strings[4]); + + gimage->resolution_unit = unit; + + for (i = 0; i < 5; i++) + g_free (unit_strings[i]); + } + break; + + case PROP_VECTORS: + { + Q_INT32 base = info->cp; + + if (xcf_load_vectors (info, gimage)) + { + if (base + prop_size != info->cp) + { + g_warning + ("Mismatch in PROP_VECTORS size: skipping %d bytes.", + base + prop_size - info->cp); + xcf_seek_pos (info, base + prop_size, NULL); + } + } + else + { + /* skip silently since we don't understand the format and + * xcf_load_vectors already explained what was wrong + */ + xcf_seek_pos (info, base + prop_size, NULL); + } + } + break; + + default: +#ifdef GIMP_UNSTABLE + g_printerr ("unexpected/unknown image property: %d (skipping)", + prop_type); +#endif + { + Q_UINT8 buf[16]; + Q_UINT32 amount; + + while (prop_size > 0) + { + amount = MIN (16, prop_size); + info->cp += xcf_read_int8 (info->fp, buf, amount); + prop_size -= MIN (16, amount); + } + } + break; + } + } + + return FALSE; +} + +static bool +xcf_load_layer_props (XcfInfo * info, + KisImage * gimage, + KisLayer * layer, + bool * apply_mask, + bool * edit_mask, + bool * show_mask, Q_INT32 * text_layer_flags) +{ + PropType prop_type; + Q_INT32 prop_size; + + while (TRUE) + { + if (!xcf_load_prop (info, &prop_type, &prop_size)) + return FALSE; + + switch (prop_type) + { + case PROP_END: + return TRUE; + + case PROP_ACTIVE_LAYER: + info->active_layer = layer; + break; + + case PROP_FLOATING_SELECTION: + info->floating_sel = layer; + info->cp += + xcf_read_int32 (info->fp, + (Q_INT32 *) & info->floating_sel_offset, 1); + break; + + case PROP_OPACITY: + { + Q_INT32 opacity; + + info->cp += xcf_read_int32 (info->fp, &opacity, 1); + layer->opacity = CLAMP ((gdouble) opacity / 255.0, + GIMP_OPACITY_TRANSPARENT, + GIMP_OPACITY_OPAQUE); + } + break; + + case PROP_VISIBLE: + { + bool visible; + + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & visible, 1); + gimp_item_set_visible (GIMP_ITEM (layer), + visible ? TRUE : FALSE, FALSE); + } + break; + + case PROP_LINKED: + { + bool linked; + + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & linked, 1); + gimp_item_set_linked (GIMP_ITEM (layer), + linked ? TRUE : FALSE, FALSE); + } + break; + + case PROP_LOCK_ALPHA: + info->cp += + xcf_read_int32 (info->fp, (Q_INT32 *) & layer->lock_alpha, 1); + break; + + case PROP_APPLY_MASK: + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) apply_mask, 1); + break; + + case PROP_EDIT_MASK: + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) edit_mask, 1); + break; + + case PROP_SHOW_MASK: + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) show_mask, 1); + break; + + case PROP_OFFSETS: + info->cp += + xcf_read_int32 (info->fp, + (Q_INT32 *) & GIMP_ITEM (layer)->offset_x, 1); + info->cp += + xcf_read_int32 (info->fp, + (Q_INT32 *) & GIMP_ITEM (layer)->offset_y, 1); + break; + + case PROP_MODE: + info->cp += xcf_read_int32 (info->fp, (Q_INT32 *) & layer->mode, 1); + break; + + case PROP_TATTOO: + info->cp += xcf_read_int32 (info->fp, + (Q_INT32 *) & GIMP_ITEM (layer)->tattoo, + 1); + break; + + case PROP_PARASITES: + { + glong base = info->cp; + KisAnnotation *p; + + while (info->cp - base < prop_size) + { + p = xcf_load_parasite (info); + gimp_item_parasite_attach (GIMP_ITEM (layer), p); + gimp_parasite_free (p); + } + if (info->cp - base != prop_size) + g_message ("Error while loading a layer's parasites"); + } + break; + + case PROP_TEXT_LAYER_FLAGS: + info->cp += xcf_read_int32 (info->fp, text_layer_flags, 1); + break; + + default: + { + Q_UINT8 buf[16]; + Q_UINT32 amount; + +#ifdef GIMP_UNSTABLE + g_printerr ("unexpected/unknown layer property: %d (skipping)", + prop_type); +#endif + while (prop_size > 0) + { + amount = MIN (16, prop_size); + info->cp += xcf_read_int8 (info->fp, buf, amount); + prop_size -= MIN (16, amount); + } + } + break; + } + } + + return FALSE; +} + +static bool +xcf_load_channel_props (XcfInfo * info, + Ki