macro_optional_add_subdirectory(kcron)
macro_optional_add_subdirectory(kdenetwork-filesharing)
macro_optional_add_subdirectory(kdeplasma-addons)
-macro_optional_add_subdirectory(lokalize)
macro_optional_add_subdirectory(libksane)
macro_optional_add_subdirectory(kcolorchooser)
macro_optional_add_subdirectory(kemu)
libavcodec-dev libavformat-dev libavutil-dev libblkid-dev libcups2-dev \
libdjvulibre-dev libepub-dev libexiv2-dev libfreetype6-dev \
libgcrypt20-dev libgettextpo-dev libgmp-dev libmms-dev \
- libhunspell-dev libjpeg-dev libpng-dev libparted-dev libqalculate-dev \
+ libjpeg-dev libpng-dev libparted-dev libqalculate-dev \
libsane-dev libspectre-dev libspeechd-dev libswscale-dev libtag1-dev \
uuid-dev libudev-dev libvncserver-dev freerdp2-dev \
libboost-dev libffmpegthumbnailer-dev libbz2-dev libtorrent-rasterbar-dev \
+++ /dev/null
-project(lokalize)
-
-if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_CURRENT_SOURCE_DIR})
- find_package(KDE4 4.21.0 REQUIRED)
- include(KDE4Defaults)
- include_directories(${KDE4_INCLUDES})
- add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
-endif()
-
-find_package(HUNSPELL)
-set_package_properties(HUNSPELL PROPERTIES
- DESCRIPTION "Library used for stemming"
- URL "http://hunspell.sourceforge.net/"
- TYPE REQUIRED
- PURPOSE "Required to build Lokalize."
-)
-
-include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
-add_subdirectory(src)
-add_subdirectory(scripts)
-add_subdirectory(icons)
+++ /dev/null
- 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.
-\f
- 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.)
-\f
-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.
-\f
- 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.
-\f
- 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
-\f
- Appendix: 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.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- 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.
-
- <signature of Ty Coon>, 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.
+++ /dev/null
- GNU Free Documentation License
- Version 1.2, November 2002
-
-
- Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
- 51 Franklin St, 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.
-
-
-0. PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document "free" in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-1. APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The "Document", below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "you". You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A "Modified Version" of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or a front-matter section of
-the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall subject
-(or to related matters) and contains nothing that could fall directly
-within that overall subject. (Thus, if the Document is in part a
-textbook of mathematics, a Secondary Section may not explain any
-mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The "Invariant Sections" are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The "Cover Texts" are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A "Transparent" copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not "Transparent" is called "Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML
-or XML using a publicly available DTD, and standard-conforming simple
-HTML, PostScript or PDF designed for human modification. Examples of
-transparent image formats include PNG, XCF and JPG. Opaque formats
-include proprietary formats that can be read and edited only by
-proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the
-machine-generated HTML, PostScript or PDF produced by some word
-processors for output purposes only.
-
-The "Title Page" means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-A section "Entitled XYZ" means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as "Acknowledgements",
-"Dedications", "Endorsements", or "History".) To "Preserve the Title"
-of such a section when you modify the Document means that it remains a
-section "Entitled XYZ" according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
-
-2. VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no other
-conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-3. COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to give
-them a chance to provide you with an updated version of the Document.
-
-
-4. MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-A. Use in the Title Page (and on the covers, if any) a title distinct
- from that of the Document, and from those of previous versions
- (which should, if there were any, be listed in the History section
- of the Document). You may use the same title as a previous version
- if the original publisher of that version gives permission.
-B. List on the Title Page, as authors, one or more persons or entities
- responsible for authorship of the modifications in the Modified
- Version, together with at least five of the principal authors of the
- Document (all of its principal authors, if it has fewer than five),
- unless they release you from this requirement.
-C. State on the Title page the name of the publisher of the
- Modified Version, as the publisher.
-D. Preserve all the copyright notices of the Document.
-E. Add an appropriate copyright notice for your modifications
- adjacent to the other copyright notices.
-F. Include, immediately after the copyright notices, a license notice
- giving the public permission to use the Modified Version under the
- terms of this License, in the form shown in the Addendum below.
-G. Preserve in that license notice the full lists of Invariant Sections
- and required Cover Texts given in the Document's license notice.
-H. Include an unaltered copy of this License.
-I. Preserve the section Entitled "History", Preserve its Title, and add
- to it an item stating at least the title, year, new authors, and
- publisher of the Modified Version as given on the Title Page. If
- there is no section Entitled "History" in the Document, create one
- stating the title, year, authors, and publisher of the Document as
- given on its Title Page, then add an item describing the Modified
- Version as stated in the previous sentence.
-J. Preserve the network location, if any, given in the Document for
- public access to a Transparent copy of the Document, and likewise
- the network locations given in the Document for previous versions
- it was based on. These may be placed in the "History" section.
- You may omit a network location for a work that was published at
- least four years before the Document itself, or if the original
- publisher of the version it refers to gives permission.
-K. For any section Entitled "Acknowledgements" or "Dedications",
- Preserve the Title of the section, and preserve in the section all
- the substance and tone of each of the contributor acknowledgements
- and/or dedications given therein.
-L. Preserve all the Invariant Sections of the Document,
- unaltered in their text and in their titles. Section numbers
- or the equivalent are not considered part of the section titles.
-M. Delete any section Entitled "Endorsements". Such a section
- may not be included in the Modified Version.
-N. Do not retitle any existing section to be Entitled "Endorsements"
- or to conflict in title with any Invariant Section.
-O. Preserve any Warranty Disclaimers.
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled "Endorsements", provided it contains
-nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-
-5. COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled "History"
-in the various original documents, forming one section Entitled
-"History"; likewise combine any sections Entitled "Acknowledgements",
-and any sections Entitled "Dedications". You must delete all sections
-Entitled "Endorsements".
-
-
-6. COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other documents
-released under this License, and replace the individual copies of this
-License in the various documents with a single copy that is included in
-the collection, provided that you follow the rules of this License for
-verbatim copying of each of the documents in all other respects.
-
-You may extract a single document from such a collection, and distribute
-it individually under this License, provided you insert a copy of this
-License into the extracted document, and follow this License in all
-other respects regarding verbatim copying of that document.
-
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an "aggregate" if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
-
-8. TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
-
-9. TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document except
-as expressly provided for under this License. Any other attempt to
-copy, modify, sublicense or distribute the Document 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.
-
-
-10. FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions
-of the GNU Free Documentation 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. See
-http://www.gnu.org/copyleft/.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation.
-
-
-ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
- Copyright (c) YEAR YOUR NAME.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.2
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
- A copy of the license is included in the section entitled "GNU
- Free Documentation License".
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the "with...Texts." line with this:
-
- with the Invariant Sections being LIST THEIR TITLES, with the
- Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
+++ /dev/null
-The most global class is 'Project'. It is a singleton and keeps project-related data/settings
-'Settings' is also a singleton (src/prefs).
-
-==LokalizeMainWindow==
-'LokalizeMainWindow' is the main window with multitabs interface.
-Uses QMdiArea for tabbing interface, and guiFactory()->addClient()/guiFactory()->removeClient()
-to merge actions from tabs (editor, project overview, tm-search tab), and StatusBarProxy to deliver info from tabs.
-Tabs are KMainWindows + KXmlGuiCleints.
-
-==Project Overview tab==
-Hacks KDirLister to merge contents from two dirs.
-uses kdesdk/strigi-analyzer/po to scan translation files
-
-==Editor tab==
-'EditorTab' is a dispatcher (controller) for one catalog editing window (tab).
-'EditorView' is msgid/msgstr viewer/editor for it.
-'MsgCtxtView', 'GlossaryView' and other QDockWidget derivatives provide specialized features.
-All specialized actions should go into views (QDockWidgets) or separate classes used from views.
-
-'Catalog' is a controller+proxymodel for CatalogStorage translation files
-'CatalogStorage' is interface for different storage models (QVector for gettext, QDom for xliff)
-
-==Translation Memory==
-Implemented as series of jobs running in second thread (src/tm/jobs.cpp).
-See initDB() for database schema
-
-==Glossary==
-SAX parser/generator based. Tries to preserve unknown metadata on saving when possible.
-
-
-API docs:
-http://api.kde.org/4.x-api/kdesdk-apidocs/lokalize/html/annotated.html
+++ /dev/null
-#! /usr/bin/env bash
-$EXTRACTRC `find . -name \*.ui -o -name \*.rc -o -name \*.kcfg` >> rc.cpp
-$XGETTEXT `find . -name \*.cpp -o -name \*.h` -o $podir/lokalize.pot
-rm -f rc.cpp
+++ /dev/null
-deps (in order of importance):
--katie 4.10, with sqlite plugin
--kdelibs 4.20
--kdesdk strigi analyzer plugins (for project overview)
--hunspell (for stemming)
--translate-toolkit (odf2xliff)
--python-lxml (explicitly for odf2xliff)
--poxml
--gettext (msginit used when creating new PO files)
--subversion (for autofetching KDE translations in new project wizard)
+++ /dev/null
--edit: \"
--autosaving(KAutoSaveFile ??)
--projects: svn
--interaction between instances (dbus)
--settings: configurable highlight regexps
--search: dont replace in tags
--db: several, msgctxt
-
--xliff
--integration with dictionary
-
-small:
--bookmarks saving
-
-==general==
--many small features that ease everyday life of translator
--polishing
-
-
-==others say==
-- "click to translate" any word on the screen (any app)
-
-
- ***
-see http://techbase.kde.org/Projects/Summer_of_Code/2007/Projects/KAider
\ No newline at end of file
+++ /dev/null
-add_subdirectory(global)
-
-kde4_install_icons(${KDE4_DATA_INSTALL_DIR}/lokalize/icons)
+++ /dev/null
-kde4_install_icons(${KDE4_ICON_INSTALL_DIR})
+++ /dev/null
-install(
- PROGRAMS find-gui-text.sh
- DESTINATION ${KDE4_DATA_INSTALL_DIR}/lokalize/scripts
-)
+++ /dev/null
-TEXT=$1
-PACKAGE=$2
-LOKALIZE_INSTANCES=`qdbus org.kde.lokalize*`
-if [ -z $LOKALIZE_INSTANCES ]; then lokalize>/dev/null 2>/dev/null & fi
-
-let COUNTER=0
-while [ -z $LOKALIZE_INSTANCES ]; do \
-let COUNTER=$COUNTER+1
-if [ $COUNTER -gt 10 ]; then exit ; fi
-sleep 1
-LOKALIZE_INSTANCES=`qdbus org.kde.lokalize*` ;\
-done
-
-for LOKALIZE_INSTANCE in $LOKALIZE_INSTANCES; do \
- qdbus $LOKALIZE_INSTANCE /ThisIsWhatYouWant org.kde.Lokalize.MainWindow.showTranslationMemory; \
- qdbus $LOKALIZE_INSTANCE /ThisIsWhatYouWant/TranslationMemory/0 org.kde.Lokalize.TranslationMemory.findGuiTextPackage "$TEXT" "$PACKAGE"; \
-done
-
+++ /dev/null
-project(lokalize)
-
-if(NOT WIN32)
- find_package(HUNSPELL REQUIRED)
-else(NOT WIN32)
- find_package(HUNSPELL)
-endif(NOT WIN32)
-
-if(HUNSPELL_FOUND)
- add_definitions(-DHAVE_HUNSPELL)
- include_directories(
- ${HUNSPELL_INCLUDE_DIR}
- )
-endif(HUNSPELL_FOUND)
-
-include_directories(
- ${CMAKE_CURRENT_SOURCE_DIR}/prefs
- ${CMAKE_CURRENT_SOURCE_DIR}/common
- ${CMAKE_CURRENT_SOURCE_DIR}/catalog
- ${CMAKE_CURRENT_SOURCE_DIR}/catalog/gettext
- ${CMAKE_CURRENT_SOURCE_DIR}/catalog/xliff
- ${CMAKE_CURRENT_SOURCE_DIR}/catalog/ts
- ${CMAKE_CURRENT_SOURCE_DIR}/cataloglistview
- ${CMAKE_CURRENT_SOURCE_DIR}/project
- ${CMAKE_CURRENT_SOURCE_DIR}/glossary
- ${CMAKE_CURRENT_SOURCE_DIR}/tm
- ${CMAKE_CURRENT_SOURCE_DIR}/filesearch
- ${CMAKE_CURRENT_SOURCE_DIR}/mergemode
- ${KDE4_INCLUDE_DIR}
- ${QT_INCLUDES}
- ${CMAKE_CURRENT_SOURCE_DIR}
- ${CMAKE_CURRENT_BINARY_DIR}
-)
-
-set(lokalize_SRCS
- main.cpp
- lokalizemainwindow.cpp
- actionproxy.cpp
-
- editortab.cpp
- editortab_findreplace.cpp
-
- editorview.cpp
- xlifftextedit.cpp
- syntaxhighlighter.cpp
-
- completionstorage.cpp
-
- phaseswindow.cpp
- noteeditor.cpp
- msgctxtview.cpp
-
- binunitsview.cpp
-
- cataloglistview/cataloglistview.cpp
- cataloglistview/catalogmodel.cpp
-
- common/domroutines.cpp
-
- common/fastsizehintitemdelegate.cpp
-
- common/flowlayout.cpp
- common/termlabel.cpp
- common/languagelistmodel.cpp
- common/stemming.cpp
- glossary/glossaryview.cpp
- glossary/glossary.cpp
- glossary/glossarywindow.cpp
-
- mergemode/mergecatalog.cpp
- mergemode/mergeview.cpp
- alttransview.cpp
- common/diff.cpp
-
- project.cpp
- projectmodel.cpp
- projectwidget.cpp
- projecttab.cpp
-
- prefs.cpp
-
- tools/widgettextcaptureconfig.cpp
-
- filesearch/filesearchtab.cpp
-
- tm/tmview.cpp
- tm/tmscanapi.cpp
- tm/jobs.cpp
- tm/dbfilesmodel.cpp
- tm/tmmanager.cpp
- tm/tmtab.cpp
- tm/qaview.cpp
- tm/qamodel.cpp
-
- catalog/phase.cpp
-
- catalog/cmd.cpp
- catalog/pos.cpp
- catalog/catalog.cpp
- catalog/catalogstring.cpp
- catalog/gettextheader.cpp
- catalog/gettext/gettextstorage.cpp
- catalog/gettext/catalogitem.cpp
- catalog/gettext/importplugin.cpp
- catalog/gettext/gettextimport.cpp
- catalog/gettext/gettextexport.cpp
- catalog/xliff/xliffstorage.cpp
- catalog/ts/tsstorage.cpp
-
- prefs_identity.ui
- prefs_editor.ui
- prefs_appearance.ui
- prefs_tm.ui
- prefs_project_advanced.ui
- prefs_project_local.ui
- prefs_projectmain.ui
- glossary/termedit.ui
- filesearch/filesearchoptions.ui
- filesearch/massreplaceoptions.ui
- tm/queryoptions.ui
- tm/managedatabases.ui
- tm/dbparams.ui
- kaider_findextension.ui
- tools/widgettextcaptureconfig.ui
-)
-
-kde4_add_kcfg_files(lokalize_SRCS
- prefs_lokalize.kcfgc
- projectbase.kcfgc
- projectlocal.kcfgc
-)
-
-#qt4_add_dbus_interface(lokalize_SRCS org.kde.lokalize.MainWindow.xml lokainterface)
-qt4_add_dbus_adaptor(lokalize_SRCS org.kde.lokalize.MainWindow.xml
- lokalizemainwindow.h LokalizeMainWindow)
-qt4_add_dbus_adaptor(lokalize_SRCS org.kde.lokalize.Editor.xml
- editortab.h EditorTab)
-qt4_add_dbus_adaptor(lokalize_SRCS filesearch/org.kde.lokalize.FileSearch.xml
- filesearch/filesearchtab.h FileSearchTab)
-qt4_add_dbus_adaptor(lokalize_SRCS tm/org.kde.lokalize.TranslationMemory.xml
- tm/tmtab.h TM::TMTab)
-qt4_add_dbus_adaptor(lokalize_SRCS org.kde.lokalize.Project.xml
- project.h Project)
-qt4_add_dbus_adaptor(lokalize_SRCS org.kde.lokalize.ProjectOverview.xml
- projecttab.h ProjectTab)
-
-
-add_executable(lokalize ${lokalize_SRCS})
-
-target_link_libraries(lokalize
- ${KDE4_KPARTS_LIBS}
- ${KDE4_KIO_LIBS}
- ${KDE4_KFILE_LIBS}
- ${KDE4_KDEUI_LIBS}
- ${KDE4_THREADWEAVER_LIBS}
- ${QT_QTSQL_LIBRARY}
-)
-if(HUNSPELL_FOUND)
- target_link_libraries(lokalize ${HUNSPELL_LIBRARIES})
-endif(HUNSPELL_FOUND)
-
-install(TARGETS lokalize ${INSTALL_TARGETS_DEFAULT_ARGS} )
-
-
-########### install files ###############
-
-install( PROGRAMS lokalize.desktop DESTINATION ${KDE4_XDG_APPS_INSTALL_DIR} )
-install( FILES lokalize.kcfg DESTINATION ${KDE4_KCFG_INSTALL_DIR} )
-install( FILES
- editorui.rc
- lokalizemainwindowui.rc
- projectmanagerui.rc
- tm/translationmemoryrui.rc
- filesearch/filesearchtabui.rc
- lokalize.notifyrc
- DESTINATION ${KDE4_DATA_INSTALL_DIR}/lokalize )
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "actionproxy.h"
-
-#include <kdebug.h>
-#include <KStatusBar>
-
-#if 0
-#include <QAction>
-
-
-ActionProxy::ActionProxy(QObject* parent,QObject* receiver,const char* slot)
- : QObject(parent)
- , m_currentAction(0)
- , m_disabled(false)
- , m_checked(false)
-// , m_checkable(false)
-{
- if (receiver)
- connect(this,SIGNAL(triggered(bool)),receiver,slot);
-
- connect(this,SIGNAL(toggled(bool)),this,SLOT(handleToggled(bool)));
-}
-
-ActionProxy::~ActionProxy()
-{
- // if the view is closed...
-}
-
-void ActionProxy::registerAction(QAction* a)
-{
- if (a==m_currentAction)
- return;
-
- m_currentAction=a;
- a->setChecked(m_checked);
- a->setDisabled(m_disabled);
- a->setStatusTip(m_statusTip);
- m_keySequence=a->shortcut();
-
- connect(a,SIGNAL(triggered(bool)),this,SIGNAL(triggered(bool)));
- connect(a,SIGNAL(toggled(bool)),this,SIGNAL(toggled(bool)));
-}
-void ActionProxy::unregisterAction(/*QAction**/)
-{
- disconnect(m_currentAction,SIGNAL(triggered(bool)),this,SIGNAL(triggered(bool)));
- disconnect(m_currentAction,SIGNAL(toggled(bool)),this,SIGNAL(toggled(bool)));
- m_currentAction->setStatusTip(QString());
- m_currentAction=0;
-}
-
-void ActionProxy::handleToggled(bool checked)
-{
- m_checked=checked;
-}
-
-void ActionProxy::setDisabled(bool disabled)
-{
- if (m_currentAction)
- m_currentAction->setDisabled(disabled);
-
- m_disabled=disabled;
-}
-
-void ActionProxy::setChecked(bool checked)
-{
- if (m_currentAction)
- m_currentAction->setChecked(checked); //handleToggled is called implicitly via signal/slot mechanism
- else
- m_checked=checked;
-}
-
-
-#endif
-
-void StatusBarProxy::insert(int key,const QString& str)
-{
- if (m_currentStatusBar)
- m_currentStatusBar->changeItem(str,key);
- QMap<int,QString>::insert(key,str);
-}
-
-void StatusBarProxy::registerStatusBar(KStatusBar* bar)
-{
- m_currentStatusBar=bar;
-
- QMap<int,QString>::const_iterator i = constBegin();
- while (i != constEnd())
- {
- bar->changeItem(i.value(),i.key());
- ++i;
- }
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef ACTIONPROXY_H
-#define ACTIONPROXY_H
-
-#include <QObject>
-#include <QKeySequence>
-#include <QMap>
-class KAction;
-class KStatusBar;
-
-#if 0
-
-/**
- * used for connecting qactions to subwindows:
- * forwards signals and saves/restores state on subwindow switch
- */
-class ActionProxy: public QObject
-{
- Q_OBJECT
-
-public:
- ActionProxy(QObject* parent,QObject* receiver=0,const char* slot=0);
- ~ActionProxy();
-
- void registerAction(QAction*);
- void unregisterAction(/*QAction**/);
-
- void setStatusTip(const QString& st){m_statusTip=st;}//for TM suggestions
- QKeySequence shortcut(){return m_keySequence;};//for TM suggestions
-
-public slots:
- void setDisabled(bool);
- void setEnabled(bool enabled){setDisabled(!enabled);}
- void setChecked(bool);
-
-private slots:
- void handleToggled(bool);
-
-signals:
- void triggered(bool=false);
- void toggled(bool);
-
-private:
- QAction* m_currentAction;
- bool m_disabled;
- bool m_checked;
- QString m_statusTip;
- QKeySequence m_keySequence;
-};
-
-#endif
-
-class StatusBarProxy: public QMap<int,QString>
-{
-public:
- StatusBarProxy():m_currentStatusBar(0){}
- ~StatusBarProxy(){}
-
- void insert(int,const QString&);
-
- void registerStatusBar(KStatusBar*);
- void unregisterStatusBar(){m_currentStatusBar=0;}
-
-private:
- KStatusBar* m_currentStatusBar;
-
-};
-
-
-#define ID_STATUS_PROGRESS 0
-#define ID_STATUS_CURRENT 1
-#define ID_STATUS_TOTAL 2
-#define ID_STATUS_FUZZY 3
-#define ID_STATUS_UNTRANS 4
-#define ID_STATUS_ISFUZZY 5
-#define TOTAL_ID_STATUSES 6
-//#define ID_STATUS_READONLY 6
-//#define ID_STATUS_CURSOR 7
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#define KDE_NO_DEBUG_OUTPUT
-
-#include "alttransview.h"
-#include <QtGui/qevent.h>
-
-#include "diff.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "project.h"
-#include "xlifftextedit.h"
-#include "tmview.h" //TextBrowser
-#include "mergecatalog.h"
-#include "prefs_lokalize.h"
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <kaction.h>
-
-#include <QSignalMapper>
-//#include <QtCore/qdatetime.h>
-#include <QFileInfo>
-#include <QToolTip>
-
-
-AltTransView::AltTransView(QWidget* parent, Catalog* catalog,const QVector<KAction*>& actions)
- : QDockWidget ( i18nc("@title:window","Alternate Translations"), parent)
- , m_browser(new TM::TextBrowser(this))
- , m_catalog(catalog)
- , m_normTitle(i18nc("@title:window","Alternate Translations"))
- , m_hasInfoTitle(m_normTitle+" [*]")
- , m_hasInfo(false)
- , m_actions(actions)
-{
- setObjectName("msgIdDiff");
- setWidget(m_browser);
- hide();
-
- m_browser->setReadOnly(true);
- m_browser->viewport()->setBackgroundRole(QPalette::Background);
- QTimer::singleShot(0,this,SLOT(initLater()));
-}
-
-void AltTransView::initLater()
-{
- setAcceptDrops(true);
-
- KConfig config;
- KConfigGroup group(&config,"AltTransView");
- m_everShown=group.readEntry("EverShown",false);
-
-
-
- QSignalMapper* signalMapper=new QSignalMapper(this);
- int i=m_actions.size();
- while(--i>=0)
- {
- connect(m_actions.at(i),SIGNAL(triggered()),signalMapper,SLOT(map()));
- signalMapper->setMapping(m_actions.at(i), i);
- }
- connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(slotUseSuggestion(int)));
-
- connect(m_browser,SIGNAL(textInsertRequested(QString)),this,SIGNAL(textInsertRequested(QString)));
- //connect(m_browser,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
-}
-
-AltTransView::~AltTransView()
-{
-}
-
-void AltTransView::dragEnterEvent(QDragEnterEvent* event)
-{
- if(event->mimeData()->hasUrls() && Catalog::extIsSupported(event->mimeData()->urls().first().path()))
- event->acceptProposedAction();
-}
-
-void AltTransView::dropEvent(QDropEvent *event)
-{
- event->acceptProposedAction();
- attachAltTransFile(event->mimeData()->urls().first().toLocalFile());
-
- //update
- m_prevEntry.entry=-1;
- QTimer::singleShot(0,this,SLOT(process()));
-}
-
-void AltTransView::attachAltTransFile(const QString& path)
-{
- MergeCatalog* altCat=new MergeCatalog(m_catalog, m_catalog, /*saveChanges*/false);
- altCat->loadFromUrl(KUrl::fromLocalFile(path));
- m_catalog->attachAltTransCatalog(altCat);
-}
-
-void AltTransView::addAlternateTranslation(int entry, const QString& trans, bool temp)
-{
- qDebug()<<trans;
- AltTrans altTrans;
- altTrans.target=trans;
- m_catalog->attachAltTrans(entry, altTrans);
-
- m_prevEntry=DocPos();
- QTimer::singleShot(0,this,SLOT(process()));
-}
-
-void AltTransView::fileLoaded()
-{
- m_prevEntry.entry=-1;
- QString absPath=m_catalog->url().toLocalFile();
- QString relPath=KUrl::relativePath(Project::instance()->projectDir(),absPath);
-
- QFileInfo info(Project::instance()->altTransDir()+'/'+relPath);
- if (info.canonicalFilePath()!=absPath && info.exists())
- attachAltTransFile(info.canonicalFilePath());
- else
- qWarning()<<"alt trans file doesn't exist:"<<info.canonicalFilePath();
-}
-
-void AltTransView::slotNewEntryDisplayed(const DocPosition& pos)
-{
- m_entry=DocPos(pos);
- QTimer::singleShot(0,this,SLOT(process()));
-}
-
-void AltTransView::process()
-{
- if (m_entry==m_prevEntry) return;
- if (m_catalog->numberOfEntries()<=m_entry.entry)
- return;//because of Qt::QueuedConnection
-
- m_prevEntry=m_entry;
- m_browser->clear();
- m_entryPositions.clear();
-
- const QVector<AltTrans>& entries=m_catalog->altTrans(m_entry.toDocPosition());
- m_entries=entries;
-
- if (entries.isEmpty())
- {
- if (m_hasInfo)
- {
- m_hasInfo=false;
- setWindowTitle(m_normTitle);
- }
- return;
- }
- if (!m_hasInfo)
- {
- m_hasInfo=true;
- setWindowTitle(m_hasInfoTitle);
- }
-
-
- CatalogString source=m_catalog->sourceWithTags(m_entry.toDocPosition());
-
- QTextBlockFormat blockFormatBase;
- QTextBlockFormat blockFormatAlternate; blockFormatAlternate.setBackground(QPalette().alternateBase());
- QTextCharFormat noncloseMatchCharFormat;
- QTextCharFormat closeMatchCharFormat; closeMatchCharFormat.setFontWeight(QFont::Bold);
- int i=0;
- int limit=entries.size();
- forever
- {
- const AltTrans& entry=entries.at(i);
-
- QTextCursor cur=m_browser->textCursor();
- QString html;
- html.reserve(1024);
- if (!entry.source.isEmpty())
- {
- html+="<p>";
-
- QString result=Qt::escape(userVisibleWordDiff(entry.source.string, source.string,Project::instance()->accel(),Project::instance()->markup()));
- //result.replace("&","&");
- //result.replace("<","<");
- //result.replace(">",">");
- result.replace("{KBABELADD}","<font style=\"background-color:"+Settings::addColor().name()+";color:black\">");
- result.replace("{/KBABELADD}","</font>");
- result.replace("{KBABELDEL}","<font style=\"background-color:"+Settings::delColor().name()+";color:black\">");
- result.replace("{/KBABELDEL}","</font>");
- result.replace("\\n","\\n<br>");
- result.replace("\\n","\\n<br>");
-
- html+=result;
- html+="<br>";
- cur.insertHtml(html); html.clear();
- }
- if (!entry.target.isEmpty())
- {
- if (Q_LIKELY( i<m_actions.size() ))
- {
- m_actions.at(i)->setStatusTip(entry.target.string);
- html+=QString("[%1] ").arg(m_actions.at(i)->shortcut().toString());
- }
- else
- html+="[ - ] ";
-
- cur.insertText(html); html.clear();
- insertContent(cur,entry.target);
- }
- m_entryPositions.insert(cur.anchor(),i);
-
- html+=i?"<br></p>":"</p>";
- cur.insertHtml(html);
-
- if (Q_UNLIKELY( ++i>=limit ))
- break;
-
- cur.insertBlock(i%2?blockFormatAlternate:blockFormatBase);
- }
-
-
- if (!m_everShown)
- {
- m_everShown=true;
- show();
-
- KConfig config;
- KConfigGroup group(&config,"AltTransView");
- group.writeEntry("EverShown",true);
- }
-}
-
-
-bool AltTransView::event(QEvent *event)
-{
- if (event->type()==QEvent::ToolTip)
- {
- QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
-
- if (m_entryPositions.isEmpty())
- {
- QString tooltip=i18nc("@info:tooltip","<p>Sometimes, if source text is changed, its translation becomes deprecated and is either marked as <emphasis>needing review</emphasis> (i.e. looses approval status), "
- "or (only in case of XLIFF file) moved to the <emphasis>alternate translations</emphasis> section accompanying the unit.</p>"
- "<p>This toolview also shows the difference between current source string and the previous source string, so that you can easily see which changes should be applied to existing translation to make it reflect current source.</p>"
- "<p>Double-clicking any word in this toolview inserts it into translation.</p>"
- "<p>Drop translation file onto this toolview to use it as a source for additional alternate translations.</p>"
- );
- QToolTip::showText(helpEvent->globalPos(),tooltip);
- return true;
- }
-
- int block1=m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).blockNumber();
- int block=*m_entryPositions.lowerBound(m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).anchor());
- if (block1!=block)
- kWarning()<<"block numbers don't match";
- if (block>=m_entries.size())
- return false;
-
- QString origin=m_entries.at(block).origin;
- if (origin.isEmpty())
- return false;
-
- QString tooltip=i18nc("@info:tooltip","Origin: %1",origin);
- QToolTip::showText(helpEvent->globalPos(),tooltip);
- return true;
- }
- return QWidget::event(event);
-}
-
-void AltTransView::slotUseSuggestion(int i)
-{
- if (Q_UNLIKELY( i>=m_entries.size() ))
- return;
-
- TM::TMEntry tmEntry;
- tmEntry.target=m_entries.at(i).target;
- CatalogString source=m_catalog->sourceWithTags(m_entry.toDocPosition());
- tmEntry.diff=userVisibleWordDiff(m_entries.at(i).source.string, source.string,Project::instance()->accel(),Project::instance()->markup());
-
- CatalogString target=TM::targetAdapted(tmEntry, source);
-
- kWarning()<<"0"<<target.string;
- if (Q_UNLIKELY( target.isEmpty() ))
- return;
-
- m_catalog->beginMacro(i18nc("@item Undo action","Use alternate translation"));
-
- QString old=m_catalog->targetWithTags(m_entry.toDocPosition()).string;
- if (!old.isEmpty())
- {
- //FIXME test!
- removeTargetSubstring(m_catalog, m_entry.toDocPosition(), 0, old.size());
- //m_catalog->push(new DelTextCmd(m_catalog,m_pos,m_catalog->msgstr(m_pos)));
- }
- kWarning()<<"1"<<target.string;
-
- //m_catalog->push(new InsTextCmd(m_catalog,m_pos,target)/*,true*/);
- insertCatalogString(m_catalog, m_entry.toDocPosition(), target, 0);
-
- m_catalog->endMacro();
-
- emit refreshRequested();
-}
-
-
-#include "moc_alttransview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef ALTTRANSVIEW_H
-#define ALTTRANSVIEW_H
-
-#define ALTTRANS_SHORTCUTS 9
-
-#include "pos.h"
-#include "alttrans.h"
-#include <QDockWidget>
-namespace TM{class TextBrowser;}
-class Catalog;
-class KAction;
-
-class AltTransView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- AltTransView(QWidget*,Catalog*,const QVector<KAction*>&);
- ~AltTransView();
-
-
-public slots:
- void slotNewEntryDisplayed(const DocPosition&);
- void fileLoaded();
- void attachAltTransFile(const QString&);
- void addAlternateTranslation(int entry, const QString&, bool temp=true);
-
-private slots:
- //void contextMenu(const QPoint & pos);
- void process();
- void initLater();
- void slotUseSuggestion(int);
-
-signals:
- void refreshRequested();
- void textInsertRequested(const QString&);
-
-private:
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent *event);
- bool event(QEvent *event);
-
-
-private:
- TM::TextBrowser* m_browser;
- Catalog* m_catalog;
- QString m_normTitle;
- QString m_hasInfoTitle;
- bool m_hasInfo;
- DocPos m_entry;
- DocPos m_prevEntry;
- bool m_everShown;
-
- QVector<AltTrans> m_entries;
- QMap<int, int> m_entryPositions;
- QVector<KAction*> m_actions;//need them to get shortcuts
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "binunitsview.h"
-#include "phaseswindow.h" //MyTreeView
-#include "catalog.h"
-#include "cmd.h"
-#include "project.h"
-
-#include <klocale.h>
-#include <krun.h>
-#include <QtGui/qevent.h>
-#include <QMenu>
-#include <kfiledialog.h>
-#include <kdirwatch.h>
-
-
-//BEGIN BinUnitsModel
-BinUnitsModel::BinUnitsModel(Catalog* catalog, QObject* parent)
- : QAbstractListModel(parent)
- , m_catalog(catalog)
-{
- connect(catalog,SIGNAL(signalFileLoaded()),this,SLOT(fileLoaded()));
- connect(catalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(entryModified(DocPosition)));
-
- connect(KDirWatch::self(),SIGNAL(dirty(QString)),this,SLOT(updateFile(QString)));
-}
-
-void BinUnitsModel::fileLoaded()
-{
- m_imageCache.clear();
- reset();
-}
-
-void BinUnitsModel::entryModified(const DocPosition& pos)
-{
- if (pos.entry<m_catalog->numberOfEntries())
- return;
-
- QModelIndex item=index(pos.entry-m_catalog->numberOfEntries(),TargetFilePath);
- emit dataChanged(item,item);
-}
-
-void BinUnitsModel::updateFile(QString path)
-{
- QString relPath=KUrl::relativePath(Project::instance()->projectDir(),path);
-
- DocPosition pos(m_catalog->numberOfEntries());
- int limit=m_catalog->numberOfEntries()+m_catalog->binUnitsCount();
- while (pos.entry<limit)
- {
- kWarning()<<m_catalog->target(pos);
- if (m_catalog->target(pos)==relPath || m_catalog->source(pos)==relPath)
- {
- int row=pos.entry-m_catalog->numberOfEntries();
- m_imageCache.remove(relPath);
- emit dataChanged(index(row,SourceFilePath),index(row,TargetFilePath));
- return;
- }
-
- pos.entry++;
- }
-}
-
-void BinUnitsModel::setTargetFilePath(int row, const QString& path)
-{
- DocPosition pos(row+m_catalog->numberOfEntries());
- QString old=m_catalog->target(pos);
- if (!old.isEmpty())
- {
- m_catalog->push(new DelTextCmd(m_catalog, pos, old));
- m_imageCache.remove(old);
- }
-
- m_catalog->push(new InsTextCmd(m_catalog, pos, KUrl::relativePath(Project::instance()->projectDir(),path)));
- QModelIndex item=index(row,TargetFilePath);
- emit dataChanged(item,item);
-}
-
-int BinUnitsModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return m_catalog->binUnitsCount();
-}
-
-QVariant BinUnitsModel::data(const QModelIndex& index, int role) const
-{
- if (role==Qt::DecorationRole)
- {
- DocPosition pos(index.row()+m_catalog->numberOfEntries());
- if (index.column()<Approved)
- {
- QString path=index.column()==SourceFilePath?m_catalog->source(pos):m_catalog->target(pos);
- if (!m_imageCache.contains(path))
- {
- QString absPath=Project::instance()->absolutePath(path);
- KDirWatch::self()->addFile(absPath); //TODO remember watched files to react only on them in dirty() signal handler
- m_imageCache.insert(path, QImage(absPath).scaled(128,128,Qt::KeepAspectRatio));
- }
- return m_imageCache.value(path);
- }
- }
- else if (role==Qt::TextAlignmentRole)
- return int(Qt::AlignLeft|Qt::AlignTop);
-
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- static const char* noyes[]={I18N_NOOP("no"),I18N_NOOP("yes")};
- DocPosition pos(index.row()+m_catalog->numberOfEntries());
- switch (index.column())
- {
- case SourceFilePath: return m_catalog->source(pos);
- case TargetFilePath: return m_catalog->target(pos);
- case Approved: return noyes[m_catalog->isApproved(pos)];
- }
- return QVariant();
-}
-
-QVariant BinUnitsModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- case SourceFilePath: return i18nc("@title:column","Source");
- case TargetFilePath: return i18nc("@title:column","Target");
- case Approved: return i18nc("@title:column","Approved");
- }
- return QVariant();
-}
-//END BinUnitsModel
-
-
-BinUnitsView::BinUnitsView(Catalog* catalog, QWidget* parent)
- : QDockWidget(i18nc("@title toolview name","Binary Units"),parent)
- , m_catalog(catalog)
- , m_model(new BinUnitsModel(catalog, this))
- , m_view(new MyTreeView(this))
-{
- setObjectName("binUnits");
- hide();
-
- setWidget(m_view);
- m_view->setModel(m_model);
- m_view->setRootIsDecorated(false);
- m_view->setAlternatingRowColors(true);
- m_view->viewport()->setBackgroundRole(QPalette::Background);
- connect(m_view,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(mouseDoubleClicked(QModelIndex)));
-
- connect(catalog,SIGNAL(signalFileLoaded()),this,SLOT(fileLoaded()));
-}
-
-void BinUnitsView::fileLoaded()
-{
- setVisible(m_catalog->binUnitsCount());
-}
-
-void BinUnitsView::selectUnit(const QString& id)
-{
- QModelIndex item=m_model->index(m_catalog->unitById(id)-m_catalog->numberOfEntries());
- m_view->setCurrentIndex(item);
- m_view->scrollTo(item);
- show();
-}
-
-void BinUnitsView::contextMenuEvent(QContextMenuEvent *event)
-{
- QModelIndex item=m_view->currentIndex();
- if (!item.isValid())
- return;
-
- QMenu menu;
- QAction* setTarget=menu.addAction(i18nc("@action:inmenu","Set the file"));
- QAction* useSource=menu.addAction(i18nc("@action:inmenu","Use source file"));
-
-// menu.addSeparator();
-// QAction* openSource=menu.addAction(i18nc("@action:inmenu","Open source file in external program"));
-// QAction* openTarget=menu.addAction(i18nc("@action:inmenu","Open target file in external program"));
-
- QAction* result=menu.exec(event->globalPos());
- if (!result)
- return;
-
- QString sourceFilePath=item.sibling(item.row(),BinUnitsModel::SourceFilePath).data().toString();
- if (result==useSource)
- m_model->setTargetFilePath(item.row(), sourceFilePath);
- else if (result==setTarget)
- {
- KUrl targetFileUrl=KFileDialog::getOpenFileName(Project::instance()->projectDir(),
- "*."+QFileInfo(sourceFilePath).completeSuffix(),this);
- if (!targetFileUrl.isEmpty())
- m_model->setTargetFilePath(item.row(), targetFileUrl.toLocalFile());
- }
- event->accept();
-}
-
-void BinUnitsView::mouseDoubleClicked(const QModelIndex& item)
-{
- //FIXME child processes don't notify us about changes ;(
- if (item.column()<BinUnitsModel::Approved)
- new KRun(Project::instance()->absolutePath(item.data().toString()),this);
-}
+++ /dev/null
-class BinUnitsModel;
-class Catalog;
-class Catalog;
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef BINUNITSWINDOW_H
-#define BINUNITSWINDOW_H
-
-class Catalog;
-class BinUnitsModel;
-class MyTreeView;
-
-#include "pos.h"
-
-#include <QHash>
-#include <QDockWidget>
-#include <QtCore/qabstractitemmodel.h>
-
-class BinUnitsView: public QDockWidget
-{
-Q_OBJECT
-public:
- BinUnitsView(Catalog* catalog, QWidget *parent);
-
-public slots:
- void selectUnit(const QString& id);
-
-private:
- void contextMenuEvent(QContextMenuEvent *event);
-private slots:
- void mouseDoubleClicked(const QModelIndex&);
- void fileLoaded();
-
-private:
- Catalog* m_catalog;
- BinUnitsModel* m_model;
- MyTreeView* m_view;
-};
-
-
-class BinUnitsModel: public QAbstractListModel
-{
-Q_OBJECT
-public:
- enum BinUnitsModelColumns
- {
- SourceFilePath=0,
- TargetFilePath,
- Approved,
- ColumnCount
- };
-
- BinUnitsModel(Catalog* catalog, QObject* parent);
- ~BinUnitsModel(){}
-
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const{Q_UNUSED(parent); return ColumnCount;}
- QVariant data(const QModelIndex&,int role=Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation, int role=Qt::DisplayRole) const;
-
- void setTargetFilePath(int row, const QString&);
-
-private slots:
- void fileLoaded();
- void entryModified(const DocPosition&);
- void updateFile(QString path);
-
-private:
- Catalog* m_catalog;
- mutable QHash<QString,QImage> m_imageCache;
-
-};
-
-#endif // BINUNITSWINDOW_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef ALTTRANS_H
-#define ALTTRANS_H
-
-#include "catalogstring.h"
-#include "tmentry.h"
-
-struct AltTrans
-{
- ///@see @link http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#alttranstype
- enum Type {Proposal, PreviousVersion, Rejected, Reference, Accepted, Other};
- Type type;
-
- CatalogString source;
- CatalogString target;
-
- short score;
-
- QString lang;
- QString origin;
- QString phase;
-
- AltTrans(const CatalogString& s=CatalogString(), const QString& o=QString()):type(Other),source(s),origin(o){}
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file contains parts of KBabel code
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2005 by Stanislav Visnovsky <visnovsky@kde.org>
- 2006 by Nicolas Goutte <goutte@kde.org>
- 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-// #define KDE_NO_DEBUG_OUTPUT
-
-#include "catalog.h"
-#include "catalog_private.h"
-#include "project.h"
-#include "projectmodel.h" //to notify about modification
-
-#include "catalogstorage.h"
-#include "gettextstorage.h"
-#include "gettextimport.h"
-#include "gettextexport.h"
-#include "xliffstorage.h"
-#include "tsstorage.h"
-
-#include "mergecatalog.h"
-
-#include "version.h"
-#include "prefs_lokalize.h"
-#include "jobs.h"
-
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QProcess>
-#include <QString>
-#include <QMap>
-#include <QFileInfo>
-#include <QBuffer>
-#include <QDir>
-
-#include <kdebug.h>
-#include <kglobal.h>
-#include <klocale.h>
-#include <kdatetime.h>
-
-#include <kio/netaccess.h>
-#include <ktemporaryfile.h>
-
-QString Catalog::supportedMimeFilters("text/x-gettext-translation application/x-xliff application/x-linguist");
-
-static const char* const extensions[]={".po",".pot",".xlf", ".ts"};
-
-static const char* const xliff_states[]={
- I18N_NOOP("New"),I18N_NOOP("Needs translation"),I18N_NOOP("Needs full localization"),I18N_NOOP("Needs adaptation"),I18N_NOOP("Translated"),
- I18N_NOOP("Needs translation review"),I18N_NOOP("Needs full localization review"),I18N_NOOP("Needs adaptation review"),I18N_NOOP("Final"),
- I18N_NOOP("Signed-off")};
-
-const char* const* Catalog::states()
-{
- return xliff_states;
-}
-
-QStringList Catalog::supportedExtensions()
-{
- QStringList result;
- int i=sizeof(extensions)/sizeof(char*);
- while (--i>=0)
- result.append(QString(extensions[i]));
- return result;
-}
-
-bool Catalog::extIsSupported(const QString& path)
-{
- QStringList ext=supportedExtensions();
- int i=ext.size();
- while (--i>=0 && !path.endsWith(ext.at(i)))
- ;
- return i!=-1;
-}
-
-Catalog::Catalog(QObject *parent)
- : QUndoStack(parent)
- , d(new CatalogPrivate(this))
- , m_storage(0)
-{
- //cause refresh events for files modified from lokalize itself aint delivered automatically
- connect(this,SIGNAL(signalFileSaved(KUrl)),
- Project::instance()->model(),SLOT(slotFileSaved(KUrl)),Qt::QueuedConnection);
-
-
- QTimer* t=&(d->_autoSaveTimer);
- t->setInterval(5*60*1000);
- t->setSingleShot(false);
- connect(t, SIGNAL(timeout()), this,SLOT(doAutoSave()));
- connect(this,SIGNAL(signalFileSaved()), t,SLOT(start()));
- connect(this,SIGNAL(signalFileLoaded()), t,SLOT(start()));
- connect(this,SIGNAL(indexChanged(int)),this,SLOT(setAutoSaveDirty()));
- connect(Project::local(),SIGNAL(configChanged()),this,SLOT(projectConfigChanged()));
-}
-
-Catalog::~Catalog()
-{
- clear();
- delete d;
- //delete m_storage; //deleted in clear();
-}
-
-
-void Catalog::clear()
-{
- setIndex(cleanIndex());//to keep TM in sync
- QUndoStack::clear();
- d->_errorIndex.clear();
- d->_nonApprovedIndex.clear();
- d->_emptyIndex.clear();
- delete m_storage;m_storage=0;
- d->_url.clear();
- d->_lastModifiedPos=DocPosition();
- d->_modifiedEntries.clear();
-
- while (!d->_altTransCatalogs.isEmpty())
- d->_altTransCatalogs.takeFirst()->deleteLater();
-
- d->_altTranslations.clear();
-/*
- d->msgidDiffList.clear();
- d->msgstr2MsgidDiffList.clear();
- d->diffCache.clear();
- */
-}
-
-
-
-void Catalog::push(QUndoCommand* cmd)
-{
- generatePhaseForCatalogIfNeeded(this);
- QUndoStack::push(cmd);
-}
-
-
-//BEGIN STORAGE TRANSLATION
-
-int Catalog::capabilities() const
-{
- if (Q_UNLIKELY( !m_storage )) return 0;
-
- return m_storage->capabilities();
-}
-
-int Catalog::numberOfEntries() const
-{
- if (Q_UNLIKELY( !m_storage )) return 0;
-
- return m_storage->size();
-}
-
-
-static DocPosition alterForSinglePlural(const Catalog* th, DocPosition pos)
-{
- //if source lang is english (implied) and target lang has only 1 plural form (e.g. Chinese)
- if (Q_UNLIKELY(th->numberOfPluralForms()==1 && th->isPlural(pos)))
- pos.form=1;
- return pos;
-}
-
-QString Catalog::msgid(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return d->CatalogPrivate::_emptyStr;
-
- return m_storage->source(alterForSinglePlural(this, pos));
-}
-
-QString Catalog::msgstr(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return d->CatalogPrivate::_emptyStr;
-
- return m_storage->target(pos);
-}
-
-CatalogString Catalog::sourceWithTags(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return CatalogString();
-
- return m_storage->sourceWithTags(alterForSinglePlural(this, pos));
-
-}
-CatalogString Catalog::targetWithTags(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return CatalogString();
-
- return m_storage->targetWithTags(pos);
-}
-
-CatalogString Catalog::catalogString(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return CatalogString();
-
- return m_storage->catalogString(pos.part==DocPosition::Source?alterForSinglePlural(this, pos):pos);
-}
-
-
-QVector<Note> Catalog::notes(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QVector<Note>();
-
- return m_storage->notes(pos);
-}
-
-QVector<Note> Catalog::developerNotes(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QVector<Note>();
-
- return m_storage->developerNotes(pos);
-}
-
-Note Catalog::setNote(const DocPosition& pos, const Note& note)
-{
- if (Q_UNLIKELY( !m_storage ))
- return Note();
-
- return m_storage->setNote(pos,note);
-}
-
-QStringList Catalog::noteAuthors() const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QStringList();
-
- return m_storage->noteAuthors();
-}
-
-void Catalog::attachAltTransCatalog(Catalog* altCat)
-{
- d->_altTransCatalogs.append(altCat);
- if (numberOfEntries()!=altCat->numberOfEntries())
- kWarning()<<altCat->url().prettyUrl()<<"has different number of entries";
-}
-
-void Catalog::attachAltTrans(int entry, const AltTrans& trans)
-{
- d->_altTranslations.insert(entry, trans);
-}
-
-QVector<AltTrans> Catalog::altTrans(const DocPosition& pos) const
-{
- QVector<AltTrans> result;
- if (m_storage)
- result=m_storage->altTrans(pos);
-
- foreach(Catalog* altCat, d->_altTransCatalogs)
- {
- if (pos.entry>=altCat->numberOfEntries())
- {
- kDebug()<<"ignoring"<<altCat->url().prettyUrl()<<"this time because"<<pos.entry<<"<"<<altCat->numberOfEntries();
- continue;
- }
-
- if (altCat->source(pos)!=source(pos))
- {
- kDebug()<<"ignoring"<<altCat->url().prettyUrl()<<"this time because <source>s don't match";
- continue;
- }
-
- QString target=altCat->msgstr(pos);
- if (!target.isEmpty() && altCat->isApproved(pos))
- {
- result<<AltTrans();
- result.last().target=target;
- result.last().type=AltTrans::Reference;
- result.last().origin=altCat->url().prettyUrl();
- }
- }
- if (d->_altTranslations.contains(pos.entry))
- result<<d->_altTranslations.value(pos.entry);
- return result;
-}
-
-QStringList Catalog::sourceFiles(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QStringList();
-
- return m_storage->sourceFiles(pos);
-}
-
-QString Catalog::id(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return d->CatalogPrivate::_emptyStr;
-
- return m_storage->id(pos);
-}
-
-QStringList Catalog::context(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QStringList();
-
- return m_storage->context(pos);
-}
-
-QString Catalog::setPhase(const DocPosition& pos, const QString& phase)
-{
- if (Q_UNLIKELY( !m_storage ))
- return QString();
-
- return m_storage->setPhase(pos,phase);
-}
-
-
-void Catalog::setActivePhase(const QString& phase, ProjectLocal::PersonRole role)
-{
- d->_phase=phase;
- d->_phaseRole=role;
- updateApprovedEmptyIndexCache();
- emit activePhaseChanged();
-}
-
-void Catalog::updateApprovedEmptyIndexCache()
-{
- if (Q_UNLIKELY( !m_storage ))
- return;
-
- //index cache TODO profile?
- d->_nonApprovedIndex.clear();
- d->_emptyIndex.clear();
-
- DocPosition pos(0);
- const int limit=m_storage->size();
- while (pos.entry<limit)
- {
- if (!isApproved(pos))
- d->_nonApprovedIndex << pos.entry;
- if (m_storage->isEmpty(pos))
- d->_emptyIndex << pos.entry;
-
- ++(pos.entry);
- }
-
- emit signalNumberOfFuzziesChanged();
- emit signalNumberOfEmptyChanged();
-}
-
-QString Catalog::phase(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QString();
-
- return m_storage->phase(pos);
-}
-
-Phase Catalog::phase(const QString& name) const
-{
- return m_storage->phase(name);
-}
-
-QList<Phase> Catalog::allPhases() const
-{
- return m_storage->allPhases();
-}
-
-QVector<Note> Catalog::phaseNotes(const QString& phase) const
-{
- return m_storage->phaseNotes(phase);
-}
-
-QVector<Note> Catalog::setPhaseNotes(const QString& phase, QVector<Note> notes)
-{
- return m_storage->setPhaseNotes(phase, notes);
-}
-
-QMap<QString,Tool> Catalog::allTools() const
-{
- return m_storage->allTools();
-}
-
-bool Catalog::isPlural(uint index) const
-{
- return m_storage && m_storage->isPlural(DocPosition(index));
-}
-
-bool Catalog::isApproved(uint index) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return false;
-
- bool extendedStates=m_storage->capabilities()&ExtendedStates;
-
- return (extendedStates&&::isApproved(state(DocPosition(index)),activePhaseRole()))
- ||(!extendedStates&&m_storage->isApproved(DocPosition(index)));
-}
-
-TargetState Catalog::state(const DocPosition& pos) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return NeedsTranslation;
-
- if (m_storage->capabilities()&ExtendedStates)
- return m_storage->state(pos);
- else
- return closestState(m_storage->isApproved(pos), activePhaseRole());
-}
-
-bool Catalog::isEmpty(uint index) const
-{
- return m_storage && m_storage->isEmpty(DocPosition(index));
-}
-
-bool Catalog::isEmpty(const DocPosition& pos) const
-{
- return m_storage && m_storage->isEmpty(pos);
-}
-
-
-bool Catalog::isEquivTrans(const DocPosition& pos) const
-{
- return m_storage && m_storage->isEquivTrans(pos);
-}
-
-int Catalog::binUnitsCount() const
-{
- return m_storage?m_storage->binUnitsCount():0;
-}
-
-int Catalog::unitById(const QString& id) const
-{
- return m_storage?m_storage->unitById(id):0;
-}
-
-QString Catalog::mimetype()
-{
- if (Q_UNLIKELY( !m_storage ))
- return QString();
-
- return m_storage->mimetype();
-}
-
-QString Catalog::sourceLangCode() const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QString();
-
- return m_storage->sourceLangCode();
-}
-
-QString Catalog::targetLangCode() const
-{
- if (Q_UNLIKELY( !m_storage ))
- return QString();
-
- return m_storage->targetLangCode();
-}
-
-//END STORAGE TRANSLATION
-
-//BEGIN OPEN/SAVE
-#define DOESNTEXIST -1
-#define ISNTREADABLE -2
-#define UNKNOWNFORMAT -3
-
-KAutoSaveFile* Catalog::checkAutoSave(const KUrl& url)
-{
- KAutoSaveFile* autoSave=0;
- QList<KAutoSaveFile*> staleFiles = KAutoSaveFile::staleFiles(url);
- foreach (KAutoSaveFile *stale, staleFiles)
- {
- if (stale->open(QIODevice::ReadOnly) && !autoSave)
- {
- autoSave=stale;
- autoSave->setParent(this);
- }
- else
- stale->deleteLater();
- }
- if (autoSave)
- kWarning()<<"autoSave"<<autoSave->fileName();
- return autoSave;
-}
-
-int Catalog::loadFromUrl(const KUrl& url, const KUrl& saidUrl, int* fileSize, bool fast)
-{
- bool readOnly=false;
- if (url.isLocalFile())
- {
- QFileInfo info(url.toLocalFile());
- if(Q_UNLIKELY( !info.exists() || info.isDir()) )
- return DOESNTEXIST;
- if(Q_UNLIKELY( !info.isReadable() ))
- return ISNTREADABLE;
- readOnly=!info.isWritable();
- }
- else
- return DOESNTEXIST;
-
-
- QTime a;a.start();
-
- QString target;
- //if(Q_UNLIKELY( !KIO::NetAccess::download(url,target,NULL) ))
- // return ISNTREADABLE;
- //QFile* file=new QFile(target);
- QFile* file=new QFile(url.toLocalFile());
- file->deleteLater();//kung-fu
- if (!file->open(QIODevice::ReadOnly))
- return ISNTREADABLE;//TODO
-
- CatalogStorage* storage=0;
- const QString& fileName=url.fileName();
- if (fileName.endsWith(".po")||fileName.endsWith(".pot"))
- storage=new GettextCatalog::GettextStorage;
- else if (fileName.endsWith(".xlf")||fileName.endsWith(".xliff"))
- storage=new XliffStorage;
- else if (fileName.endsWith(".ts"))
- storage=new TsStorage;
- else
- {
- //try harder
- QTextStream in(file);
- int i=0;
- bool gettext=false;
- while (!in.atEnd()&& i<64 && !gettext)
- gettext=in.readLine().contains("msgid");
- if (gettext) storage=new GettextCatalog::GettextStorage;
- else return UNKNOWNFORMAT;
- }
-
- int line=storage->load(file);
-
- file->close();
- KIO::NetAccess::removeTempFile(target);
-
- if (Q_UNLIKELY(line!=0 || (!storage->size() && (line=-1) ) ))
- {
- delete storage;
- return line;
- }
-
- kWarning() <<"file opened in"<<a.elapsed();
-
- //ok...
- clear();
-
- //commit transaction
- m_storage=storage;
-
- updateApprovedEmptyIndexCache();
-
- d->_numberOfPluralForms = storage->numberOfPluralForms();
- d->_autoSaveDirty=true;
- d->_readOnly=readOnly;
- d->_url=saidUrl.isEmpty()?url:saidUrl;
-
- if (!fast)
- {
- KAutoSaveFile* autoSave=checkAutoSave(d->_url);
- d->_autoSaveRecovered=autoSave;
- if (autoSave)
- {
- d->_autoSave->deleteLater();
- d->_autoSave=autoSave;
-
- //restore 'modified' status for entries
- MergeCatalog* mergeCatalog=new MergeCatalog(this,this);
- int errorLine=mergeCatalog->loadFromUrl(KUrl::fromPath(autoSave->fileName()));
- if (Q_LIKELY(errorLine==0))
- mergeCatalog->copyToBaseCatalog();
- mergeCatalog->deleteLater();
- }
- else
- d->_autoSave->setManagedFile(d->_url);
- }
-
- if (fileSize)
- *fileSize=file->size();
-
- emit signalFileLoaded();
- emit signalFileLoaded(d->_url);
- return 0;
-}
-
-bool Catalog::save()
-{
- return saveToUrl(d->_url);
-}
-
-//this function is not called if QUndoStack::isClean() !
-bool Catalog::saveToUrl(KUrl url)
-{
- if (Q_UNLIKELY( !m_storage ))
- return true;
-
- bool nameChanged=false;
- if (Q_LIKELY( url.isEmpty() ))
- url = d->_url;
- else
- nameChanged=true;
-
-
- bool remote=!url.isLocalFile();
- QFile* file;
- if (Q_UNLIKELY( remote ))
- file=new KTemporaryFile();
- else
- {
- QString localFilePath=url.toLocalFile();
- QString localPath=QFileInfo(localFilePath).absolutePath();
- if (!QFileInfo(localPath).exists())
- if (!QDir::root().mkpath(localPath))
- return false;
- file=new QFile(localFilePath);
- }
- file->deleteLater(); //kung-fu ;)
- if (Q_UNLIKELY( !file->open(QIODevice::WriteOnly) )) //i18n("Wasn't able to open file %1",filename.ascii());
- return false;
-
- bool belongsToProject=url.path().contains(Project::instance()->poDir());
- if (Q_UNLIKELY( !m_storage->save(file, belongsToProject) ))
- return false;
-
- QString localFile=file->fileName();
- file->close();
- if (Q_UNLIKELY(remote && !KIO::NetAccess::upload(localFile, url, NULL) ))
- return false;
-
- d->_autoSave->remove();
- setClean(); //undo/redo
- if (nameChanged)
- {
- d->_url=url;
- d->_autoSave->setManagedFile(url);
- }
- d->_autoSaveRecovered=false;
-
- //Settings::self()->setCurrentGroup("Bookmarks");
- //Settings::self()->addItemIntList(d->_url.url(),d->_bookmarkIndex);
-
- emit signalFileSaved();
- emit signalFileSaved(url);
- return true;
-/*
- else if (status==NO_PERMISSIONS)
- {
- if (KMessageBox::warningContinueCancel(this,
- i18n("You do not have permission to write to file:\n%1\n"
- "Do you want to save to another file or cancel?", _currentURL.prettyUrl()),
- i18n("Error"),KStandardGuiItem::save())==KMessageBox::Continue)
- return fileSaveAs();
-
- }
-*/
-}
-
-void Catalog::doAutoSave()
-{
- if (isClean()||!(d->_autoSaveDirty))
- return;
- if (Q_UNLIKELY( !m_storage ))
- return;
- if (!d->_autoSave->open(QIODevice::WriteOnly))
- {
- emit signalFileAutoSaveFailed(d->_autoSave->fileName());
- return;
- }
- qWarning()<<"doAutoSave"<<d->_autoSave->fileName();
- m_storage->save(d->_autoSave);
- d->_autoSave->close();
- d->_autoSaveDirty=false;
-}
-
-void Catalog::projectConfigChanged()
-{
- setActivePhase(activePhase(), Project::local()->role());
-}
-
-QByteArray Catalog::contents()
-{
- QBuffer buf;
- buf.open(QIODevice::WriteOnly);
- m_storage->save(&buf);
- buf.close();
- return buf.data();
-}
-
-//END OPEN/SAVE
-
-
-
- /**
- * helper method to keep db in a good shape :)
- * called on
- * 1) entry switch
- * 2) automatic editing code like replace or undo/redo operation
- **/
-static void updateDB(
- const QString& filePath,
- const QString& ctxt,
- const CatalogString& english,
- const CatalogString& newTarget,
- int form,
- bool approved
- //const DocPosition&,//for back tracking
- )
-{
- TM::UpdateJob* j=new TM::UpdateJob(filePath,ctxt,english,newTarget,form,approved,
- Project::instance()->projectID());
- j->connect(j,SIGNAL(done(ThreadWeaver::Job*)),j,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(j);
-}
-
-
-//BEGIN UNDO/REDO
-const DocPosition& Catalog::undo()
-{
- QUndoStack::undo();
- return d->_lastModifiedPos;
-}
-
-const DocPosition& Catalog::redo()
-{
- QUndoStack::redo();
- return d->_lastModifiedPos;
-}
-
-void Catalog::flushUpdateDBBuffer()
-{
- if (!Settings::autoaddTM())
- return;
-
- DocPosition pos=d->_lastModifiedPos;
- if (pos.entry==-1 || pos.entry>=numberOfEntries())
- {
- //nothing to flush
- //kWarning()<<"nothing to flush or new file opened";
- return;
- }
- if (Project::instance()->targetLangCode()!=targetLangCode())
- {
- kWarning()<<"not updating because target languages don't match";
- return;
- }
- kWarning()<<"updating!!";
- int form=-1;
- if (isPlural(pos.entry))
- form=pos.form;
- updateDB(url().pathOrUrl(),
- context(pos.entry).first(),
- sourceWithTags(pos),
- targetWithTags(pos),
- form,
- isApproved(pos.entry));
-
- d->_lastModifiedPos=DocPosition();
-}
-
-void Catalog::setLastModifiedPos(const DocPosition& pos)
-{
- if (pos.entry>=numberOfEntries()) //bin-units
- return;
-
- bool entryChanged=DocPos(d->_lastModifiedPos)!=DocPos(pos);
- if (entryChanged)
- flushUpdateDBBuffer();
-
- d->_lastModifiedPos=pos;
-}
-
-bool CatalogPrivate::addToEmptyIndexIfAppropriate(CatalogStorage* storage, const DocPosition& pos, bool alreadyEmpty)
-{
- if ((!pos.offset)&&(storage->target(pos).isEmpty())&&(!alreadyEmpty))
- {
- insertInList(_emptyIndex,pos.entry);
- return true;
- }
- return false;
-}
-
-void Catalog::targetDelete(const DocPosition& pos, int count)
-{
- if (Q_UNLIKELY( !m_storage ))
- return;
-
- bool alreadyEmpty = m_storage->isEmpty(pos);
- m_storage->targetDelete(pos,count);
-
- if (d->addToEmptyIndexIfAppropriate(m_storage,pos,alreadyEmpty))
- emit signalNumberOfEmptyChanged();
- emit signalEntryModified(pos);
-}
-
-bool CatalogPrivate::removeFromUntransIndexIfAppropriate(CatalogStorage* storage, const DocPosition& pos)
-{
- if ((!pos.offset)&&(storage->isEmpty(pos)))
- {
- _emptyIndex.removeAll(pos.entry);
- return true;
- }
- return false;
-}
-
-void Catalog::targetInsert(const DocPosition& pos, const QString& arg)
-{
- if (Q_UNLIKELY( !m_storage ))
- return;
-
- if (d->removeFromUntransIndexIfAppropriate(m_storage,pos))
- emit signalNumberOfEmptyChanged();
-
- m_storage->targetInsert(pos,arg);
- emit signalEntryModified(pos);
-}
-
-void Catalog::targetInsertTag(const DocPosition& pos, const InlineTag& tag)
-{
- if (Q_UNLIKELY( !m_storage ))
- return;
-
- if (d->removeFromUntransIndexIfAppropriate(m_storage,pos))
- emit signalNumberOfEmptyChanged();
-
- m_storage->targetInsertTag(pos,tag);
- emit signalEntryModified(pos);
-}
-
-InlineTag Catalog::targetDeleteTag(const DocPosition& pos)
-{
- if (Q_UNLIKELY( !m_storage ))
- return InlineTag();
-
- bool alreadyEmpty = m_storage->isEmpty(pos);
- InlineTag tag=m_storage->targetDeleteTag(pos);
-
- if (d->addToEmptyIndexIfAppropriate(m_storage,pos,alreadyEmpty))
- emit signalNumberOfEmptyChanged();
- emit signalEntryModified(pos);
- return tag;
-}
-
-void Catalog::setTarget(DocPosition pos, const CatalogString& s)
-{
- //TODO for case of markup present
- m_storage->setTarget(pos, s.string);
-}
-
-TargetState Catalog::setState(const DocPosition& pos, TargetState state)
-{
- bool extendedStates=m_storage->capabilities()&ExtendedStates;
- bool approved=::isApproved(state,activePhaseRole());
- if (Q_UNLIKELY( !m_storage
- || (extendedStates && m_storage->state(pos)==state)
- || (!extendedStates && m_storage->isApproved(pos)==approved)))
- return this->state(pos);
-
- TargetState prevState;
- if (extendedStates)
- {
- prevState=m_storage->setState(pos,state);
- d->_statesIndex[prevState].removeAll(pos.entry);
- insertInList(d->_statesIndex[state],pos.entry);
- }
- else
- {
- prevState=closestState(!approved,activePhaseRole());
- m_storage->setApproved(pos,approved);
- }
-
- if (!approved)
- insertInList(d->_nonApprovedIndex,pos.entry);
- else
- d->_nonApprovedIndex.removeAll(pos.entry);
-
- emit signalNumberOfFuzziesChanged();
- emit signalEntryModified(pos);
-
- return prevState;
-}
-
-Phase Catalog::updatePhase(const Phase& phase)
-{
- return m_storage->updatePhase(phase);
-}
-
-void Catalog::setEquivTrans(const DocPosition& pos, bool equivTrans)
-{
- if (m_storage) m_storage->setEquivTrans(pos, equivTrans);
-}
-
-bool Catalog::setModified(DocPos entry, bool modified)
-{
- if (modified)
- {
- if (d->_modifiedEntries.contains(entry))
- return false;
- d->_modifiedEntries.insert(entry);
- }
- else
- d->_modifiedEntries.remove(entry);
- return true;
-}
-
-bool Catalog::isModified(DocPos entry) const
-{
- return d->_modifiedEntries.contains(entry);
-}
-
-bool Catalog::isModified(int entry) const
-{
- if (!isPlural(entry))
- return isModified(DocPos(entry,0));
-
- int f=numberOfPluralForms();
- while(--f>=0)
- if (isModified(DocPos(entry,f)))
- return true;
- return false;
-}
-
-//END UNDO/REDO
-
-
-
-
-int findNextInList(const QLinkedList<int>& list, int index)
-{
- int nextIndex=-1;
- foreach(int key, list)
- {
- if (Q_UNLIKELY( key>index ))
- {
- nextIndex = key;
- break;
- }
- }
- return nextIndex;
-}
-
-int findPrevInList(const QLinkedList<int>& list, int index)
-{
- int prevIndex=-1;
- foreach(int key, list)
- {
- if (Q_UNLIKELY( key>=index ))
- break;
- prevIndex = key;
- }
- return prevIndex;
-}
-
-void insertInList(QLinkedList<int>& list, int index)
-{
- QLinkedList<int>::Iterator it=list.begin();
- while(it != list.end() && index > *it)
- ++it;
- list.insert(it,index);
-}
-
-void Catalog::setBookmark(uint idx, bool set)
-{
- if (set)
- insertInList(d->_bookmarkIndex,idx);
- else
- d->_bookmarkIndex.removeAll(idx);
-}
-
-
-bool isApproved(TargetState state, ProjectLocal::PersonRole role)
-{
- static const TargetState marginStates[]={Translated, Final, SignedOff};
- return state>=marginStates[role];
-}
-
-bool isApproved(TargetState state)
-{
- static const TargetState marginStates[]={Translated, Final, SignedOff};
- return state==marginStates[0] || state==marginStates[1] || state==marginStates[2];
-}
-
-TargetState closestState(bool approved, ProjectLocal::PersonRole role)
-{
- static const TargetState approvementStates[][3]={
- {NeedsTranslation, NeedsReviewTranslation, NeedsReviewTranslation},
- {Translated, Final, SignedOff}
- };
- return approvementStates[approved][role];
-}
-
-
-bool Catalog::isObsolete(int entry) const
-{
- if (Q_UNLIKELY( !m_storage ))
- return false;
-
- return m_storage->isObsolete(entry);
-}
-
-
-#include "moc_catalog.cpp"
+++ /dev/null
-/*****************************************************************************
- This file is part of Lokalize
- This file contains parts of KBabel code
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2004 by Stanislav Visnovsky <visnovsky@kde.org>
- 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#ifndef CATALOG_H
-#define CATALOG_H
-
-#include "pos.h"
-#include "catalogstring.h"
-#include "catalogcapabilities.h"
-#include "note.h"
-#include "state.h"
-#include "phase.h"
-#include "alttrans.h"
-#include "catalog_private.h"
-class CatalogStorage;
-
-#include <QUndoStack>
-#include <kurl.h>
-
-namespace GettextCatalog {
- class CatalogImportPlugin;
- class CatalogExportPlugin;
-}
-
-
-bool isApproved(TargetState state, ProjectLocal::PersonRole role);
-bool isApproved(TargetState state); //disregarding Phase
-TargetState closestState(bool approved, ProjectLocal::PersonRole role);
-int findPrevInList(const QLinkedList<int>& list,int index);
-int findNextInList(const QLinkedList<int>& list,int index);
-void insertInList(QLinkedList<int>& list, int index); // insert index in the right place in the list
-
-
-/**
- * This class represents a catalog
- * It uses CatalogStorage interface to work with catalogs in different formats
- * Also it defines all necessary functions to set and get the entries
- *
- * @short Wrapper class that represents a translation catalog
- * @author Nick Shaforostoff <shafff@ukr.net>
-*/
-class Catalog: public QUndoStack
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.Lokalize.FileContainer")
-
-public:
- Catalog(QObject* parent);
- virtual ~Catalog();
-
- QString msgid(const DocPosition&) const;
- virtual QString msgstr(const DocPosition&) const;
-
- static QStringList supportedExtensions();
- static bool extIsSupported(const QString& path);
- static const char* const* states();
-
- int capabilities() const;
-
- void push(QUndoCommand* cmd);
-
-public slots: //DBus interface
- QString source(const DocPosition& pos) const {return msgid(pos);}
- QString target(const DocPosition& pos) const {return msgstr(pos);}
- // used by XLIFF storage)
- CatalogString sourceWithTags(const DocPosition& pos) const;
- CatalogString targetWithTags(const DocPosition& pos) const;
- CatalogString catalogString(const DocPosition& pos) const;
-
- /**
- * @a pos.form is note number
- * @returns previous note contents, if any
- */
- Note setNote(const DocPosition& pos, const Note& note);
- QVector<Note> notes(const DocPosition& pos) const;
- QVector<Note> developerNotes(const DocPosition& pos) const;
- QStringList noteAuthors() const;
- QVector<AltTrans> altTrans(const DocPosition& pos) const;
- QStringList sourceFiles(const DocPosition& pos) const;
- //QString msgctxt(uint index) const;
- //the result is guaranteed to have at least 1 string
- QStringList context(const DocPosition& pos) const;
- QString id(const DocPosition& pos) const;
- ///@returns previous phase-name
- QString setPhase(const DocPosition& pos, const QString& phase);
- QString phase(const DocPosition& pos) const;
- QString activePhase() const{return d->_phase;}
- ProjectLocal::PersonRole activePhaseRole() const{return d->_phaseRole;}
- void setActivePhase(const QString& phase, ProjectLocal::PersonRole role=ProjectLocal::Approver);
- Phase phase(const QString& name) const;
- QList<Phase> allPhases() const;
- QMap<QString,Tool> allTools() const;
- QVector<Note> phaseNotes(const QString& phase) const;
- ///@arg pos.entry - number of phase, @arg pos.form - number of note
- QVector<Note> setPhaseNotes(const QString& phase, QVector<Note>);
-
- bool isPlural(uint index) const;
- bool isPlural(const DocPosition& pos) const{return isPlural(pos.entry);}
- bool isApproved(uint index) const;
- bool isApproved(const DocPosition& pos) const{return isApproved(pos.entry);}
- TargetState state(const DocPosition& pos) const;
- bool isEquivTrans(const DocPosition&) const;
- ///@returns true if at least one form is untranslated
- bool isEmpty(uint index) const;
- bool isEmpty(const DocPosition&) const;
- bool isModified(DocPos entry) const;
- bool isModified(int entry) const;
- bool isObsolete(int entry) const;
-
- /// so DocPosition::entry may actually be < size()+binUnitsCount()
- int binUnitsCount() const;
-
- int unitById(const QString& id) const;
-
- bool isBookmarked(uint index) const{return d->_bookmarkIndex.contains(index);}
- void setBookmark(uint, bool);
-
- int numberOfPluralForms() const {return d->_numberOfPluralForms;}
- int numberOfEntries() const;
- int numberOfNonApproved() const {return d->_nonApprovedIndex.size();}
- int numberOfUntranslated() const {return d->_emptyIndex.size();}
-
-
-public:
- int firstFuzzyIndex() const {return d->_nonApprovedIndex.isEmpty()?numberOfEntries():d->_nonApprovedIndex.first();}
- int lastFuzzyIndex() const {return d->_nonApprovedIndex.isEmpty()?-1:d->_nonApprovedIndex.last();}
- int nextFuzzyIndex(uint index) const {return findNextInList(d->_nonApprovedIndex,index);}
- int prevFuzzyIndex(uint index) const {return findPrevInList(d->_nonApprovedIndex,index);}
- int firstUntranslatedIndex() const {return d->_emptyIndex.isEmpty()?numberOfEntries():d->_emptyIndex.first();}
- int lastUntranslatedIndex() const {return d->_emptyIndex.isEmpty()?-1:d->_emptyIndex.last();}
- int nextUntranslatedIndex(uint index) const {return findNextInList(d->_emptyIndex,index);}
- int prevUntranslatedIndex(uint index) const {return findPrevInList(d->_emptyIndex,index);}
-
- int firstBookmarkIndex() const {return d->_bookmarkIndex.isEmpty()?numberOfEntries():d->_bookmarkIndex.first();}
- int lastBookmarkIndex() const {return d->_bookmarkIndex.isEmpty()?-1:d->_bookmarkIndex.last();}
- int nextBookmarkIndex(uint index) const {return findNextInList(d->_bookmarkIndex,index);}
- int prevBookmarkIndex(uint index) const {return findPrevInList(d->_bookmarkIndex,index);}
-
- bool autoSaveRecovered(){return d->_autoSaveRecovered;}
-public:
- void clear();
- bool isEmpty(){return !m_storage;}
- bool isReadOnly(){return d->_readOnly;}
-
- void attachAltTransCatalog(Catalog*);
- void attachAltTrans(int entry, const AltTrans& trans);
-
-
- virtual const DocPosition& undo();
- virtual const DocPosition& redo();
-
- void setTarget(DocPosition pos, const CatalogString& s); //for batch use only!
-
- //void setErrorIndex(const QList<int>& errors){d->_errorIndex=errors;}
- void setUrl(const KUrl& u){d->_url=u;}//used for template load
-public slots: //DBus interface
- const KUrl& url() const {return d->_url;}
- ///@returns 0 if success, >0 erroneous line (parsing error)
- int loadFromUrl(const KUrl& url, const KUrl& saidUrl=KUrl(), int* fileSize=0, bool fast = false);
- bool saveToUrl(KUrl url);
- bool save();
- QByteArray contents();
- QString mimetype();
- QString sourceLangCode() const;
- QString targetLangCode() const;
-
-protected:
- virtual KAutoSaveFile* checkAutoSave(const KUrl& url);
-
-protected slots:
- /**
- * updates DB for _posBuffer and accompanying _originalForLastModified
- */
- void flushUpdateDBBuffer();
-
- void doAutoSave();
- void setAutoSaveDirty(){d->_autoSaveDirty=true;}
-
- void projectConfigChanged();
-
-protected:
- /**
- * (EDITING)
- * accessed from undo/redo code
- * called _BEFORE_ modification
- */
- void setLastModifiedPos(const DocPosition&);
-
- /**
- * (EDITING)
- * accessed from undo/redo code
- * accessed from mergeCatalog)
- * it _does_ check if action should be taken
- */
- void setApproved(const DocPosition& pos, bool approved);
- void targetDelete(const DocPosition& pos, int count);
- void targetInsert(const DocPosition& pos, const QString& arg);
- InlineTag targetDeleteTag(const DocPosition& pos);
- void targetInsertTag(const DocPosition& pos, const InlineTag& tag);
- TargetState setState(const DocPosition& pos, TargetState state);
- Phase updatePhase(const Phase& phase);
- void setEquivTrans(const DocPosition&, bool equivTrans);
-
- /// @returns true if entry wasn't modified before
- bool setModified(DocPos entry, bool modif);
-
- void updateApprovedEmptyIndexCache();
-
-protected:
- CatalogPrivate *d;
- CatalogStorage *m_storage;
-
- friend class GettextCatalog::CatalogImportPlugin;
- friend class GettextCatalog::CatalogExportPlugin;
- friend class LokalizeUnitCmd;
- friend class InsTextCmd;
- friend class DelTextCmd;
- friend class InsTagCmd;
- friend class DelTagCmd;
- friend class SetStateCmd;
- friend class SetNoteCmd;
- friend class UpdatePhaseCmd;
- friend class MergeCatalog;
- friend class SetEquivTransCmd;
-
-public:
- static QString supportedMimeFilters;
-
-signals:
- void signalEntryModified(const DocPosition&);
- void activePhaseChanged();
- void signalNumberOfFuzziesChanged();
- void signalNumberOfEmptyChanged();
- Q_SCRIPTABLE void signalFileLoaded();
- void signalFileLoaded(const KUrl&);
- Q_SCRIPTABLE void signalFileSaved();
- void signalFileSaved(const KUrl&);
- void signalFileAutoSaveFailed(const QString&);
-};
-
-
-#endif
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file is based on the one from KBabel
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2004 by Stanislav Visnovsky <visnovsky@kde.org>
- 2007 by Nick Shaforostoff <shafff@ukr.net>
-
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#ifndef CATALOGPRIVATE_H
-#define CATALOGPRIVATE_H
-
-#include "projectlocal.h"
-#include "state.h"
-#include "pos.h"
-#include "alttrans.h"
-
-#include <kurl.h>
-#include <kautosavefile.h>
-
-#include <QList>
-#include <QLinkedList>
-#include <QStringList>
-#include <QVector>
-#include <QMap>
-#include <QSet>
-#include <QTimer>
-
-#include <QTextCodec>
-class CatalogStorage;
-class Catalog;
-
-class CatalogPrivate
-{
-
-public:
-
- /** url of the po-file, that belongs to this catalog */
- KUrl _url;
- QString _packageName;
- QString _packageDir;
-
- /** identification string for used import filter*/
- QString _importID;
- QString _mimeTypes;
-
- QTextCodec *fileCodec;
-
- QString _emptyStr;
-
- int _numberOfPluralForms;
-
- QTimer _autoSaveTimer;
- KAutoSaveFile* _autoSave;
- bool _autoSaveDirty;
- bool _autoSaveRecovered;
-
- bool _readOnly;
- //for wrapping
- short _maxLineLength;
-
- QLinkedList<int> _nonApprovedIndex;
- QLinkedList<int> _emptyIndex;
- QLinkedList<int> _errorIndex;
-
- QLinkedList<int> _bookmarkIndex;
-
- QVector< QLinkedList<int> > _statesIndex;
-
-
- QLinkedList<Catalog*> _altTransCatalogs;
- QMap<int, AltTrans> _altTranslations;
-
- //for undo/redo
- //keeps pos of the entry that was last modified
- DocPosition _lastModifiedPos;
-
- QSet<DocPos> _modifiedEntries;//just for the nice gui
-
- QString _phase;
- ProjectLocal::PersonRole _phaseRole;
-
- explicit CatalogPrivate(QObject* parent)
- : _mimeTypes( "text/plain" )
- , fileCodec(0)
- , _numberOfPluralForms(-1)
- , _autoSave(new KAutoSaveFile(parent))
- , _autoSaveDirty(true)
- , _autoSaveRecovered(false)
- , _readOnly(false)
- , _phaseRole(ProjectLocal::Undefined)
- {
- _statesIndex.resize(StateCount);
- }
-
- bool addToEmptyIndexIfAppropriate(CatalogStorage*, const DocPosition& pos, bool alreadyEmpty);
- bool removeFromUntransIndexIfAppropriate(CatalogStorage*, const DocPosition& pos);
-};
-
-
-#endif //CatalogPrivate_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef CATALOGCAPABILITIES_H
-#define CATALOGCAPABILITIES_H
-
-enum CatalogCapabilities
-{
- KeepsNoteAuthors=1,
- MultipleNotes=2,
- Phases=4,
- ExtendedStates=8,
- Tags=16
-};
-
-#endif
+++ /dev/null
-/*
-Copyright 2008-2009 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef CATALOGSTORAGE_H
-#define CATALOGSTORAGE_H
-
-#include "pos.h"
-#include "catalogstring.h"
-#include "note.h"
-#include "state.h"
-#include "phase.h"
-#include "alttrans.h"
-#include "catalogcapabilities.h"
-
-#include <kurl.h>
-#include <QStringList>
-
-
-/**
- * Abstract interface for storage of translation file
- *
- * format-specific elements like \" for gettext PO should be eliminated
- *
- * @short Abstract interface for storage of translation file
- * @author Nick Shaforostoff <shafff@ukr.net>
-*/
-class CatalogStorage {
-public:
- CatalogStorage();
- virtual ~CatalogStorage();
-
- virtual int capabilities() const=0;
-
- virtual int load(QIODevice* device)=0;
- virtual bool save(QIODevice* device, bool belongsToProject=false)=0;
-
- virtual int size() const=0;
- int numberOfEntries()const{return size();}
- int numberOfPluralForms() const{return m_numberOfPluralForms;}
-
- /**
- * flat-model interface (ignores XLIFF grouping)
- *
- * format-specific texts like \" for gettext PO should be eliminated
- **/
- virtual QString source(const DocPosition& pos) const=0;
- virtual QString target(const DocPosition& pos) const=0;
- virtual CatalogString sourceWithTags(DocPosition pos) const=0;
- virtual CatalogString targetWithTags(DocPosition pos) const=0;
- virtual CatalogString catalogString(const DocPosition& pos) const=0;
-
- /**
- * edit operations used by undo/redo system and sync-mode
- **/
- virtual void targetDelete(const DocPosition& pos, int count)=0;
- virtual void targetInsert(const DocPosition& pos, const QString& arg)=0;
- virtual void setTarget(const DocPosition& pos, const QString& arg)=0;//called for mergeCatalog TODO switch to CatalogString
- virtual void targetInsertTag(const DocPosition&, const InlineTag&){}
- virtual InlineTag targetDeleteTag(const DocPosition&){return InlineTag();}
- virtual Phase updatePhase(const Phase&){return Phase();}
- virtual QList<Phase> allPhases() const{return QList<Phase>();}
- virtual QMap<QString,Tool> allTools() const{return QMap<QString,Tool>();}
-
- /// all plural forms. pos.form doesn't matter
- virtual QStringList sourceAllForms(const DocPosition& pos, bool stripNewLines=false) const=0;
- virtual QStringList targetAllForms(const DocPosition& pos, bool stripNewLines=false) const=0;
-
- virtual QVector<AltTrans> altTrans(const DocPosition& pos) const=0;
- virtual QVector<Note> notes(const DocPosition& pos) const=0;
- virtual Note setNote(DocPosition pos, const Note& note)=0;
- virtual QStringList noteAuthors() const{return QStringList();}
- virtual QVector<Note> developerNotes(const DocPosition& pos) const=0;
- virtual QStringList sourceFiles(const DocPosition& pos) const=0;
-
- virtual QString setPhase(const DocPosition& pos, const QString& phase){Q_UNUSED(pos); Q_UNUSED(phase); return QString();}
- virtual QString phase(const DocPosition& pos) const {Q_UNUSED(pos); return QString();}
- virtual Phase phase(const QString& name) const{Q_UNUSED(name); return Phase();}
- virtual QVector<Note> phaseNotes(const QString& phase) const{Q_UNUSED(phase); return QVector<Note>();}
- virtual QVector<Note> setPhaseNotes(const QString& phase, QVector<Note> notes){Q_UNUSED(phase); Q_UNUSED(notes); return QVector<Note>();}
-
- //the result must be guaranteed to have at least 1 string
- virtual QStringList context(const DocPosition&) const=0;
- //DocPosition.form - number of <context>
- //virtual QString context(const DocPosition&) const=0;
- //virtual int contextCount(const DocPosition&) const=0;
-
- /**
- * user-invisible data for matching, e.g. during TM database lookup
- * it is comprised of several strings
- *
- * database stores <!--hashes of each of--> them and thus it is possible to
- * fuzzy-match 'matchData' later
- *
- * it is responsibility of CatalogStorage implementations to
- * separate/assemble the list properly according to the format specifics
- *
- * pos.form doesn't matter
- **/
- virtual QStringList matchData(const DocPosition&) const=0;
-
- /**
- * entry id unique for this file
- *
- * pos.form doesn't matter
- **/
- virtual QString id(const DocPosition&) const=0;
-
- virtual bool isPlural(const DocPosition&) const=0;
-
- virtual bool isEmpty(const DocPosition&) const=0;
-
- virtual bool isEquivTrans(const DocPosition&) const{return true;}
- virtual void setEquivTrans(const DocPosition&, bool equivTrans){Q_UNUSED(equivTrans);}
-
- virtual bool isApproved(const DocPosition&) const{return true;}
- virtual void setApproved(const DocPosition&, bool approved){Q_UNUSED(approved);}
- virtual TargetState state(const DocPosition&) const{return New;}
- virtual TargetState setState(const DocPosition&, TargetState){return New;}
-
- virtual bool isObsolete(int entry) const{return false;}
-
- virtual int binUnitsCount() const {return 0;}
- virtual int unitById(const QString& id) const {Q_UNUSED(id); return 0;}
-
- const KUrl& url() const {return m_url;}
- void setUrl(const KUrl& u){m_url=u;}//TODO
-
- virtual QString mimetype() const=0;
-
- QString sourceLangCode() const{return m_sourceLangCode;}
- QString targetLangCode() const{return m_targetLangCode;}
-
-protected:
- KUrl m_url;
- QString m_sourceLangCode;
- QString m_targetLangCode;
-
- int m_numberOfPluralForms;
-};
-
-inline CatalogStorage::CatalogStorage()
- : m_sourceLangCode("en_US")
- , m_numberOfPluralForms(0)
-{
-}
-
-inline CatalogStorage::~CatalogStorage()
-{
-}
-
-
-
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "catalogstring.h"
-#include <kdebug.h>
-#include <klocale.h>
-
-
-const char* InlineTag::getElementName(InlineElement type)
-{
- static const char* inlineElementNames[(int)InlineElementCount]={
- "_unknown",
- "bpt",
- "ept",
- "ph",
- "it",
- //"_NEVERSHOULDBECHOSEN",
- "mrk",
- "g",
- "sub",
- "_NEVERSHOULDBECHOSEN",
- "x",
- "bx",
- "ex"
- };
-
- return inlineElementNames[(int)type];
-}
-
-InlineTag InlineTag::getPlaceholder() const
-{
- InlineTag tagRange=*this;
- tagRange.start=-1;
- tagRange.end=-1;
- return tagRange;
-}
-
-InlineTag::InlineElement InlineTag::getElementType(const QByteArray& tag)
-{
- int i=InlineTag::InlineElementCount;
- while(--i>0)
- if (getElementName(InlineElement(i))==tag)
- break;
- return InlineElement(i);
-}
-
-
-QString InlineTag::displayName() const
-{
- static const char* inlineElementNames[(int)InlineElementCount]={
- "_unknown",
- I18N_NOOP2("XLIFF inline tag name", "Start of paired tag"),
- I18N_NOOP2("XLIFF inline tag name", "End of paired tag"),
- I18N_NOOP2("XLIFF inline tag name", "Stand-alone tag"),
- I18N_NOOP2("XLIFF inline tag name", "Isolated tag"),
- //"_NEVERSHOULDBECHOSEN",
- I18N_NOOP2("XLIFF inline tag name", "Marker"),
- I18N_NOOP2("XLIFF inline tag name", "Generic group placeholder"),
- I18N_NOOP2("XLIFF inline tag name", "Sub-flow"),
- "_NEVERSHOULDBECHOSEN",
- I18N_NOOP2("XLIFF inline tag name", "Generic placeholder"),
- I18N_NOOP2("XLIFF inline tag name", "Start of paired placeholder"),
- I18N_NOOP2("XLIFF inline tag name", "End of paired placeholder")
- };
-
- QString result=i18nc("XLIFF inline tag name", inlineElementNames[type]);
-
- if (type==mrk)
- {
- static const char* mrkTypes[]={
- "abbrev",
- "abbreviated-form",
- "abbreviation",
- "acronym",
- "appellation",
- "collocation",
- "common-name",
- "datetime",
- "equation",
- "expanded-form",
- "formula",
- "head-term",
- "initialism",
- "international-scientific-term",
- "internationalism",
- "logical-expression",
- "materials-management-unit",
- "name",
- "near-synonym",
- "part-number",
- "phrase",
- "phraseological-unit",
- "protected",
- "romanized-form",
- "seg",
- "set-phrase",
- "short-form",
- "sku",
- "standard-text",
- "symbol",
- "synonym",
- "synonymous-phrase",
- "term",
- "transcribed-form",
- "transliterated-form",
- "truncated-term",
- "variant"
- };
-
- static const char* mrkTypeNames[]={
- I18N_NOOP2("XLIFF mark type", "abbreviation"),
- I18N_NOOP2("XLIFF mark type", "abbreviated form: a term resulting from the omission of any part of the full term while designating the same concept"),
- I18N_NOOP2("XLIFF mark type", "abbreviation: an abbreviated form of a simple term resulting from the omission of some of its letters (e.g. 'adj.' for 'adjective')"),
- I18N_NOOP2("XLIFF mark type", "acronym: an abbreviated form of a term made up of letters from the full form of a multiword term strung together into a sequence pronounced only syllabically (e.g. 'radar' for 'radio detecting and ranging')"),
- I18N_NOOP2("XLIFF mark type", "appellation: a proper-name term, such as the name of an agency or other proper entity"),
- I18N_NOOP2("XLIFF mark type", "collocation: a recurrent word combination characterized by cohesion in that the components of the collocation must co-occur within an utterance or series of utterances, even though they do not necessarily have to maintain immediate proximity to one another"),
- I18N_NOOP2("XLIFF mark type", "common name: a synonym for an international scientific term that is used in general discourse in a given language"),
- I18N_NOOP2("XLIFF mark type", "date and/or time"),
- I18N_NOOP2("XLIFF mark type", "equation: an expression used to represent a concept based on a statement that two mathematical expressions are, for instance, equal as identified by the equal sign (=), or assigned to one another by a similar sign"),
- I18N_NOOP2("XLIFF mark type", "expanded form: The complete representation of a term for which there is an abbreviated form"),
- I18N_NOOP2("XLIFF mark type", "formula: figures, symbols or the like used to express a concept briefly, such as a mathematical or chemical formula"),
- I18N_NOOP2("XLIFF mark type", "head term: the concept designation that has been chosen to head a terminological record"),
- I18N_NOOP2("XLIFF mark type", "initialism: an abbreviated form of a term consisting of some of the initial letters of the words making up a multiword term or the term elements making up a compound term when these letters are pronounced individually (e.g. 'BSE' for 'bovine spongiform encephalopathy')"),
- I18N_NOOP2("XLIFF mark type", "international scientific term: a term that is part of an international scientific nomenclature as adopted by an appropriate scientific body"),
- I18N_NOOP2("XLIFF mark type", "internationalism: a term that has the same or nearly identical orthographic or phonemic form in many languages"),
- I18N_NOOP2("XLIFF mark type", "logical expression: an expression used to represent a concept based on mathematical or logical relations, such as statements of inequality, set relationships, Boolean operations, and the like"),
- I18N_NOOP2("XLIFF mark type", "materials management unit: a unit to track object"),
- I18N_NOOP2("XLIFF mark type", "name"),
- I18N_NOOP2("XLIFF mark type", "near synonym: a term that represents the same or a very similar concept as another term in the same language, but for which interchangeability is limited to some contexts and inapplicable in others"),
- I18N_NOOP2("XLIFF mark type", "part number: a unique alphanumeric designation assigned to an object in a manufacturing system"),
- I18N_NOOP2("XLIFF mark type", "phrase"),
- I18N_NOOP2("XLIFF mark type", "phraseological: a group of two or more words that form a unit, the meaning of which frequently cannot be deduced based on the combined sense of the words making up the phrase"),
- I18N_NOOP2("XLIFF mark type", "protected: the marked text should not be translated"),
- I18N_NOOP2("XLIFF mark type", "romanized form: a form of a term resulting from an operation whereby non-Latin writing systems are converted to the Latin alphabet"),
- I18N_NOOP2("XLIFF mark type", "segment: the marked text represents a segment"),
- I18N_NOOP2("XLIFF mark type", "set phrase: a fixed, lexicalized phrase"),
- I18N_NOOP2("XLIFF mark type", "short form: a variant of a multiword term that includes fewer words than the full form of the term (e.g. 'Group of Twenty-four' for 'Intergovernmental Group of Twenty-four on International Monetary Affairs')"),
- I18N_NOOP2("XLIFF mark type", "stock keeping unit: an inventory item identified by a unique alphanumeric designation assigned to an object in an inventory control system"),
- I18N_NOOP2("XLIFF mark type", "standard text: a fixed chunk of recurring text"),
- I18N_NOOP2("XLIFF mark type", "symbol: a designation of a concept by letters, numerals, pictograms or any combination thereof"),
- I18N_NOOP2("XLIFF mark type", "synonym: a term that represents the same or a very similar concept as the main entry term in a term entry"),
- I18N_NOOP2("XLIFF mark type", "synonymous phrase: phraseological unit in a language that expresses the same semantic content as another phrase in that same language"),
- I18N_NOOP2("XLIFF mark type", "term"),
- I18N_NOOP2("XLIFF mark type", "transcribed form: a form of a term resulting from an operation whereby the characters of one writing system are represented by characters from another writing system, taking into account the pronunciation of the characters converted"),
- I18N_NOOP2("XLIFF mark type", "transliterated form: a form of a term resulting from an operation whereby the characters of an alphabetic writing system are represented by characters from another alphabetic writing system"),
- I18N_NOOP2("XLIFF mark type", "truncated term: an abbreviated form of a term resulting from the omission of one or more term elements or syllables (e.g. 'flu' for 'influenza')"),
- I18N_NOOP2("XLIFF mark type", "variant: one of the alternate forms of a term")
- };
- int i=sizeof(mrkTypes)/sizeof(char*);
- while(--i>=0 && mrkTypes[i]!=id)
- ;
- if (i!=-1)
- {
- result=i18nc("XLIFF mark type", mrkTypeNames[i]);
- if (!result.isEmpty())
- result[0]=result.at(0).toUpper();
- }
- }
-
- if (!ctype.isEmpty())
- result+=" ("+ctype+")";
-
- return result;
-}
-
-
-QMap<QString,int> CatalogString::tagIdToIndex() const
-{
- QMap<QString,int> result;
- int index=0;
- int count=tags.size();
- for (int i=0;i<count;++i)
- {
- if (!result.contains(tags.at(i).id))
- result.insert(tags.at(i).id, index++);
- }
- return result;
-}
-
-QByteArray CatalogString::tagsAsByteArray()const
-{
- QByteArray result;
- if (tags.size())
- {
- QDataStream stream(&result,QIODevice::WriteOnly);
- stream<<tags;
- }
- return result;
-}
-
-CatalogString::CatalogString(QString str, QByteArray tagsByteArray)
- : string(str)
-{
- if (tagsByteArray.size())
- {
- QDataStream stream(tagsByteArray);
- stream>>tags;
- }
-}
-
-static void adjustTags(QList<InlineTag>& tags, int position, int value)
-{
- int i=tags.size();
- while(--i>=0)
- {
- InlineTag& t=tags[i];
- if (t.start>position)
- t.start+=value;
- if (t.end>=position) //cases when strict > is needed?
- t.end+=value;
- }
-}
-
-void CatalogString::remove(int position, int len)
-{
- string.remove(position,len);
- adjustTags(tags,position,-len);
-}
-
-void CatalogString::insert(int position, const QString& str)
-{
- string.insert(position, str);
- adjustTags(tags,position,str.size());
-}
-
-
-QDataStream &operator<<(QDataStream &out, const InlineTag &t)
-{
- return out<<int(t.type)<<t.start<<t.end<<t.id;
-}
-
-QDataStream &operator>>(QDataStream &in, InlineTag &t)
-{
- int type;
- in>>type>>t.start>>t.end>>t.id;
- t.type=InlineTag::InlineElement(type);
- return in;
-}
-
-QDataStream &operator<<(QDataStream &out, const CatalogString &myObj)
-{
- return out<<myObj.string<<myObj.tags;
-}
-QDataStream &operator>>(QDataStream &in, CatalogString &myObj)
-{
- return in>>myObj.string>>myObj.tags;
-}
-
-
-
-void adaptCatalogString(CatalogString& target, const CatalogString& ref)
-{
- kWarning()<<"HERE"<<target.string;
- QHash<QString,int> id2tagIndex;
- QMultiMap<InlineTag::InlineElement,int> tagType2tagIndex;
- int i=ref.tags.size();
- while(--i>=0)
- {
- const InlineTag& t=ref.tags.at(i);
- id2tagIndex.insert(t.id,i);
- tagType2tagIndex.insert(t.type,i);
- kWarning()<<"inserting"<<t.id<<t.type<<i;
- }
-
- QList<InlineTag> oldTags=target.tags;
- target.tags.clear();
- //we actually walking from beginning to end:
- qSort(oldTags.begin(), oldTags.end(), qGreater<InlineTag>());
- i=oldTags.size();
- while(--i>=0)
- {
- const InlineTag& targetTag=oldTags.at(i);
- if (id2tagIndex.contains(targetTag.id))
- {
- kWarning()<<"matched"<<targetTag.id<<i;
- target.tags.append(targetTag);
- tagType2tagIndex.remove(targetTag.type, id2tagIndex.take(targetTag.id));
- oldTags.removeAt(i);
- }
- }
- kWarning()<<"HERE 0"<<target.string;
-
- //now all the tags left have to ID (exact) matches
- i=oldTags.size();
- while(--i>=0)
- {
- InlineTag targetTag=oldTags.at(i);
- if (tagType2tagIndex.contains(targetTag.type))
- {
- //try to match by position
- //we're _taking_ first so the next one becomes new 'first' for the next time.
- QList<InlineTag> possibleRefMatches;
- foreach(int i, tagType2tagIndex.values(targetTag.type))
- possibleRefMatches<<ref.tags.at(i);
- qSort(possibleRefMatches);
- kWarning()<<"setting id:"<<targetTag.id<<possibleRefMatches.first().id;
- targetTag.id=possibleRefMatches.first().id;
-
- target.tags.append(targetTag);
- kWarning()<<"id??:"<<targetTag.id<<target.tags.first().id;
- tagType2tagIndex.remove(targetTag.type, id2tagIndex.take(targetTag.id));
- oldTags.removeAt(i);
- }
- }
- kWarning()<<"HERE 1"<<target.string;
- //now walk through unmatched tags and properly remove them.
- foreach(const InlineTag& tag, oldTags)
- {
- if (tag.isPaired())
- target.remove(tag.end, 1);
- target.remove(tag.start, 1);
- }
- kWarning()<<"HERE 2"<<target.string;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef CATALOGSTRING_H
-#define CATALOGSTRING_H
-
-#include <QList>
-#include <QMap>
-#include <QString>
-#include <QMetaType>
-
-//#define TAGRANGE_IMAGE_SYMBOL 65532
-#define TAGRANGE_IMAGE_SYMBOL QChar::ObjectReplacementCharacter
-
-/**
- * data structure used to pass info about inline elements
- * a XLIFF tag is represented by a TAGRANGE_IMAGE_SYMBOL in the 'plainttext'
- * and a struct TagRange
- *
- * describes which tag is behind TAGRANGE_IMAGE_SYMBOL char
- * (or chars -- starting and ending) in source or target string
- * start==end for non-paired tags
- */
-struct InlineTag
-{
- //sub = can contain <sub>-flow tag
- //recursive = can contain other inline markup tags
- ///@see http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html
- enum InlineElement
- {
- _unknown,
- bpt, //sub
- ept, //sub
- ph, //sub
- it, //sub
- //_subContainersDelimiter,
- mrk, //recursive, no id
- g, //recursive
- sub, //recursive, no id
- _pairedXmlTagDelimiter,
- x, //empty
- bx, //empty
- ex, //empty
- InlineElementCount
- };
-
-
- int start;
- int end;
- InlineElement type;
- QString id;
- QString xid;
- QString equivText;
- QString ctype;
-
- explicit InlineTag(): start(-1), end(-1), type(_unknown){}
-
- InlineTag(int start_, int end_, InlineElement type_,QString id_=QString(),QString xid_=QString(),QString equivText_=QString(),QString ctype_=QString())
- : start(start_), end(end_), type(type_), id(id_), xid(xid_), equivText(equivText_), ctype(ctype_){}
-
- /**
- * for situations when target doesn't contain tag
- * (of the same type and with the same id) from source
- * true means that the object corresponds to some tag in source,
- * but target does not contain it.
- *
- * @see getPlaceholder()
- */
- bool isEmpty()const{return start==-1;}
-
- /**
- * used to denote tag that doesn't present in target,
- * to have parallel numbering in view
- *
- * @returns TagRange object prototype to be inserted into target
- * @see isEmpty()
- */
- InlineTag getPlaceholder() const;
-
- ///@returns 0 if type is unknown
- static InlineElement getElementType(const QByteArray&);
- static const char* getElementName(InlineElement type);
- const char* getElementName()const{return getElementName(type);}
- const char* name()const{return getElementName();}
- static bool isPaired(InlineElement type){return type<InlineTag::_pairedXmlTagDelimiter;}
- bool isPaired()const{return isPaired(type);}
-
- QString displayName() const;
-
- bool operator<(const InlineTag& other)const
- {
- return start<other.start;
- }
-
-};
-Q_DECLARE_METATYPE(InlineTag)
-Q_DECLARE_METATYPE(QList<InlineTag>)
-
-
-/**
- * data structure used to pass info about inline elements
- * a XLIFF tag is represented by a TAGRANGE_IMAGE_SYMBOL in the 'plainttext'
- * and a struct TagRange
- *
- * string has each XLIFF markup tag represented by 1 symbol
- * ranges is set to list describing which tag (type, id) at which position
- */
-struct CatalogString
-{
- QString string;
- QList<InlineTag> tags;
-
- CatalogString(){}
- CatalogString(QString str):string(str){}
- CatalogString(QString str, QByteArray tagsByteArray);
- QMap<QString,int> tagIdToIndex() const; //assigns same indexes for tags with same ids
-
- QByteArray tagsAsByteArray()const;
-
- void remove(int position, int len);
- void insert(int position, const QString& str);
- void replace(int position, int len, const QString& str){remove(position,len);insert(position,str);}
- void clear(){string.clear();tags.clear();}
- bool isEmpty() const {return string.isEmpty();}
-};
-Q_DECLARE_METATYPE(CatalogString)
-
-
-#include <QDataStream>
-QDataStream &operator<<(QDataStream &out, const InlineTag &myObj);
-QDataStream &operator>>(QDataStream &in, InlineTag &myObj);
-QDataStream &operator<<(QDataStream &out, const CatalogString &myObj);
-QDataStream &operator>>(QDataStream &in, CatalogString &myObj);
-
-
-/// prepares @arg target for using it as @arg ref translation
-void adaptCatalogString(CatalogString& target, const CatalogString& ref);
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "cmd.h"
-
-#include <QString>
-
-#include <klocale.h>
-#include <kdebug.h>
-
-#include "catalog_private.h"
-#include "catalogitem_private.h"
-#include "catalog.h"
-#include <project.h>
-
-
-//BEGIN LokalizeUnitCmd
-LokalizeUnitCmd::LokalizeUnitCmd(Catalog *catalog, const DocPosition& pos, const QString& name=QString())
- : QUndoCommand(name)
- , _catalog(catalog)
- , _pos(pos)
- , _firstModificationForThisEntry(false)
-{}
-
-static QString setPhaseForPart(Catalog* catalog, const QString& phase, DocPosition phasePos, DocPosition::Part part)
-{
- phasePos.part=part;
- return catalog->setPhase(phasePos,phase);
-}
-
-void LokalizeUnitCmd::redo()
-{
- setJumpingPos();
- doRedo();
- _firstModificationForThisEntry=_catalog->setModified(DocPos(_pos),true);
- _prevPhase=setPhaseForPart(_catalog,_catalog->activePhase(),_pos,DocPosition::UndefPart);
-}
-
-void LokalizeUnitCmd::undo()
-{
- setJumpingPos();
- doUndo();
- if (_firstModificationForThisEntry)
- _catalog->setModified(DocPos(_pos),false);
- setPhaseForPart(_catalog,_prevPhase,_pos,DocPosition::UndefPart);
-}
-
-void LokalizeUnitCmd::setJumpingPos()
-{
- _catalog->setLastModifiedPos(_pos);
-}
-//END LokalizeUnitCmd
-
-//BEGIN LokalizeTargetCmd
-LokalizeTargetCmd::LokalizeTargetCmd(Catalog *catalog, const DocPosition& pos, const QString& name=QString())
- : LokalizeUnitCmd(catalog,pos,name)
-{}
-
-void LokalizeTargetCmd::redo()
-{
- LokalizeUnitCmd::redo();
- _prevTargetPhase=setPhaseForPart(_catalog,_catalog->activePhase(),_pos,DocPosition::Target);
-}
-
-void LokalizeTargetCmd::undo()
-{
- LokalizeUnitCmd::undo();
- setPhaseForPart(_catalog,_prevTargetPhase,_pos,DocPosition::Target);
-}
-//END LokalizeTargetCmd
-
-//BEGIN InsTextCmd
-InsTextCmd::InsTextCmd(Catalog *catalog, const DocPosition& pos, const QString& str)
- : LokalizeTargetCmd(catalog,pos,i18nc("@item Undo action item","Insertion"))
- , _str(str)
-{}
-
-bool InsTextCmd::mergeWith(const QUndoCommand *other)
-{
- const DocPosition otherPos=static_cast<const LokalizeUnitCmd*>(other)->pos();
- if ((other->id() != id())
- || (otherPos.entry!=_pos.entry)
- || (otherPos.form!=_pos.form)
- || (otherPos.offset!=_pos.offset+_str.size())
- )
- return false;
- const QString& otherStr = static_cast<const InsTextCmd*>(other)->_str;
-
- if (otherStr.isEmpty() || _str.isEmpty()) //just a precaution
- return false;
-
- //be close to behaviour of LibreOffice
- if (!_str.at(_str.size()-1).isSpace() && otherStr.at(0).isSpace())
- return false;
-
- _str += otherStr;
- return true;
-}
-
-void InsTextCmd::doRedo()
-{
- Catalog& catalog=*_catalog;
- DocPosition pos=_pos; pos.offset+=_str.size();
- catalog.setLastModifiedPos(pos);
- catalog.targetInsert(_pos,_str);
-}
-
-void InsTextCmd::doUndo()
-{
- _catalog->targetDelete(_pos,_str.size());
-}
-//END InsTextCmd
-
-
-//BEGIN DelTextCmd
-DelTextCmd::DelTextCmd(Catalog *catalog,const DocPosition &pos,const QString &str)
- : LokalizeTargetCmd(catalog,pos,i18nc("@item Undo action item","Deletion"))
- , _str(str)
-{}
-
-bool DelTextCmd::mergeWith(const QUndoCommand *other)
-{
- const DocPosition otherPos=static_cast<const LokalizeUnitCmd*>(other)->pos();
- if (
- (other->id() != id())
- || (otherPos.entry!=_pos.entry)
- || (otherPos.form!=_pos.form)
- )
- return false;
-
- //Delete
- if (otherPos.offset==_pos.offset)
- {
- _str += static_cast<const DelTextCmd*>(other)->_str;
- return true;
- }
-
- //BackSpace
- if (otherPos.offset==_pos.offset-static_cast<const DelTextCmd*>(other)->_str.size())
- {
- _str.prepend(static_cast<const DelTextCmd*>(other)->_str);
- _pos.offset=otherPos.offset;
- return true;
- }
-
- return false;
-}
-void DelTextCmd::doRedo()
-{
- _catalog->targetDelete(_pos,_str.size());
-}
-void DelTextCmd::doUndo()
-{
- //DocPosition pos=_pos; //pos.offset+=_str.size();
- //_catalog.setLastModifiedPos(pos);
- _catalog->targetInsert(_pos,_str);
-}
-//END DelTextCmd
-
-
-//BEGIN SetStateCmd
-void SetStateCmd::push(Catalog *catalog, const DocPosition& pos, bool approved)
-{
- catalog->push(new SetStateCmd(catalog,pos,closestState(approved,catalog->activePhaseRole())));
-}
-void SetStateCmd::instantiateAndPush(Catalog *catalog, const DocPosition& pos, TargetState state)
-{
- catalog->push(new SetStateCmd(catalog,pos,state));
-}
-
-SetStateCmd::SetStateCmd(Catalog *catalog, const DocPosition& pos, TargetState state)
- : LokalizeUnitCmd(catalog,pos,i18nc("@item Undo action item","Approvement toggling"))
- , _state(state)
-{}
-
-void SetStateCmd::doRedo()
-{
- _prevState=_catalog->setState(_pos,_state);
-}
-
-void SetStateCmd::doUndo()
-{
- _catalog->setState(_pos,_prevState);
-}
-//END SetStateCmd
-
-
-//BEGIN InsTagCmd
-InsTagCmd::InsTagCmd(Catalog *catalog, const DocPosition& pos, const InlineTag& tag)
- : LokalizeTargetCmd(catalog,pos,i18nc("@item Undo action item","Markup Insertion"))
- , _tag(tag)
-{
- _pos.offset=tag.start;
-}
-
-void InsTagCmd::doRedo()
-{
- Catalog& catalog=*_catalog;
- DocPosition pos=_pos; pos.offset++; //between paired tags or after single tag
- catalog.setLastModifiedPos(pos);
- catalog.targetInsertTag(_pos,_tag);
-}
-
-void InsTagCmd::doUndo()
-{
- _catalog->targetDeleteTag(_pos);
-}
-//END InsTagCmd
-
-//BEGIN DelTagCmd
-DelTagCmd::DelTagCmd(Catalog *catalog, const DocPosition& pos)
- : LokalizeTargetCmd(catalog,pos,i18nc("@item Undo action item","Markup Deletion"))
-{}
-
-void DelTagCmd::doRedo()
-{
- _tag=_catalog->targetDeleteTag(_pos);
- kWarning()<<"tag properties:"<<_tag.start<<_tag.end;
-}
-
-void DelTagCmd::doUndo()
-{
- Catalog& catalog=*_catalog;
- DocPosition pos=_pos; pos.offset++; //between paired tags or after single tag
- catalog.setLastModifiedPos(pos);
- catalog.targetInsertTag(_pos,_tag);
-}
-//END DelTagCmd
-
-
-//BEGIN SetNoteCmd
-SetNoteCmd::SetNoteCmd(Catalog *catalog, const DocPosition& pos, const Note& note)
- : LokalizeUnitCmd(catalog,pos,i18nc("@item Undo action item","Note setting"))
- , _note(note)
-{
- _pos.part=DocPosition::Comment;
-}
-
-static void setNote(Catalog& catalog, DocPosition& _pos, const Note& note, Note& resultNote)
-{
- resultNote=catalog.setNote(_pos,note);
- int size=catalog.notes(_pos).size();
- if (_pos.form==-1) _pos.form = size-1;
- else if (_pos.form>=size) _pos.form = -1;
-}
-
-void SetNoteCmd::doRedo()
-{
- setNote(*_catalog,_pos,_note,_prevNote);
-}
-
-void SetNoteCmd::doUndo()
-{
- Note tmp; setNote(*_catalog,_pos,_prevNote,tmp);
-}
-
-void SetNoteCmd::setJumpingPos()
-{
- DocPosition pos=_pos;
- pos.form=0;
- _catalog->setLastModifiedPos(pos);
-}
-//END SetNoteCmd
-
-//BEGIN UpdatePhaseCmd
-UpdatePhaseCmd::UpdatePhaseCmd(Catalog *catalog, const Phase& phase)
- : QUndoCommand(i18nc("@item Undo action item","Update/add workflow phase"))
- , _catalog(catalog)
- , _phase(phase)
-{}
-
-void UpdatePhaseCmd::redo()
-{
- _prevPhase=_catalog->updatePhase(_phase);
-}
-
-void UpdatePhaseCmd::undo()
-{
- _catalog->updatePhase(_prevPhase);
-}
-//END UpdatePhaseCmd
-
-
-
-
-//BEGIN SetEquivTransCmd
-SetEquivTransCmd::SetEquivTransCmd(Catalog *catalog, const DocPosition& pos, bool equivTrans)
- : LokalizeTargetCmd(catalog,pos,i18nc("@item Undo action item","Translation Equivalence Setting"))
- , _equivTrans(equivTrans)
-{}
-
-void SetEquivTransCmd::doRedo()
-{
- _catalog->setEquivTrans(_pos,_equivTrans);
-}
-
-void SetEquivTransCmd::doUndo()
-{
- _catalog->setEquivTrans(_pos,!_equivTrans);
-}
-//END SetEquivTransCmd
-
-
-
-
-
-
-bool fillTagPlaces(QMap<int,int>& tagPlaces,
- const CatalogString& catalogString,
- int start,
- int len
- )
-{
- QString target=catalogString.string;
- if (len==-1)
- len=target.size();
-
- int t=start;
- while ((t=target.indexOf(TAGRANGE_IMAGE_SYMBOL,t))!=-1 && t<(start+len))
- tagPlaces[t++]=0;
-
-
- int i=catalogString.tags.size();
- while(--i>=0)
- {
- //qWarning()<<catalogString.ranges.at(i).getElementName();
- const InlineTag& tag=catalogString.tags.at(i);
- if (tagPlaces.contains(tag.start)
- &&tagPlaces.contains(tag.end))
- {
- //qWarning()<<"start"<<catalogString.ranges.at(i).start<<"end"<<catalogString.ranges.at(i).end;
- tagPlaces[tag.end]=2;
- tagPlaces[tag.start]=1;
- }
- }
-
- QMap<int,int>::const_iterator it = tagPlaces.constBegin();
- while (it != tagPlaces.constEnd() && it.value())
- ++it;
-
- return it==tagPlaces.constEnd();
-}
-
-bool removeTargetSubstring(Catalog* catalog, DocPosition pos, int delStart, int delLen)
-{
- CatalogString targetWithTags=catalog->targetWithTags(pos);
- QString target=targetWithTags.string;
- kWarning()<<"called with"<<delStart<<"delLen"<<delLen<<"target:"<<target;
- if (delLen==-1)
- delLen=target.length()-delStart;
-
- bool doTags=catalog->capabilities()&Tags;
- QMap<int,int> tagPlaces;
- if (target.isEmpty() || doTags && !fillTagPlaces(tagPlaces,targetWithTags,delStart,delLen))
- {
- kWarning()<<"error removing text"<<target;
- return false;
- }
-
- catalog->beginMacro(i18nc("@item Undo action item","Remove text with markup"));
-
- //all indexes are ok (or target is just plain text)
- //modified=true;
- //kWarning()<<"all indexes are ok";
- QMapIterator<int,int> it(tagPlaces);
- it.toBack();
- while (it.hasPrevious())
- {
- it.previous();
- if (it.value()!=1) continue;
- pos.offset=it.key();
- DelTagCmd* cmd=new DelTagCmd(catalog,pos);
- catalog->push(cmd);
- delLen-=1+cmd->tag().isPaired();
- QString tmp=catalog->targetWithTags(pos).string;
- tmp.replace(TAGRANGE_IMAGE_SYMBOL, "*");
- kWarning()<<"\tdeleting at"<<it.key()<<"current string:"<<tmp<<"delLen"<<delLen;
- }
- //charsRemoved-=lenDecrement;
- QString tmp=catalog->targetWithTags(pos).string;
- tmp.replace(TAGRANGE_IMAGE_SYMBOL, "*");
- kWarning()<<"offset"<<delStart<<delLen<<"current string:"<<tmp;
- pos.offset=delStart;
- if (delLen)
- {
- QString rText=catalog->targetWithTags(pos).string.mid(delStart,delLen);
- rText.remove(TAGRANGE_IMAGE_SYMBOL);
- kWarning()<<"rText"<<rText<<"delStart"<<delStart<<rText.size();
- if (!rText.isEmpty())
- catalog->push(new DelTextCmd(catalog,pos,rText));
- }
- tmp=catalog->targetWithTags(pos).string;
- tmp.replace(TAGRANGE_IMAGE_SYMBOL, "*");
- kWarning()<<"current string:"<<tmp;
-
- catalog->endMacro();
- return true;
-}
-
-
-void insertCatalogString(Catalog* catalog, DocPosition pos, const CatalogString& catStr, int start)
-{
- QMap<int,int> posToTag;
- int i=catStr.tags.size();
- bool containsMarkup=i;
- while(--i>=0)
- {
- //kWarning()<<"\t"<<catStr.tags.at(i).getElementName()<<catStr.tags.at(i).id<<catStr.tags.at(i).start<<catStr.tags.at(i).end;
- kWarning()<<"\ttag"<<catStr.tags.at(i).start<<catStr.tags.at(i).end;
- posToTag.insert(catStr.tags.at(i).start,i);
- posToTag.insert(catStr.tags.at(i).end,i);
- }
-
- if (containsMarkup) catalog->beginMacro(i18nc("@item Undo action item","Insert text with markup"));
-
- i=0;
- int prev=0;
- while ((i = catStr.string.indexOf(TAGRANGE_IMAGE_SYMBOL, i)) != -1)
- {
- kWarning()<<"TAGRANGE_IMAGE_SYMBOL"<<i;
- //text that was before tag we found
- if (i-prev)
- {
- pos.offset=start+prev;
- catalog->push(new InsTextCmd(catalog,pos,catStr.string.mid(prev,i-prev)));
- }
-
- //now dealing with tag
- kWarning()<<"posToTag.value(i)"<<posToTag.value(i)<<catStr.tags.size();
- if (posToTag.value(i)<catStr.tags.size())
- {
- InlineTag tag=catStr.tags.at(posToTag.value(i));
- kWarning()<<i<<"testing for tag"<<tag.name()<<tag.start<<tag.start;
- if (tag.start==i) //this is an opening tag (may be single tag)
- {
- pos.offset=start+i;
- tag.start+=start;
- tag.end+=start;
- catalog->push(new InsTagCmd(catalog,pos,tag));
- }
- }
- else
- {
- //HACK to keep positions in sync
- pos.offset=start+i;
- catalog->push(new InsTextCmd(catalog,pos," "));
- }
- prev=++i;
- }
- pos.offset=start+prev;
- if (catStr.string.length()-prev>0)
- catalog->push(new InsTextCmd(catalog,pos,catStr.string.mid(prev)));
- if (containsMarkup) catalog->endMacro();
-}
-
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef CMD_H
-#define CMD_H
-
-#include <QtGui/qundostack.h>
-
-#include "pos.h"
-#include "note.h"
-#include "phase.h"
-#include "state.h"
-#include "catalogstring.h"
-class Catalog;
-
-enum Commands
-{
- Insert, Delete,
- InsertTag, DeleteTag,
- ToggleApprovement, EquivTrans,
- SetNote, UpdatePhase
-};
-
-class LokalizeUnitCmd: public QUndoCommand
-{
-public:
- LokalizeUnitCmd(Catalog *catalog, const DocPosition& pos, const QString& name);
- virtual ~LokalizeUnitCmd(){};
- virtual void undo();
- virtual void redo();
- DocPosition pos()const{return _pos;}
-protected:
- virtual void doRedo()=0;
- virtual void doUndo()=0;
- /**
- * may be overridden to set customized pos
- * alternatively customized pos may be set manually in do*()
- */
- virtual void setJumpingPos();
-protected:
- Catalog* _catalog;
- DocPosition _pos;
- bool _firstModificationForThisEntry;
- QString _prevPhase;
-};
-
-class LokalizeTargetCmd: public LokalizeUnitCmd
-{
-public:
- LokalizeTargetCmd(Catalog *catalog, const DocPosition& pos, const QString& name);
- virtual ~LokalizeTargetCmd(){};
- void undo();
- void redo();
-protected:
- QString _prevTargetPhase;
-};
-
-/**
- * how undo system works:
- * undo() and redo() functions call appropriate private method of Catalog to change catalog contents,
- * then set DocPosition (posBuffer var in Catalog), which is used to navigate editor to appr. place
- * @short Do insert text
- */
-class InsTextCmd: public LokalizeTargetCmd
-{
-public:
- InsTextCmd(Catalog *catalog, const DocPosition& pos, const QString& str);
- ~InsTextCmd(){};
- int id () const {return Insert;}
- bool mergeWith(const QUndoCommand *other);
- void doRedo();
- void doUndo();
-private:
- QString _str;
-};
-
-/// @see InsTextCmd
-class DelTextCmd: public LokalizeTargetCmd
-{
-public:
- DelTextCmd(Catalog *catalog, const DocPosition& pos, const QString& str);
- ~DelTextCmd(){};
- int id () const {return Delete;}
- bool mergeWith(const QUndoCommand *other);
- void doRedo();
- void doUndo();
-private:
- QString _str;
-};
-
-class SetStateCmd: public LokalizeUnitCmd
-{
-private:
- SetStateCmd(Catalog *catalog, const DocPosition& pos, TargetState state);
-public:
- ~SetStateCmd(){};
-
- int id () const {return ToggleApprovement;}
- void doRedo();
- void doUndo();
-
- static void push(Catalog *catalog, const DocPosition& pos, bool approved);
- static void instantiateAndPush(Catalog *catalog, const DocPosition& pos, TargetState state);
-
- TargetState _state;
- TargetState _prevState;
-};
-
-/// @short Do insert tag
-class InsTagCmd: public LokalizeTargetCmd
-{
-public:
- /// offset is taken from @a tag and not from @a pos
- InsTagCmd(Catalog *catalog, const DocPosition& pos, const InlineTag& tag);
- ~InsTagCmd(){};
- int id () const {return InsertTag;}
- void doRedo();
- void doUndo();
-private:
- InlineTag _tag;
-};
-
-/**
- * TagRange is filled from document
- *
- * @short Do delete tag
- */
-class DelTagCmd: public LokalizeTargetCmd
-{
-public:
- DelTagCmd(Catalog *catalog, const DocPosition& pos);
- ~DelTagCmd(){};
- int id () const {return DeleteTag;}
- void doRedo();
- void doUndo();
- InlineTag tag()const{return _tag;}//used to get proprties of deleted tag
-private:
- InlineTag _tag;
-};
-
-/// @short Insert or remove (if content is empty) a note
-class SetNoteCmd: public LokalizeUnitCmd
-{
-public:
- /// @a pos.form is note number
- SetNoteCmd(Catalog *catalog, const DocPosition& pos, const Note& note);
- ~SetNoteCmd(){};
- int id () const {return SetNote;}
-protected:
- void doRedo();
- void doUndo();
- void setJumpingPos();
-private:
- Note _note;
- Note _prevNote;
-};
-
-/// @short Add or remove (if content is empty) a phase
-class UpdatePhaseCmd: public QUndoCommand
-{
-public:
- /// @a pos.form is note number
- UpdatePhaseCmd(Catalog *catalog, const Phase& phase);
- ~UpdatePhaseCmd(){};
- int id () const {return UpdatePhase;}
- void redo();
- void undo();
-private:
- Catalog* _catalog;
- Phase _phase;
- Phase _prevPhase;
-};
-
-
-class SetEquivTransCmd: public LokalizeTargetCmd
-{
-public:
- SetEquivTransCmd(Catalog *catalog, const DocPosition& pos, bool equivTrans);
- ~SetEquivTransCmd(){};
- int id () const {return EquivTrans;}
- void doRedo();
- void doUndo();
-private:
- bool _equivTrans;
-};
-
-/**
- * CatalogString cmds helper function.
- *
- * tagPlaces: pos -> int:
- * >0 if both start and end parts of tag were (to be) deleted
- * 1 means this is start, 2 means this is end
- * @returns false if it can't find second part of any paired tag in the range
- */
-bool fillTagPlaces(QMap<int,int>& tagPlaces, const CatalogString& catalogString, int start, int len);
-bool removeTargetSubstring(Catalog* catalog, DocPosition pos, int delStart=0, int delLen=-1);
-void insertCatalogString(Catalog* catalog, DocPosition pos, const CatalogString& catStr, int start=0);
-
-#endif // CMD_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of KAider
- This file contains parts of KBabel code
-
- Copyright (C) 2002-2003 by Stanislav Visnovsky
- <visnovsky@kde.org>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-**************************************************************************** */
-#ifndef KATALOGFILEPLUGIN_H
-#define KATALOGFILEPLUGIN_H
-
-#include <kdemacros.h>
-#include <QList>
-#include <QTextCodec>
-#include <QIODevice>
-#include <QString>
-#include <QStringList>
-
-namespace GettextCatalog {
-
-class GettextStorage;
-class CatalogItem;
-class CatalogImportPluginPrivate;
-class CatalogExportPluginPrivate;
-
-/**
- * Result of the conversion
- */
-enum ConversionStatus {
- OK=0,
- NOT_IMPLEMENTED,
- NO_FILE,
- NO_PERMISSIONS,
- PARSE_ERROR,
- RECOVERED_PARSE_ERROR,
- OS_ERROR,
- NO_PLUGIN,
- UNSUPPORTED_TYPE,
- RECOVERED_HEADER_ERROR, ///< Header error that could be recovered @since 1.11.2 (KDE 3.5.2)
- STOPPED,
- BUSY,
- NO_ENTRY_ERROR ///< The loaded catalog has not any entry! @since 1.11.2 (KDE 3.5.2)
-};
-
-/**
- * HISTORY: this was a base class for Catalog import plugins in KBabel,
- * but this architecture isn't not suitable for XML-based files
- * (when whole DOM-tree is stored in memory to prevent file clashes)
- *
- * This class is the base for import plugins for catalogs.
- * It provides "transactional behavior", so the changes are stored in
- * catalog only if the import process finishes successfully.
- *
- * To use it, just subclass and redefine load() and id() methods.
- * When importing, you can use the protected methods for setting
- * the catalog. New catalog items can be added using appendCatalogItem.
- *
- * @short Base class for GettextCatalog import plugins
- * @author Stanislav Visnovsky <visnovsky@kde.org>
- */
-class CatalogImportPlugin
-{
-public:
- CatalogImportPlugin();
- virtual ~CatalogImportPlugin();
-
- /**
- * Load the file and fill the corresponding catalog. The file
- * is considered to be of @ref mimetype MIME type.
- *
- * @param file local file name to be opened
- * @param mimetype the MIME type is should be handled as
- * @param catalog the catalog to be filled
- * @return result of the operation
- */
- ConversionStatus open(QIODevice*, GettextStorage* catalog, int* errorLine);
-
- /**
- * Reimplement this method to load the local file passed as an argument.
- * Throughout the run, you can use the protected methods for setting
- * the contents of the resulting catalog.
- * This method must call \see setMimeTypes to setup correct MIME types
- * for the loaded file. Also, it should use \see isStopped to
- * abort loading and the signals for providing user feedback.
- * @param file file to be loaded
- * @param mimetype the expected MIME type (the type used for plugin selection
- */
- virtual ConversionStatus load(QIODevice*) = 0;
-
-protected:
- /** Append a new catalog item, either as normal or as an obsolete one
- * @param item the new item
- * @param obsolete flag that the item is obsolete
- */
- void appendCatalogItem( const CatalogItem& item, const bool obsolete = false );
-
- /** set flag that the file is generated from DocBook */
- void setGeneratedFromDocbook(const bool fromDocbook);
- /** set the list of parse error indexes */
- void setErrorIndex(const QList<int>& errors);
-
- /** set extra data for the catalog, which can't be stored in
- * @ref CatalogItem. The format can be arbitrary */
- void setCatalogExtraData( const QStringList& data );
- /** set the header catalog item */
- void setHeader( const CatalogItem& header );
-
- /** Set the character encoding used in the catalog file. */
- void setCodec( QTextCodec* codec );
-
- /** start a new transaction. You should never call this method. */
- void startTransaction();
- /** commit the data in the current transaction. You should never call this method. */
- void commitTransaction();
-
- short _maxLineLength;
- short _trailingNewLines;
- int _errorLine;
-
-private:
- CatalogImportPluginPrivate* d;
-};
-
-}
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is based on the one from KBabel
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2002 by Stanislav Visnovsky <visnovsky@nenya.ms.mff.cuni.cz>
- Copyright (C) 2006 by Nicolas GOUTTE <goutte@kde.org>
- 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "catalogitem.h"
-#include "catalogitem_private.h"
-
-#include <kdebug.h>
-#include <QtCore/qmutex.h>
-
-using namespace GettextCatalog;
-
-CatalogItem::CatalogItem()
- : d(new CatalogItemPrivate())
-{
-}
-
-CatalogItem::CatalogItem(const CatalogItem& item)
- : d(new CatalogItemPrivate())
-{
- *d=*(item.d);
-}
-
-CatalogItem::~CatalogItem()
-{
- delete d;
-}
-
-
-
-QString CatalogItem::comment() const
-{
- return QString::fromUtf8(d->_comment);
-}
-
-const QString& CatalogItem::msgctxt(const bool noNewlines) const
-{
- if (noNewlines) return (d->_msgctxt).replace('\n', ' '); //" " or "" ?
- else return d->_msgctxt;
-}
-
-const QString& CatalogItem::msgid(const int form) const
-{
- return d->msgid(form);
-}
-
-const QString& CatalogItem::msgstr(const int form) const
-{
- if (Q_LIKELY (form<d->_msgstrPlural.size()))
- return d->_msgstrPlural.at(form);
- else
- return d->_msgstrPlural.last();
-}
-
-bool CatalogItem::prependEmptyForMsgid(const int form) const
-{
- return d->_prependMsgIdEmptyLine;
-}
-
-bool CatalogItem::prependEmptyForMsgstr(const int form) const
-{
- return d->_prependMsgStrEmptyLine;
-}
-
-const QVector<QString>& CatalogItem::msgstrPlural() const
-{
- return d->_msgstrPlural;
-}
-
-QStringList CatalogItem::allPluralForms(CatalogItem::Part part, bool stripNewLines) const
-{
- QStringList result=(part==CatalogItem::Source?d->_msgidPlural:d->_msgstrPlural).toList();
- if (stripNewLines)
- {
- static QString nl="\n";
- result.replaceInStrings(nl, QString());
- }
- return result;
-}
-
-bool CatalogItem::isValid() const
-{
- return d->_valid;
-}
-
-void CatalogItem::setValid(bool a)
-{
- d->_valid=a;
-}
-
-void CatalogItem::setMsgctxt(const QString& msg)
-{
- d->_msgctxt=msg;
- d->_msgctxt.squeeze();
- d->_keepEmptyMsgCtxt=msg.isEmpty();
-}
-
-bool CatalogItem::keepEmptyMsgCtxt() const
-{
- return d->_keepEmptyMsgCtxt;
-}
-
-void CatalogItem::setMsgid(const QString& msg, const int form)
-{
- if (form>=d->_msgidPlural.size())
- d->_msgidPlural.resize(form+1);
- d->_msgidPlural[form]=msg;
-}
-
-void CatalogItem::setMsgid(const QStringList& msg)
-{
- d->_msgidPlural=msg.toVector(); //TODO
- for (QVector<QString>::iterator it=d->_msgidPlural.begin();it!=d->_msgidPlural.end();++it)
- it->squeeze();
-}
-
-void CatalogItem::setMsgid(const QStringList& msg, bool prependEmptyLine)
-{
- d->_prependMsgIdEmptyLine=prependEmptyLine;
- d->_msgidPlural=msg.toVector(); //TODO
- for (QVector<QString>::iterator it=d->_msgidPlural.begin();it!=d->_msgidPlural.end();++it)
- it->squeeze();
-}
-
-void CatalogItem::setMsgid(const QVector<QString>& msg)
-{
- d->_msgidPlural=msg;
- for (QVector<QString>::iterator it=d->_msgidPlural.begin();it!=d->_msgidPlural.end();++it)
- it->squeeze();
-}
-
-void CatalogItem::setMsgstr(const QString& msg, const int form)
-{
- if (form>=d->_msgstrPlural.size())
- d->_msgstrPlural.resize(form+1);
- d->_msgstrPlural[form]=msg;
-}
-
-void CatalogItem::setMsgstr(const QStringList& msg)
-{
- //TODO
- d->_msgstrPlural=msg.toVector();
-}
-
-void CatalogItem::setMsgstr(const QStringList& msg, bool prependEmptyLine)
-{
- d->_prependMsgStrEmptyLine=prependEmptyLine;
- d->_msgstrPlural=msg.toVector();
-}
-
-void CatalogItem::setMsgstr(const QVector<QString>& msg)
-{
- d->_msgstrPlural=msg;
-}
-
-void CatalogItem::setComment(const QString& com)
-{
- static QMutex reMutex;
- QMutexLocker reLock(&reMutex); //avoid crash #281033
- static QRegExp fuzzyRegExp("((?:^|\n)#(?:,[^,]*)*),\\s*fuzzy");
- d->_fuzzyCached=com.contains( fuzzyRegExp );
- d->_comment=com.toUtf8();
- d->_comment.squeeze();
-}
-
-void CatalogItem::setPlural(bool plural)
-{
- d->_plural=plural;
-}
-
-bool CatalogItem::isPlural() const
-{
- return d->_plural;
-}
-
-bool CatalogItem::isFuzzy() const
-{
- return d->_fuzzyCached;
-}
-
-bool CatalogItem::isUntranslated() const
-{
- return d->isUntranslated();
-}
-
-bool CatalogItem::isUntranslated(uint form) const
-{
- return d->isUntranslated(form);
-}
-
-#if 0
-QStringList CatalogItem::errors() const
-{
- return d->_errors;
-}
-
-bool CatalogItem::isCformat() const
-{
- // Allow "possible-c-format" (from xgettext --debug) or "c-format"
- // Note the regexp (?: ) is similar to () but it does not capture (so it is faster)
- return d->_comment.indexOf( QRegExp(",\\s*(?:possible-)c-format") ) == -1;
-}
-
-bool CatalogItem::isNoCformat() const
-{
- return d->_comment.indexOf( QRegExp(",\\s*no-c-format") ) == -1;
-}
-
-bool CatalogItem::isQtformat() const
-{
- return d->_comment.indexOf( QRegExp(",\\s*qt-format") ) == -1;
-}
-
-bool CatalogItem::isNoQtformat() const
-{
- return d->_comment.indexOf( QRegExp(",\\s*no-qt-format") ) == -1;
-}
-
-bool CatalogItem::isUntranslated() const
-{
- return d->_msgstr.first().isEmpty();
-}
-
-int CatalogItem::totalLines() const
-{
- int lines=0;
- if(!d->_comment.isEmpty())
- {
- lines = d->_comment.count('\n')+1;
- }
- int msgctxtLines=0;
- if(!d->_msgctxt.isEmpty())
- {
- msgctxtLines=d->_msgctxt.count('\n')+1;
- }
- int msgidLines=0;
- QStringList::ConstIterator it;
- for(it=d->_msgid.begin(); it != d->_msgid.end(); ++it)
- {
- msgidLines += (*it).count('\n')+1;
- }
- int msgstrLines=0;
- for(it=d->_msgstr.begin(); it != d->_msgstr.end(); ++it)
- {
- msgstrLines += (*it).count('\n')+1;
- }
-
- if(msgctxtLines>1)
- msgctxtLines++;
- if(msgidLines>1)
- msgidLines++;
- if(msgstrLines>1)
- msgstrLines++;
-
- lines+=( msgctxtLines+msgidLines+msgstrLines );
-
- return lines;
-}
-
-
-void CatalogItem::setSyntaxError(bool on)
-{
- if(on && !d->_errors.contains("syntax error"))
- d->_errors.append("syntax error");
- else
- d->_errors.removeAll("syntax error");
-}
-
-#endif
-
-void CatalogItem::clear()
-{
- d->clear();
-}
-
-void CatalogItem::operator=(const CatalogItem& rhs)
-{
- d->assign(*rhs.d);
-}
-
-
-QStringList CatalogItem::msgstrAsList() const
-{
- if (d->_msgstrPlural.isEmpty())
- {
- kWarning()<<"This should never happen!";
- return QStringList();
- }
- QStringList list(d->_msgstrPlural.first().split('\n', QString::SkipEmptyParts ));
-
- if(d->_msgstrPlural.first()=="\n")
- list.prepend(QString());
-
- if(list.isEmpty())
- list.append(QString());
-
- return list;
-}
-
-
-
-void CatalogItem::setFuzzy()
-{
- d->_fuzzyCached=true;
-
- if (d->_comment.isEmpty())
- {
- d->_comment="#, fuzzy";
- return;
- }
-
- int p=d->_comment.indexOf("#,");
- if(p!=-1)
- {
- d->_comment.replace(p,2,"#, fuzzy,");
- return;
- }
-
- QString comment=QString::fromUtf8(d->_comment);
- static QRegExp a("\\#\\:[^\n]*\n");
- p=a.indexIn(comment);
- if (p!=-1)
- {
- d->_comment=comment.insert(p+a.matchedLength(),"#, fuzzy\n").toUtf8();
- return;
- }
-
- if( !(d->_comment.endsWith('\n')) )
- d->_comment+='\n';
- d->_comment+="#, fuzzy";
-}
-
-void CatalogItem::unsetFuzzy()
-{
- d->_fuzzyCached=false;
-
- QString comment=QString::fromUtf8(d->_comment);
-
- static const QRegExp rmFuzzyRe(",\\s*fuzzy");
- comment.remove( rmFuzzyRe );
-
- // remove empty comment lines
- comment.remove( QRegExp("\n#\\s*$") );
- comment.remove( QRegExp("^#\\s*$") );
- comment.remove( QRegExp("#\\s*\n") );
- comment.remove( QRegExp("^#\\s*\n") );
-
- d->_comment=comment.toUtf8();
-}
-
-
-
-
-#if 0
-QString CatalogItem::nextError() const
-{
- return d->_errors.first();
-}
-
-void CatalogItem::clearErrors()
-{
- d->_errors.clear();
-}
-
-void CatalogItem::appendError(const QString& error )
-{
- if( !d->_errors.contains( error ) )
- d->_errors.append(error);
-}
-
-void CatalogItem::removeError(const QString& error )
-{
- d->_errors.removeAt( d->_errors.indexOf( error ) );
-}
-#endif
-
-// kate: space-indent on; indent-width 4; replace-tabs on;
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file is based on the one from KBabel
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- Copyright (C) 2002-2003 by Stanislav Visnovsky <visnovsky@kde.org>
- Copyright (C) 2006 by Nicolas GOUTTE <goutte@kde.org>
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef CATALOGITEM_H
-#define CATALOGITEM_H
-
-#include <QStringList>
-
-namespace GettextCatalog {
-
-class CatalogItemPrivate;
-
-/**
- * This class represents an entry in a catalog.
- * It contains the comment, the Msgid and the Msgstr.
- * It defines some functions to query the state of the entry
- * (fuzzy, untranslated, cformat).
- *
- * @short Represents an entry in a Gettext catalog
- * @author Matthias Kiefer <matthias.kiefer@gmx.de>
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class CatalogItem
-{
-
-public:
- explicit CatalogItem();
- CatalogItem(const CatalogItem&);
- ~CatalogItem();
-
- bool isFuzzy() const; //", fuzzy" in comment
- bool isCformat() const; //", c-format" or possible-c-format in comment (from the debug parameter of xgettext)
- bool isNoCformat() const; //", no-c-format" in comment
- bool isQtformat() const; //", qt-format" in comment
- bool isNoQtformat() const; //", no-qt-format" in comment
- bool isUntranslated() const;
- bool isUntranslated(uint form) const;
-
-
- bool isPlural() const;
- void setPlural(bool plural=true);
-
- void setSyntaxError(bool);
-
- /** returns the number of lines, the entry will need in a file */
- int totalLines() const;
-
- /** cleares the item */
- void clear();
-
- QString comment() const;
- const QString& msgctxt(const bool noNewlines = false) const;
- const QString& msgid(const int form=0) const;
- const QString& msgstr(const int form=0) const;
- const QVector<QString>& msgstrPlural() const;
- enum Part {Source, Target};
- QStringList allPluralForms(CatalogItem::Part, bool stripNewLines=false) const;
- bool prependEmptyForMsgid(const int form=0) const;
- bool prependEmptyForMsgstr(const int form=0) const;
- bool keepEmptyMsgCtxt() const;
-
- QStringList msgstrAsList() const;
- void setComment(const QString& com);
- void setMsgctxt(const QString& msg);
- void setMsgid(const QString& msg, const int form=0);
- void setMsgid(const QStringList& msg);
- void setMsgid(const QStringList& msg, bool prependEmptyLine);
- void setMsgid(const QVector<QString>& msg);
- void setMsgstr(const QString& msg, const int form=0);
- void setMsgstr(const QStringList& msg);
- void setMsgstr(const QStringList& msg, bool prependEmptyLine);
- void setMsgstr(const QVector<QString>& msg);
-
- void setValid(bool);
- bool isValid() const;
-#if 0
- /**
- * @return the list of all errors of this item
- */
- QStringList errors() const;
-
- QString nextError() const;
- void clearErrors();
- void removeError(const QString& error);
- void appendError(const QString& error);
-
- /**
- * makes some sanity checks and set status accordingly
- * @return the new status of this item
- * @see CatalogItem::Error
- * @param accelMarker a char, that marks the keyboard accelerators
- * @param contextInfo a regular expression, that determines what is
- * the context information
- * @param singularPlural a regular expression, that determines what is
- * string with singular and plural form
- * @param neededLines how many lines a string with singular-plural form
- * must have
- */
- int checkErrors(QChar accelMarker, const QRegExp& contextInfo
- , const QRegExp& singularPlural, const int neededLines);
-
-#endif
- void operator=(const CatalogItem& rhs);
-
-private:
- CatalogItemPrivate* const d;
-
- friend class GettextStorage;
- void setFuzzy();
- void unsetFuzzy();
-
-};
-
-}
-
-#endif // CATALOGITEM_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file is based on the one from KBabel
-
- Copyright (C) 1999-2000 by Matthias Kiefer
- <matthias.kiefer@gmx.de>
- 2002 by Stanislav Visnovsky <visnovsky@kde.org>
- 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef CATALOGITEMPRIVATE_H
-#define CATALOGITEMPRIVATE_H
-
-#include <QVector>
-#include <QString>
-#include <QByteArray>
-
-namespace GettextCatalog {
-
-/**
-* This class represents data for an entry in a catalog.
-* It contains the comment, the Msgid and the Msgstr.
-* It defines some functions to query the state of the entry
-* (fuzzy, untranslated, cformat).
-*
-* @short Class, representing an entry in a catalog
-* @author Matthias Kiefer <matthias.kiefer@gmx.de>
-* @author Stanislav Visnovsky <visnovsky@kde.org>
-* @author Nick Shaforostoff <shafff@ukr.net>
-*/
-
-class CatalogItemPrivate
-{
-
-public:
- bool _plural;
- bool _valid;
- bool _fuzzyCached;
- bool _prependMsgIdEmptyLine;
- bool _prependMsgStrEmptyLine;
- bool _keepEmptyMsgCtxt;
-
- QByteArray _comment;
- QString _msgctxt;
-
- QVector<QString> _msgidPlural;
- QVector<QString> _msgstrPlural;
-
- //QVector<QString> _errors;
-
- CatalogItemPrivate()
- : _plural(false)
- , _valid(true)
- , _fuzzyCached(false)
- , _prependMsgIdEmptyLine(false)
- , _prependMsgStrEmptyLine(false)
- , _keepEmptyMsgCtxt(false)
- {}
-
- void clear();
- void assign(const CatalogItemPrivate& other);
- bool isUntranslated() const;
- bool isUntranslated(uint form) const;
- const QString& msgid(const int form) const;
-
-};
-
-inline
-void CatalogItemPrivate::clear()
-{
- _plural=false;
- _valid=true;
- _comment.clear();
- _msgctxt.clear();
- _msgidPlural.clear();
- _msgstrPlural.clear();
- //_errors.clear();
-}
-
-inline
-void CatalogItemPrivate::assign(const CatalogItemPrivate& other)
-{
- _comment=other._comment;
- _msgctxt=other._msgctxt;
- _msgidPlural=other._msgidPlural;
- _msgstrPlural=other._msgstrPlural;
- _valid=other._valid;
- //_errors=other._errors;
- _plural=other._plural;
- _fuzzyCached=other._fuzzyCached;
-}
-
-inline
-bool CatalogItemPrivate::isUntranslated() const
-{
- int i=_msgstrPlural.size();
- while (--i>=0)
- if (_msgstrPlural.at(i).isEmpty())
- return true;
- return false;
-}
-
-inline
-bool CatalogItemPrivate::isUntranslated(uint form) const
-{
- if ((int)form<_msgstrPlural.size())
- return _msgstrPlural.at(form).isEmpty();
- else
- return true;
-}
-
-inline
-const QString& CatalogItemPrivate::msgid(const int form) const
-{
- //if original lang is english, we have only 2 formz
- return (form<_msgidPlural.size())?_msgidPlural.at(form):_msgidPlural.last();
-}
-
-}
-
-#endif // CATALOGITEMPRIVATE_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of KAider
- This file is based on the one from KBabel
-
- Copyright (C) 2002-2003 by Stanislav Visnovsky <visnovsky@kde.org>
- 2007 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "catalogfileplugin.h"
-
-using namespace GettextCatalog;
-
-CatalogExportPlugin::CatalogExportPlugin()
-// : d(new CatalogExportPluginPrivate)
-{
-}
-
-CatalogExportPlugin::~CatalogExportPlugin()
-{
-// delete d;
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file contains parts of KBabel code
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2002 by Stanislav Visnovsky <visnovsky@kde.org>
- Copyright (C) 2005,2006 by Nicolas GOUTTE <goutte@kde.org>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "gettextexport.h"
-
-//#include <resources.h>
-#include "gettextstorage.h"
-#include "catalogitem.h"
-
-#include <QFile>
-#include <QTextCodec>
-#include <QList>
-#include <QTextStream>
-#include <QEventLoop>
-
-#include <ksavefile.h>
-#include <kapplication.h>
-#include <klocale.h>
-#include <kdebug.h>
-
-
-using namespace GettextCatalog;
-
-GettextExportPlugin::GettextExportPlugin(short wrapWidth, short trailingNewLines)
- : m_wrapWidth(wrapWidth)
- , m_trailingNewLines(trailingNewLines)
-{
-}
-
-ConversionStatus GettextExportPlugin::save(QIODevice* device,
- const GettextStorage* catalog,
- QTextCodec* codec)
-{
- QTextStream stream(device);
- stream.setCodec(codec);
-
- //if ( m_wrapWidth == -1 ) m_wrapWidth=80;
-
- // only save header if it is not empty
- const QString& headerComment( catalog->m_header.comment() );
- // ### why is this useful to have a header with an empty msgstr?
- if ( !headerComment.isEmpty() || !catalog->m_header.msgstrPlural().isEmpty() )
- {
- // write header
- writeComment( stream, headerComment );
-
- const QString& headerMsgid (catalog->m_header.msgid());
-
- // Gettext PO files should have an empty msgid as header
- if ( !headerMsgid.isEmpty() )
- {
- // ### perhaps it is grave enough for a user message
- kWarning() << "Non-empty msgid for the header, assuming empty msgid!" << endl << headerMsgid << "---";
- }
-
- // ### FIXME: if it is the header, then the msgid should be empty! (Even if KBabel has made something out of a non-header first entry!)
- stream << "msgid \"\"\n";
-
- writeKeyword( stream, "msgstr", catalog->m_header.msgstr(), false );
- }
-
-
- const QVector<CatalogItem>& catalogEntries=catalog->m_entries;
- int limit=catalog->numberOfEntries();
- QStringList list;
- for (int counter = 0; counter < limit; counter++)
- {
- stream << '\n';
-
- const CatalogItem& catalogItem = catalogEntries.at(counter);
- // write entry
- writeComment( stream, catalogItem.comment() );
-
- const QString& msgctxt = catalogItem.msgctxt();
- if (! msgctxt.isEmpty() || catalogItem.keepEmptyMsgCtxt())
- writeKeyword( stream, "msgctxt", msgctxt );
-
- writeKeyword( stream, "msgid", catalogItem.msgid(), true, catalogItem.prependEmptyForMsgid() );
- if ( catalogItem.isPlural() )
- writeKeyword( stream, "msgid_plural", catalogItem.msgid(1), true, catalogItem.prependEmptyForMsgid() );
-
- if (!catalogItem.isPlural())
- writeKeyword( stream, "msgstr", catalogItem.msgstr(), true, catalogItem.prependEmptyForMsgstr() );
- else
- {
- kDebug() << "Saving gettext plural form";
- //TODO check len of the actual stringlist??
- const int forms = catalog->numberOfPluralForms();
- for ( int i = 0; i < forms; ++i )
- {
- QString keyword = "msgstr[" + QString::number( i ) + ']';
- writeKeyword( stream, keyword, catalogItem.msgstr(i), true, catalogItem.prependEmptyForMsgstr() );
- }
- }
- }
-
-#if 0
-//legacy
- if ( _saveSettings.saveObsolete )
-#endif
- {
- QList<QString>::const_iterator oit;
- const QStringList& _obsolete=catalog->m_catalogExtraData;
- oit=_obsolete.constBegin();
- if (oit!=_obsolete.constEnd())
- {
- stream << "\n" << (*oit);
- while((++oit)!=_obsolete.constEnd())
- stream << "\n\n" << (*oit);
- }
- }
-
- int i=m_trailingNewLines+1;
- while (--i>=0)
- stream << '\n';
-
- return OK;
-}
-
-void GettextExportPlugin::writeComment( QTextStream& stream, const QString& comment ) const
-{
- if( !comment.isEmpty() )
- {
- // We must check that each comment line really starts with a #, to avoid syntax errors
- int pos = 0;
- for(;;)
- {
- const int newpos = comment.indexOf( '\n', pos, Qt::CaseInsensitive );
- if ( newpos == pos )
- {
- ++pos;
- stream << '\n';
- continue;
- }
- const QString& span ((newpos==-1 ) ? comment.mid(pos) : comment.mid(pos, newpos-pos) );
-
- const int len = span.length();
- QString spaces; // Stored leading spaces
- for ( int i = 0 ; i < len ; ++i )
- {
- const QChar& ch = span[ i ];
- if ( ch == '#' )
- {
- stream << spaces << span.mid( i );
- break;
- }
- else if ( ch == ' ' || ch == '\t' )
- {
- // We have a leading white space character, so store it temporary
- spaces += ch;
- }
- else
- {
- // Not leading white space and not a # character. so consider that the # character was missing at first position.
- stream << "# " << spaces << span.mid( i );
- break;
- }
- }
- stream << '\n';
-
- if ( newpos == -1 )
- break;
- else
- pos = newpos + 1;
- }
- }
-}
-
-void GettextExportPlugin::writeKeyword( QTextStream& stream, const QString& keyword, QString text, bool containsHtml, bool startedWithEmptyLine ) const
-{
- if ( text.isEmpty() )
- {
- // Whatever the wrapping mode, an empty line is an empty line
- stream << keyword << " \"\"\n";
- return;
- }
-
- //TODO remove this for KDE 4.4
- //NOTE not?
- int pos=0;
- while ((pos=text.indexOf("\\\"",pos))!=-1)
- {
- if (pos==0 || text.at(pos-1)!='\\')
- text.replace(pos,2,'"');
- else
- pos++;
- }
- text.replace('"',"\\\"");
-#if 0
- if ( m_wrapWidth == -1 )
- {
- // Traditional KBabel wrapping
- QStringList list = text.split( '\n', QString::SkipEmptyParts );
-
- if ( text.startsWith( '\n' ) )
- list.prepend( QString() );
-
- if(list.isEmpty())
- list.append( QString() );
-
- if( list.count() > 1 )
- list.prepend( QString() );
-
- stream << keyword << ' ';
-
- QStringList::const_iterator it;
- for( it = list.constBegin(); it != list.constEnd(); ++it )
- stream << '\"' << (*it) << "\"\n";
- return;
- }
-#endif
-
- if ( m_wrapWidth == 0 ) // Unknown special wrapping, so assume "no wrap" instead
- {
- // No wrapping (like Gettext's --no.wrap or -w0 )
- // we need to remove the \n characters, as they are extra characters
- QString realText( text );
- realText.remove( '\n' );
- stream << keyword << " \"" << realText << "\"\n";
- return;
- }
- else if ( m_wrapWidth < 0 )
- {
- // No change in wrapping
- QStringList list = text.split( '\n');
- if (list.count()>1 || startedWithEmptyLine /* || keyword.length()+3+text.length()>=80*/)
- list.prepend(QString());
-
- stream << keyword << " ";
- QStringList::const_iterator it;
- for( it = list.constBegin(); it != list.constEnd(); ++it )
- stream << "\"" << (*it) << "\"\n";
-
- return;
- }
-
- // lazy wrapping
- QStringList list = text.split( '\n', QString::SkipEmptyParts );
-
- if ( text.startsWith( '\n' ) )
- list.prepend( QString() );
-
- if(list.isEmpty())
- list.append( QString() );
-
- //static QRegExp breakStopReForHtml("[ >.%/:,]", Qt::CaseSensitive, QRegExp::Wildcard);
- //static QRegExp breakStopReForText("[ .%/:,]", Qt::CaseSensitive, QRegExp::Wildcard);
- static QRegExp breakStopReForHtml("[ >%]", Qt::CaseSensitive, QRegExp::Wildcard);
- static QRegExp breakStopReForText("[ &%]", Qt::CaseSensitive, QRegExp::Wildcard);
- QRegExp breakStopRe=containsHtml?breakStopReForHtml:breakStopReForText;
-
- int max=m_wrapWidth-2;
- bool prependedEmptyLine=false;
- QStringList::iterator itm;
- for( itm = list.begin(); itm != list.end(); ++itm )
- {
- if (list.count()==1 && keyword.length()+1+itm->length()>=max)
- {
- prependedEmptyLine=true;
- itm=list.insert(itm,QString());
- }
-
- if (itm->length()>max)
- {
- int pos = itm->lastIndexOf(breakStopRe,max-1);
- if (pos>(max/2))
- {
- int pos2 = itm->indexOf('<',pos);
- if (pos2>0&&pos2<max-1)
- pos=itm->indexOf('<',pos);
- ++pos;
- }
- else
- {
- if (itm->at(max-1)=='\\')
- {
- do {--max;}
- while (max>=2 && itm->at(max-1)=='\\');
- }
- pos=max;
- }
- //itm=list.insert(itm,itm->left(pos));
- QString t=*itm;
- itm=list.insert(itm,t);
- ++itm;
- if (itm != list.end())
- {
- (*itm)=itm->remove(0,pos);
- --itm;
- if (itm != list.end())
- itm->truncate(pos);
- }
- }
- }
-
- if( !prependedEmptyLine && list.count() > 1 )
- list.prepend( QString() );
-
- stream << keyword << " ";
-
- QStringList::const_iterator it;
- for( it = list.constBegin(); it != list.constEnd(); ++it )
- stream << "\"" << (*it) << "\"\n";
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file contains parts of KBabel code
-
- Copyright (C) 2002 by Stanislav Visnovsky <visnovsky@kde.org>
- Copyright (C) 2006 by Nicolas GOUTTE <goutte@kde.org>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef GETTEXTEXPORTPLUGIN_H
-#define GETTEXTEXPORTPLUGIN_H
-
-#include <catalogfileplugin.h>
-
-#include <QStringList>
-#include <QTextCodec>
-#include <QTextStream>
-
-namespace GettextCatalog {
-class GettextStorage;
-
-
-/**
- * @brief The class for exporting GNU gettext PO files.
- *
- * As an extra information, it stores the list of all obsolete entries.
- */
-
-class GettextExportPlugin
-{
-public:
- GettextExportPlugin(short wrapWidth=-1, short trailingNewLines=1);
- ConversionStatus save(QIODevice* device,
- const GettextStorage* catalog,
- QTextCodec* codec);
-
-private:
- /**
- * Write a PO comment to @p stream and take care that each comment lines start with a # character
- */
- void writeComment( QTextStream& stream, const QString& comment ) const;
-
- /**
- * Write a PO keyword (msgctxt, msgid, msgstr, msgstr_plural, msgstr[0]) and the corresponding text.
- * This includes wrapping the text.
- */
- void writeKeyword( QTextStream& stream, const QString& keyword, QString text, bool containsHtml=true, bool startedWithEmptyLine=false ) const;
-
-public:
- /**
- * @brief Width of the wrap
- *
- * This is the width of the wrap in characters (not bytes), including everything
- * (e.g. keyword, quote characters, spaces).
- *
- * - A value of 0 means no wrap
- * - A value of -1 means the traditional KBabel wrapping
- * - Other negative values are reserved for future extensions (by default: no wrap)
- * @note
- * - Gettext's default value is 78 characters
- * - Too small values might not be correctly supported.
- */
- short m_wrapWidth;
- short m_trailingNewLines;
-};
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file is based on the one from KBabel
-
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2003 by Stanislav Visnovsky <visnovsky@kde.org>
- 2006 by Nicolas GOUTTE <nicolasg@snafu.de>
- 2007 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#define KDE_NO_DEBUG_OUTPUT
-
-#include "gettextimport.h"
-//#include <resources.h>
-
-#include <QFile>
-#include <QtCore/qdatetime.h>
-#include <QFileInfo>
-#include <QRegExp>
-#include <QTextCodec>
-#include <QList>
-#include <QTextStream>
-#include <QEventLoop>
-
-#include <kapplication.h>
-#include <kdebug.h>
-#include <kpluginfactory.h>
-#include <klocale.h>
-
-#include "catalogitem.h"
-
-using namespace GettextCatalog;
-
-// GettextImportPlugin::GettextImportPlugin(ExtraDataSaver* extraDataSaver)
-// : CatalogImportPlugin()
-// , _extraDataSaver(extraDataSaver)
-GettextImportPlugin::GettextImportPlugin()
- : CatalogImportPlugin()
- , _rxMsgCtxt ("^msgctxt\\s*\".*\"$")
- , _rxMsgId ("^msgid\\s*\".*\"$")
- , _rxMsgIdPlural ("^msgid_plural\\s*\".*\"$")
- , _rxMsgIdPluralBorked("^msgid_plural\\s*\"?.*\"?$")
- , _rxMsgIdBorked ("^msgid\\s*\"?.*\"?$")
- , _rxMsgIdRemQuotes ("^msgid\\s*\"")
- , _rxMsgLineRemEndQuote ("\"$")
- , _rxMsgLineRemStartQuote ("^\"")
- , _rxMsgLine ("^\".*\\n?\"$")
- , _rxMsgLineBorked ("^\"?.+\\n?\"?$")
- , _rxMsgStr ("^msgstr\\s*\".*\\n?\"$")
- , _rxMsgStrOther ("^msgstr\\s*\"?.*\\n?\"?$")
- , _rxMsgStrPluralStart("^msgstr\\[0\\]\\s*\".*\\n?\"$")
- , _rxMsgStrPluralStartBorked ("^msgstr\\[0\\]\\s*\"?.*\\n?\"?$")
- , _rxMsgStrPlural ("^msgstr\\[[0-9]+\\]\\s*\".*\\n?\"$")
- , _rxMsgStrPluralBorked ("^msgstr\\[[0-9]\\]\\s*\"?.*\\n?\"?$")
- , _rxMsgStrRemQuotes ("^msgstr\\s*\"?")
-// , _rxMsgId ("^msgid\\s*\"?.*\"?$")
- , _obsoleteStart("#~")
- , _msgctxtStart("msgctxt")
-
-{
-}
-
-ConversionStatus GettextImportPlugin::load(QIODevice* device)
-{
- _testBorked=false;
- _errorLine=0;
-
- // find codec for file
- // bool hadCodec;
- QTextCodec* codec=codecForDevice(device/*, &hadCodec*/ );
- QTextStream stream(device);
- stream.seek(0);
- stream.setCodec(codec);
-
- //QIODevice *dev = stream.device();
- //int fileSize = dev->size();
-
- // if somethings goes wrong with the parsing, we don't have deleted the old contents
- CatalogItem tempHeader;
-
- kDebug() << "start parsing...";
- QTime aaa;
- aaa.start();
- // first read header
- const ConversionStatus status = readEntry(stream);
-
- bool recoveredErrorInHeader = false;
- if (Q_UNLIKELY( status == RECOVERED_PARSE_ERROR ))
- {
- kDebug() << "Recovered error in header entry";
- recoveredErrorInHeader = true;
- }
- else if (Q_UNLIKELY( status != OK ))
- {
- kWarning() << "Parse error in header entry";
- return status;
- }
-
- bool reconstructedHeader=!_msgid.isEmpty() && !_msgid.first().isEmpty();
- //kWarning() << "HEADER MSGID: " << _msgid;
- //kWarning() << "HEADER MSGSTR: " << _msgstr;
- if (Q_UNLIKELY( reconstructedHeader ))
- {
- // The header must have an empty msgid
- kWarning() << "Header entry has non-empty msgid. Creating a temporary header! " << _msgid;
- tempHeader.setMsgid( QString() );
- QString tmp(
- "Content-Type: text/plain; charset=UTF-8\\n" // Unknown charset
- "Content-Transfer-Encoding: 8bit\\n"
- "Mime-Version: 1.0" );
- tempHeader.setMsgstr( tmp);
- // We keep the comment of the first entry, as it might really be a header comment (at least partially)
- const QString comment( "# Header entry was created by Lokalize.\n#\n" + _comment );
- tempHeader.setComment( comment );
- recoveredErrorInHeader = true;
- }
- else
- {
- tempHeader.setMsgid( _msgid );
- tempHeader.setMsgstr( _msgstr );
- tempHeader.setComment( _comment );
- }
-// if(tempHeader.isFuzzy())
-// {
-// tempHeader.removeFuzzy();
-// }
-
- // check if header seems to indicate docbook content generated by xml2pot
- const bool docbookContent = tempHeader.msgstr().contains( "application/x-xml2pot" );
-
-
-
-
-
-
-
- // now parse the rest of the file
- uint counter=0;
- QList<int> errorIndex;
- bool recoveredError=false;
- bool docbookFile=false;
-
- ExtraDataSaver _extraDataSaver;
- ConversionStatus success=OK;
- while( !stream.atEnd() )
- {
- if (reconstructedHeader)
- reconstructedHeader=false;
- else
- success=readEntry(stream);
-
- if(Q_LIKELY(success==OK))
- {
- if( _obsolete )
- _extraDataSaver(_comment);
- else
- {
- CatalogItem tempCatItem;
- tempCatItem.setPlural(_gettextPluralForm);
- tempCatItem.setMsgid( _msgid, _msgidMultiline );
- tempCatItem.setMsgstr( _msgstr, _msgstrMultiline );
- if (_msgctxtPresent) tempCatItem.setMsgctxt( _msgctxt );
- tempCatItem.setComment( _comment );
-
- // add new entry to the list of entries
- appendCatalogItem(tempCatItem);
- // check if first comment seems to indicate a docbook source file
- if(counter==0)
- docbookFile = tempCatItem.comment().contains(".docbook" );
- }
- }
- else if(Q_UNLIKELY( success==RECOVERED_PARSE_ERROR ))
- {
- kDebug() << "Recovered parse error in entry: " << counter;
- recoveredError=true;
- errorIndex.append(counter);
-
- CatalogItem tempCatItem;
- tempCatItem.setPlural(_gettextPluralForm);
- tempCatItem.setMsgid( _msgid );
- tempCatItem.setMsgstr( _msgstr );
- if (_msgctxtPresent) tempCatItem.setMsgctxt( _msgctxt );
- tempCatItem.setComment( _comment );
-
-
- // add new entry to the list of entries
- appendCatalogItem(tempCatItem);
- }
- else if (success == PARSE_ERROR)
- {
- kDebug() << "Parse error in entry: " << counter;
- return PARSE_ERROR;
- }
- else
- {
- kDebug() << "Unknown success status, assumig parse error " << success;
- return PARSE_ERROR;
- }
- counter++;
-
- }
-
- // TODO: can we check that there is no useful entry?
- if (Q_UNLIKELY( !counter && !recoveredErrorInHeader ))
- {
- // Empty file? (Otherwise, there would be a try of getting an entry and the count would be 1 !)
- kDebug() << " Empty file?";
- return PARSE_ERROR;
- }
-
- kDebug() << " ready";
-
- // We have successfully loaded the file (perhaps with recovered errors)
-
-// qWarning() << " done in " << aaa.elapsed() <<_extraDataSaver->extraData.size() << endl;
-
- setGeneratedFromDocbook(docbookContent || docbookFile);
- setHeader(tempHeader);
- setCatalogExtraData(_extraDataSaver.extraData);
- setErrorIndex(errorIndex);
- setCodec(codec);
- //setMimeTypes( "text/x-gettext-translation" );
-#if 0
- if (Q_UNLIKELY( recoveredErrorInHeader ))
- {
- kDebug() << " Returning: header error";
- return RECOVERED_HEADER_ERROR;
- }
- else if (Q_UNLIKELY( recoveredError ))
- {
- kDebug() << " Returning: recovered parse error";
- return RECOVERED_PARSE_ERROR;
- }
- else
-#endif
- {
- kDebug() << " Returning: OK! :-)";
- return OK;
- }
-}
-
-QTextCodec* GettextImportPlugin::codecForDevice(QIODevice* device/*, bool* hadCodec*/)
-{
- QTextStream stream( device );
- stream.seek(0);
- _errorLine=0;
- stream.setCodec( "UTF-8" );
- stream.setAutoDetectUnicode(true); //this way we can
- QTextCodec* codec=stream.codec(); //detect UTF-16
-
- ConversionStatus status = readEntry(stream);
- if (Q_UNLIKELY( status!=OK && status != RECOVERED_PARSE_ERROR ))
- {
- kDebug() << "wasn't able to read header";
- return codec;
- }
-
- QRegExp regexp("Content-Type:\\s*\\w+/[-\\w]+;?\\s*charset\\s*=\\s*(\\S+)\\s*\\\\n");
- if ( regexp.indexIn( _msgstr.first() ) == -1 )
- {
- kDebug() << "no charset entry found";
- return codec;
- }
-
- const QString charset = regexp.cap(1);
- kDebug() << "charset: " << charset;
-
- if (charset.isEmpty())
- {
- kWarning() << "No charset defined! Assuming UTF-8!";
- return codec;
- }
-
- // "CHARSET" is the default charset entry in a template (pot).
- // characters in a template should be either pure ascii or
- // at least utf8, so utf8-codec can be used for both.
- if ( charset.contains("CHARSET"))
- {
- kDebug() << QString("file seems to be a template: using utf-8 encoding.");
- return QTextCodec::codecForName("utf8");;
- }
-
- QTextCodec* t=0;
- t = QTextCodec::codecForName(charset.toLatin1());
-
- if (t)
- return t;
- else
- kWarning() << "charset found, but no codec available, using UTF-8 instead";
-
- return codec;//UTF-8
-}
-
-ConversionStatus GettextImportPlugin::readEntry(QTextStream& stream)
-{
- ConversionStatus result=readEntryRaw(stream);
- _msgstr.replaceInStrings("\\\"","\"");
- _msgid.replaceInStrings("\\\"","\"");
- _msgctxt.replace("\\\"","\"");
- return result;
-}
-
-ConversionStatus GettextImportPlugin::readEntryRaw(QTextStream& stream)
-{
- //kDebug() << " START";
- enum {Begin,Comment,Msgctxt,Msgid,Msgstr} part=Begin;
-
- _trailingNewLines=0;
- bool error=false;
- bool recoverableError=false;
- bool seenMsgctxt=false;
- _msgstr.clear();
- _msgstr.append(QString());
- _msgid.clear();
- _msgid.append(QString());
- _msgctxt.clear();
- _msgctxtPresent=false;
- _comment.clear();
- _gettextPluralForm=false;
- _obsolete=false;
-
- QStringList::Iterator msgstrIt=_msgstr.begin();
- QString line;
-
- while( !stream.atEnd() )
- {
- _errorLine++;
- //line=stream.readLine();
- if (!_bufferedLine.isEmpty())
- {
- line=_bufferedLine;
- _bufferedLine.clear();
- }
- else
- line=stream.readLine();
-
- kDebug() << "Parsing line: " << line;
-
- static const QString lesslessless="<<<<<<<";
- static const QString isisis="=======";
- static const QString moremoremore=">>>>>>>";
- if (Q_UNLIKELY( line.startsWith( lesslessless ) || line.startsWith( isisis ) || line.startsWith( moremoremore ) ))
- {
- // We have found a CVS/SVN conflict marker. Abort.
- // (It cannot be any useful data of the PO file, as otherwise the line would start with at least a quote)
- kError() << "CVS/SVN conflict marker found! Aborting!" << endl << line << endl;
- return PARSE_ERROR;
- }
-
- // remove whitespaces from beginning and end of line
- line = line.trimmed();
-
- // remember wrapping state to save file nicely
- int len=line.length();
- if (len)
- {
- _trailingNewLines=0;
- if (_maxLineLength<len && line.at(0)!='#')
- _maxLineLength=len;
- }
- else
- ++_trailingNewLines;
-
-
- if(part==Begin)
- {
- // ignore trailing newlines
- if(!len)
- continue;
-
- if(line.startsWith(_obsoleteStart))
- {
- _obsolete=true;
- part=Comment;
- _comment=line;
- }
- else if(line.startsWith('#'))
- {
- part=Comment;
- _comment=line;
- }
- else if( line.startsWith(_msgctxtStart) && line.contains( _rxMsgCtxt ) )
- {
- part=Msgctxt;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgctxt\\s*\""));
- line.remove(_rxMsgLineRemEndQuote);
- _msgctxt=line;
- _msgctxtPresent=true;
- seenMsgctxt=true;
- }
- else if( line.contains( _rxMsgId ) )
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgIdRemQuotes);
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
-
- }
- // one of the quotation marks is missing
- else if(Q_UNLIKELY( /*_testBorked&&*/ line.contains( _rxMsgIdBorked ) ))
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgid\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else
- {
- kDebug() << "no comment, msgctxt or msgid found after a comment: " << line;
- error=true;
- break;
- }
- }
- else if(part==Comment)
- {
- if(!len && _obsolete ) return OK;
- if(!len) continue;
- else if(line.startsWith(_obsoleteStart))
- {
- _comment+=('\n'+line);
- _obsolete=true;
- }
- else if(line.startsWith('#'))
- {
- _comment+=('\n'+line);
- }
- else if( line.startsWith(_msgctxtStart) &&line.contains( _rxMsgCtxt ) )
- {
- part=Msgctxt;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgctxt\\s*\""));
- line.remove(_rxMsgLineRemEndQuote);
- _msgctxt=line;
- _msgctxtPresent=true;
- seenMsgctxt=true;
- }
- else if( line.contains( _rxMsgId ) )
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgIdRemQuotes);
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
- }
- // one of the quotation marks is missing
- else if(Q_UNLIKELY( /*_testBorked&&*/line.contains( _rxMsgIdBorked ) ))
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgid\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else
- {
- kDebug() << "no comment or msgid found after a comment while parsing: " << _comment;
- error=true;
- break;
- }
- }
- else if(part==Msgctxt)
- {
- if(!len)
- continue;
- else if( line.contains( _rxMsgLine ) )
- {
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgLineRemStartQuote);
- line.remove(_rxMsgLineRemEndQuote);
-
- // add Msgctxt line to item
- if(_msgctxt.isEmpty())
- _msgctxt=line;
- else
- _msgctxt+=('\n'+line);
- _msgctxtPresent=true;
- }
- else if( line.contains( _rxMsgId ) )
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgIdRemQuotes);
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
- }
- // one of the quotation marks is missing
- else if(Q_UNLIKELY(/*_testBorked&&*/ line.contains ( _rxMsgIdBorked ) ))
- {
- part=Msgid;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgid\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgidMultiline=line.isEmpty();
- (*(_msgid).begin())=line;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else
- {
- kDebug() << "no msgid found after a msgctxt while parsing: " << _msgctxt;
- error=true;
- break;
- }
- }
- else if(part==Msgid)
- {
- if(!len)
- continue;
- else if( line.contains( _rxMsgLine ) )
- {
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgLineRemStartQuote);
- line.remove(_rxMsgLineRemEndQuote);
-
- QStringList::Iterator it;
- if(_gettextPluralForm)
- {
- it=_msgid.end();
- --it;
- }
- else
- it = _msgid.begin();
-
- // add Msgid line to item
- if(it->isEmpty())
- (*it)=line;
- else
- (*it)+=('\n'+line);
- }
- else if( line.contains( _rxMsgIdPlural) )
- {
- part=Msgid;
- _gettextPluralForm = true;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgid_plural\\s*\""));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgid.append(line);
- }
- // one of the quotation marks is missing
- else if(Q_UNLIKELY(/*_testBorked&&*/ line.contains( _rxMsgIdPluralBorked ) ))
- {
- part=Msgid;
- _gettextPluralForm = true;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgid_plural\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgid.append(line);
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else if( !_gettextPluralForm && ( line.contains( _rxMsgStr ) ) )
- {
- part=Msgstr;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgStrRemQuotes);
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstrMultiline=line.isEmpty();
- (*msgstrIt)=line;
- }
- else if( !_gettextPluralForm && ( line.contains( _rxMsgStrOther )) )
- {
- part=Msgstr;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgStrRemQuotes);
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstrMultiline=line.isEmpty();
- (*msgstrIt)=line;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else if( _gettextPluralForm && ( line.contains( _rxMsgStrPluralStart ) ) )
- {
- part=Msgstr;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgstr\\[0\\]\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstrMultiline=line.isEmpty();
- (*msgstrIt)=line;
- }
- else if(Q_UNLIKELY( /*_testBorked&&*/ _gettextPluralForm && line.contains( _rxMsgStrPluralStartBorked ) ))
- {
- part=Msgstr;
-
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgstr\\[0\\]\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstrMultiline=line.isEmpty();
- (*msgstrIt)=line;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else if ( line.startsWith( '#' ) )
- {
- // ### TODO: could this be considered recoverable?
- kDebug() << "comment found after a msgid while parsing: " << _msgid.first();
- error=true;
- break;
- }
- else if ( line.startsWith( "msgid" ) )
- {
- kDebug() << "Another msgid found after a msgid while parsing: " << _msgid.first();
- error=true;
- break;
- }
- // a line of the msgid with a missing quotation mark
- else if(Q_UNLIKELY( /*_testBorked&&*/line.contains( _rxMsgLineBorked ) ))
- {
- recoverableError=true;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgLineRemStartQuote);
- line.remove(_rxMsgLineRemEndQuote);
-
- QStringList::Iterator it;
- if( _gettextPluralForm )
- {
- it=_msgid.end();
- --it;
- }
- else
- it = _msgid.begin();
-
- // add Msgid line to item
- if(it->isEmpty())
- (*it)=line;
- else
- (*it)+=('\n'+line);
- }
- else
- {
- kDebug() << "no msgstr found after a msgid while parsing: " << _msgid.first();
- error=true;
- break;
- }
- }
- else if(part==Msgstr)
- {
- if(!len)
- break;
- // another line of the msgstr
- else if( line.contains( _rxMsgLine ) )
- {
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgLineRemStartQuote);
- line.remove(_rxMsgLineRemEndQuote);
-
- if(!(*msgstrIt).isEmpty())
- (*msgstrIt)+='\n';
- (*msgstrIt)+=line;
- }
- else if( _gettextPluralForm && ( line.contains( _rxMsgStrPlural ) ) )
- {
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgstr\\[[0-9]+\\]\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstr.append(line);
- msgstrIt=_msgstr.end();
- --msgstrIt;
- }
- else if ( line.startsWith( '#' ) || line.startsWith( "msgid" ) )
- {
- _errorLine--;
- _bufferedLine=line;
- break;
- }
- else if(Q_UNLIKELY(/*_testBorked&&*/ _gettextPluralForm && ( line.contains( _rxMsgStrPluralBorked ) ) ))
- {
- // remove quotes at beginning and the end of the lines
- line.remove(QRegExp("^msgstr\\[[0-9]\\]\\s*\"?"));
- line.remove(_rxMsgLineRemEndQuote);
-
- _msgstr.append(line);
- msgstrIt=_msgstr.end();
- --msgstrIt;
-
- if(!line.isEmpty())
- recoverableError=true;
- }
- else if(line.startsWith("msgstr"))
- {
- kDebug() << "Another msgstr found after a msgstr while parsing: " << line << _msgstr.last();
- error=true;
- break;
- }
- // another line of the msgstr with a missing quotation mark
- else if(Q_UNLIKELY( /*_testBorked&&*/line.contains( _rxMsgLineBorked ) ))
- {
- recoverableError=true;
-
- // remove quotes at beginning and the end of the lines
- line.remove(_rxMsgLineRemStartQuote);
- line.remove(_rxMsgLineRemEndQuote);
-
- if(!(*msgstrIt).isEmpty())
- (*msgstrIt)+='\n';
- (*msgstrIt)+=line;
- }
- else
- {
- kDebug() << "no msgid or comment found after a msgstr while parsing: " << _msgstr.last();
- error=true;
- break;
- }
- }
- }
-
-/*
- if(_gettextPluralForm)
- {
- kDebug() << "gettext plural form:\n"
- << "msgid:\n" << _msgid.first() << "\n"
- << "msgid_plural:\n" << _msgid.last() << "\n" << endl;
- int counter=0;
- for(QStringList::Iterator it = _msgstr.begin(); it != _msgstr.end(); ++it)
- {
- kDebug() << "msgstr[" << counter << "]:\n"
- << (*it) << endl;
- counter++;
- }
- }
- */
-
- //kDebug() << " NEAR RETURN";
- if(Q_UNLIKELY(error))
- return PARSE_ERROR;
- else if(Q_UNLIKELY(recoverableError))
- return RECOVERED_PARSE_ERROR;
- else
- return OK;
-}
-
-// kate: space-indent on; indent-width 4; replace-tabs on;
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
- This file is based on the one from KBabel
-
- Copyright; 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef GETTEXTIMPORTPLUGIN_H
-#define GETTEXTIMPORTPLUGIN_H
-
-#include "catalogfileplugin.h"
-
-#include <kdebug.h>
-
-#include <QStringList>
-#include <QTextStream>
-
-#include <QTextCodec>
-
-namespace GettextCatalog {
-
-class ExtraDataSaver
-{
-public:
- ExtraDataSaver(){}
- virtual ~ExtraDataSaver(){}
- void operator()(const QString& comment){extraData.append(comment);}
- QStringList extraData;
-};
-
-class ExtraDataSkipSaver:public ExtraDataSaver
-{
-public:
- ExtraDataSkipSaver(){}
- void operator()(const QString&){};
-};
-
-/**
- * The class for importing GNU gettext PO files.
- * As an extra information, it stores the list of all obsolete entries.
- * @short Gettext PO parser
- */
-
-class GettextImportPlugin: public CatalogImportPlugin
-{
-public:
- GettextImportPlugin();
- //GettextImportPlugin(ExtraDataSaver* extraDataSaver);
- //~GettextImportPlugin(){delete _extraDataSaver;}
- ConversionStatus load(QIODevice*);
- const QString id() {return "GNU gettext";}
-
-private:
- QTextCodec* codecForDevice(QIODevice* /*, bool* hadCodec*/);
- ConversionStatus readEntryRaw(QTextStream& stream);
- ConversionStatus readEntry(QTextStream& stream);
-
- // description of the last read entry
- QString _msgctxt;
- QStringList _msgid;
- QStringList _msgstr;
- QString _comment;
- bool _msgidMultiline;
- bool _msgstrMultiline;
- bool _gettextPluralForm;
- bool _testBorked;
- bool _obsolete;
- bool _msgctxtPresent;
-
- //ExtraDataSaver* _extraDataSaver;
-
- QRegExp _rxMsgCtxt;
- QRegExp _rxMsgId;
- QRegExp _rxMsgIdPlural;
- QRegExp _rxMsgIdPluralBorked;
- QRegExp _rxMsgIdBorked;
- QRegExp _rxMsgIdRemQuotes;
- QRegExp _rxMsgLineRemEndQuote;
- QRegExp _rxMsgLineRemStartQuote;
- QRegExp _rxMsgLine;
- QRegExp _rxMsgLineBorked;
- QRegExp _rxMsgStr;
- QRegExp _rxMsgStrOther;
- QRegExp _rxMsgStrPluralStart;
- QRegExp _rxMsgStrPluralStartBorked;
- QRegExp _rxMsgStrPlural;
- QRegExp _rxMsgStrPluralBorked;
- QRegExp _rxMsgStrRemQuotes;
-
- QString _obsoleteStart;
- QString _msgctxtStart;
- QString _bufferedLine;
-};
-}
-#endif
+++ /dev/null
-/*
-Copyright 2008 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "gettextstorage.h"
-
-#include "gettextheader.h"
-#include "catalogitem_private.h"
-#include "gettextimport.h"
-#include "gettextexport.h"
-
-#include "project.h"
-
-#include "version.h"
-#include "prefs_lokalize.h"
-
-#include "diff.h"
-
-#include <QProcess>
-#include <QString>
-#include <QMap>
-
-#include <kdebug.h>
-
-// static QString GNUPluralForms(const QString& lang);
-
-using namespace GettextCatalog;
-
-GettextStorage::GettextStorage()
- : CatalogStorage()
-{
-}
-
-
-GettextStorage::~GettextStorage()
-{
-}
-
-//BEGIN OPEN/SAVE
-
-int GettextStorage::load(QIODevice* device/*, bool readonly*/)
-{
- //GettextImportPlugin importer=GettextImportPlugin(readonly?(new ExtraDataSaver()):(new ExtraDataListSaver()));
- GettextImportPlugin importer;
- ConversionStatus status = OK;
- int errorLine;
- status = importer.open(device,this,&errorLine);
-
- //for langs with more than 2 forms
- //we create any form-entries additionally needed
- uint i=0;
- uint lim=size();
- while (i<lim)
- {
- CatalogItem& item=m_entries[i];
- if (item.isPlural()
- && item.msgstrPlural().count()<m_numberOfPluralForms
- )
- {
- QVector<QString> msgstr(item.msgstrPlural());
- while (msgstr.count()<m_numberOfPluralForms)
- msgstr.append(QString());
- item.setMsgstr(msgstr);
- }
- ++i;
-
- }
- //qCompress(m_storage->m_catalogExtraData.join("\n\n").toUtf8(),9);
-
- return status==OK?0:(errorLine+1);
-}
-
-bool GettextStorage::save(QIODevice* device, bool belongsToProject)
-{
- QString header=m_header.msgstr();
- QString comment=m_header.comment();
- QString catalogProjectId;//=m_url.fileName();
- //catalogProjectId=catalogProjectId.left(catalogProjectId.lastIndexOf('.'));
- updateHeader(header,
- comment,
- m_targetLangCode,
- m_numberOfPluralForms,
- catalogProjectId,
- m_generatedFromDocbook,
- belongsToProject,
- /*forSaving*/true,
- m_codec);
- m_header.setMsgstr(header);
- m_header.setComment(comment);
-
- //GettextExportPlugin exporter(m_maxLineLength>70?m_maxLineLength:-1, m_trailingNewLines);// this is kinda hackish...
- GettextExportPlugin exporter(Project::instance()->wordWrap(), m_trailingNewLines);
-
- ConversionStatus status = OK;
- status = exporter.save(device/*x-gettext-translation*/,this, m_codec);
-
- return status==OK;
-}
-
-//END OPEN/SAVE
-
-//BEGIN STORAGE TRANSLATION
-
-int GettextStorage::size() const
-{
- return m_entries.size();
-}
-
-
-static const QChar altSep(156);
-static InlineTag makeInlineTag(int i)
-{
- static const QString altSepText(" | ");
- static const QString ctype=i18n("separator for different-length string alternatives");
- return InlineTag(i,i,InlineTag::x,QString::number(i),QString(),altSepText,ctype);
-}
-
-static CatalogString makeCatalogString(const QString& string)
-{
- CatalogString result;
- result.string=string;
-
- int i=0;
-
- while((i=result.string.indexOf(altSep, i))!=-1)
- {
- result.string[i]=TAGRANGE_IMAGE_SYMBOL;
- result.tags.append(makeInlineTag(i));
- ++i;
- }
- return result;
-}
-
-//flat-model interface (ignores XLIFF grouping)
-CatalogString GettextStorage::sourceWithTags(DocPosition pos) const
-{
- return makeCatalogString(source(pos));
-}
-CatalogString GettextStorage::targetWithTags(DocPosition pos) const
-{
- return makeCatalogString(target(pos));
-}
-
-QString GettextStorage::source(const DocPosition& pos) const
-{
- return m_entries.at(pos.entry).msgid(pos.form);
-}
-QString GettextStorage::target(const DocPosition& pos) const
-{
- return m_entries.at(pos.entry).msgstr(pos.form);
-}
-
-void GettextStorage::targetDelete(const DocPosition& pos, int count)
-{
- m_entries[pos.entry].d->_msgstrPlural[pos.form].remove(pos.offset, count);
-}
-void GettextStorage::targetInsert(const DocPosition& pos, const QString& arg)
-{
- m_entries[pos.entry].d->_msgstrPlural[pos.form].insert(pos.offset, arg);
-}
-void GettextStorage::setTarget(const DocPosition& pos, const QString& arg)
-{
- m_entries[pos.entry].d->_msgstrPlural[pos.form]=arg;
-}
-
-
-void GettextStorage::targetInsertTag(const DocPosition& pos, const InlineTag& tag)
-{
- Q_UNUSED(tag);
- targetInsert(pos,altSep);
-}
-
-InlineTag GettextStorage::targetDeleteTag(const DocPosition& pos)
-{
- targetDelete(pos,1);
- return makeInlineTag(pos.offset);
-}
-
-QStringList GettextStorage::sourceAllForms(const DocPosition& pos, bool stripNewLines) const
-{
- return m_entries.at(pos.entry).allPluralForms(CatalogItem::Source, stripNewLines);
-}
-
-QStringList GettextStorage::targetAllForms(const DocPosition& pos, bool stripNewLines) const
-{
- return m_entries.at(pos.entry).allPluralForms(CatalogItem::Target, stripNewLines);
-}
-
-QVector<AltTrans> GettextStorage::altTrans(const DocPosition& pos) const
-{
- QStringList prev=m_entries.at(pos.entry).comment().split('\n').filter(QRegExp("^#\\|"));
-
- QString oldSingular;
- QString oldPlural;
-
- QString* cur=&oldSingular;
- QStringList::iterator it=prev.begin();
- static const QString msgid_plural_alt="#| msgid_plural \"";
- while (it!=prev.end())
- {
- if (it->startsWith(msgid_plural_alt))
- cur=&oldPlural;
-
- int start=it->indexOf('\"')+1;
- int end=it->lastIndexOf('\"');
- if (start&&end!=-1)
- {
- if (!cur->isEmpty())
- (*cur)+='\n';
- if (!( cur->isEmpty() && (end-start)==0 ))//for multiline msgs
- (*cur)+=it->midRef(start,end-start);
- }
- ++it;
- }
- if (pos.form==0)
- cur=&oldSingular;
-
- cur->replace("\\\"","\"");
-
- QVector<AltTrans> result;
- if (!cur->isEmpty())
- result<<AltTrans(CatalogString(*cur), i18n("Previous source value, saved by Gettext during transition to a newer POT template"));
-
- return result;
-}
-
-Note GettextStorage::setNote(DocPosition pos, const Note& note)
-{
- //kWarning()<<"s"<<m_entries.at(pos.entry).comment();
- Note oldNote;
- QVector<Note> l=notes(pos);
- if (l.size()) oldNote=l.first();
-
- QStringList comment=m_entries.at(pos.entry).comment().split('\n');
- //remove previous comment;
- QStringList::iterator it=comment.begin();
- while (it!=comment.end())
- {
- if (it->startsWith("# "))
- it=comment.erase(it);
- else
- ++it;
- }
- if (note.content.size())
- comment.prepend("# "+note.content.split('\n').join("\n# "));
- m_entries[pos.entry].setComment(comment.join("\n"));
-
- //kWarning()<<"e"<<m_entries.at(pos.entry).comment();
- return oldNote;
-}
-
-QVector<Note> GettextStorage::notes(const DocPosition& docPosition, const QRegExp& re, int preLen) const
-{
- QVector<Note> result;
- QString content;
-
- QStringList note=m_entries.at(docPosition.entry).comment().split('\n').filter(re);
-
- foreach(const QString &s, note)
- {
- if (s.size()>=preLen)
- {
- content+=s.midRef(preLen);
- content+='\n';
- }
- }
-
- if (!content.isEmpty())
- {
- content.chop(1);
- result<<Note(content);
- }
- return result;
-
-//i18nc("@info PO comment parsing. contains filename","<i>Place:</i>");
-//i18nc("@info PO comment parsing","<i>GUI place:</i>");
-}
-
-QVector<Note> GettextStorage::notes(const DocPosition& docPosition) const
-{
- static const QRegExp nre("^# ");
- return notes(docPosition,nre,2);
-}
-
-QVector<Note> GettextStorage::developerNotes(const DocPosition& docPosition) const
-{
- static const QRegExp dnre("^#\\. (?!i18n: file:)");
- return notes(docPosition,dnre,3);
-}
-
-QStringList GettextStorage::sourceFiles(const DocPosition& pos) const
-{
- QStringList result;
- QStringList commentLines=m_entries.at(pos.entry).comment().split('\n');
-
- static const QRegExp i18n_file_re("^#. i18n: file: ");
- foreach(const QString &uiLine, commentLines.filter(i18n_file_re))
- {
- result+=uiLine.mid(15).split(' ');
- }
-
- bool hasUi=!result.isEmpty();
- static const QRegExp cpp_re("^#: ");
- foreach(const QString &cppLine, commentLines.filter(cpp_re))
- {
- if (hasUi && cppLine.startsWith("#: rc.cpp")) continue;
- QStringList cppFiles=cppLine.mid(3).split(' ');
- result+=cppFiles;
- }
- return result;
-}
-
-QStringList GettextStorage::context(const DocPosition& pos) const
-{
- return matchData(pos);
-}
-
-QStringList GettextStorage::matchData(const DocPosition& pos) const
-{
- QString ctxt=m_entries.at(pos.entry).msgctxt();
-
- //KDE-specific
- //Splits @info:whatsthis and actual note
-/* if (ctxt.startsWith('@') && ctxt.contains(' '))
- {
- QStringList result(ctxt.section(' ',0,0,QString::SectionSkipEmpty));
- result<<ctxt.section(' ',1,-1,QString::SectionSkipEmpty);
- return result;
- }*/
- return QStringList(ctxt);
-}
-
-QString GettextStorage::id(const DocPosition& pos) const
-{
- //entries in gettext format may be non-unique
- //only if their msgctxts are different
-
- QString result=source(pos);
- result.remove('\n');
- result.prepend(m_entries.at(pos.entry).msgctxt()+":\n");
- return result;
-/* QByteArray result=source(pos).toUtf8();
- result+=m_entries.at(pos.entry).msgctxt().toUtf8();
- return QString qChecksum(result);*/
-}
-
-bool GettextStorage::isPlural(const DocPosition& pos) const
-{
- return m_entries.at(pos.entry).isPlural();
-}
-
-bool GettextStorage::isApproved(const DocPosition& pos) const
-{
- return !m_entries.at(pos.entry).isFuzzy();
-}
-void GettextStorage::setApproved(const DocPosition& pos, bool approved)
-{
- if (approved)
- m_entries[pos.entry].unsetFuzzy();
- else
- m_entries[pos.entry].setFuzzy();
-}
-
-bool GettextStorage::isEmpty(const DocPosition& pos) const
-{
- return m_entries.at(pos.entry).isUntranslated();
-}
-
-//END STORAGE TRANSLATION
-
-
-
-
-//called from importer
-bool GettextStorage::setHeader(const CatalogItem& newHeader)
-{
- if(newHeader.isValid())
- {
- // normalize the values - ensure every key:value pair is only on a single line
- QString values = newHeader.msgstr();
- values.replace ("\\n", "\\n\n");
-// kDebug () << "Normalized header: " << values;
- QString comment=newHeader.comment();
- QString catalogProjectId;//=m_url.fileName(); FIXME m_url is always empty
- //catalogProjectId=catalogProjectId.left(catalogProjectId.lastIndexOf('.'));
- bool belongsToProject=m_url.path().contains(Project::instance()->poDir());
-
- updateHeader(values,
- comment,
- m_targetLangCode,
- m_numberOfPluralForms,
- catalogProjectId,
- m_generatedFromDocbook,
- belongsToProject,
- /*forSaving*/true,
- m_codec);
- m_header=newHeader;
- m_header.setComment(comment);
- m_header.setMsgstr(values);
-
-// setClean(false);
- //emit signalHeaderChanged();
-
- return true;
- }
- kWarning () << "header Not valid";
- return false;
-}
-
-
-
+++ /dev/null
-/*
-Copyright 2008-2009 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef GETTEXTSTORAGE_H
-#define GETTEXTSTORAGE_H
-
-#include <QTextCodec>
-#include <QVector>
-#include "catalogitem.h"
-#include "catalogstorage.h"
-
-/**
- * Implementation of Gettext PO format support
- */
-namespace GettextCatalog {
-
-/**
- * @short Implementation of storage for Gettext PO
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class GettextStorage: public CatalogStorage
-{
-public:
- GettextStorage();
- ~GettextStorage();
-
- int capabilities() const{return 0;}
-
- int load(QIODevice* device/*, bool readonly=false*/);
- bool save(QIODevice* device, bool belongsToProject=false);
-
- int size() const;
-
- //flat-model interface (ignores XLIFF grouping)
- QString source(const DocPosition& pos) const;
- QString target(const DocPosition& pos) const;
- CatalogString sourceWithTags(DocPosition pos) const;
- CatalogString targetWithTags(DocPosition pos) const;
- CatalogString catalogString(const DocPosition& pos) const{return pos.part==DocPosition::Target?targetWithTags(pos):sourceWithTags(pos);}
-
- void targetDelete(const DocPosition& pos, int count);
- void targetInsert(const DocPosition& pos, const QString& arg);
- void setTarget(const DocPosition& pos, const QString& arg);//called for mergeCatalog
-
- void targetInsertTag(const DocPosition&, const InlineTag&);
- InlineTag targetDeleteTag(const DocPosition&);
-
- QStringList sourceAllForms(const DocPosition& pos, bool stripNewLines=false) const;
- QStringList targetAllForms(const DocPosition& pos, bool stripNewLines=false) const;
-
- QVector<Note> notes(const DocPosition& pos) const;
- Note setNote(DocPosition pos, const Note& note);
- QVector<AltTrans> altTrans(const DocPosition& pos) const;
- QStringList sourceFiles(const DocPosition& pos) const;
- QVector<Note> developerNotes(const DocPosition& pos) const;
-
- QStringList context(const DocPosition& pos) const;
-
- QStringList matchData(const DocPosition& pos) const;
- QString id(const DocPosition& pos) const;
-
- bool isPlural(const DocPosition& pos) const;
-
- bool isApproved(const DocPosition& pos) const;
- void setApproved(const DocPosition& pos, bool approved);
-
- bool isEmpty(const DocPosition& pos) const;
-
- QString mimetype()const{return "text/x-gettext-translation";}
-
-private:
- bool setHeader(const CatalogItem& newHeader);
- void setCodec(QTextCodec* codec) {m_codec = codec;}
-
- QVector<Note> notes(const DocPosition& pos, const QRegExp& re, int preLen) const;
-
-private:
- QVector<CatalogItem> m_entries;
- QVector<CatalogItem> m_obsoleteEntries;
- CatalogItem m_header;
- QTextCodec* m_codec;
-
- short m_maxLineLength;
- short m_trailingNewLines;
- bool m_generatedFromDocbook;
-
- QStringList m_catalogExtraData;
- QByteArray m_catalogExtraDataCompressed;
-
- friend class CatalogImportPlugin;
- friend class GettextExportPlugin;
-};
-
-}
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of KAider
- This file is based on the one from KBabel
-
- Copyright (C) 2002-2003 by Stanislav Visnovsky <visnovsky@kde.org>
- 2007 by Nick Shaforostoff <shafff@ukr.net>
-
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "catalogfileplugin.h"
-#include "importplugin_private.h"
-
-#include "gettextstorage.h"
-
-#include <QStringList>
-#include <QLinkedList>
-
-#include <kdebug.h>
-#include <kmessagebox.h>
-//#include <kservicetypetrader.h>
-
-namespace GettextCatalog
-{
-
-CatalogImportPlugin::CatalogImportPlugin()
- : _maxLineLength(0)
- , d(new CatalogImportPluginPrivate)
-{
-}
-
-CatalogImportPlugin::~CatalogImportPlugin()
-{
- delete d;
-}
-
-void CatalogImportPlugin::appendCatalogItem( const CatalogItem& item, const bool obsolete )
-{
- if (item.msgid().isEmpty())
- return;
- if( obsolete )
- d->_obsoleteEntries.append(item);
- else
- d->_entries.append(item);
-}
-
-void CatalogImportPlugin::setCatalogExtraData( const QStringList& data )
-{
- d->_catalogExtraData=data;
- d->_updateCatalogExtraData=true;
-}
-
-void CatalogImportPlugin::setGeneratedFromDocbook( const bool generated )
-{
- d->_generatedFromDocbook = generated;
- d->_updateGeneratedFromDocbook = true;
-}
-
-void CatalogImportPlugin::setErrorIndex(const QList<int>& errors)
-{
- d->_errorList = errors;
- d->_updateErrorList = true;
-}
-
-void CatalogImportPlugin::setHeader( const CatalogItem& item )
-{
- d->_header=item;
- d->_updateHeader=true;
-}
-
-void CatalogImportPlugin::setCodec( QTextCodec* codec )
-{
- d->_codec = codec;
-}
-
-ConversionStatus CatalogImportPlugin::open(QIODevice* device, GettextStorage* catalog, int* line)
-{
- d->_catalog=catalog;
- startTransaction();
-
- ConversionStatus result = load(device);
-
- if( result == OK || result == RECOVERED_PARSE_ERROR || result == RECOVERED_HEADER_ERROR )
- commitTransaction();
- if (line)
- (*line)=_errorLine;
- return result;
-}
-
-void CatalogImportPlugin::startTransaction()
-{
- d->_updateCodec = false;
- d->_updateCatalogExtraData = false;
- d->_updateGeneratedFromDocbook = false;
- d->_updateErrorList = false;
- d->_updateHeader = false;
- d->_entries.clear();
-}
-
-void CatalogImportPlugin::commitTransaction()
-{
- GettextStorage* catalog=d->_catalog;
-
- //catalog->clear();
-
- // fill in the entries
- QVector<CatalogItem>& entries=catalog->m_entries;
- entries.reserve( d->_entries.count() ); //d->_catalog->setEntries( e );
- for( QLinkedList<CatalogItem>::const_iterator it = d->_entries.begin(); it != d->_entries.end(); ++it/*,++i*/ )
- entries.append( *it );
-
- // The codec is specified in the header, so it must be updated before the header is.
- catalog->setCodec(d->_codec);
-
- catalog->m_catalogExtraData=d->_catalogExtraData;
- catalog->m_generatedFromDocbook=d->_generatedFromDocbook;
- catalog->setHeader(d->_header);
- //if( d->_updateErrorList ) d->_catalog->setErrorIndex(d->_errorList);
-
- catalog->m_maxLineLength=_maxLineLength;
- catalog->m_trailingNewLines=_trailingNewLines;
-}
-
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of KAider
- This file contains parts of KBabel code
-
- Copyright (C) 2002-2003 by Stanislav Visnovsky
- <visnovsky@kde.org>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef IMPORTPLUGINPRIVATE_H
-#define IMPORTPLUGINPRIVATE_H
-
-#include "catalogitem.h"
-#include "catalog.h"
-
-#include <QLinkedList>
-#include <QTextCodec>
-
-#include <QTextCodec>
-namespace GettextCatalog {
-class GettextStorage;
-
-class CatalogImportPluginPrivate
-{
-public:
- GettextStorage* _catalog;
- bool _updateHeader;
- bool _updateGeneratedFromDocbook;
- bool _updateCodec;
- bool _updateErrorList;
- bool _updateCatalogExtraData;
-
- bool _generatedFromDocbook;
- QLinkedList<CatalogItem> _entries;
- QLinkedList<CatalogItem> _obsoleteEntries;
- CatalogItem _header;
- QTextCodec* _codec;
- QList<int> _errorList;
- QStringList _catalogExtraData;
-
-};
-
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "gettextheader.h"
-
-#include "project.h"
-
-#include "version.h"
-#include "prefs_lokalize.h"
-
-#include <QProcess>
-#include <QString>
-#include <QMap>
-#include <QTextCodec>
-
-#include <kdebug.h>
-#include <kglobal.h>
-#include <klocale.h>
-#include <kdatetime.h>
-
-#include <kio/netaccess.h>
-#include <ktemporaryfile.h>
-
-/**
- * this data was obtained by running GNUPluralForms()
- * on all languages KDE knows of
-**/
-#define NUM_LANG_WITH_INFO 41
-static const char* langsWithPInfo[NUM_LANG_WITH_INFO]={
-"ar",
-"cs",
-"da",
-"de",
-"el",
-"en",
-"en_GB",
-"en_US",
-"eo",
-"es",
-"et",
-"fi",
-"fo",
-"fr",
-"ga",
-"he",
-"hr",
-"hu",
-"it",
-"ja",
-"ko",
-"lt",
-"lv",
-"nb",
-"nl",
-"nn",
-"pl",
-"pt",
-"pt_BR",
-"ro",
-"ru",
-"sk",
-"sl",
-"sr",
-"sr@latin",
-"sv",
-"th",
-"tr",
-"uk",
-"vi",
-"zh_CN"
-// '\0'
-};
-
-static const char* pInfo[NUM_LANG_WITH_INFO]={
-"nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;",
-"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n > 1);",
-"nplurals=3; plural=n==1 ? 0 : n==2 ? 1 : 2;",
-"nplurals=2; plural=(n != 1);",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=1; plural=0;",
-"nplurals=1; plural=0;",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=2; plural=(n > 1);",
-"nplurals=3; plural=n==1 ? 0 : (n==0 || (n%100 > 0 && n%100 < 20)) ? 1 : 2;",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;",
-"nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=2; plural=(n != 1);",
-"nplurals=1; plural=0;",
-"nplurals=2; plural=(n > 1);",
-"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
-"nplurals=1; plural=0;",
-"nplurals=1; plural=0;"
-};
-
-
-int numberOfPluralFormsFromHeader(const QString& header)
-{
- QRegExp rxplural("Plural-Forms:\\s*nplurals=(.);");
- if (rxplural.indexIn(header) == -1)
- return 0;
- bool ok;
- int result=rxplural.cap(1).toShort(&ok);
- return ok?result:0;
-
-}
-
-int numberOfPluralFormsForLangCode(const QString& langCode)
-{
- QString expr=GNUPluralForms(langCode);
-
- QRegExp rxplural("nplurals=(.);");
- if (rxplural.indexIn(expr) == -1)
- return 0;
- bool ok;
- int result=rxplural.cap(1).toShort(&ok);
- return ok?result:0;
-
-}
-
-QString GNUPluralForms(const QString& lang)
-{
- QByteArray l(lang.toUtf8());
- int i=NUM_LANG_WITH_INFO;
- while(--i>=0 && l!=langsWithPInfo[i])
- ;
- //if (Q_LIKELY( langsWithPInfo[i]))
- if (Q_LIKELY( i>=0 ))
- return QString::fromLatin1(pInfo[i]);
-
-
- //BEGIN alternative
- qWarning()<<"gonna call msginit";
- QString def="nplurals=2; plural=n != 1;";
-
- QStringList arguments;
- arguments << "-l" << lang
- << "-i" << "-"
- << "-o" << "-"
- << "--no-translator"
- << "--no-wrap";
- QProcess msginit;
- msginit.start("msginit", arguments);
-
- msginit.waitForStarted(5000);
- if (Q_UNLIKELY( msginit.state()!=QProcess::Running ))
- {
- //kWarning()<<"msginit error";
- return def;
- }
-
- msginit.write(
- "# SOME DESCRIPTIVE TITLE.\n"
- "# Copyright (C) YEAR Free Software Foundation, Inc.\n"
- "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.\n"
- "#\n"
- "#, fuzzy\n"
- "msgid \"\"\n"
- "msgstr \"\"\n"
- "\"Project-Id-Version: PACKAGE VERSION\\n\"\n"
- "\"POT-Creation-Date: 2002-06-25 03:23+0200\\n\"\n"
- "\"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n\"\n"
- "\"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n\"\n"
- "\"Language-Team: LANGUAGE <LL@li.org>\\n\"\n"
- "\"Language: LL\\n\"\n"
- "\"MIME-Version: 1.0\\n\"\n"
- "\"Content-Type: text/plain; charset=UTF-8\\n\"\n"
- "\"Content-Transfer-Encoding: ENCODING\\n\"\n"
-// "\"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n\"\n"
- );
- msginit.closeWriteChannel();
-
- if (Q_UNLIKELY( !msginit.waitForFinished(5000) ))
- {
- kWarning()<<"msginit error";
- return def;
- }
-
-
- QByteArray result = msginit.readAll();
- int pos = result.indexOf("Plural-Forms: ");
- if (Q_UNLIKELY( pos==-1 ))
- {
- //kWarning()<<"msginit error"<<result;
- return def;
- }
- pos+=14;
-
- int end = result.indexOf('"',pos);
- if (Q_UNLIKELY( pos==-1 ))
- {
- //kWarning()<<"msginit error"<<result;
- return def;
- }
-
- return QString( result.mid(pos,end-pos-2) );
- //END alternative
-}
-
-
-void updateHeader(QString& header,
- QString& comment,
- QString& langCode,
- int& numberOfPluralForms,
- const QString& CatalogProjectId,
- bool generatedFromDocbook,
- bool belongsToProject,
- bool forSaving,
- QTextCodec* codec)
-{
- QStringList headerList(header.split('\n',QString::SkipEmptyParts));
- QStringList commentList(comment.split('\n',QString::SkipEmptyParts));
-
-//BEGIN header itself
- QStringList::Iterator it,ait;
- QString temp;
- QString authorNameEmail;
-
- bool found=false;
- authorNameEmail=Settings::authorName();
- if (!Settings::authorEmail().isEmpty())
- authorNameEmail+=(" <" + Settings::authorEmail() + '>');
- temp="Last-Translator: " + authorNameEmail + "\\n";
-
- QRegExp lt("^ *Last-Translator:.*");
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- if (it->contains(lt))
- {
- if (forSaving) *it = temp;
- found=true;
- }
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
- QString dateTimeString = KDateTime::currentLocalDateTime().toString("%Y-%m-%d %H:%M%z");
- temp="PO-Revision-Date: " + dateTimeString + "\\n";
- QRegExp poRevDate("^ *PO-Revision-Date:.*");
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- found=it->contains(poRevDate);
- if (found && forSaving) *it = temp;
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
- temp="Project-Id-Version: " + CatalogProjectId + "\\n";
- //temp.replace( "@PACKAGE@", packageName());
- QRegExp projectIdVer("^ *Project-Id-Version:.*");
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- found=it->contains(projectIdVer);
- if (found && it->contains("PACKAGE VERSION"))
- *it = temp;
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
-
- langCode=Project::instance()->isLoaded()?
- Project::instance()->langCode():
- Settings::defaultLangCode();
- QString language; //initialized with preexisting value or later
- QString mailingList; //initialized with preexisting value or later
-
- QRegExp langTeamRegExp("^ *Language-Team:.*");
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- found=it->contains(langTeamRegExp);
- if (found)
- {
- //really parse header
- QMap<QString,QString> map;
- foreach (const QString &runningLangCode, KGlobal::locale()->allLanguagesList())
- {
- map[KGlobal::locale()->languageCodeToName(runningLangCode)]=runningLangCode;
- }
-
- QRegExp re("^ *Language-Team: *(.*) *<([^>]*)>");
- if (re.indexIn(*it) != -1 )
- {
- if (map.contains( re.cap(1).trimmed() ))
- {
- language=re.cap(1).trimmed();
- mailingList=re.cap(2).trimmed();
- langCode=map.value(language);
- }
- }
-
- ait=it;
- }
- }
-
- if (language.isEmpty())
- {
- //language=locale.languageCodeToName(d->_langCode);
- language=KGlobal::locale()->languageCodeToName(langCode);
- if (language.isEmpty())
- language=langCode;
- }
-
- if (mailingList.isEmpty() || belongsToProject)
- {
- if (Project::instance()->isLoaded())
- mailingList=Project::instance()->mailingList();
- else //if (mailingList.isEmpty())
- mailingList=Settings::defaultMailingList();
- }
-
-
-
- temp="Language-Team: " + language + " <" + mailingList + '>';
- temp+="\\n";
- if (Q_LIKELY( found ))
- (*ait) = temp;
- else
- headerList.append(temp);
-
- QRegExp langCodeRegExp("^ *Language: *([^ \\\\]*)");
- temp="Language: " + langCode + "\\n";
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- found=(langCodeRegExp.indexIn(*it)!=-1);
- if (found && langCodeRegExp.cap(1).isEmpty())
- *it=temp;
- //if (found) qWarning()<<"got explicit lang code:"<<langCodeRegExp.cap(1);
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
- temp="Content-Type: text/plain; charset=" + codec->name() + "\\n";
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- {
- found=it->contains(QRegExp("^ *Content-Type:.*"));
- if (found) *it=temp;
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
-
- found=false;
- temp="Content-Transfer-Encoding: 8bit\\n";
-
- for ( it = headerList.begin(),found=false; it != headerList.end() && !found; ++it )
- found=it->contains(QRegExp("^ *Content-Transfer-Encoding:.*"));
- if (!found)
- headerList.append(temp);
-
- // ensure MIME-Version header
- temp="MIME-Version: 1.0\\n";
- for ( it = headerList.begin(),found=false; it != headerList.end()&& !found; ++it )
- {
- found=it->contains(QRegExp("^ *MIME-Version:"));
- if (found) *it = temp;
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
-
- //kDebug()<<"testing for GNUPluralForms";
- // update plural form header
- for ( it = headerList.begin(),found=false; it != headerList.end()&& !found; ++it )
- found=it->contains(QRegExp("^ *Plural-Forms:"));
- if (found)
- {
- --it;
-
- //kDebug()<<"GNUPluralForms found";
- int num=numberOfPluralFormsFromHeader(header);
- if (!num)
- {
- if (generatedFromDocbook)
- num=1;
- else
- {
- kWarning()<<"No plural form info in header, using project-defined one"<<langCode;
- QString t=GNUPluralForms(langCode);
- //kWarning()<<"generated: " << t;
- if ( !t.isEmpty() )
- {
- QRegExp pf("^ *Plural-Forms:\\s*nplurals.*\\\\n");
- pf.setMinimal(true);
- temp=QString("Plural-Forms: %1\\n").arg(t);
- it->replace(pf,temp);
- num=numberOfPluralFormsFromHeader(temp);
- }
- else
- {
- kWarning()<<"no... smth went wrong :(\ncheck your gettext install";
- num=2;
- }
- }
- }
- numberOfPluralForms=num;
-
- }
- else if ( !generatedFromDocbook)
- {
- //kDebug()<<"generating GNUPluralForms"<<langCode;
- QString t= GNUPluralForms(langCode);
- //kDebug()<<"here it is:";
- if ( !t.isEmpty() ) {
- const QString pluralFormLine=QString("Plural-Forms: %1\\n").arg(t);
- headerList.append(pluralFormLine);
- numberOfPluralForms=numberOfPluralFormsFromHeader(pluralFormLine);
- }
- }
-
- temp="X-Generator: Lokalize %1\\n";
- temp=temp.arg(LOKALIZE_VERSION);
-
- for ( it = headerList.begin(),found=false; it != headerList.end()&& !found; ++it )
- {
- found=it->contains(QRegExp("^ *X-Generator:.*"));
- if (found) *it = temp;
- }
- if (Q_UNLIKELY( !found ))
- headerList.append(temp);
-
- //m_header.setMsgstr( headerList.join( "\n" ) );
- header=headerList.join("\n");
-//END header itself
-
-//BEGIN comment = description, copyrights
- // U+00A9 is the Copyright sign
- QRegExp fsfc("^# *Copyright (\\(C\\)|\\x00a9).*Free Software Foundation, Inc");
- for ( it = commentList.begin(),found=false; it != commentList.end()&&!found; ++it )
- {
- found=it->contains( fsfc ) ;
- if (found)
- it->replace("YEAR", QDate::currentDate().toString("yyyy"));
- }
-/*
- if( saveOptions.FSFCopyright == ProjectSettingsBase::Update )
- {
- //update years
- QString cy = QDate::currentDate().toString("yyyy");
- if( !it->contains( QRegExp(cy)) ) // is the year already included?
- {
- int index = it->lastIndexOf( QRegExp("[\\d]+[\\d\\-, ]*") );
- if( index == -1 )
- {
- KMessageBox::information(0,i18n("Free Software Foundation Copyright does not contain any year. "
- "It will not be updated."));
- } else {
- it->insert(index+1, QString(", ")+cy);
- }
- }
- }*/
-#if 0
- if ( ( !usePrefs || saveOptions.updateDescription )
- && ( !saveOptions.descriptionString.isEmpty() ) )
- {
- temp = "# "+saveOptions.descriptionString;
- temp.replace( "@PACKAGE@", packageName());
- temp.replace( "@LANGUAGE@", identityOptions.languageName);
- temp = temp.trimmed();
-
- // The description strings has often buggy variants already in the file, these must be removed
- QString regexpstr = "^#\\s+" + QRegExp::escape( saveOptions.descriptionString.trimmed() ) + "\\s*$";
- regexpstr.replace( "@PACKAGE@", ".*" );
- regexpstr.replace( "@LANGUAGE@", ".*" );
- //kDebug() << "REGEXPSTR: " << regexpstr;
- QRegExp regexp ( regexpstr );
-
- // The buggy variants exist in English too (of a time before KBabel got a translation for the corresponding language)
- QRegExp regexpUntranslated ( "^#\\s+translation of .* to .*\\s*$" );
-
-
- kDebug () << "Temp is '" << temp << "'";
-
- found=false;
- bool foundTemplate=false;
-
- it = commentList.begin();
- while ( it != commentList.end() )
- {
- kDebug () << "testing '" << (*it) << "'";
- bool deleteItem = false;
-
- if ( (*it) == temp )
- {
- kDebug () << "Match ";
- if ( found )
- deleteItem = true;
- else
- found=true;
- }
- else if ( regexp.indexIn( *it ) >= 0 )
- {
- // We have a similar (translated) string (from another project or another language (perhaps typos)). Remove it.
- deleteItem = true;
- }
- else if ( regexpUntranslated.indexIn( *it ) >= 0 )
- {
- // We have a similar (untranslated) string (from another project or another language (perhaps typos)). Remove it.
- deleteItem = true;
- }
- else if ( (*it) == "# SOME DESCRIPTIVE TITLE." )
- {
- // We have the standard title placeholder, remove it
- deleteItem = true;
- }
-
- if ( deleteItem )
- it = commentList.erase( it );
- else
- ++it;
- }
- if (!found) commentList.prepend(temp);
- }
-#endif
- // kDebug() << "HEADER COMMENT: " << commentList;
-
- /* if ( (!usePrefs || saveOptions.updateTranslatorCopyright)
- && ( ! identityOptions->readEntry("authorName","").isEmpty() )
- && ( ! identityOptions->readEntry("Email","").isEmpty() ) ) // An email address can be used as ersatz of a name
- {*/
-// return;
- QStringList foundAuthors;
-
- temp="# " + authorNameEmail + ", " + QDate::currentDate().toString("yyyy") + '.';
-
- // ### TODO: it would be nice if the entry could start with "COPYRIGHT" and have the "(C)" symbol (both not mandatory)
- QRegExp regexpAuthorYear( "^#.*(<.+@.+>)?,\\s*([\\d]+[\\d\\-, ]*|YEAR)" );
- QRegExp regexpYearAlone( "^# , \\d{4}.?\\s*$" );
- if (commentList.isEmpty())
- {
- commentList.append(temp);
- commentList.append(QString());
- }
- else
- {
- it = commentList.begin();
- while ( it != commentList.end() )
- {
- bool deleteItem = false;
- if ( it->indexOf( "copyright", 0, Qt::CaseInsensitive ) != -1 )
- {
- // We have a line with a copyright. It should not be moved.
- }
- else if ( it->contains( QRegExp("#, *fuzzy") ) )
- deleteItem = true;
- else if ( it->contains( regexpYearAlone ) )
- {
- // We have found a year number that is preceded by a comma.
- // That is typical of KBabel 1.10 (and earlier?) when there is neither an author name nor an email
- // Remove the entry
- deleteItem = true;
- }
- else if ( it->contains( "# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.") )
- deleteItem = true;
- else if ( it->contains( "# SOME DESCRIPTIVE TITLE"))
- deleteItem = true;
- else if ( it->contains( regexpAuthorYear ) ) // email address followed by year
- {
- if ( !foundAuthors.contains( (*it) ) )
- {
- // The author line is new (and not a duplicate), so add it to the author line list
- foundAuthors.append( (*it) );
- }
- // Delete also non-duplicated entry, as now all what is needed will be processed in foundAuthors
- deleteItem = true;
- }
-
- if ( deleteItem )
- it = commentList.erase( it );
- else
- ++it;
- }
-
- if ( !foundAuthors.isEmpty() )
- {
- found = false;
- bool foundAuthor = false;
-
- const QString cy = QDate::currentDate().toString("yyyy");
-
- ait = foundAuthors.end();
- for ( it = foundAuthors.begin() ; it!=foundAuthors.end(); ++it )
- {
- if ( it->contains(Settings::authorName()) || it->contains(Settings::authorEmail()) )
- {
- foundAuthor = true;
- if ( it->contains( cy ) )
- found = true;
- else
- ait = it;
- }
- }
- if ( !found )
- {
- if ( !foundAuthor )
- foundAuthors.append(temp);
- else if ( ait != foundAuthors.end() )
- {
- //update years
- const int index = (*ait).lastIndexOf( QRegExp("[\\d]+[\\d\\-, ]*") );
- if ( index == -1 )
- (*ait)+=", " + cy;
- else
- ait->insert(index+1, ", " + cy);
- }
- else
- kDebug() << "INTERNAL ERROR: author found but iterator dangling!";
- }
-
- }
- else
- foundAuthors.append(temp);
-
-
- foreach (QString author, foundAuthors)
- {
- // ensure dot at the end of copyright
- if ( !author.endsWith('.') ) author += '.';
- commentList.append(author);
- }
- }
-
- //m_header.setComment( commentList.join( "\n" ) );
- comment=commentList.join("\n");
-
-//END comment = description, copyrights
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef GETTEXTHEADER_H
-#define GETTEXTHEADER_H
-
-#include <QString>
-#include <QTextCodec>
-
-int numberOfPluralFormsFromHeader(const QString& header);
-QString GNUPluralForms(const QString& lang);
-
-void updateHeader(QString& header,
- QString& comment,
- QString& langCode,
- int& numberOfPluralForms,
- const QString& CatalogProjectId,
- bool generatedFromDocbook,
- bool belongsToProject,
- bool forSaving,
- QTextCodec* codec);
-
-
-//for XLIFF
-int numberOfPluralFormsForLangCode(const QString& langCode);
-
-#endif
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef NOTE_H
-#define NOTE_H
-
-#include <QString>
-
-struct Note
-{
- enum Owner{General,Source,Target};
-
- QString content;
- char priority;//1 is the highest
- Owner annotates;
- QString from;
- QString lang;
-
- Note(const QString& content_=QString())
- : content(content_)
- , priority(5)
- , annotates(General)
- {}
-
- Note(const QString& content_,char priority_,Owner annotates_,const QString& from_,const QString& lang_)
- : content(content_)
- , priority(priority_)
- , annotates(annotates_)
- , from(from_)
- , lang(lang_)
- {}
-
- bool operator<(const Note& other) const
- {
- return priority<other.priority;
- }
-
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "phase.h"
-#include "cmd.h"
-#include "catalog.h"
-#include "project.h"
-#include "prefs_lokalize.h"
-
-#include <QSet>
-
-const char* const* processes()
-{
- static const char* const processes[]={"translation","review","approval"};
- return processes;
-}
-
-//guess role
-ProjectLocal::PersonRole roleForProcess(const QString& process)
-{
- int i=ProjectLocal::Undefined;
- while (i>=0 && !process.startsWith(processes()[--i]))
- ;
- return (i==-1)?Project::local()->role():ProjectLocal::PersonRole(i);
-}
-
-void generatePhaseForCatalogIfNeeded(Catalog* catalog)
-{
- if (Q_LIKELY( !(catalog->capabilities()&Phases) || catalog->activePhaseRole()==ProjectLocal::Undefined ))
- return;
-
- Phase phase;
- phase.process=processes()[Project::local()->role()];
-
- if (initPhaseForCatalog(catalog, phase))
- static_cast<QUndoStack*>(catalog)->push(new UpdatePhaseCmd(catalog, phase));
-
- catalog->setActivePhase(phase.name, roleForProcess(phase.process));
-}
-
-
-bool initPhaseForCatalog(Catalog* catalog, Phase& phase, int options)
-{
- phase.contact=Settings::authorName();
-
- QSet<QString> names;
- QList<Phase> phases=catalog->allPhases();
- qSort(phases.begin(), phases.end(), qGreater<Phase>());
- foreach (const Phase& p, phases)
- {
- if (!(options&ForceAdd) && p.contact==phase.contact && p.process==phase.process)
- {
- phase=p;
- break;
- }
- names.insert(p.name);
- }
-
- if (phase.name.isEmpty())
- {
- int i=0;
- while (names.contains(phase.name=phase.process+QString("-%1").arg(++i)))
- ;
- phase.date=QDate::currentDate();
- phase.email=Settings::authorEmail();
- return true;
- }
- return false;
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PHASE_H
-#define PHASE_H
-
-#include "version.h"
-#include "projectlocal.h"
-
-#include <QString>
-#include <QtCore/qdatetime.h>
-
-class Catalog;
-struct Phase
-{
- QString name;
- QString process;
- QString company;
- QDate date;
- QString contact;
- QString email;
- QString phone;
- QString tool;
-
- Phase()
- : date(QDate::currentDate())
- , tool("lokalize-" LOKALIZE_VERSION)
- {}
-
- Phase(const Phase& rhs)
- : name(rhs.name)
- , process(rhs.process)
- , company(rhs.company)
- , date(rhs.date)
- , contact(rhs.contact)
- , email(rhs.email)
- , phone(rhs.phone)
- , tool(rhs.tool)
- {}
-
- bool operator<(const Phase& other) const
- {
- return date<other.date;
- }
-};
-
-
-struct Tool
-{
- QString tool;
- QString name;
- QString version;
- QString company;
-};
-
-const char* const* processes();
-ProjectLocal::PersonRole roleForProcess(const QString& phase);
-enum InitOptions {ForceAdd=1};
-///@returns true if phase must be added to catalog;
-bool initPhaseForCatalog(Catalog* catalog, Phase& phase, int options=0);
-void generatePhaseForCatalogIfNeeded(Catalog* catalog);
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "pos.h"
-#include "catalog.h"
-
-#include <QDBusArgument>
-
-bool switchPrev(Catalog*& catalog,DocPosition& pos,int parts)
-{
- bool switchEntry=false;
- bool switchCommentIndex=false;
- if (pos.part==DocPosition::Comment)
- switchCommentIndex=true;
- else if (pos.part==DocPosition::Target)
- {
- if (parts&DocPosition::Source)
- pos.part=DocPosition::Source;
- switchEntry=!(parts&DocPosition::Source);
- }
- else if (pos.part==DocPosition::Source)
- switchEntry=true;
-
- bool skipCommentThisTime=false;
- if (switchCommentIndex)
- {
- if (pos.form)
- pos.form--;
- switchEntry=pos.form; //pos.form is zero again
- skipCommentThisTime=pos.form;
- }
-
- if (!switchEntry)
- return true;
-
- if (Q_UNLIKELY( pos.form>0
- && catalog->isPlural(pos.entry)))
- pos.form--;
- else if (Q_UNLIKELY( pos.entry==0 ))
- return false;
- else
- {
- pos.entry--;
- pos.form=catalog->isPlural(pos.entry)*(catalog->numberOfPluralForms()-1);
- }
- pos.offset=0;
-
- if (parts&DocPosition::Comment && !skipCommentThisTime && pos.form==0 && catalog->notes(pos).size())
- {
- pos.part=DocPosition::Comment;
- pos.form=catalog->notes(pos).size()-1;
- }
- else
- pos.part=DocPosition::Target;
-
- return true;
-}
-
-bool switchNext(Catalog*& catalog,DocPosition& pos,int parts)
-{
- bool switchEntry=false;
- bool switchCommentIndex=false;
- if (pos.part==DocPosition::Source)
- pos.part=DocPosition::Target;
- else if (pos.part==DocPosition::Target)
- {
- if (parts&DocPosition::Comment && pos.form==0 && catalog->notes(pos).size())
- pos.part=DocPosition::Comment;
- else
- switchEntry=true;
- }
- else if (pos.part==DocPosition::Comment)
- switchCommentIndex=true;
-
- if (switchCommentIndex)
- {
- pos.form++;
- if (catalog->notes(pos).size()==pos.form)
- {
- pos.form=0;
- switchEntry=true;
- }
- }
-
- if (!switchEntry)
- return true;
-
-
- if (Q_UNLIKELY( pos.entry!=-1
- && pos.form+1 < catalog->numberOfPluralForms()
- && catalog->isPlural(pos.entry)))
- pos.form++;
- else if (Q_UNLIKELY( pos.entry==catalog->numberOfEntries()-1 ))
- return false;
- else
- {
- pos.entry++;
- pos.form=0;
- }
- pos.offset=0;
-
- pos.part=(parts&DocPosition::Source)?DocPosition::Source:DocPosition::Target;
-
- return true;
-}
-
-const QDBusArgument &operator>>(const QDBusArgument &argument, DocPosition& pos)
-{
- int entry;
- int form;
- uint offset;
-
- argument.beginStructure();
- argument >> entry >> form >> offset;
- argument.endStructure();
-
- pos.entry=entry;
- pos.form=form;
- pos.offset=offset;
-
- return argument;
-}
-
-QDBusArgument &operator<<(QDBusArgument &argument, const DocPosition &pos)
-{
- int entry=pos.entry;
- int form=pos.form;
- uint offset=pos.offset;
-
- argument.beginStructure();
- argument << entry << form << offset;
- argument.endStructure();
-
- return argument;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef POS_H
-#define POS_H
-
-#include <QMetaType>
-#include <QHash>
-
-class Catalog;
-
-/**
- * This struct represents a position in a catalog.
- * A position is a tuple (index,pluralform,textoffset).
- *
- * @short Structure that represents a position in a catalog
- */
-struct DocPosition
-{
- enum Part
- {
- UndefPart=0,
- Source=1,
- Target=2,
- Comment=4
- };
-
- int entry:32;
- Part part:8;
- char form:8;
- uint offset:16;
-
- DocPosition(): entry(-1),part(Target),form(0),offset(0){}
-
- DocPosition(int entry_, Part part_, char form_=0, uint offset_=0)
- : entry(entry_)
- , part(part_)
- , form(form_)
- , offset(offset_)
- {}
-
- DocPosition(int entry_, char form_=0, uint offset_=0)
- : entry(entry_)
- , part(Target)
- , form(form_)
- , offset(offset_)
- {}
-
- bool operator==(const DocPosition& pos) const
- {return entry==pos.entry && form==pos.form;};
-
-};
-Q_DECLARE_METATYPE(DocPosition)
-
-bool switchPrev(Catalog*&,DocPosition& pos,int parts=DocPosition::Target);
-bool switchNext(Catalog*&,DocPosition& pos,int parts=DocPosition::Target);
-
-
-/**
- * simpler version of DocPosition for use in QMap
- */
-struct DocPos
-{
- int entry:24;
- uchar form:8;
-
- DocPos():entry(-1), form(0){}
-
- DocPos(int _entry, uchar _form):
- entry(_entry),
- form(_form)
- {}
- DocPos(const DocPosition& pos):
- entry(pos.entry),
- form(pos.form)
- {}
-
- bool operator<(const DocPos& pos) const
- {return entry==pos.entry?form<pos.form:entry<pos.entry;};
-
- bool operator==(const DocPos& pos) const
- {return entry==pos.entry && form==pos.form;};
-
- bool operator!=(const DocPos& pos) const
- {return entry!=pos.entry || form!=pos.form;};
-
- DocPosition toDocPosition()
- {
- return DocPosition(entry, DocPosition::Target, form);
- }
-
-};
-Q_DECLARE_METATYPE(DocPos)
-
-
-inline uint qHash(const DocPos &key)
-{
- return qHash((key.entry<<8)|key.form);
-}
-
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef STATE_H
-#define STATE_H
-
-#include "projectlocal.h"
-
-///@see @link http://docs.oasis-open.org/xliff/v1.2/os/xliff-core.html#state
-enum TargetState
-{
- New,
- NeedsTranslation,
- NeedsL10n,
- NeedsAdaptation,
- Translated,
- NeedsReviewTranslation,
- NeedsReviewL10n,
- NeedsReviewAdaptation,
- Final,
- SignedOff,
- StateCount
-};
-
-
-#endif
+++ /dev/null
-/*
-Copyright 2008-2012 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "tsstorage.h"
-
-#include "gettextheader.h"
-#include "project.h"
-#include "version.h"
-#include "prefs_lokalize.h"
-
-#include <QProcess>
-#include <QString>
-#include <QMap>
-#include <QtXml/qdom.h>
-#include <QtCore/qdatetime.h>
-#include <QPair>
-#include <QList>
-
-
-#include <kdebug.h>
-#include <kglobal.h>
-#include <klocale.h>
-#include <kdatetime.h>
-#include <QtXml/qxml.h>
-
-static const char* const noyes[]={"no","yes"};
-
-static const QString names[]={"source" ,"translation","oldsource" ,"translatorcomment","comment" ,"name" ,"numerus"};
-enum TagNames {SourceTag,TargetTag ,OldSourceTag,NoteTag ,DevNoteTag,NameTag,PluralTag};
-
-static const QString attrnames[]={"location" ,"type" ,"obsolete"};
-enum AttrNames {LocationAttr,TypeAttr,ObsoleteAttr};
-
-static const QString attrvalues[]={"obsolete"};
-enum AttValues {ObsoleteVal};
-
-TsStorage::TsStorage()
- : CatalogStorage()
-{
-}
-
-TsStorage::~TsStorage()
-{
-}
-
-int TsStorage::capabilities() const
-{
- return 0;//MultipleNotes;
-}
-
-//BEGIN OPEN/SAVE
-
-int TsStorage::load(QIODevice* device)
-{
- QTime chrono;chrono.start();
-
-
- QXmlSimpleReader reader;
- reader.setFeature("http://qtsoftware.com/xml/features/report-whitespace-only-CharData",true);
- reader.setFeature("http://xml.org/sax/features/namespaces",false);
- QXmlInputSource source(device);
-
- QString errorMsg;
- int errorLine;//+errorColumn;
- bool success=m_doc.setContent(&source, &reader, &errorMsg, &errorLine/*,errorColumn*/);
-
- if (!success)
- {
- kWarning()<<errorMsg;
- return errorLine+1;
- }
-
-
- QDomElement file=m_doc.elementsByTagName("TS").at(0).toElement();
- m_sourceLangCode=file.attribute("sourcelanguage");
- m_targetLangCode=file.attribute("language");
- m_numberOfPluralForms=numberOfPluralFormsForLangCode(m_targetLangCode);
-
- //Create entry mapping.
- //Along the way: for langs with more than 2 forms
- //we create any form-entries additionally needed
-
- entries=m_doc.elementsByTagName("message");
- int size=entries.size();
-
- kWarning()<<chrono.elapsed();
- return 0;
-}
-
-bool TsStorage::save(QIODevice* device, bool belongsToProject)
-{
- QTextStream stream(device);
- m_doc.save(stream,4);
- return true;
-}
-//END OPEN/SAVE
-
-//BEGIN STORAGE TRANSLATION
-
-int TsStorage::size() const
-{
- //return m_map.size();
-
- return entries.size();
-}
-
-
-
-
-/**
- * helper structure used during XLIFF XML walk-through
- */
-struct ContentEditingData
-{
- enum ActionType{Get,DeleteText,InsertText,CheckLength};
-
- QString stringToInsert;
- int pos;
- int lengthOfStringToRemove;
- ActionType actionType;
-
- ///Get
- ContentEditingData(ActionType type=Get)
- : pos(-1)
- , lengthOfStringToRemove(-1)
- , actionType(type)
- {}
-
- ///DeleteText
- ContentEditingData(int p, int l)
- : pos(p)
- , lengthOfStringToRemove(l)
- , actionType(DeleteText)
- {}
-
- ///InsertText
- ContentEditingData(int p,const QString& s)
- : stringToInsert(s)
- , pos(p)
- , lengthOfStringToRemove(-1)
- , actionType(InsertText)
- {}
-};
-
-static QString doContent(QDomElement elem, int startingPos, ContentEditingData* data);
-
-/**
- * walks through XLIFF XML and performs actions depending on ContentEditingData:
- * - reads content
- * - deletes content, or
- * - inserts content
- */
-static QString content(QDomElement elem, ContentEditingData* data=0)
-{
- return doContent(elem, 0, data);
-}
-
-static QString doContent(QDomElement elem, int startingPos, ContentEditingData* data)
-{
- //actually startingPos is current pos
-
- QString result;
-
- if (elem.isNull()
- || (!result.isEmpty() && ContentEditingData::CheckLength))
- return QString();
-
- bool seenCharacterDataAfterElement=false;
-
- QDomNode n = elem.firstChild();
- while (!n.isNull())
- {
- if (n.isCharacterData())
- {
- seenCharacterDataAfterElement=true;
-
- QDomCharacterData c=n.toCharacterData();
- QString cData=c.data();
-
- if (data && data->pos!=-1 &&
- data->pos>=startingPos && data->pos<=startingPos+cData.size())
- {
- // time to do some action! ;)
- int localStartPos=data->pos-startingPos;
-
- //BEGIN DELETE TEXT
- if (data->actionType==ContentEditingData::DeleteText) //(data->lengthOfStringToRemove!=-1)
- {
- if (localStartPos+data->lengthOfStringToRemove>cData.size())
- {
- //text is fragmented into several QDomCharacterData
- int localDelLen=cData.size()-localStartPos;
- //qWarning()<<"text is fragmented into several QDomCharacterData. localDelLen:"<<localDelLen<<"cData:"<<cData;
- c.deleteData(localStartPos,localDelLen);
- //setup data for future iterations
- data->lengthOfStringToRemove=data->lengthOfStringToRemove-localDelLen;
- //data->pos=startingPos;
- //qWarning()<<"\tsetup:"<<data->pos<<data->lengthOfStringToRemove;
- }
- else
- {
- //qWarning()<<"simple delete"<<localStartPos<<data->lengthOfStringToRemove;
- c.deleteData(localStartPos,data->lengthOfStringToRemove);
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//so it exits 100%
- }
- }
- //END DELETE TEXT
- //INSERT
- else if (data->actionType==ContentEditingData::InsertText)
- {
- c.insertData(localStartPos,data->stringToInsert);
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//so it exits 100%
- }
- cData=c.data();
- }
- //else
- // if (data&&data->pos!=-1/*&& n.nextSibling().isNull()*/)
- // kWarning()<<"arg!"<<startingPos<<"data->pos"<<data->pos;
-
- result += cData;
- startingPos+=cData.size();
- }
- n = n.nextSibling();
- }
- if (!seenCharacterDataAfterElement)
- {
- //add empty charData child so that user could add some text
- elem.appendChild( elem.ownerDocument().createTextNode(QString()) );
- }
-
- return result;
-}
-
-
-
-//flat-model interface (ignores XLIFF grouping)
-
-CatalogString TsStorage::catalogString(QDomElement contentElement) const
-{
- CatalogString catalogString;
- ContentEditingData data(ContentEditingData::Get);
- catalogString.string=content(contentElement, &data);
- return catalogString;
-}
-
-CatalogString TsStorage::catalogString(const DocPosition& pos) const
-{
- return catalogString(pos.part==DocPosition::Target?targetForPos(pos):sourceForPos(pos.entry));
-}
-
-CatalogString TsStorage::targetWithTags(DocPosition pos) const
-{
- return catalogString(targetForPos(pos));
-}
-CatalogString TsStorage::sourceWithTags(DocPosition pos) const
-{
- return catalogString(sourceForPos(pos.entry));
-}
-
-QString TsStorage::source(const DocPosition& pos) const
-{
- return content(sourceForPos(pos.entry));
-}
-QString TsStorage::target(const DocPosition& pos) const
-{
- return content(targetForPos(pos));
-}
-
-
-void TsStorage::targetDelete(const DocPosition& pos, int count)
-{
- ContentEditingData data(pos.offset,count);
- content(targetForPos(pos),&data);
-}
-
-void TsStorage::targetInsert(const DocPosition& pos, const QString& arg)
-{
- kWarning()<<pos.entry<<arg;
- QDomElement targetEl=targetForPos(pos);
- //BEGIN add <*target>
- if (targetEl.isNull())
- {
- QDomNode unitEl=unitForPos(pos.entry);
- QDomNode refNode=unitEl.firstChildElement(names[SourceTag]);
- targetEl = unitEl.insertAfter(m_doc.createElement(names[TargetTag]),refNode).toElement();
-
- if (pos.entry<size())
- {
- targetEl.appendChild(m_doc.createTextNode(arg));//i bet that pos.offset is 0 ;)
- return;
- }
- }
- //END add <*target>
- if (arg.isEmpty()) return; //means we were called just to add <taget> tag
-
- ContentEditingData data(pos.offset,arg);
- content(targetEl,&data);
-}
-
-void TsStorage::setTarget(const DocPosition& pos, const QString& arg)
-{
- Q_UNUSED(pos);
- Q_UNUSED(arg);
-//TODO
-}
-
-
-QVector<AltTrans> TsStorage::altTrans(const DocPosition& pos) const
-{
- QVector<AltTrans> result;
-
- QString oldsource=content(unitForPos(pos.entry).firstChildElement(names[OldSourceTag]));
- if (!oldsource.isEmpty())
- result<<AltTrans(CatalogString(oldsource), i18n("Previous source value, saved by lupdate tool"));
-
- return result;
-}
-
-
-QStringList TsStorage::sourceFiles(const DocPosition& pos) const
-{
- QStringList result;
-
- QDomElement elem = unitForPos(pos.entry).firstChildElement(attrnames[LocationAttr]);
- while (!elem.isNull())
- {
- QString sourcefile=elem.attribute("filename");
- QString linenumber=elem.attribute("line");
- if (!( sourcefile.isEmpty()&&linenumber.isEmpty() ))
- result.append(sourcefile+':'+linenumber);
-
- elem=elem.nextSiblingElement(attrnames[LocationAttr]);
- }
- //qSort(result);
-
- return result;
-}
-
-QVector<Note> TsStorage::notes(const DocPosition& pos) const
-{
- QVector<Note> result;
-
- QDomElement elem = unitForPos(pos.entry).firstChildElement(names[NoteTag]);
- while (!elem.isNull())
- {
- Note note;
- note.content=elem.text();
- result.append(note);
-
- elem=elem.nextSiblingElement(names[NoteTag]);
- }
- return result;
-}
-
-QVector<Note> TsStorage::developerNotes(const DocPosition& pos) const
-{
- QVector<Note> result;
-
- QDomElement elem = unitForPos(pos.entry).firstChildElement(names[DevNoteTag]);
- while (!elem.isNull())
- {
- Note note;
- note.content=elem.text();
- result.append(note);
-
- elem=elem.nextSiblingElement(names[DevNoteTag]);
- }
- return result;
-}
-
-Note TsStorage::setNote(DocPosition pos, const Note& note)
-{
- //kWarning()<<int(pos.form)<<note.content;
- QDomElement unit=unitForPos(pos.entry);
- QDomElement elem;
- Note oldNote;
- if (pos.form==-1 && !note.content.isEmpty())
- {
- QDomElement ref=unit.lastChildElement(names[NoteTag]);
- elem=unit.insertAfter( m_doc.createElement(names[NoteTag]),ref).toElement();
- elem.appendChild(m_doc.createTextNode(QString()));
- }
- else
- {
- QDomNodeList list=unit.elementsByTagName(names[NoteTag]);
- if (pos.form==-1) pos.form=list.size()-1;
- if (pos.form<list.size())
- {
- elem = unit.elementsByTagName(names[NoteTag]).at(pos.form).toElement();
- oldNote.content=elem.text();
- }
- }
-
- if (elem.isNull()) return oldNote;
-
- if (!elem.text().isEmpty())
- {
- ContentEditingData data(0,elem.text().size());
- content(elem,&data);
- }
-
- if (!note.content.isEmpty())
- {
- ContentEditingData data(0,note.content);
- content(elem,&data);
- }
- else
- unit.removeChild(elem);
-
- return oldNote;
-}
-
-QStringList TsStorage::context(const DocPosition& pos) const
-{
- QStringList result;
-
- QDomElement unit=unitForPos(pos.entry);
- QDomElement context=unit.parentNode().toElement();
- //if (context.isNull())
- // return result;
-
- QDomElement name=context.firstChildElement(names[NameTag]);
- if (name.isNull())
- return result;
-
- result.append(name.text());
- return result;
-}
-
-QStringList TsStorage::matchData(const DocPosition& pos) const
-{
- Q_UNUSED(pos);
- return QStringList();
-}
-
-QString TsStorage::id(const DocPosition& pos) const
-{
- QString result=source(pos);
- result.remove('\n');
- QStringList ctxt=context(pos);
- if (ctxt.size())
- result.prepend(ctxt.first());
- return result;
-}
-
-bool TsStorage::isPlural(const DocPosition& pos) const
-{
- QDomElement unit=unitForPos(pos.entry);
-
- return unit.hasAttribute(names[PluralTag]);
-}
-
-void TsStorage::setApproved(const DocPosition& pos, bool approved)
-{
- targetInsert(pos,QString()); //adds <taget> if needed
- QDomElement target=unitForPos(pos.entry).firstChildElement(names[TargetTag]); //asking directly to bypass plural state detection
- if (target.attribute(attrnames[TypeAttr])==attrvalues[ObsoleteVal])
- return;
- if (approved)
- target.removeAttribute(attrnames[TypeAttr]);
- else
- target.setAttribute(attrnames[TypeAttr],"unfinished");
-}
-
-bool TsStorage::isApproved(const DocPosition& pos) const
-{
- QDomElement target=unitForPos(pos.entry).firstChildElement(names[TargetTag]);
- return !target.hasAttribute(attrnames[TypeAttr]);
-}
-
-bool TsStorage::isObsolete(int entry) const
-{
- QDomElement target=unitForPos(entry).firstChildElement(names[TargetTag]);
- return target.attribute(attrnames[TypeAttr])==attrvalues[ObsoleteVal];
-}
-
-bool TsStorage::isEmpty(const DocPosition& pos) const
-{
- ContentEditingData data(ContentEditingData::CheckLength);
- return content(targetForPos(pos),&data).isEmpty();
-}
-
-bool TsStorage::isEquivTrans(const DocPosition& pos) const
-{
- return true;//targetForPos(pos.entry).attribute("equiv-trans")!="no";
-}
-
-void TsStorage::setEquivTrans(const DocPosition& pos, bool equivTrans)
-{
- //targetForPos(pos.entry).setAttribute("equiv-trans",noyes[equivTrans]);
-}
-
-QDomElement TsStorage::unitForPos(int pos) const
-{
- return entries.at(pos).toElement();
-}
-
-QDomElement TsStorage::targetForPos(DocPosition pos) const
-{
- QDomElement unit=unitForPos(pos.entry);
- QDomElement translation=unit.firstChildElement(names[TargetTag]);
- if (!unit.hasAttribute(names[PluralTag]))
- return translation;
-
- if (pos.form==-1) pos.form=0;
-
- QDomNodeList forms=translation.elementsByTagName("numerusform");
- while (pos.form>=forms.size())
- translation.appendChild( unit.ownerDocument().createElement("numerusform") );
- return forms.at(pos.form).toElement();
-}
-
-QDomElement TsStorage::sourceForPos(int pos) const
-{
- return unitForPos(pos).firstChildElement(names[SourceTag]);
-}
-
-//END STORAGE TRANSLATION
-
-
+++ /dev/null
-/*
-Copyright 2008-2012 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef TSSTORAGE_H
-#define TSSTORAGE_H
-
-#include "catalogstorage.h"
-#include <QtXml/qdom.h>
-
-#include <QVector>
-#include <QMap>
-// #include <QDomDocument>
-
-class TsStorage: public CatalogStorage
-{
-public:
- TsStorage();
- ~TsStorage();
-
- int capabilities() const;
-
- int load(QIODevice* device);
- bool save(QIODevice* device, bool belongsToProject=false);
-
- int size() const;
- bool isEmpty() const;
-
- //flat-model interface (ignores TS grouping)
- QString source(const DocPosition& pos) const;
- QString target(const DocPosition& pos) const;
- CatalogString targetWithTags(DocPosition pos) const;
- CatalogString sourceWithTags(DocPosition pos) const;
- CatalogString catalogString(const DocPosition& pos) const;
-
- /// all plural forms. pos.form doesn't matter TODO
- QStringList sourceAllForms(const DocPosition& pos, bool stripNewLines=false) const{Q_UNUSED(pos); return QStringList();}
- QStringList targetAllForms(const DocPosition& pos, bool stripNewLines=false) const{Q_UNUSED(pos); return QStringList();}
-
- void targetDelete(const DocPosition& pos, int count);
- void targetInsert(const DocPosition& pos, const QString& arg);
- void setTarget(const DocPosition& pos, const QString& arg);//called for mergeCatalog
-
- QStringList sourceFiles(const DocPosition& pos) const;
- QVector<AltTrans> altTrans(const DocPosition& pos) const;
-
- ///@a pos.form is note number
- Note setNote(DocPosition pos, const Note& note);
- QVector<Note> notes(const DocPosition& pos) const;
- QVector<Note> developerNotes(const DocPosition& pos) const;
-
- QStringList context(const DocPosition& pos) const;
-
- QStringList matchData(const DocPosition& pos) const;
- QString id(const DocPosition& pos) const;
-
- bool isPlural(const DocPosition& pos) const;
- bool isEmpty(const DocPosition& pos) const;
-
- bool isEquivTrans(const DocPosition& pos) const;
- void setEquivTrans(const DocPosition& pos, bool equivTrans);
-
- bool isApproved(const DocPosition& pos) const;
- void setApproved(const DocPosition& pos, bool approved);
-
- bool isObsolete(int entry) const;
-
- QString mimetype()const{return "application/x-linguist";}
-
-private:
- QDomElement unitForPos(int pos) const;
- QDomElement targetForPos(DocPosition pos) const;
- QDomElement sourceForPos(int pos) const;
- CatalogString catalogString(QDomElement contentElement) const;
-
-private:
- mutable QDomDocument m_doc;
-
- QDomNodeList entries;
-
-};
-
-#endif
+++ /dev/null
-/*
-Copyright 2008-2009 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "xliffstorage.h"
-
-#include "gettextheader.h"
-#include "project.h"
-#include "version.h"
-#include "prefs_lokalize.h"
-
-#include <QProcess>
-#include <QString>
-#include <QMap>
-#include <QtXml/qdom.h>
-#include <QtCore/qdatetime.h>
-#include <QPair>
-#include <QList>
-
-
-#include <kdebug.h>
-#include <kglobal.h>
-#include <klocale.h>
-#include <kdatetime.h>
-#include <QtXml/qxml.h>
-
-static const QString noyes[]={"no","yes"};
-static const QString bintargettarget[]={"bin-target","target"};
-static const QString binsourcesource[]={"bin-source","source"};
-
-XliffStorage::XliffStorage()
- : CatalogStorage()
-{
-}
-
-XliffStorage::~XliffStorage()
-{
-}
-
-int XliffStorage::capabilities() const
-{
- return KeepsNoteAuthors|MultipleNotes|Phases|ExtendedStates|Tags;
-}
-
-//BEGIN OPEN/SAVE
-
-int XliffStorage::load(QIODevice* device)
-{
- QTime chrono;chrono.start();
-
-
- QXmlSimpleReader reader;
- reader.setFeature("http://qtsoftware.com/xml/features/report-whitespace-only-CharData",true);
- reader.setFeature("http://xml.org/sax/features/namespaces",false);
- QXmlInputSource source(device);
-
- QString errorMsg;
- int errorLine;//+errorColumn;
- bool success=m_doc.setContent(&source, &reader, &errorMsg, &errorLine/*,errorColumn*/);
-
- if (!success)
- {
- kWarning()<<errorMsg;
- return errorLine+1;
- }
-
-
- QDomElement file=m_doc.elementsByTagName("file").at(0).toElement();
- m_sourceLangCode=file.attribute("source-language");
- m_targetLangCode=file.attribute("target-language");
- m_numberOfPluralForms=numberOfPluralFormsForLangCode(m_targetLangCode);
-
- //Create entry mapping.
- //Along the way: for langs with more than 2 forms
- //we create any form-entries additionally needed
-
- entries=m_doc.elementsByTagName("trans-unit");
- int size=entries.size();
- m_map.clear();
- m_map.reserve(size);
- for(int i=0;i<size;++i)
- {
- QDomElement parentElement=entries.at(i).parentNode().toElement();
- //if (Q_UNLIKELY( e.isNull() ))//sanity
- // continue;
- m_map<<i;
- m_unitsById[entries.at(i).toElement().attribute("id")]=i;
-
- if (parentElement.tagName()=="group" && parentElement.attribute("restype")=="x-gettext-plurals")
- {
- m_plurals.insert(i);
- int localPluralNum=m_numberOfPluralForms;
- while (--localPluralNum>0 && (++i)<size)
- {
- QDomElement p=entries.at(i).parentNode().toElement();
- if (p.tagName()=="group" && p.attribute("restype")=="x-gettext-plurals")
- continue;
-
- parentElement.appendChild(entries.at(m_map.last()).cloneNode());
- }
- }
- }
-
- binEntries=m_doc.elementsByTagName("bin-unit");
- size=binEntries.size();
- int offset=m_map.size();
- for(int i=0;i<size;++i)
- m_unitsById[binEntries.at(i).toElement().attribute("id")]=offset+i;
-
-// entries=m_doc.elementsByTagName("body");
-// uint i=0;
-// uint lim=size();
-// while (i<lim)
-// {
-// CatalogItem& item=m_entries[i];
-// if (item.isPlural()
-// && item.msgstrPlural().count()<m_numberOfPluralForms
-// )
-// {
-// QVector<QString> msgstr(item.msgstrPlural());
-// while (msgstr.count()<m_numberOfPluralForms)
-// msgstr.append(QString());
-// item.setMsgstr(msgstr);
-//
-// }
-// ++i;
-//
-// }
-
-
- QDomElement header=file.firstChildElement("header");
- if (header.isNull())
- header=file.insertBefore(m_doc.createElement("header"), QDomElement()).toElement();
- QDomElement toolElem=header.firstChildElement("tool");
- while (!toolElem.isNull() && toolElem.attribute("tool-id")!="lokalize-" LOKALIZE_VERSION)
- toolElem=toolElem.nextSiblingElement("tool");
-
- if (toolElem.isNull())
- {
- toolElem=header.appendChild(m_doc.createElement("tool")).toElement();
- toolElem.setAttribute("tool-id","lokalize-" LOKALIZE_VERSION);
- toolElem.setAttribute("tool-name","Lokalize");
- toolElem.setAttribute("tool-version",LOKALIZE_VERSION);
- }
-
- kWarning()<<chrono.elapsed();
- return 0;
-}
-
-bool XliffStorage::save(QIODevice* device, bool belongsToProject)
-{
- QTextStream stream(device);
- m_doc.save(stream,2);
- return true;
-}
-//END OPEN/SAVE
-
-//BEGIN STORAGE TRANSLATION
-
-int XliffStorage::size() const
-{
- return m_map.size();
-}
-
-
-
-
-/**
- * helper structure used during XLIFF XML walk-through
- */
-struct ContentEditingData
-{
- enum ActionType{Get,DeleteText,InsertText,DeleteTag,InsertTag,CheckLength};
-
- QList<InlineTag> tags;
- QString stringToInsert;
- int pos;
- int lengthOfStringToRemove;
- ActionType actionType;
-
- ///Get
- ContentEditingData(ActionType type=Get)
- : pos(-1)
- , lengthOfStringToRemove(-1)
- , actionType(type)
- {}
-
- ///DeleteText
- ContentEditingData(int p, int l)
- : pos(p)
- , lengthOfStringToRemove(l)
- , actionType(DeleteText)
- {}
-
- ///InsertText
- ContentEditingData(int p,const QString& s)
- : stringToInsert(s)
- , pos(p)
- , lengthOfStringToRemove(-1)
- , actionType(InsertText)
- {}
-
- ///InsertTag
- ContentEditingData(int p,const InlineTag& range)
- : pos(p)
- , lengthOfStringToRemove(-1)
- , actionType(InsertTag)
- {
- tags.append(range);
- }
-
- ///DeleteTag
- ContentEditingData(int p)
- : pos(p)
- , lengthOfStringToRemove(-1)
- , actionType(DeleteTag)
- {}
-
-};
-
-static QString doContent(QDomElement elem, int startingPos, ContentEditingData* data);
-
-/**
- * walks through XLIFF XML and performs actions depending on ContentEditingData:
- * - reads content
- * - deletes content, or
- * - inserts content
- */
-static QString content(QDomElement elem, ContentEditingData* data=0)
-{
- return doContent(elem, 0, data);
-}
-
-static QString doContent(QDomElement elem, int startingPos, ContentEditingData* data)
-{
- //actually startingPos is current pos
-
- QString result;
-
- if (elem.isNull()
- || (!result.isEmpty() && ContentEditingData::CheckLength))
- return QString();
-
- bool seenCharacterDataAfterElement=false;
-
- QDomNode n = elem.firstChild();
- while (!n.isNull())
- {
- if (n.isCharacterData())
- {
- seenCharacterDataAfterElement=true;
-
- QDomCharacterData c=n.toCharacterData();
- QString cData=c.data();
-
- if (data && data->pos!=-1 &&
- data->pos>=startingPos && data->pos<=startingPos+cData.size())
- {
- // time to do some action! ;)
- int localStartPos=data->pos-startingPos;
-
- //BEGIN DELETE TEXT
- if (data->actionType==ContentEditingData::DeleteText) //(data->lengthOfStringToRemove!=-1)
- {
- if (localStartPos+data->lengthOfStringToRemove>cData.size())
- {
- //text is fragmented into several QDomCharacterData
- int localDelLen=cData.size()-localStartPos;
- //qWarning()<<"text is fragmented into several QDomCharacterData. localDelLen:"<<localDelLen<<"cData:"<<cData;
- c.deleteData(localStartPos,localDelLen);
- //setup data for future iterations
- data->lengthOfStringToRemove=data->lengthOfStringToRemove-localDelLen;
- //data->pos=startingPos;
- //qWarning()<<"\tsetup:"<<data->pos<<data->lengthOfStringToRemove;
- }
- else
- {
- //qWarning()<<"simple delete"<<localStartPos<<data->lengthOfStringToRemove;
- c.deleteData(localStartPos,data->lengthOfStringToRemove);
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//so it exits 100%
- }
- }
- //END DELETE TEXT
- //INSERT
- else if (data->actionType==ContentEditingData::InsertText)
- {
- c.insertData(localStartPos,data->stringToInsert);
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//so it exits 100%
- }
- //BEGIN INSERT TAG
- else if (data->actionType==ContentEditingData::InsertTag)
- {
- const InlineTag& tag=data->tags.first();
- QString mid=cData.mid(localStartPos);
- qWarning()<<"inserting tag"<<tag.name()<<tag.id<<tag.start<<tag.end<<mid<<data->pos<<startingPos;
- if (mid.size())
- c.deleteData(localStartPos,mid.size());
- QDomElement newNode=elem.insertAfter( elem.ownerDocument().createElement(tag.getElementName()),n).toElement();
- newNode.setAttribute("id",tag.id);
- if (!tag.xid.isEmpty())
- newNode.setAttribute("xid",tag.xid);
-
- if (tag.isPaired()&&tag.end>(tag.start+1))
- {
- //qWarning()<<"isPaired";
- int len=tag.end-tag.start-1;//-image symbol
- int localLen=qMin(len,mid.size());
- if (localLen)//appending text
- {
- //qWarning()<<"localLen. appending"<<localLen<<mid.left(localLen);
- newNode.appendChild( elem.ownerDocument().createTextNode(mid.left(localLen)) );
- mid=mid.mid(localLen);
- }
- if (len-localLen) //need to eat more (strings or elements) into newNode
- {
- int missingLen=len-localLen;
- //qWarning()<<"len-localLen";
- //iterate over siblings until we get childrenCumulativeLen>missingLen (or siblings end)
- int childrenCumulativeLen=0;
- QDomNode sibling=newNode.nextSibling();
- while(!sibling.isNull())//&&(childrenCumulativeLen<missingLen))
- {
- QDomNode tmp=sibling;
- sibling=sibling.nextSibling();
- if (tmp.isAttr())
- continue;
- ContentEditingData subData(ContentEditingData::Get);
- if (tmp.isElement())
- {
- childrenCumulativeLen++;
- childrenCumulativeLen+=InlineTag::isPaired(InlineTag::getElementType(tmp.toElement().tagName().toUtf8()));
- kWarning()<<"calling sub";
- QString subContent=doContent(tmp.toElement(),/*we don't care about position*/0,&subData);
- kWarning()<<"called sub";
- childrenCumulativeLen+=subContent.size();
- }
- else if (tmp.isCharacterData())
- childrenCumulativeLen+=tmp.toCharacterData().data().size();
- //qWarning()<<"brbr"<<tmp.nodeName()<<tmp.nodeValue()
- //<<childrenCumulativeLen<<missingLen;
-
- if (childrenCumulativeLen>missingLen)
- {
- if (tmp.isCharacterData())
- {
- //divide the last string
- const QString& endData=tmp.toCharacterData().data();
- QString last=endData.left(endData.size()-(childrenCumulativeLen-missingLen));
- newNode.appendChild( elem.ownerDocument().createTextNode(last));
- tmp.toCharacterData().deleteData(0,last.size());
- //qWarning()<<"end of add"<<last;
- }
- break;
- }
- newNode.appendChild( tmp );
- }
-
- }
- if (!newNode.lastChild().isCharacterData())
- newNode.appendChild( elem.ownerDocument().createTextNode(QString()));
- }
- if (!mid.isEmpty())
- elem.insertAfter( elem.ownerDocument().createTextNode(mid),newNode);
- else if (!newNode.nextSibling().isCharacterData()) //keep our DOM in a nice state
- elem.insertAfter( elem.ownerDocument().createTextNode(QString()),newNode);
-
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//we're done here
- }
- //END INSERT TAG
- cData=c.data();
- }
- //else
- // if (data&&data->pos!=-1/*&& n.nextSibling().isNull()*/)
- // kWarning()<<"arg!"<<startingPos<<"data->pos"<<data->pos;
-
- result += cData;
- startingPos+=cData.size();
- }
- else if (n.isElement())
- {
- QDomElement el=n.toElement();
- //BEGIN DELETE TAG
- if (data&&data->actionType==ContentEditingData::DeleteTag
- &&data->pos==startingPos)
- {
- //qWarning()<<"start deleting tag";
- data->tags.append(InlineTag(startingPos, -1, InlineTag::getElementType(el.tagName().toUtf8()), el.attribute("id"), el.attribute("xid")));
- if (data->tags.first().isPaired())
- {
- //get end position
- ContentEditingData subData(ContentEditingData::Get);
- QString subContent=doContent(el,startingPos,&subData);
- data->tags[0].end=1+startingPos+subContent.size();//tagsymbol+text
- //qWarning()<<"get end position"<<startingPos<<subContent.size();
-
- //move children upper
- QDomNode local = n.firstChild();
- QDomNode refNode=n;
- while (!local.isNull())
- {
- QDomNode tmp=local;
- local = local.nextSibling();
- if (!tmp.isAttr())
- {
- //qWarning()<<"here is another child"<<tmp.nodeType()<<tmp.nodeName()<<tmp.nodeValue();
- refNode=elem.insertAfter(tmp,refNode);
- }
- }
-
- }
- QDomNode temp=n;
- n=n.nextSibling();
- elem.removeChild(temp);
- data->actionType=ContentEditingData::CheckLength;
- return QString('a');//we're done here
- }
- //END DELETE TAG
-
- if (!seenCharacterDataAfterElement) //add empty charData child so that user could add some text
- elem.insertBefore( elem.ownerDocument().createTextNode(QString()),n);
- seenCharacterDataAfterElement=false;
-
- if (data)
- {result += QChar(TAGRANGE_IMAGE_SYMBOL); ++startingPos;}
- int oldStartingPos=startingPos;
-
- //detect type of the tag
- InlineTag::InlineElement i=InlineTag::getElementType(el.tagName().toUtf8());
-
- //1 or 2 images to represent it?
- //2 = there may be content inside
- if (InlineTag::isPaired(i))
- {
- QString recursiveContent=doContent(el,startingPos,data);
- if (!recursiveContent.isEmpty())
- result += recursiveContent; startingPos+=recursiveContent.size();
- if (data)
- {result += QChar(TAGRANGE_IMAGE_SYMBOL); ++startingPos;}
- }
-
- if (data&&data->actionType==ContentEditingData::Get)
- {
- QString id=el.attribute("id");
- if (i==InlineTag::mrk)//TODO attr map
- id=el.attribute("mtype");
-
- //kWarning()<<"tagName"<<el.tagName()<<"id"<<id<<"start"<<oldStartingPos-1<<startingPos-1;
- data->tags.append(InlineTag(oldStartingPos-1,startingPos-1,i,id,el.attribute("xid")));
- }
- }
- n = n.nextSibling();
- }
- if (!seenCharacterDataAfterElement)
- {
- //add empty charData child so that user could add some text
- elem.appendChild( elem.ownerDocument().createTextNode(QString()));
- }
-
- return result;
-}
-
-
-
-//flat-model interface (ignores XLIFF grouping)
-
-CatalogString XliffStorage::catalogString(QDomElement unit, DocPosition::Part part) const
-{
- static const QString names[]={"source","target"};
- CatalogString catalogString;
- ContentEditingData data(ContentEditingData::Get);
- catalogString.string=content(unit.firstChildElement( names[part==DocPosition::Target]), &data );
- catalogString.tags=data.tags;
- return catalogString;
-}
-
-CatalogString XliffStorage::catalogString(const DocPosition& pos) const
-{
- return catalogString(unitForPos(pos.entry), pos.part);
-}
-
-CatalogString XliffStorage::targetWithTags(DocPosition pos) const
-{
- return catalogString(unitForPos(pos.entry), DocPosition::Target);
-}
-CatalogString XliffStorage::sourceWithTags(DocPosition pos) const
-{
- return catalogString(unitForPos(pos.entry), DocPosition::Source);
-}
-
-static QString genericContent(QDomElement elem, bool nonbin)
-{
- return nonbin?content(elem):elem.firstChildElement("external-file").attribute("href");
-}
-QString XliffStorage::source(const DocPosition& pos) const
-{
- return genericContent(sourceForPos(pos.entry),pos.entry<size());
-}
-QString XliffStorage::target(const DocPosition& pos) const
-{
- return genericContent(targetForPos(pos.entry),pos.entry<size());
-}
-
-
-void XliffStorage::targetDelete(const DocPosition& pos, int count)
-{
- if (pos.entry<size())
- {
- ContentEditingData data(pos.offset,count);
- content(targetForPos(pos.entry),&data);
- }
- else
- {
- //only bulk delete requests are generated
- targetForPos(pos.entry).firstChildElement("external-file").setAttribute("href",QString());
- }
-}
-
-void XliffStorage::targetInsert(const DocPosition& pos, const QString& arg)
-{
- kWarning()<<pos.entry<<arg;
- QDomElement targetEl=targetForPos(pos.entry);
- //BEGIN add <*target>
- if (targetEl.isNull())
- {
- QDomNode unitEl=unitForPos(pos.entry);
- QDomNode refNode=unitEl.firstChildElement("seg-source");//obey standard
- if (refNode.isNull()) refNode=unitEl.firstChildElement(binsourcesource[pos.entry<size()]);
- targetEl = unitEl.insertAfter(m_doc.createElement(bintargettarget[pos.entry<size()]),refNode).toElement();
- targetEl.setAttribute("state","new");
-
- if (pos.entry<size())
- {
- targetEl.appendChild(m_doc.createTextNode(arg));//i bet that pos.offset is 0 ;)
- return;
- }
- }
- //END add <*target>
- if (arg.isEmpty()) return; //means we were called just to add <taget> tag
-
- if (pos.entry>=size())
- {
- QDomElement ef=targetEl.firstChildElement("external-file");
- if (ef.isNull())
- ef=targetEl.appendChild(m_doc.createElement("external-file")).toElement();
- ef.setAttribute("href",arg);
- return;
- }
-
- ContentEditingData data(pos.offset,arg);
- content(targetEl,&data);
-}
-
-void XliffStorage::targetInsertTag(const DocPosition& pos, const InlineTag& tag)
-{
- targetInsert(pos,QString()); //adds <taget> if needed
- ContentEditingData data(tag.start,tag);
- content(targetForPos(pos.entry),&data);
-}
-
-InlineTag XliffStorage::targetDeleteTag(const DocPosition& pos)
-{
- ContentEditingData data(pos.offset);
- content(targetForPos(pos.entry),&data);
- if (data.tags[0].end==-1) data.tags[0].end=data.tags[0].start;
- return data.tags.first();
-}
-
-void XliffStorage::setTarget(const DocPosition& pos, const QString& arg)
-{
- Q_UNUSED(pos);
- Q_UNUSED(arg);
-//TODO
-}
-
-
-QVector<AltTrans> XliffStorage::altTrans(const DocPosition& pos) const
-{
- QVector<AltTrans> result;
-
- QDomElement elem = unitForPos(pos.entry).firstChildElement("alt-trans");
- while (!elem.isNull())
- {
- AltTrans aTrans;
- aTrans.source=catalogString(elem, DocPosition::Source);
- aTrans.target=catalogString(elem, DocPosition::Target);
- aTrans.phase=elem.attribute("phase-name");
- aTrans.origin=elem.attribute("origin");
- aTrans.score=elem.attribute("match-quality").toInt();
- aTrans.lang=elem.firstChildElement("target").attribute("xml:lang");
-
- const char* const types[]={
- "proposal",
- "previous-version",
- "rejected",
- "reference",
- "accepted"
- };
- QString typeStr=elem.attribute("alttranstype");
- int i=-1;
- while (++i<int(sizeof(types)/sizeof(char*)) && types[i]!=typeStr)
- ;
- aTrans.type=AltTrans::Type(i);
-
- result<<aTrans;
-
- elem=elem.nextSiblingElement("alt-trans");
- }
- return result;
-}
-
-static QDomElement phaseElement(QDomDocument m_doc, const QString& name, QDomElement& phasegroup)
-{
- QDomElement file=m_doc.elementsByTagName("file").at(0).toElement();
- QDomElement header=file.firstChildElement("header");
- phasegroup=header.firstChildElement("phase-group");
- if (phasegroup.isNull())
- {
- phasegroup=m_doc.createElement("phase-group");
- //order following XLIFF spec
- QDomElement skl=header.firstChildElement("skl");
- if (!skl.isNull())
- header.insertAfter(phasegroup, skl);
- else
- header.insertBefore(phasegroup, header.firstChildElement());
- }
- QDomElement phaseElem=phasegroup.firstChildElement("phase");
- while (!phaseElem.isNull() && phaseElem.attribute("phase-name")!=name)
- phaseElem=phaseElem.nextSiblingElement("phase");
-
- return phaseElem;
-}
-
-static Phase phaseFromElement(QDomElement phaseElem)
-{
- Phase phase;
- phase.name =phaseElem.attribute("phase-name");
- phase.process =phaseElem.attribute("process-name");
- phase.company =phaseElem.attribute("company-name");
- phase.contact =phaseElem.attribute("contact-name");
- phase.email =phaseElem.attribute("contact-email");
- phase.phone =phaseElem.attribute("contact-phone");
- phase.tool =phaseElem.attribute("tool-id");
- phase.date=QDate::fromString(phaseElem.attribute("date"),Qt::ISODate);
- return phase;
-}
-
-Phase XliffStorage::updatePhase(const Phase& phase)
-{
- QDomElement phasegroup;
- QDomElement phaseElem=phaseElement(m_doc,phase.name,phasegroup);
- Phase prev=phaseFromElement(phaseElem);
-
- if (phaseElem.isNull()&&!phase.name.isEmpty())
- {
- phaseElem=phasegroup.appendChild(m_doc.createElement("phase")).toElement();
- phaseElem.setAttribute("phase-name",phase.name);
- }
-
- phaseElem.setAttribute("process-name", phase.process);
- if (!phase.company.isEmpty()) phaseElem.setAttribute("company-name", phase.company);
- phaseElem.setAttribute("contact-name", phase.contact);
- phaseElem.setAttribute("contact-email",phase.email);
- if (!phase.phone.isEmpty()) phaseElem.setAttribute("contact-phone",phase.phone);
- phaseElem.setAttribute("tool-id", phase.tool);
- if (phase.date.isValid()) phaseElem.setAttribute("date",phase.date.toString(Qt::ISODate));
- return prev;
-}
-
-QList<Phase> XliffStorage::allPhases() const
-{
- QList<Phase> result;
- QDomElement file=m_doc.elementsByTagName("file").at(0).toElement();
- QDomElement header=file.firstChildElement("header");
- QDomElement phasegroup=header.firstChildElement("phase-group");
- QDomElement phaseElem=phasegroup.firstChildElement("phase");
- while (!phaseElem.isNull())
- {
- result.append(phaseFromElement(phaseElem));
- phaseElem=phaseElem.nextSiblingElement("phase");
- }
- return result;
-}
-
-Phase XliffStorage::phase(const QString& name) const
-{
- QDomElement phasegroup;
- QDomElement phaseElem=phaseElement(m_doc,name,phasegroup);
-
- return phaseFromElement(phaseElem);
-}
-
-QMap<QString,Tool> XliffStorage::allTools() const
-{
- QMap<QString,Tool> result;
- QDomElement file=m_doc.elementsByTagName("file").at(0).toElement();
- QDomElement header=file.firstChildElement("header");
- QDomElement toolElem=header.firstChildElement("tool");
- while (!toolElem.isNull())
- {
- Tool tool;
- tool.tool =toolElem.attribute("tool-id");
- tool.name =toolElem.attribute("tool-name");
- tool.version =toolElem.attribute("tool-version");
- tool.company =toolElem.attribute("tool-company");
-
- result.insert(tool.tool, tool);
- toolElem=toolElem.nextSiblingElement("tool");
- }
- return result;
-}
-
-QStringList XliffStorage::sourceFiles(const DocPosition& pos) const
-{
- QStringList result;
-
- QDomElement elem = unitForPos(pos.entry).firstChildElement("context-group");
- while (!elem.isNull())
- {
- if (elem.attribute("purpose").contains("location"))
- {
- QDomElement context = elem.firstChildElement("context");
- while (!context.isNull())
- {
- QString sourcefile;
- QString linenumber;
- if (context.attribute("context-type")=="sourcefile")
- sourcefile=context.text();
- else if (context.attribute("context-type")=="linenumber")
- linenumber=context.text();
- if (!( sourcefile.isEmpty()&&linenumber.isEmpty() ))
- result.append(sourcefile+':'+linenumber);
-
- context=context.nextSiblingElement("context");
- }
- }
-
- elem=elem.nextSiblingElement("context-group");
- }
- //qSort(result);
-
- return result;
-}
-
-static void initNoteFromElement(Note& note, QDomElement elem)
-{
- note.content=elem.text();
- note.from=elem.attribute("from");
- note.lang=elem.attribute("xml:lang");
- if (elem.attribute("annotates")=="source")
- note.annotates=Note::Source;
- else if (elem.attribute("annotates")=="target")
- note.annotates=Note::Target;
- bool ok;
- note.priority=elem.attribute("priority").toInt(&ok);
- if (!ok) note.priority=0;
-}
-
-QVector<Note> XliffStorage::notes(const DocPosition& pos) const
-{
- QList<Note> result;
-
- QDomElement elem = entries.at(m_map.at(pos.entry)).firstChildElement("note");
- while (!elem.isNull())
- {
- Note note;
- initNoteFromElement(note,elem);
- result.append(note);
- elem=elem.nextSiblingElement("note");
- }
- qSort(result);
- return result.toVector();
-}
-
-QVector<Note> XliffStorage::developerNotes(const DocPosition& pos) const
-{
- Q_UNUSED(pos);
- //TODO
- return QVector<Note>();
-}
-
-Note XliffStorage::setNote(DocPosition pos, const Note& note)
-{
- //kWarning()<<int(pos.form)<<note.content;
- QDomElement unit=unitForPos(pos.entry);
- QDomElement elem;
- Note oldNote;
- if (pos.form==-1 && !note.content.isEmpty())
- {
- QDomElement ref=unit.lastChildElement("note");
- elem=unit.insertAfter( m_doc.createElement("note"),ref).toElement();
- elem.appendChild(m_doc.createTextNode(QString()));
- }
- else
- {
- QDomNodeList list=unit.elementsByTagName("note");
- if (pos.form==-1) pos.form=list.size()-1;
- if (pos.form<list.size())
- {
- elem = unit.elementsByTagName("note").at(pos.form).toElement();
- initNoteFromElement(oldNote,elem);
- }
- }
-
- if (elem.isNull()) return oldNote;
-
- if (!elem.text().isEmpty())
- {
- ContentEditingData data(0,elem.text().size());
- content(elem,&data);
- }
-
- if (!note.content.isEmpty())
- {
- ContentEditingData data(0,note.content); content(elem,&data);
- if (!note.from.isEmpty()) elem.setAttribute("from",note.from);
- if (note.priority) elem.setAttribute("priority",note.priority);
- }
- else
- unit.removeChild(elem);
-
- return oldNote;
-}
-
-QStringList XliffStorage::noteAuthors() const
-{
- QSet<QString> result;
- QDomNodeList notes=m_doc.elementsByTagName("note");
- int i=notes.size();
- while (--i>=0)
- {
- QString from=notes.at(i).toElement().attribute("from");
- if (!from.isEmpty())
- result.insert(from);
- }
- return result.toList();
-}
-
-QVector<Note> phaseNotes(QDomDocument m_doc, const QString& phasename, bool remove=false)
-{
- QVector<Note> result;
-
- QDomElement phasegroup;
- QDomElement phaseElem=phaseElement(m_doc,phasename,phasegroup);
-
- QDomElement noteElem=phaseElem.firstChildElement("note");
- while (!noteElem.isNull())
- {
- Note note;
- initNoteFromElement(note,noteElem);
- result.append(note);
- QDomElement old=noteElem;
- noteElem=noteElem.nextSiblingElement("note");
- if (remove) phaseElem.removeChild(old);
- }
- return result;
-}
-
-QVector<Note> XliffStorage::phaseNotes(const QString& phasename) const
-{
- return ::phaseNotes(m_doc, phasename, false);
-}
-
-QVector<Note> XliffStorage::setPhaseNotes(const QString& phasename, QVector<Note> notes)
-{
- QVector<Note> result=::phaseNotes(m_doc, phasename, true);
-
- QDomElement phasegroup;
- QDomElement phaseElem=phaseElement(m_doc,phasename,phasegroup);
-
- foreach(const Note& note, notes)
- {
- QDomElement elem=phaseElem.appendChild(m_doc.createElement("note")).toElement();
- elem.appendChild(m_doc.createTextNode(note.content));
- if (!note.from.isEmpty()) elem.setAttribute("from",note.from);
- if (note.priority) elem.setAttribute("priority",note.priority);
- }
-
- return result;
-}
-
-
-QString XliffStorage::setPhase(const DocPosition& pos, const QString& phase)
-{
- targetInsert(pos,QString()); //adds <taget> if needed
-
- QDomElement target=targetForPos(pos.entry);
- QString result=target.attribute("phase-name");
- if (phase.isEmpty())
- target.removeAttribute("phase-name");
- else
- target.setAttribute("phase-name",phase);
-
- return result;
-}
-
-QString XliffStorage::phase(const DocPosition& pos) const
-{
- QDomElement target=targetForPos(pos.entry);
- return target.attribute("phase-name");
-}
-
-QStringList XliffStorage::context(const DocPosition& pos) const
-{
- Q_UNUSED(pos);
- //TODO
- return QStringList(QString());
-}
-
-QStringList XliffStorage::matchData(const DocPosition& pos) const
-{
- Q_UNUSED(pos);
- return QStringList();
-}
-
-QString XliffStorage::id(const DocPosition& pos) const
-{
- return unitForPos(pos.entry).attribute("id");
-}
-
-bool XliffStorage::isPlural(const DocPosition& pos) const
-{
- return m_plurals.contains(pos.entry);
-}
-/*
-bool XliffStorage::isApproved(const DocPosition& pos) const
-{
- return entries.at(m_map.at(pos.entry)).toElement().attribute("approved")=="yes";
-}
-void XliffStorage::setApproved(const DocPosition& pos, bool approved)
-{
- static const char* const noyes[]={"no","yes"};
- entries.at(m_map.at(pos.entry)).toElement().setAttribute("approved",noyes[approved]);
-}
-*/
-
-static const char* const states[]={
- "new", "needs-translation", "needs-l10n", "needs-adaptation", "translated",
- "needs-review-translation", "needs-review-l10n", "needs-review-adaptation", "final",
- "signed-off"};
-
-
-static TargetState stringToState(const QString& state)
-{
- int i=sizeof(states)/sizeof(char*);
- while (--i>0 && state!=states[i])
- ;
- return TargetState(i);
-}
-
-TargetState XliffStorage::setState(const DocPosition& pos, TargetState state)
-{
- targetInsert(pos,QString()); //adds <taget> if needed
- QDomElement target=targetForPos(pos.entry);
- TargetState prev=stringToState(target.attribute("state"));
- target.setAttribute("state",states[state]);
- return prev;
-}
-
-TargetState XliffStorage::state(const DocPosition& pos) const
-{
- QDomElement target=targetForPos(pos.entry);
- if (!target.hasAttribute("state") && unitForPos(pos.entry).attribute("approved")=="yes")
- return SignedOff;
- return stringToState(target.attribute("state"));
-}
-
-bool XliffStorage::isEmpty(const DocPosition& pos) const
-{
- ContentEditingData data(ContentEditingData::CheckLength);
- return content(targetForPos(pos.entry),&data).isEmpty();
-}
-
-bool XliffStorage::isEquivTrans(const DocPosition& pos) const
-{
- return targetForPos(pos.entry).attribute("equiv-trans")!="no";
-}
-
-void XliffStorage::setEquivTrans(const DocPosition& pos, bool equivTrans)
-{
- targetForPos(pos.entry).setAttribute("equiv-trans",noyes[equivTrans]);
-}
-
-QDomElement XliffStorage::unitForPos(int pos) const
-{
- if (pos<size())
- return entries.at(m_map.at(pos)).toElement();
-
- return binEntries.at(pos-size()).toElement();
-}
-
-QDomElement XliffStorage::targetForPos(int pos) const
-{
- return unitForPos(pos).firstChildElement(bintargettarget[pos<size()]);
-}
-
-QDomElement XliffStorage::sourceForPos(int pos) const
-{
- return unitForPos(pos).firstChildElement(binsourcesource[pos<size()]);
-}
-
-int XliffStorage::binUnitsCount() const
-{
- return binEntries.size();
-}
-
-int XliffStorage::unitById(const QString& id) const
-{
- return m_unitsById.contains(id)?m_unitsById.value(id):-1;
-}
-
-
-//END STORAGE TRANSLATION
-
-
+++ /dev/null
-/*
-Copyright 2008-2009 Nick Shaforostoff <shaforostoff@kde.ru>
-
-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) version 3 or any later version
-accepted by the membership of KDE e.V. (or its successor approved
-by the membership of KDE e.V.), which shall act as a proxy
-defined in Section 14 of version 3 of the license.
-
-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, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#ifndef XLIFFSTORAGE_H
-#define XLIFFSTORAGE_H
-
-#include "catalogstorage.h"
-#include <QtXml/qdom.h>
-
-#include <QVector>
-#include <QMap>
-// #include <QDomDocument>
-
-class XliffStorage: public CatalogStorage
-{
-public:
- XliffStorage();
- ~XliffStorage();
-
- int capabilities() const;
-
- int load(QIODevice* device);
- bool save(QIODevice* device, bool belongsToProject=false);
-
- int size() const;
- bool isEmpty() const;
-
- //flat-model interface (ignores XLIFF grouping)
- QString source(const DocPosition& pos) const;
- QString target(const DocPosition& pos) const;
- CatalogString targetWithTags(DocPosition pos) const;
- CatalogString sourceWithTags(DocPosition pos) const;
- CatalogString catalogString(const DocPosition& pos) const;
-
- /// all plural forms. pos.form doesn't matter TODO
- QStringList sourceAllForms(const DocPosition& pos, bool stripNewLines=false) const{Q_UNUSED(pos); return QStringList();}
- QStringList targetAllForms(const DocPosition& pos, bool stripNewLines=false) const{Q_UNUSED(pos); return QStringList();}
-
- void targetDelete(const DocPosition& pos, int count);
- void targetInsert(const DocPosition& pos, const QString& arg);
- void setTarget(const DocPosition& pos, const QString& arg);//called for mergeCatalog
- void targetInsertTag(const DocPosition&, const InlineTag&);
- InlineTag targetDeleteTag(const DocPosition&);
- Phase updatePhase(const Phase& phase);
- QList<Phase> allPhases() const;
- Phase phase(const QString& name) const;
- QMap<QString,Tool> allTools() const;
- QVector<Note> phaseNotes(const QString& phase) const;
- QVector<Note> setPhaseNotes(const QString& phase, QVector<Note> notes);
-
- QStringList sourceFiles(const DocPosition& pos) const;
- QVector<AltTrans> altTrans(const DocPosition& pos) const;
-
- ///@a pos.form is note number
- Note setNote(DocPosition pos, const Note& note);
- QVector<Note> notes(const DocPosition& pos) const;
- QStringList noteAuthors() const;
- QVector<Note> developerNotes(const DocPosition& pos) const;
-
- QString setPhase(const DocPosition& pos, const QString& phase);
- QString phase(const DocPosition& pos) const;
-
- QStringList context(const DocPosition& pos) const;
-
- QStringList matchData(const DocPosition& pos) const;
- QString id(const DocPosition& pos) const;
-
- bool isPlural(const DocPosition& pos) const;
- bool isEmpty(const DocPosition& pos) const;
-
- bool isEquivTrans(const DocPosition& pos) const;
- void setEquivTrans(const DocPosition& pos, bool equivTrans);
-
- TargetState state(const DocPosition& pos) const;
- TargetState setState(const DocPosition& pos, TargetState state);
-
-
- int binUnitsCount() const;
- int unitById(const QString& id) const;
-
- QString mimetype()const{return "application/x-xliff";}
-
-private:
- QDomElement unitForPos(int pos) const;
- QDomElement targetForPos(int pos) const;
- QDomElement sourceForPos(int pos) const;
- CatalogString catalogString(QDomElement unit, DocPosition::Part part) const;
-
-private:
- mutable QDomDocument m_doc;
- QVector<int> m_map;//need mapping to treat plurals as 1 entry
- QSet<int> m_plurals;
-
- QDomNodeList entries;
- QDomNodeList binEntries;
- QMap<QString,int> m_unitsById;
-
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "cataloglistview.h"
-#include "catalogmodel.h"
-#include "catalog.h"
-#include "project.h"
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <klineedit.h>
-#include <KConfigGroup>
-
-#include <QtCore/qdatetime.h>
-#include <QTreeView>
-#include <QHeaderView>
-#include <QtCore/qabstractitemmodel.h>
-#include <QToolButton>
-#include <QVBoxLayout>
-#include <QAction>
-#include <QMenu>
-#include <QShortcut>
-
-#include <QMdiSubWindow>
-#include <QMdiArea>
-
-#include <QtGui/qevent.h>
-
-class CatalogTreeView: public QTreeView
-{
- public:
- CatalogTreeView(QWidget * parent)
- : QTreeView(parent) {}
- ~CatalogTreeView() {}
-
- protected:
- void keyReleaseEvent(QKeyEvent *e) {
- if (e->key() == Qt::Key_Return && currentIndex().isValid()) {
- emit clicked(currentIndex());
- e->accept();
- } else {
- QTreeView::keyReleaseEvent(e);
- }
- }
-
-};
-
-
-CatalogView::CatalogView(QWidget* parent, Catalog* catalog)
- : QDockWidget ( i18nc("@title:window aka Message Tree","Translation Units"), parent)
- , m_browser(new CatalogTreeView(this))
- , m_lineEdit(new KLineEdit(this))
- , m_model(new CatalogTreeModel(this,catalog))
- , m_proxyModel(new CatalogTreeFilterModel(this))
-{
- setObjectName("catalogTreeView");
-
- QWidget* w=new QWidget(this);
- QVBoxLayout* layout=new QVBoxLayout(w);
- layout->setContentsMargins(0,0,0,0);
- QHBoxLayout* l=new QHBoxLayout;
- l->setContentsMargins(0,0,0,0);
- l->setSpacing(0);
- layout->addLayout(l);
-
- m_lineEdit->setClearButtonShown(true);
- m_lineEdit->setClickMessage(i18n("Quick search..."));
- m_lineEdit->setToolTip(i18nc("@info:tooltip","Activated by Ctrl+L.")+" "+i18nc("@info:tooltip","Accepts regular expressions"));
- connect (m_lineEdit,SIGNAL(textChanged(QString)),this,SLOT(setFilterRegExp()),Qt::QueuedConnection);
- // QShortcut* ctrlEsc=new QShortcut(QKeySequence(Qt::META+Qt::Key_Escape),this,SLOT(reset()),0,Qt::WidgetWithChildrenShortcut);
- QShortcut* esc=new QShortcut(QKeySequence(Qt::Key_Escape),this,0,0,Qt::WidgetWithChildrenShortcut);
- connect(esc,SIGNAL(activated()),this,SIGNAL(escaped()));
-
-
- QToolButton* btn=new QToolButton(w);
- btn->setPopupMode(QToolButton::InstantPopup);
- btn->setText(i18n("options"));
- //btn->setArrowType(Qt::DownArrow);
- btn->setMenu(new QMenu(this));
- m_filterOptionsMenu=btn->menu();
- connect(m_filterOptionsMenu,SIGNAL(aboutToShow()),this,SLOT(fillFilterOptionsMenu()));
- connect(m_filterOptionsMenu,SIGNAL(triggered(QAction*)),this,SLOT(filterOptionToggled(QAction*)));
-
- l->addWidget(m_lineEdit);
- l->addWidget(btn);
- layout->addWidget(m_browser);
-
-
- setTabOrder(m_lineEdit, btn);
- setTabOrder(btn, m_browser);
- setFocusProxy(m_lineEdit);
-
- setWidget(w);
-
- connect(m_browser,SIGNAL(clicked(QModelIndex)),this,SLOT(slotItemActivated(QModelIndex)));
- m_browser->setRootIsDecorated(false);
- m_browser->setAllColumnsShowFocus(true);
- m_browser->setAlternatingRowColors(true);
- m_browser->viewport()->setBackgroundRole(QPalette::Background);
-
- m_proxyModel->setSourceModel(m_model);
- m_browser->setModel(m_proxyModel);
- m_browser->setColumnWidth(0,m_browser->columnWidth(0)/3);
- m_browser->setSortingEnabled(true);
- m_browser->sortByColumn(0, Qt::AscendingOrder);
- m_browser->setWordWrap(false);
- m_browser->setUniformRowHeights(true);
- m_browser->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
-
-
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- m_browser->header()->restoreState(QByteArray::fromBase64( cg.readEntry("TreeHeaderState", QByteArray()) ));
-}
-
-CatalogView::~CatalogView()
-{
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- cg.writeEntry("TreeHeaderState",m_browser->header()->saveState().toBase64());
-}
-
-void CatalogView::setFocus()
-{
- QDockWidget::setFocus();
- m_lineEdit->selectAll();
-}
-
-void CatalogView::slotNewEntryDisplayed(const DocPosition& pos)
-{
- QModelIndex item=m_proxyModel->mapFromSource(m_model->index(pos.entry,0));
- m_browser->setCurrentIndex(item);
- m_browser->scrollTo(item/*,QAbstractItemView::PositionAtCenter*/);
-}
-
-void CatalogView::setFilterRegExp()
-{
- QString expr=m_lineEdit->text();
- if (m_proxyModel->filterRegExp().pattern()!=expr)
- m_proxyModel->setFilterRegExp(m_proxyModel->filerOptions()&CatalogTreeFilterModel::IgnoreAccel?expr.remove(Project::instance()->accel()):expr);
-}
-
-void CatalogView::slotItemActivated(const QModelIndex& idx)
-{
- emit gotoEntry(DocPosition(m_proxyModel->mapToSource(idx).row()),0);
-}
-
-void CatalogView::filterOptionToggled(QAction* action)
-{
- if (action->data().isNull())
- return;
-
- int opt=action->data().toInt();
- if (opt>0)
- m_proxyModel->setFilerOptions(m_proxyModel->filerOptions()^opt);
- else
- {
- if (opt!=-1) opt=-opt-2;
- m_proxyModel->setFilterKeyColumn(opt);
- }
- m_filterOptionsMenu->clear();
-}
-void CatalogView::fillFilterOptionsMenu()
-{
- m_filterOptionsMenu->clear();
-
- if (m_proxyModel->individualRejectFilterEnabled())
- m_filterOptionsMenu->addAction(i18n("Reset individual filter"),this,SLOT(setEntriesFilteredOut()));
-
-
- bool extStates=m_model->catalog()->capabilities()&ExtendedStates;
-
- const char* const basicTitles[]={
- I18N_NOOP("Case insensitive"),
- I18N_NOOP("Ignore accelerator marks"),
- I18N_NOOP("Ready"),
- I18N_NOOP("Non-ready"),
- I18N_NOOP("Non-empty"),
- I18N_NOOP("Empty"),
- I18N_NOOP("Changed since file open"),
- I18N_NOOP("Unchanged since file open"),
- I18N_NOOP("Same in sync file"),
- I18N_NOOP("Different in sync file"),
- I18N_NOOP("Not in sync file")
- };
- const char* const* extTitles=Catalog::states();
- const char* const* alltitles[2]={basicTitles,extTitles};
-
- QMenu* basicMenu=m_filterOptionsMenu->addMenu(i18nc("@title:inmenu","Basic"));
- QMenu* extMenu=extStates?m_filterOptionsMenu->addMenu(i18nc("@title:inmenu","States")):0;
- QMenu* allmenus[2]={basicMenu,extMenu};
- QMenu* columnsMenu=m_filterOptionsMenu->addMenu(i18nc("@title:inmenu","Searchable column"));
-
- QAction* txt;
- for (int i=0;(1<<i)<CatalogTreeFilterModel::MaxOption;++i)
- {
- bool ext=(1<<i)>=CatalogTreeFilterModel::New;
- if (!extStates&&ext) break;
- txt=allmenus[ext]->addAction(i18n(alltitles[ext][i-ext*FIRSTSTATEPOSITION]));
- txt->setData(1<<i);
- txt->setCheckable(true);
- txt->setChecked(m_proxyModel->filerOptions()&(1<<i));
- if ((1<<i)==CatalogTreeFilterModel::IgnoreAccel)
- basicMenu->addSeparator();
- }
- if (!extStates)
- m_filterOptionsMenu->addSeparator();
- for (int i=-1;i<CatalogTreeModel::DisplayedColumnCount;++i)
- {
- kWarning()<<i;
- txt=columnsMenu->addAction((i==-1)?i18nc("@item:inmenu all columns","All"):
- m_model->headerData(i,Qt::Horizontal,Qt::DisplayRole).toString());
- txt->setData(-i-2);
- txt->setCheckable(true);
- txt->setChecked(m_proxyModel->filterKeyColumn()==i);
- }
-}
-
-void CatalogView::reset()
-{
- m_proxyModel->setFilterKeyColumn(-1);
- m_proxyModel->setFilerOptions(CatalogTreeFilterModel::AllStates);
- m_lineEdit->clear();
- //emit gotoEntry(DocPosition(m_proxyModel->mapToSource(m_browser->currentIndex()).row()),0);
- slotItemActivated(m_browser->currentIndex());
-}
-
-void CatalogView::setMergeCatalogPointer(MergeCatalog* pointer)
-{
- m_proxyModel->setMergeCatalogPointer(pointer);
-}
-
-int CatalogView::siblingEntry(int step)
-{
- QModelIndex item=m_browser->currentIndex();
- int lastRow=m_proxyModel->rowCount()-1;
- if (!item.isValid())
- {
- if (lastRow==-1)
- return -1;
- item=m_proxyModel->index((step==1)?0:lastRow,0);
- m_browser->setCurrentIndex(item);
- }
- else
- {
- if ( item.row() == ((step==-1)?0:lastRow) )
- return -1;
- item=item.sibling(item.row()+step,0);
- }
- return m_proxyModel->mapToSource(item).row();
-}
-
-int CatalogView::nextEntry()
-{
- return siblingEntry(1);
-}
-
-int CatalogView::prevEntry()
-{
- return siblingEntry(-1);
-}
-
-static int edgeEntry(CatalogTreeFilterModel* m_proxyModel, int row)
-{
- if (!m_proxyModel->rowCount())
- return -1;
-
- return m_proxyModel->mapToSource(m_proxyModel->index(row,0)).row();
-}
-
-int CatalogView::firstEntry()
-{
- return edgeEntry(m_proxyModel,0);
-}
-
-int CatalogView::lastEntry()
-{
- return edgeEntry(m_proxyModel,m_proxyModel->rowCount()-1);
-}
-
-
-void CatalogView::setEntryFilteredOut(int entry, bool filteredOut)
-{
- m_proxyModel->setEntryFilteredOut(entry,filteredOut);
-}
-
-void CatalogView::setEntriesFilteredOut(bool filteredOut)
-{
- show();
- m_proxyModel->setEntriesFilteredOut(filteredOut);
-}
-
-
-#include "moc_cataloglistview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef CATALOGLISTVIEW_H
-#define CATALOGLISTVIEW_H
-
-#include "pos.h"
-#include "mergecatalog.h"
-
-#include <QDockWidget>
-#include <QTreeView>
-class CatalogTreeFilterModel;
-class CatalogTreeModel;
-class Catalog;
-class KLineEdit;
-#include <QMenu>
-#include <QAction>
-#include <QModelIndex>
-class CatalogTreeView;
-
-class CatalogView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- CatalogView(QWidget*,Catalog*);
- ~CatalogView();
-
- void setEntryFilteredOut(int entry, bool filteredOut);
-
- int nextEntry();
- int prevEntry();
- int firstEntry();
- int lastEntry();
-private:
- int siblingEntry(int step);
-
-public slots:
- void slotNewEntryDisplayed(const DocPosition&);
- void setEntriesFilteredOut(bool filteredOut=false);
- void setFocus();
- void reset();
- void setMergeCatalogPointer(MergeCatalog* pointer);
-
-signals:
- void gotoEntry(const DocPosition&, int selection);
- void escaped();
-
-private slots:
- void slotItemActivated(const QModelIndex&);
- void setFilterRegExp();
- void fillFilterOptionsMenu();
- void filterOptionToggled(QAction*);
-
-private:
- CatalogTreeView* m_browser;
- KLineEdit* m_lineEdit;
- QMenu* m_filterOptionsMenu;
- CatalogTreeModel* m_model;
- CatalogTreeFilterModel* m_proxyModel;
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "catalogmodel.h"
-
-#include "catalog.h"
-#include "project.h"
-
-#include <kdebug.h>
-#include <klocale.h>
-
-#include <QApplication>
-#include <QFontMetrics>
-#include <kcolorscheme.h>
-
-#define DYNAMICFILTER_LIMIT 256
-
-QVector<QVariant> CatalogTreeModel::m_fonts;
-
-
-CatalogTreeModel::CatalogTreeModel(QObject* parent, Catalog* catalog)
- : QAbstractItemModel(parent)
- , m_catalog(catalog)
- , m_ignoreAccel(true)
-{
- if (m_fonts.isEmpty())
- {
- QVector<QFont> fonts(4, QApplication::font());
- fonts[1].setItalic(true); //fuzzy
-
- fonts[2].setBold(true); //modified
-
- fonts[3].setItalic(true); //fuzzy
- fonts[3].setBold(true); //modified
-
- m_fonts.reserve(4);
- for(int i=0;i<4;i++) m_fonts<<fonts.at(i);
- }
- connect(catalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(reflectChanges(DocPosition)));
- connect(catalog,SIGNAL(signalFileLoaded()),this,SLOT(fileLoaded()));
-}
-
-QModelIndex CatalogTreeModel::index(int row,int column,const QModelIndex& /*parent*/) const
-{
- return createIndex(row, column);
-}
-
-QModelIndex CatalogTreeModel::parent(const QModelIndex& /*index*/) const
-{
- return QModelIndex();
-}
-
-int CatalogTreeModel::columnCount(const QModelIndex& parent) const
-{
- Q_UNUSED(parent);
- return DisplayedColumnCount;
-}
-
-void CatalogTreeModel::fileLoaded()
-{
- reset();
-}
-
-void CatalogTreeModel::reflectChanges(DocPosition pos)
-{
- emit dataChanged(index(pos.entry,0),index(pos.entry,DisplayedColumnCount-1));
-
-#if 0
- I disabled dynamicSortFilter function
- //lazy sorting/filtering
- if (rowCount()<DYNAMICFILTER_LIMIT || m_prevChanged!=pos)
- {
- kWarning()<<"first dataChanged emitment"<<pos.entry;
- emit dataChanged(index(pos.entry,0),index(pos.entry,DisplayedColumnCount-1));
- if (!( rowCount()<DYNAMICFILTER_LIMIT ))
- {
- kWarning()<<"second dataChanged emitment"<<m_prevChanged.entry;
- emit dataChanged(index(m_prevChanged.entry,0),index(m_prevChanged.entry,DisplayedColumnCount-1));
- }
- }
- m_prevChanged=pos;
-#endif
-}
-
-int CatalogTreeModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return m_catalog->numberOfEntries();
-}
-
-QVariant CatalogTreeModel::headerData(int section, Qt::Orientation /*orientation*/, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- case Key: return i18nc("@title:column","Entry");
- case Source: return i18nc("@title:column Original text","Source");
- case Target: return i18nc("@title:column Text in target language","Target");
- case Notes: return i18nc("@title:column","Notes");
- case TranslationStatus: return i18nc("@title:column","Translation Status");
- }
- return QVariant();
-}
-
-QVariant CatalogTreeModel::data(const QModelIndex& index, int role) const
-{
- if (m_catalog->numberOfEntries()<=index.row() )
- return QVariant();
-
- if (role==Qt::SizeHintRole)
- {
- //no need to cache because of uniform row heights
- return QFontMetrics(QApplication::font()).size(Qt::TextSingleLine, QString::fromLatin1(" "));
- }
- else if (role==Qt::FontRole/* && index.column()==Target*/)
- {
- bool fuzzy=!m_catalog->isApproved(index.row());
- bool modified=m_catalog->isModified(index.row());
- return m_fonts.at(fuzzy*1 | modified*2);
- }
- else if (role==Qt::ForegroundRole)
- {
- if (m_catalog->isBookmarked(index.row()))
- {
- static KColorScheme colorScheme(QPalette::Normal);
- return colorScheme.foreground(KColorScheme::LinkText);
- }
- if (m_catalog->isObsolete(index.row()))
- {
- static KColorScheme colorScheme(QPalette::Normal);
- return colorScheme.foreground(KColorScheme::InactiveText);
- }
- }
- else if (role==Qt::UserRole)
- {
- switch (index.column())
- {
- case TranslationStatus: return m_catalog->isApproved(index.row());
- case Empty: return m_catalog->isEmpty(index.row());
- case State: return int(m_catalog->state(index.row()));
- case Modified: return m_catalog->isModified(index.row());
- default: role=Qt::DisplayRole;
- }
- }
- else if (role==StringFilterRole) //exclude UI strings
- {
- if (index.column()>Notes)
- return QVariant();
- else if (index.column()) //>Key
- {
- static const DocPosition::Part parts[]={DocPosition::Source, DocPosition::Target};
- QString str=m_catalog->catalogString(DocPosition(index.row(),parts[index.column()==Target])).string;
- return m_ignoreAccel?str.remove(Project::instance()->accel()):str;
- }
- role=Qt::DisplayRole;
- }
- if (role!=Qt::DisplayRole)
- return QVariant();
-
-
-
- switch (index.column())
- {
- case Key: return index.row()+1;
- case Source: return m_catalog->msgid(index.row());
- case Target: return m_catalog->msgstr(index.row());
- case Notes:
- {
- QString result;
- foreach(const Note ¬e, m_catalog->notes(index.row()))
- result+=note.content;
- return result;
- }
- case TranslationStatus:
- static QString statuses[]={i18nc("@info:status 'non-fuzzy' in gettext terminology","Ready"),
- i18nc("@info:status 'fuzzy' in gettext terminology","Needs review"),
- i18nc("@info:status","Untranslated")};
- if (m_catalog->isEmpty(index.row()))
- return statuses[2];
- return statuses[!m_catalog->isApproved(index.row())];
- }
- return QVariant();
-}
-
-CatalogTreeFilterModel::CatalogTreeFilterModel(QObject* parent)
- : QSortFilterProxyModel(parent)
- , m_filerOptions(AllStates)
- , m_individualRejectFilterEnable(false)
- , m_mergeCatalog(NULL)
-{
- setFilterKeyColumn(-1);
- setFilterCaseSensitivity(Qt::CaseInsensitive);
- setFilterRole(CatalogTreeModel::StringFilterRole);
- //setDynamicSortFilter(true);
-}
-
-void CatalogTreeFilterModel::setSourceModel(QAbstractItemModel* sourceModel)
-{
- QSortFilterProxyModel::setSourceModel(sourceModel);
- connect(sourceModel,SIGNAL(modelReset()),SLOT(setEntriesFilteredOut()));
- setEntriesFilteredOut(false);
-}
-
-void CatalogTreeFilterModel::setEntriesFilteredOut(bool filteredOut)
-{
- m_individualRejectFilter.fill(filteredOut, sourceModel()->rowCount());
- m_individualRejectFilterEnable=filteredOut;
- invalidateFilter();
-}
-
-void CatalogTreeFilterModel::setEntryFilteredOut(int entry, bool filteredOut)
-{
-// if (entry>=m_individualRejectFilter.size())
-// sourceModelReset();
- m_individualRejectFilter[entry]=filteredOut;
- m_individualRejectFilterEnable=true;
- invalidateFilter();
-}
-
-void CatalogTreeFilterModel::setFilerOptions(int o)
-{
- m_filerOptions=o;
- setFilterCaseSensitivity(o&CaseInsensitive?Qt::CaseInsensitive:Qt::CaseSensitive);
- static_cast<CatalogTreeModel*>(sourceModel())->setIgnoreAccel(o&IgnoreAccel);
- invalidateFilter();
-}
-
-bool CatalogTreeFilterModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-{
- int filerOptions=m_filerOptions;
- bool accepts=true;
- if (bool(filerOptions&Ready)!=bool(filerOptions&NotReady))
- {
- bool ready=sourceModel()->index(source_row,CatalogTreeModel::TranslationStatus,source_parent).data(Qt::UserRole).toBool();
- accepts=(ready==bool(filerOptions&Ready) || ready!=bool(filerOptions&NotReady));
- }
- if (accepts&&bool(filerOptions&NonEmpty)!=bool(filerOptions&Empty))
- {
- bool untr=sourceModel()->index(source_row,CatalogTreeModel::Empty,source_parent).data(Qt::UserRole).toBool();
- accepts=(untr==bool(filerOptions&Empty) || untr!=bool(filerOptions&NonEmpty));
- }
- if (accepts&&bool(filerOptions&Modified)!=bool(filerOptions&NonModified))
- {
- bool modified=sourceModel()->index(source_row,CatalogTreeModel::Modified,source_parent).data(Qt::UserRole).toBool();
- accepts=(modified==bool(filerOptions&Modified) || modified!=bool(filerOptions&NonModified));
- }
-
- // These are the possible sync options of a row:
- // * SameInSync: The sync file contains a row with the same msgid and the same msgstr.
- // * DifferentInSync: The sync file contains a row with the same msgid and different msgstr.
- // * NotInSync: The sync file does not contain any row with the same msgid.
- //
- // The code below takes care of filtering rows when any of those options is not checked.
- //
- const int mask=(SameInSync|DifferentInSync|NotInSync);
- if (accepts && m_mergeCatalog && (filerOptions&mask) && (filerOptions&mask)!=mask)
- {
- bool isPresent = m_mergeCatalog->isPresent(source_row);
- bool isDifferent = m_mergeCatalog->isDifferent(source_row);
-
- accepts = !
- ( isPresent && !isDifferent && !bool(filerOptions&SameInSync) ||
- isPresent && isDifferent && !bool(filerOptions&DifferentInSync) ||
- !isPresent && !bool(filerOptions&NotInSync)
- );
- }
-
- if (accepts && (filerOptions&STATES)!=STATES)
- {
- int state=sourceModel()->index(source_row,CatalogTreeModel::State,source_parent).data(Qt::UserRole).toInt();
- accepts=(filerOptions&(1<<(state+FIRSTSTATEPOSITION)));
- }
-
- accepts=accepts&&!(m_individualRejectFilterEnable && source_row<m_individualRejectFilter.size() && m_individualRejectFilter.at(source_row));
-
- return accepts&&QSortFilterProxyModel::filterAcceptsRow(source_row,source_parent);
-}
-
-void CatalogTreeFilterModel::setMergeCatalogPointer(MergeCatalog* pointer)
-{
- m_mergeCatalog = pointer;
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef CATALOGMODEL_H
-#define CATALOGMODEL_H
-
-#include "mergecatalog.h"
-#include "pos.h"
-
-#include <QAbstractItemModel>
-#include <QSortFilterProxyModel>
-#include <QVector>
-
-class Catalog;
-
-
-
-/**
- * MVC wrapper for Catalog
- */
-class CatalogTreeModel: public QAbstractItemModel
-{
-Q_OBJECT
-public:
-
- enum CatalogModelColumns
- {
- Key=0,
- Source,
- Target,
- Notes,
- TranslationStatus,
- Empty,
- State,
- Modified,
- ColumnCount,
- DisplayedColumnCount=TranslationStatus+1
- };
-
- enum Roles
- {
- StringFilterRole=Qt::UserRole+1
- };
-
- CatalogTreeModel(QObject* parent, Catalog* catalog);
- ~CatalogTreeModel(){}
-
- QModelIndex index (int row, int column, const QModelIndex& parent=QModelIndex())const;
- QModelIndex parent(const QModelIndex&) const;
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const;
- QVariant data(const QModelIndex&,int role=Qt::DisplayRole) const;
- QVariant headerData(int section,Qt::Orientation, int role=Qt::DisplayRole) const;
-
- Catalog* catalog()const{return m_catalog;}
-
- void setIgnoreAccel(bool n){m_ignoreAccel=n;}
-
-public slots:
- void reflectChanges(DocPosition);
- void fileLoaded();
-private:
- Catalog* m_catalog;
- bool m_ignoreAccel;
-
- static QVector<QVariant> m_fonts;
- //DocPos m_prevChanged;
-};
-
-
-
-
-
-
-
-
-class CatalogTreeFilterModel: public QSortFilterProxyModel
-{
-Q_OBJECT
-public:
- enum FilterOptions
- {
- CaseInsensitive=1<<0,
- IgnoreAccel=1<<1,
-
- Ready=1<<2,
- NotReady=1<<3,
- NonEmpty=1<<4,
- Empty=1<<5,
- Modified=1<<6,
- NonModified=1<<7,
- SameInSync=1<<8,
- DifferentInSync=1<<9,
- NotInSync=1<<10,
-
- //states (see defines below)
- New=1<<11,
- NeedsTranslation=1<<12,
- NeedsL10n=1<<13,
- NeedsAdaptation=1<<14,
- Translated=1<<15,
- NeedsReviewTranslation=1<<16,
- NeedsReviewL10n=1<<17,
- NeedsReviewAdaptation=1<<18,
- Final=1<<19,
- SignedOff=1<<20,
- MaxOption=1<<21,
- AllStates=MaxOption-1
- };
-
-#define STATES ((0xffff<<11)&(AllStates))
-#define FIRSTSTATEPOSITION 11
-
-
- CatalogTreeFilterModel(QObject* parent);
- ~CatalogTreeFilterModel(){}
-
- bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-
- void setFilerOptions(int o);
- int filerOptions()const{return m_filerOptions;}
-
- void setSourceModel(QAbstractItemModel* sourceModel);
-
- bool individualRejectFilterEnabled(){return m_individualRejectFilterEnable;}
- void setEntryFilteredOut(int entry, bool filteredOut);
-
- void setMergeCatalogPointer(MergeCatalog* pointer);
-
-public slots:
- void setEntriesFilteredOut(bool filteredOut=false);
-
-private:
- int m_filerOptions;
- bool m_individualRejectFilterEnable;
- QVector<bool> m_individualRejectFilter;
- MergeCatalog* m_mergeCatalog;
-};
-
-
-
-
-#endif
+++ /dev/null
-/* **************************************************************************
- This file is part of Lokalize
-
- wordDiff algorithm adoption and further refinement:
- 2007 (C) Nick Shaforostoff <shafff@ukr.net>
- (based on Markus Stengel's GPL implementation of LCS-Delta algorithm as it is described in "Introduction to Algorithms", MIT Press, 2001, Second Edition, written by Thomas H. Cormen et. al. It uses dynamic programming to solve the Longest Common Subsequence (LCS) problem. - http://www.markusstengel.de/text/en/i_4_1_5_3.html)
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-************************************************************************** */
-
-#include "diff.h"
-
-// #include "project.h"
-#include "prefs_lokalize.h"
-
-#include <QVector>
-#include <QStringList>
-#include <QLinkedList>
-
-#include <kdebug.h>
-
-
-typedef enum
-{
- NOTHING = 0,
- ARROW_UP = 1,
- ARROW_LEFT = 2,
- ARROW_UP_LEFT = 3,
- FINAL = 4
-} LCSMarker;
-
-static QString addMarkerStart="<KBABELADD>";
-static QString addMarkerEnd="</KBABELADD>";
-static QString delMarkerStart="<KBABELDEL>";
-static QString delMarkerEnd="</KBABELDEL>";
-
-QStringList calcLCS(const QStringList& s1Words,
- const QStringList& s2Words,
- const QStringList& s1Space,
- const QStringList& s2Space
- );
-
-
-/**
- * The class is used for keeping "global" params of recursive function
- *
- * @short Class for keeping "global" params of recursive function
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
- class LCSprinter
-{
- public:
- LCSprinter(const QStringList &s_1,
- const QStringList& s_2,
- QVector<LCSMarker> *b_,
- const uint nT_,
- uint index,
- const QStringList& s1Space_,
- const QStringList& s2Space_
- );
- ~LCSprinter() {};
- void printLCS(uint index);
- inline QStringList operator()();
-
- private:
- QStringList s1, s2;
- QLinkedList<QString> resultString;
- QStringList s1Space, s2Space;
- QStringList::const_iterator it1, it2;
- QStringList::const_iterator it1Space, it2Space;
- uint nT:31;//we're using 1d vector as 2d
- bool haveSpaces:1;//"word: sfdfs" space is ": "
- QVector<LCSMarker> *b;
- //QStringList::iterator it1Space, it2Space;
-};
-
-inline
-QStringList LCSprinter::operator()()
-{
- QStringList result;
- foreach(const QString& str, resultString)
- result<<str;
-
- return result;
-}
-
-
-inline
-LCSprinter::LCSprinter(const QStringList& s_1,
- const QStringList& s_2,
- QVector<LCSMarker> *b_,
- const uint nT_,
- uint index,
- const QStringList& s1Space_,
- const QStringList& s2Space_
- )
- : s1(s_1)
- , s2(s_2)
- , s1Space(s1Space_)
- , s2Space(s2Space_)
- , it1(s1.constBegin())
- , it2(s2.constBegin())
- , it1Space(s1Space.constBegin())
- , it2Space(s2Space.constBegin())
- , nT(nT_)
- , b(b_)
-
-{
- haveSpaces=!s1Space_.isEmpty();
- printLCS(index);
-}
-
-
-static QStringList prepareForInternalDiff(const QString& str)
-{
- QStringList result;
- int i=str.size();
- while(--i>=0)
- result.prepend(QString(str.at(i)));
- result.prepend(QString());
- return result;
-}
-
-void LCSprinter::printLCS(uint index)
-{
- //fprintf(stderr,"%2d. %2d. %2d. %2d\n",(uint)(*b)[index],nT,index%nT, index);
- if (index % nT == 0 || index < nT)
- {
- // original LCS algo does not have to deal with ins before first common
- uint bound = index%nT;
- for (index=0; index<bound; ++index)
- {
- resultString.append(addMarkerStart);
- resultString.append(*it2);
- ++it2;
- if (haveSpaces)
- {
- resultString.append(*it2Space);
- ++it2Space;
- }
- resultString.append(addMarkerEnd);
- }
-
- return;
- }
-
- if (ARROW_UP_LEFT == b->at(index))
- {
- printLCS(index-nT-1);
- if (it1!=s1.constEnd())
- {
- //kWarning() << "upleft '" << *it1 <<"'";
- //kWarning() << "upleft 1s" << *it1Space;
- //kWarning() << "upleft 2s" << *it2Space;
- if (haveSpaces)
- {
- if((*it1)==(*it2))//case and accels
- resultString.append(*it1);
- else
- {
- QStringList word1=prepareForInternalDiff(*it1);
- QStringList word2=prepareForInternalDiff(*it2);
-
- QStringList empty;
- resultString.append(calcLCS(word1,word2,empty,empty).join(QString()));
- }
-
- if((*it1Space)==(*it2Space))
- resultString.append(*it1Space);
- else
- {
- QStringList word1=prepareForInternalDiff(*it1Space);
- QStringList word2=prepareForInternalDiff(*it2Space);
-
- QStringList empty;
- //empty=calcLCS(word1,word2,empty,empty);
-//???this is not really good if we use diff result in autosubst
-
- empty=calcLCS(word2,word1,empty,empty);
- empty.replaceInStrings("KBABELADD>","KBABELTMP>");
- empty.replaceInStrings("KBABELDEL>","KBABELADD>");
- empty.replaceInStrings("KBABELTMP>","KBABELDEL>");
-
- resultString.append(empty.join(QString()));
- }
- ++it1Space;
- ++it2Space;
- //kWarning() << " common " << *it1;
- }
- else
- resultString.append(*it1);//we may guess that this is a batch job, i.e. TM search
- ++it1;
- ++it2;
- }
- }
- else if (ARROW_UP == b->at(index))
- {
- printLCS(index-nT);
-// if (it1!=s1.end())
- {
- //kWarning()<<"APPENDDEL "<<*it1;
- //kWarning()<<"APPENDDEL "<<*it1Space;
- resultString.append(delMarkerStart);
- resultString.append(*it1);
- ++it1;
- if (haveSpaces)
- {
- resultString.append(*it1Space);
- ++it1Space;
- }
- resultString.append(delMarkerEnd);
- }
- }
- else
- {
- printLCS(index-1);
- resultString.append(addMarkerStart);
- resultString.append(*it2);
- ++it2;
- if (haveSpaces)
- {
- //kWarning() << "add2 " << *it2;
- resultString.append(*it2Space);
- ++it2Space;
- }
- resultString.append(addMarkerEnd);
- }
-}
-
-
-
-
-// calculate the LCS
-QStringList calcLCS(const QStringList& s1Words,
- const QStringList& s2Words,
- const QStringList& s1Space,
- const QStringList& s2Space
- )
-{
-
- uint i;
- uint j;
-
- uint mX = s1Words.count();
- uint nY = s2Words.count();
-
- //create lowered lists for matching,
- //and use original ones for printing (but only for non-batch)
- QStringList s1(s1Words);
- QStringList s2(s2Words);
-
- if (!s1Space.isEmpty())
- {
- //accels are only removed by batch jobs
- //and this is not the one
- //also, lower things a bit :)
-
- for (i=0;i<mX;++i)
- s1[i]=s1.at(i).toLower();
- for (i=0;i<nY;++i)
- s2[i]=s2.at(i).toLower();
-#if 0 //i'm too lazy...
- QString accel(Project::instance()->accel());
- i=mX;
- while(--i>0)
- {
- if ((s1Space.at(i)==accel))
- {
- s1[i]+=s1[i+1];
- s1.removeAt(i+1);
- s1Space.removeAt(i);
- s1Words[i]+=s1[i+1];
- s1Words.removeAt(i+1);
- --mX;
- --nY;
- }
- }
-#endif
- }
-
-
- uint mT = mX+1;
- uint nT = nY+1;
-
- QVector<LCSMarker> b(mT*nT, NOTHING);
- QVector<uint> c(mT*nT, 0);
-
-
-
- b[0] = FINAL;
- uint index_cache = 0;
- QStringList::const_iterator it1, it2;
-
- for (i=1, it1 = s1.constBegin(); i<mT; ++i, ++it1)
- {
- for (j=1, it2 = s2.constBegin(); j<nT; ++j, ++it2)
- {
- index_cache = i*nT+j;
- if ((*it1)==(*it2))
- {
- c[index_cache] = c.at(index_cache-nT-1) + 1;
- b[index_cache] = ARROW_UP_LEFT;
- }
- else if (c.at(index_cache-nT) >= c.at(index_cache-1))
- {
- c[index_cache] = c.at(index_cache-nT);
- b[index_cache] = ARROW_UP;
- }
- else
- {
- c[index_cache] = c.at(index_cache-1);
- b[index_cache] = ARROW_LEFT;
- }
- }
- }
-
- c.clear();
-
- LCSprinter printer(s1Words, s2Words, &b, nT, index_cache, s1Space, s2Space);
-
- return printer();
-
-}
-
-QString wordDiff(QStringList s1, QStringList s2)
-{
- static QString space(" ");
- s1.prepend(space);
- s2.prepend(space);
-
- static QStringList empty;
- QStringList list=calcLCS(s1,s2,empty,empty);
- bool r=list.first()==" ";
- if (r)
- list.removeFirst();
- else
- qDebug()<<"first ' ' assumption is wrong"<<list.first();
-
- QString result=list.join(QString());
-
-
- if (!r)
- result.remove(0,1);
- result.remove("</KBABELADD><KBABELADD>");
- result.remove("</KBABELDEL><KBABELDEL>");
-
- return result;
-}
-
-
-//this also separates punctuation marks etc from words as _only_ they may have changed
-static void prepareLists(QString str, QStringList& main, QStringList& space, const QString& accel, QString markup)
-{
- Q_UNUSED(accel);
- int pos=0;
-
- //accels are only removed by batch jobs
- //and this is not the one
-#if 0
- QRegExp rxAccelInWord("[^\\W|\\d]"+accel+"[^\\W|\\d]");
- int accelLen=accel.size();
- while ((pos=rxAccelInWord.indexIn(str,pos))!=-1)
- {
- str.remove(rxAccelInWord.pos()+1,accelLen);
- pos+=2;//two letters
- }
-#endif
-
- //QRegExp rxSplit("\\W+|\\d+");
- //i tried that but it failed:
- if (!markup.isEmpty())
- markup+='|';
- QRegExp rxSplit('(' + markup + "\\W+|\\d+)+");
-
- main=str.split(rxSplit,QString::SkipEmptyParts);
- main.prepend("\t");//little hack
-
-
- //ensure the string always begins with the space part
- str.prepend('\b');
- pos=0;
- while ((pos=rxSplit.indexIn(str,pos))!=-1)
- {
- space.append(rxSplit.cap(0));
- pos+=rxSplit.matchedLength();
- }
- space.append(QString());//so we don't have to worry about list boundaries
- space.append(QString());//so we don't have to worry about list boundaries
-}
-
-QString userVisibleWordDiff(const QString& str1ForMatching,
- const QString& str2ForMatching,
- const QString& accel,
- const QString& markup,
- int options)
-{
- QStringList s1, s2;
- QStringList s1Space, s2Space;
-
-
- prepareLists(str1ForMatching, s1, s1Space, accel, markup);
- prepareLists(str2ForMatching, s2, s2Space, accel, markup);
-
- //QRegExp rxSpace("[^(\\W+|\\d+)]");
- //i tried that but it failed:
- //QRegExp rxSpace("[^("+Project::instance()->markup()+"|\\W+|\\d+)]");
- //QStringList s1Space(str1ForMatching.split(rxSpace,QString::SkipEmptyParts));
- //QStringList s2Space(str2ForMatching.split(rxSpace,QString::SkipEmptyParts));
-
-
- QStringList result(calcLCS(s1,s2,s1Space,s2Space));
- result.removeFirst();//\t
- result.first().remove(0,1);//\b
-// kWarning()<<"wordDiff 1 '" <<result<<"'";
- result.replaceInStrings("<KBABELDEL></KBABELDEL>","");
- result.replaceInStrings("<KBABELADD></KBABELADD>","");
-
- result.replaceInStrings("<KBABELADD>","{KBABELADD}");
- result.replaceInStrings("</KBABELADD>","{/KBABELADD}");
- result.replaceInStrings("<KBABELDEL>","{KBABELDEL}");
- result.replaceInStrings("</KBABELDEL>","{/KBABELDEL}");
-
- if (options&Html)
- {
- result.replaceInStrings("&","&");
- result.replaceInStrings("<","<");
- result.replaceInStrings(">",">");
- }
-
- //result.last().chop(1);//\b
- //kWarning()<<"DIFF RESULT '" <<result<<"' '"<<result<<"'";
-
- QString res(result.join(QString()));
- res.remove("{/KBABELADD}{KBABELADD}");
- res.remove("{/KBABELDEL}{KBABELDEL}");
-
- if (options&Html)
- {
- res.replace("{KBABELADD}","<font style=\"background-color:" + Settings::addColor().name() + ";color:black\">");
- res.replace("{/KBABELADD}","</font>");
- res.replace("{KBABELDEL}","<font style=\"background-color:" + Settings::delColor().name() + ";color:black\">");
- res.replace("{/KBABELDEL}","</font>");
- res.replace("\\n","\\n<br>");
- }
-
- return res;
-}
-
+++ /dev/null
-/* **************************************************************************
- This file is part of Lokalize
-
- wordDiff algorithm adoption and further refinement:
- 2007 (C) Nick Shaforostoff <shafff@ukr.net>
- (based on Markus Stengel's GPL implementation of LCS-Delta algorithm as it is described in "Introduction to Algorithms", MIT Press, 2001, Second Edition, written by Thomas H. Cormen et. al. It uses dynamic programming to solve the Longest Common Subsequence (LCS) problem. - http://www.markusstengel.de/text/en/i_4_1_5_3.html)
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-************************************************************************** */
-#ifndef DIFF_H
-#define DIFF_H
-
-#include <QString>
-
-
-/**
- * @short Word-by-word diff algorithm
- *
- * Word-by-word diff algorithm
- *
- * Based on Markus Stengel's GPLv2+ implementation of LCS-Delta algorithm
- * as it is described in "Introduction to Algorithms", MIT Press, 2001, Second Edition, written by Thomas H. Cormen et. al.
- * It uses dynamic programming to solve the Longest Common Subsequence (LCS) problem.
- * http://www.markusstengel.de/text/en/i_4_1_5_3.html)
- *
- * This is high-level wrapper
- *
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-enum {Html=1};
-QString userVisibleWordDiff(const QString& oldString,
- const QString& newString,
- const QString& accelRx,
- const QString& markupRx,
- int options=0);
-
-
-
-/**
- * This is low-level wrapper used for evaluating translation memory search results
- *
- * You have to explicitly prepend lists with identical strings
- */
-QString wordDiff(QStringList s1, QStringList s2);
-
-
-#endif // DIFF_H
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "domroutines.h"
-
-void setText(QDomElement element, QString text)
-{
- QDomNodeList children=element.childNodes();
- for (int i=0;i<children.count();i++)
- {
- if (children.at(i).isCharacterData())
- {
- children.at(i).toCharacterData().setData(text);
- text.clear();
- }
- }
-
- if (!text.isEmpty())
- element.appendChild( element.ownerDocument().createTextNode(text));
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef DOMROUTINES_H
-#define DOMROUTINES_H
-#include <QtXml/qdom.h>
-
-void setText(QDomElement element, QString text);
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#include "fastsizehintitemdelegate.h"
-
-#include <QPainter>
-#include <QTextDocument>
-
-FastSizeHintItemDelegate::FastSizeHintItemDelegate(QObject *parent, const QVector<bool>& slc, const QVector<bool>& rtc)
- : QItemDelegate(parent)
- , singleLineColumns(slc)
- , richTextColumns(rtc)
- , activeScheme(QPalette::Active, KColorScheme::View)
-{}
-
-void FastSizeHintItemDelegate::reset()
-{
- cache.clear();
-}
-
-QSize FastSizeHintItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
-{
- int lineCount=1;
- int nPos=20;
- if (!singleLineColumns.at(index.column()))
- {
- QString text=index.data().toString();
- nPos=text.indexOf('\n');
- if (nPos==-1)
- nPos=text.size();
- else
- lineCount+=text.count('\n');
- }
- static QFontMetrics metrics(option.font);
- return QSize(metrics.averageCharWidth()*nPos, metrics.height()*lineCount);
-}
-
-void FastSizeHintItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
-{
- painter->save();
-
- const KColorScheme& scheme=activeScheme;
- //painter->save();
- painter->setClipping(true);
- painter->setClipRect(option.rect);
- QBrush bgBrush;
- if (option.state&QStyle::State_MouseOver)
- bgBrush=scheme.background(KColorScheme::LinkBackground);
- else if (index.row()%2)
- bgBrush=scheme.background(KColorScheme::AlternateBackground);
- else
- bgBrush=scheme.background(KColorScheme::NormalBackground);
-
- painter->fillRect(option.rect, bgBrush);
- painter->setClipRect(option.rect.adjusted(0,0,-2,0));
- //painter->setFont(option.font);
-
- RowColumnUnion rc;
- rc.index.row=index.row();
- rc.index.column=index.column();
- //TMDBModel* m=static_cast<const TMDBModel*>(index.model());
- if (!cache.contains(rc.v))
- {
- QString text=index.data(FastSizeHintItemDelegate::HtmlDisplayRole).toString();
- cache.insert(rc.v, new QStaticText(text));
- cache.object(rc.v)->setTextFormat(richTextColumns.at(index.column())?Qt::RichText:Qt::PlainText);
- }
- int rectWidth=option.rect.width();
- QStaticText* staticText=cache.object(rc.v);
- //staticText->setTextWidth(rectWidth-4);
- QPoint textStartPoint=option.rect.topLeft();
- textStartPoint.rx()+=2;
- painter->drawStaticText(textStartPoint, *staticText);
-
-
- if (staticText->size().width()<=rectWidth-4)
- {
- painter->restore();
- return;
- }
-
- painter->setPen(bgBrush.color());
- QPoint p1=option.rect.topRight();
- QPoint p2=option.rect.bottomRight();
- int limit=qMin(8, rectWidth-2);
- int i=limit;
- while(--i>0)
- {
- painter->setOpacity(float(i)/limit);
- painter->drawLine(p1, p2);
- p1.rx()--;
- p2.rx()--;
- }
- painter->restore();
-}
-
-QString convertToHtml(QString str, bool italics)
-{
-/*
- if (str.isEmpty())
- return str;
-*/
-
- str=Qt::convertFromPlainText(str); //FIXME use another routine (this has bugs)
-
- if (italics)
- str="<p><i>" + QString::fromRawData(str.unicode()+3, str.length()-3-4) + "</i></p>";
-
- return str;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef FASTSIZEHINTITEMDELEGATE_H
-#define FASTSIZEHINTITEMDELEGATE_H
-
-#include <QItemDelegate>
-#include <QStaticText>
-#include <QCache>
-
-#include <KColorScheme>
-
-QString convertToHtml(QString string, bool italics=false);
-
-/**
- * remember to connect appropriate signals to reset slot
- * for delegate to have actual cache
- *
- * @author Nick Shaforostoff
- */
-class FastSizeHintItemDelegate: public QItemDelegate
-{
- Q_OBJECT
-
-public:
- enum Roles
- {
- HtmlDisplayRole=Qt::UserRole+5
- };
-
- FastSizeHintItemDelegate(QObject *parent, const QVector<bool>& slc, const QVector<bool>& rtc);
- ~FastSizeHintItemDelegate(){}
-
- void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const;
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-
-public slots:
- void reset();
-
-private:
- QVector<bool> singleLineColumns;
- QVector<bool> richTextColumns;
-
- struct RowColumn
- {
- short row:16;
- short column:16;
- };
- union RowColumnUnion
- {
- RowColumn index;
- int v;
- };
- mutable QCache<int, QStaticText> cache;
-
- KColorScheme activeScheme;
-};
-#endif // FASTSIZEHINTITEMDELEGATE_H
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of KAider
-
- Copyright (C) 2007 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "flowlayout.h"
-#include "termlabel.h"
-//#include "project.h"
-
-// #include <klocale.h>
-#include <kdebug.h>
-#include <kaction.h>
-
-using namespace GlossaryNS;
-
-FlowLayout::FlowLayout(User user,
- QWidget *signalingWidget,
- const QVector<KAction*>& actions,
- int margin,
- int spacing)
- : QLayout()
- , m_index(0)
- , m_receiver(signalingWidget)
-{
- setSizeConstraint(QLayout::SetMinAndMaxSize);
- setMargin(margin);
- setSpacing(spacing);
-
- if (user==glossary)
- {
- foreach (KAction* action, actions)
- {
- TermLabel* label=new TermLabel(action); /*this,m_keys.at(count())*/
- connect(action,SIGNAL(triggered(bool)),label,SLOT(insert()));
- connect(label,SIGNAL(insertTerm(QString)),m_receiver,SIGNAL(termInsertRequested(QString)));
- label->hide();
- addWidget(label);
- }
- }
-
-// if (m_keys.isEmpty())
-// {
-// // Qt::Key key=Qt::Key_A;
-// // for (;key<=Qt::Key_Z;++key)
-// // {
-// // if (KGlobalAccel::findActionNameSystemwide(Qt::ALT+key).isEmpty())
-// // {
-// // keys.append(key);
-// // }
-// // }
-// int i=(int)Qt::Key_A;
-// for (;i<=(int)Qt::Key_Z;++i)
-// {
-// if (KGlobalAccel::findActionNameSystemwide(Qt::ALT+Qt::CTRL+(Qt::Key)i).isEmpty())
-// {
-// m_keys.append((Qt::Key)i);
-// }
-// }
-//
-// }
-
-}
-
-
-FlowLayout::~FlowLayout()
-{
- QLayoutItem *item;
- while ((item = takeAt(0)))
- delete item;
-}
-
-QLayoutItem *FlowLayout::takeAt(int index)
-{
- if (index >= 0 && index < itemList.size())
- return itemList.takeAt(index);
- else
- return 0;
-}
-
-QLayoutItem *FlowLayout::itemAt(int index) const
-{
- return itemList.value(index);
-}
-
-void FlowLayout::addItem(QLayoutItem *item) {itemList.append(item);}
-int FlowLayout::count() const {return itemList.size();}
-Qt::Orientations FlowLayout::expandingDirections() const {return 0;}
-bool FlowLayout::hasHeightForWidth() const {return true;}
-
-int FlowLayout::heightForWidth(int width) const
-{
- int height = doLayout(QRect(0, 0, width, 0), true);
- return height;
-}
-
-void FlowLayout::setGeometry(const QRect &rect)
-{
- QLayout::setGeometry(rect);
- doLayout(rect, false);
-}
-
-QSize FlowLayout::sizeHint() const
-{
- return minimumSize();
-}
-
-QSize FlowLayout::minimumSize() const
-{
- QSize size;
- foreach (QLayoutItem* item, itemList)
- size = size.expandedTo(item->minimumSize());
-
- size += QSize(2*margin(), 2*margin());
- return size;
-}
-
-int FlowLayout::doLayout(const QRect &rect, bool testOnly) const
-{
- int x = rect.x();
- int y = rect.y();
- int lineHeight = 0;
-
- foreach (QLayoutItem* item, itemList)
- {
- int nextX = x + item->sizeHint().width() + spacing();
- if (nextX - spacing() > rect.right() && lineHeight > 0)
- {
- x = rect.x();
- y = y + lineHeight + spacing();
- nextX = x + item->sizeHint().width() + spacing();
- lineHeight = 0;
- }
-
- if (!testOnly)
- item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
-
- x = nextX;
- lineHeight = qMax(lineHeight, item->sizeHint().height());
- }
- return y + lineHeight - rect.y();
-}
-
-void FlowLayout::clearTerms()
-{
- setEnabled(false);
- foreach (QLayoutItem* item, itemList)
- static_cast<TermLabel*>(item->widget())->hide();
- m_index=0;
- setEnabled(true);
-}
-
-void FlowLayout::addTerm(const QString& term, const QByteArray& entryId, bool capFirst)
-{
- //fill layout with labels
- while (m_index>=count())
- {
- TermLabel* label=new TermLabel;
- connect(label,SIGNAL(insertTerm(QString)),m_receiver,SIGNAL(termInsertRequested(QString)));
- addWidget(label);
- }
- TermLabel* label=static_cast<TermLabel*>(itemAt(m_index)->widget());
- label->setText(term, entryId, capFirst);
- label->show();
- ++m_index;
-}
-
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-#ifndef FLOWLAYOUT_H
-#define FLOWLAYOUT_H
-
-#include "glossary.h"
-
-#include <QLayout>
-#include <QVector>
-class KAction;
-
-/**
- * used in glossary
- *
- * copied from 'pretty' docs
- */
-class FlowLayout: public QLayout
-{
-public:
-
- enum User
- {
- glossary,
- standard
- };
-
- /**
- * c'tor for glossary view
- */
- FlowLayout(User user=standard, QWidget *signalingWidget = 0,
- const QVector<KAction*>& actions=QVector<KAction*>(), int margin = 0, int spacing = -1);
-
- ~FlowLayout();
-
- void addItem(QLayoutItem *item);
- Qt::Orientations expandingDirections() const;
- bool hasHeightForWidth() const;
- int heightForWidth(int) const;
- int count() const;
- QLayoutItem *itemAt(int index) const;
- QSize minimumSize() const;
- void setGeometry(const QRect &rect);
- QSize sizeHint() const;
- QLayoutItem *takeAt(int index);
-
- /**
- * @param term is the term matched
- * @param entry is index of entry in the Glossary list
- */
- void addTerm(const QString& term, const QByteArray& entryId, bool capFirst=false);
- void clearTerms();
-
-private:
- int doLayout(const QRect &rect, bool testOnly) const;
-
- QList<QLayoutItem *> itemList;
- int m_index; //of the nearest free label ; or the next index of btn
- QWidget *m_receiver;
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "languagelistmodel.h"
-#include <kglobal.h>
-#include <kdebug.h>
-#include <kstandarddirs.h>
-#include <kiconloader.h>
-#include <kicon.h>
-#include <klocale.h>
-
-#include <QCoreApplication>
-#include <QSortFilterProxyModel>
-
-
-
-LanguageListModel* LanguageListModel::_instance=0;
-LanguageListModel* LanguageListModel::_emptyLangInstance=0;
-void LanguageListModel::cleanupLanguageListModel()
-{
- delete LanguageListModel::_instance; LanguageListModel::_instance = 0;
- delete LanguageListModel::_emptyLangInstance; LanguageListModel::_emptyLangInstance = 0;
-}
-
-LanguageListModel* LanguageListModel::instance()
-{
- if (_instance==0 )
- {
- _instance=new LanguageListModel();
- qAddPostRoutine(LanguageListModel::cleanupLanguageListModel);
- }
- return _instance;
-}
-
-LanguageListModel* LanguageListModel::emptyLangInstance()
-{
- if (_emptyLangInstance==0 )
- _emptyLangInstance=new LanguageListModel(EmptyLang);
- return _emptyLangInstance;
-}
-
-
-LanguageListModel::LanguageListModel(ModelType type, QObject* parent)
- : QStringListModel(KGlobal::locale()->allLanguagesList(),parent)
- , m_sortModel(new QSortFilterProxyModel(this))
-{
- if (type==EmptyLang) insertRows(rowCount(), 1);
- KIconLoader::global()->addExtraDesktopThemes();
- //kWarning()<<KIconLoader::global()->hasContext(KIconLoader::International);
- //kDebug()<<KIconLoader::global()->queryIconsByContext(KIconLoader::NoGroup,KIconLoader::International);
- m_sortModel->setSourceModel(this);
- m_sortModel->sort(0);
-}
-
-QVariant LanguageListModel::data(const QModelIndex& index, int role) const
-{
- if (role==Qt::DecorationRole)
- {
- static QMap<QString,QVariant> iconCache;
-
- QString langCode=stringList().at(index.row());
- if (!iconCache.contains(langCode))
- {
- // NOTE workaround for QTBUG-9370 - it will be removed later
- QString code;
- if(langCode == "mn")
- code = "mn_MN";
- else if(langCode == "ne")
- code = "ne_NP";
- else
- code=QLocale(langCode).name();
- QString path;
- if (code.contains('_')) code=QString::fromRawData(code.unicode()+3, 2).toLower();
- if (code!="C")
- {
- static QString flagPath("l10n/%1/flag.png");
- path=KStandardDirs::locate("locale", flagPath.arg(code));
- }
- iconCache[langCode]=QIcon(path);
- }
- return iconCache.value(langCode);
- }
- else if (role==Qt::DisplayRole)
- {
- const QString& code=stringList().at(index.row());
- if (code.isEmpty()) return code;
- //kDebug()<<"languageCodeToName"<<code;
- return QVariant::fromValue<QString>(KGlobal::locale()->languageCodeToName(code)+" ("+code+")");
- }
- return QStringListModel::data(index, role);
-}
-
-QFlags< Qt::ItemFlag > LanguageListModel::flags(const QModelIndex& index) const
-{
- return QStringListModel::flags(index);
-}
-
-int LanguageListModel::sortModelRowForLangCode(const QString& langCode)
-{
- return m_sortModel->mapFromSource(index(stringList().indexOf(langCode))).row();
-}
-
-QString LanguageListModel::langCodeForSortModelRow(int row)
-{
- return stringList().at(m_sortModel->mapToSource(m_sortModel->index(row,0)).row());
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef LANGUAGELISTMODEL_H
-#define LANGUAGELISTMODEL_H
-
-#include <QStringListModel>
-#include <QSortFilterProxyModel>
-
-
-class LanguageListModel: public QStringListModel
-{
- enum ModelType
- {
- Default,
- EmptyLang
- };
-public:
- static LanguageListModel* instance();
- static LanguageListModel* emptyLangInstance();
-
-private:
- static LanguageListModel * _instance;
- static LanguageListModel * _emptyLangInstance;
- static void cleanupLanguageListModel();
-
- LanguageListModel(ModelType type=Default, QObject* parent=0);
- QSortFilterProxyModel* m_sortModel;
-
-public:
- QVariant data(const QModelIndex& index, int role) const;
- QFlags< Qt::ItemFlag > flags(const QModelIndex& index) const;
-
- QSortFilterProxyModel* sortModel() const{return m_sortModel;};
- int sortModelRowForLangCode(const QString&);
- QString langCodeForSortModelRow(int);
-};
-
-#endif // LANGUAGELISTMODEL_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "stemming.h"
-
-#include <QMap>
-#include <QFileInfo>
-#include <QMutex>
-#include <QtCore/qmutex.h>
-#include <QDebug>
-
-QString enhanceLangCode(const QString& langCode)
-{
- if (langCode.length()!=2)
- return langCode;
-
- return QLocale(langCode).name();
-}
-
-
-#ifdef HAVE_HUNSPELL
-#include <hunspell/hunspell.hxx>
-#include <QTextCodec>
-
-struct SpellerAndCodec
-{
- Hunspell* speller;
- QTextCodec* codec;
- SpellerAndCodec():speller(0){}
- SpellerAndCodec(const QString& langCode);
-};
-
-SpellerAndCodec::SpellerAndCodec(const QString& langCode)
-: speller(0)
-{
- QString dic=QString("/usr/share/myspell/dicts/%1.dic").arg(langCode);
- if (!QFileInfo(dic).exists())
- dic=QString("/usr/share/myspell/dicts/%1.dic").arg(enhanceLangCode(langCode));;
- if (QFileInfo(dic).exists())
- {
- speller = new Hunspell(QString("/usr/share/myspell/dicts/%1.aff").arg(langCode).toUtf8().constData(),dic.toUtf8().constData());
- codec=QTextCodec::codecForName(speller->get_dic_encoding());
- if (!codec)
- codec=QTextCodec::codecForLocale();
- }
-}
-
-static QMap<QString,SpellerAndCodec> hunspellers;
-
-#endif
-
-QString stem(const QString& langCode, const QString& word)
-{
- QString result=word;
-
-#ifdef HAVE_HUNSPELL
- static QMutex mutex;
- QMutexLocker locker(&mutex);
-
- if (!hunspellers.contains(langCode))
- {
- hunspellers.insert(langCode,SpellerAndCodec(langCode));
- }
-
- SpellerAndCodec sc(hunspellers.value(langCode));
- Hunspell* speller=sc.speller;
- if (!speller)
- return word;
-
- char** result1;
- char** result2;
- int n1 = speller->analyze(&result1, sc.codec->fromUnicode(word));
- int n2 = speller->stem(&result2, result1, n1);
-
- if (n2)
- result=sc.codec->toUnicode(result2[0]);
-
- speller->free_list(&result1, n1);
- speller->free_list(&result2, n2);
-#endif
-
- return result;
-}
-
-void cleanupSpellers()
-{
-#ifdef HAVE_HUNSPELL
- foreach(const SpellerAndCodec& sc, hunspellers)
- delete sc.speller;
-
-#endif
-}
-
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef STEMMING_H
-#define STEMMING_H
-
-#include <QString>
-
-QString enhanceLangCode(const QString& langCode); //it -> it_IT
-QString stem(const QString& langCode, const QString& word);
-void cleanupSpellers();
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "termlabel.h"
-#include "glossarywindow.h"
-
-#include <QEvent>
-#include <QMouseEvent>
-#include <QMenu>
-
-#include <klineedit.h>
-#include <kdialog.h>
-#include <kdebug.h>
-#include <klocale.h>
-#include <kaction.h>
-
-using namespace GlossaryNS;
-
-
-// TermLabel::TermLabel(QAction* action/*const QString& shortcutQWidget* parent,Qt::Key key,const QString& termTransl*/)
-// : m_action(action)
-// //: m_shortcut(shortcut)
-// // : QLabel(/*parent*/)
-// //, m_termTransl(termTransl)
-// {
-// // setFlat(true);
-// // grabShortcut(Qt::ALT+Qt::CTRL+key);
-// // kWarning() << "dsds " << grabShortcut(Qt::ALT+key);
-// }
-// //~TermLabel(){}
-// // bool TermLabel::event(QEvent *event)
-// // {
-// // if (event->type() != QEvent::Shortcut)
-// // return QLabel::event(event);
-// //
-// // // kWarning() << "dsds " << m_termTransl;
-// // emit insertTerm(m_termTransl);
-// // return true;
-// // }
-
-void TermLabel::insert()
-{
- GlossaryNS::Glossary* glossary=Project::instance()->glossary();
- if (m_entryId.isEmpty())
- return;
- QString termTrans;
- const QStringList& termTarget=glossary->terms(m_entryId, Project::instance()->targetLangCode());
- if( termTarget.count()>1)
- {
- QMenu menu;
-
- int limit=termTarget.count();
- menu.setActiveAction(menu.addAction(termTarget.at(0)));
- int i=1;
- for (;i<limit;++i)
- menu.addAction(termTarget.at(i));
-
- QAction* txt=menu.exec(mapToGlobal(QPoint(0,0)));
- if (!txt)
- return;
- termTrans=txt->text();
- }
- else if (termTarget.count() == 1)
- termTrans=termTarget.first();
-
- if (m_capFirst && !termTrans.isEmpty())
- termTrans[0]=termTrans.at(0).toUpper();
-
- emit insertTerm(termTrans);
-}
-
-void TermLabel::mousePressEvent (QMouseEvent* event)
-{
- if (event->button()==Qt::RightButton)
- {
- QMenu menu;
-
- menu.addAction(i18nc("@action:inmenu Edit term","Edit"));
-
- QAction* txt=menu.exec(event->globalPos());
- if (txt)
- {
- GlossaryNS::GlossaryWindow* glossaryWindow=Project::instance()->showGlossary();
- if (glossaryWindow)
- glossaryWindow->selectEntry(m_entryId);
- }
- }
- else
- insert();
-}
-
-void TermLabel::setText(const QString& term, const QByteArray& entryId, bool capFirst)
-{
- m_entryId=entryId;
- m_capFirst=capFirst;
- QLabel::setText(QString(term + QString(m_action?QString(" [" + m_action->shortcut().toString()+"] \n "):" \n ")//m_shortcut
- + Project::instance()->glossary()->terms(m_entryId, Project::instance()->targetLangCode()).join(" \n ")
- + " \n "));
-}
-
-
-#if 0
-void QueryResultBtn::insert()
-{
-// kWarning()<<"ins "<<text();
- emit insertText(m_text);
-}
-
-QueryResultBtn::QueryResultBtn(QAction* a)
- : QLabel()
- , m_action(a)
-{
- setWordWrap(true);
-// kWarning()<<"ctor";
- //connect(this,SIGNAL(clicked(bool)),this,SLOT(insert()));
-}
-
-void QueryResultBtn::mousePressEvent (QMouseEvent*/* event*/)
-{
- emit insertText(m_text);
-}
-
-#endif
-
-#include "moc_termlabel.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef TERMLABEL_H
-#define TERMLABEL_H
-
-#include <QLabel>
-#include <kaction.h>
-#include "glossary.h"
-#include "project.h"
-
-namespace GlossaryNS {
-/**
- * flowlayout item
- */
-class TermLabel: public QLabel//QPushButton
-{
- Q_OBJECT
-public:
- TermLabel(QAction* a=0): m_action(a){};
- ~TermLabel(){}
-
- /**
- * @param term is the term matched
- * @param entry is a whole entry
- */
- void setText(const QString& term, const QByteArray& entryId, bool capFirst);
- void mousePressEvent (QMouseEvent* /* event*/);
-
-public slots:
- void insert();
-// bool event(QEvent *event);
-signals:
- void insertTerm(const QString&);
-
-private:
- QByteArray m_entryId;
- bool m_capFirst;
- QAction* m_action; //used only for shortcut purposes
-};
-
-
-
-
-
-
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "completionstorage.h"
-#include "project.h"
-#include "prefs_lokalize.h"
-#include <QCoreApplication>
-
-
-
-CompletionStorage* CompletionStorage::_instance=0;
-void CompletionStorage::cleanupCompletionStorage()
-{
- delete CompletionStorage::_instance; CompletionStorage::_instance = 0;
-}
-
-CompletionStorage* CompletionStorage::instance()
-{
- if (_instance==0 )
- {
- _instance=new CompletionStorage();
- qAddPostRoutine(CompletionStorage::cleanupCompletionStorage);
- }
- return _instance;
-}
-
-
-void CompletionStorage::scanCatalog(Catalog* catalog)
-{
- QTime a;a.start();
-
- int wordCompletionLength=Settings::self()->wordCompletionLength();
- /* we can't skip the scanning because there might be explicit completion triggered
- if (wordCompletionLength<3 || !catalog->numberOfEntries())
- return;
- */
- wordCompletionLength+=3;//only long words
-
- QString accel=Project::instance()->accel();
-
- DocPosition pos(0);
- do
- {
- QString string=catalog->targetWithTags(pos).string;
- string.remove(accel);
-
- const QStringList& words=string.toLower().split(rxSplit,QString::SkipEmptyParts);
- foreach(const QString& word, words)
- {
- if (word.length()<wordCompletionLength)
- continue;
- m_words[word]++;
- }
- }
- while (switchNext(catalog,pos));
-
- kDebug()<<"indexed"<<catalog->url()<<"for word completion in"<<a.elapsed()<<"msecs";
-}
-
-QStringList CompletionStorage::makeCompletion(const QString& word) const
-{
- //QTime a;a.start();
- if (word.isEmpty())
- return QStringList();
- QMultiMap<int,QString> hits; //we use the fact that qmap sorts it's items by keys
- QString cleanWord=word.toLower();
- QMap<QString,int>::const_iterator it=m_words.lowerBound(cleanWord);
- while(it!=m_words.constEnd() && it.key().startsWith(cleanWord))
- {
- hits.insert(-it.value(),it.key().mid(word.length()));
- ++it;
- }
- //kDebug()<<"hits generated in"<<a.elapsed()<<"msecs";
- return hits.values();
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef COMPLETIONSTORAGE_H
-#define COMPLETIONSTORAGE_H
-#include <QMap>
-#include "catalog.h"
-
-class CompletionStorage
-{
-private:
- CompletionStorage():rxSplit("\\W+|\\d+"){};
- ~CompletionStorage(){};
- static CompletionStorage* _instance;
- static void cleanupCompletionStorage();
-public:
- static CompletionStorage* instance();
-
- void scanCatalog(Catalog*);
- QStringList makeCompletion(const QString&) const;
-
-public:
- QRegExp rxSplit;
-private:
- QMap<QString,int> m_words;//how many occurencies a word has
- //QSet save which files we scanned?
-};
-
-#endif // COMPLETIONSTORAGE_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "editortab.h"
-#include "actionproxy.h"
-#include "editorview.h"
-#include "catalog.h"
-#include "pos.h"
-#include "cmd.h"
-#include "prefs_lokalize.h"
-
-#include "completionstorage.h"
-
-//views
-#include "msgctxtview.h"
-#include "alttransview.h"
-#include "mergeview.h"
-#include "cataloglistview.h"
-#include "glossaryview.h"
-#include "tmview.h"
-#include "binunitsview.h"
-
-#include "phaseswindow.h"
-#include "projectlocal.h"
-#include "projectmodel.h"
-
-
-#include "project.h"
-#include "prefs.h"
-
-#include <kglobal.h>
-#include <klocale.h>
-#include <kicon.h>
-#include <ktoolbarpopupaction.h>
-#include <kstatusbar.h>
-#include <kdebug.h>
-
-#if QT_VERSION >= 0x040400
- #include <kfadewidgeteffect.h>
-#endif
-
-
-#include <kio/netaccess.h>
-#include <kaction.h>
-#include <kactioncollection.h>
-#include <kstandardaction.h>
-#include <kstandardshortcut.h>
-#include <kxmlguifactory.h>
-#include <kurl.h>
-#include <kmenu.h>
-#include <kactioncategory.h>
-
-#include <kinputdialog.h>
-
-#include <kfiledialog.h>
-#include <kmessagebox.h>
-#include <ktabbar.h>
-
-#include <QActionGroup>
-#include <QMdiArea>
-#include <QMdiSubWindow>
-#include <QMenuBar>
-
-
-#include <QDir>
-#include <QtCore/qdatetime.h>
-#include <threadweaver/ThreadWeaver.h>
-
-
-
-
-
-EditorTab::EditorTab(QWidget* parent, bool valid)
- : LokalizeSubwindowBase2(parent)
- , _project(Project::instance())
- , m_catalog(new Catalog(this))
- , m_view(new EditorView(this,m_catalog/*,new keyEventHandler(this,m_catalog)*/))
- , m_sonnetDialog(0)
- , _spellcheckStartUndoIndex(0)
- , _spellcheckStop(false)
- , m_currentIsApproved(true)
- , m_currentIsUntr(true)
- , m_fullPathShown(false)
- , m_doReplaceCalled(false)
- , _find(0)
- , _replace(0)
- , m_syncView(0)
- , m_syncViewSecondary(0)
- , m_valid(valid)
- , m_dbusId(-1)
-{
- //QTime chrono;chrono.start();
-
- setAcceptDrops(true);
- setCentralWidget(m_view);
- setupStatusBar(); //--NOT called from initLater() !
- setupActions();
-
-
- dbusObjectPath();
-
- connect(m_view, SIGNAL(signalChanged(uint)), this, SLOT(msgStrChanged())); msgStrChanged();
- connect(SettingsController::instance(),SIGNAL(generalSettingsChanged()),m_view, SLOT(settingsChanged()));
- connect(m_view->tabBar(),SIGNAL(currentChanged(int)),this,SLOT(switchForm(int)));
-
- connect(m_view, SIGNAL(gotoEntryRequested(DocPosition)),this,SLOT(gotoEntry(DocPosition)));
- connect(m_view, SIGNAL(tmLookupRequested(DocPosition::Part,QString)), this, SLOT(lookupSelectionInTranslationMemory()));
-
- connect(this, SIGNAL(fileOpened()), this, SLOT(indexWordsForCompletion()),Qt::QueuedConnection);
-
- connect (m_catalog,SIGNAL(signalFileAutoSaveFailed(QString)),this,SLOT(fileAutoSaveFailedWarning(QString)));
-
-
- //defer some work to make window appear earlier (~200 msec on my Core Duo)
- //QTimer::singleShot(0,this,SLOT(initLater()));
- //kWarning()<<chrono.elapsed();
-}
-
-void EditorTab::initLater()
-{
-}
-
-EditorTab::~EditorTab()
-{
- if (!m_catalog->isEmpty())
- {
- emit fileAboutToBeClosed();
- emit fileClosed();
- emit fileClosed(currentFile());
- }
-
- ids.removeAll(m_dbusId);
-}
-
-
-void EditorTab::setupStatusBar()
-{
- statusBarItems.insert(ID_STATUS_CURRENT,i18nc("@info:status message entry","Current: %1",0));
- statusBarItems.insert(ID_STATUS_TOTAL,i18nc("@info:status message entries","Total: %1",0));
- statusBarItems.insert(ID_STATUS_FUZZY,i18nc("@info:status message entries\n'fuzzy' in gettext terminology","Not ready: %1",0));
- statusBarItems.insert(ID_STATUS_UNTRANS,i18nc("@info:status message entries","Untranslated: %1",0));
- statusBarItems.insert(ID_STATUS_ISFUZZY,QString());
-
- connect(m_catalog,SIGNAL(signalNumberOfFuzziesChanged()),this,SLOT(numberOfFuzziesChanged()));
- connect(m_catalog,SIGNAL(signalNumberOfEmptyChanged()),this,SLOT(numberOfUntranslatedChanged()));
-}
-
-void LokalizeSubwindowBase::reflectNonApprovedCount(int count, int total)
-{
- QString text=i18nc("@info:status message entries\n'fuzzy' in gettext terminology","Not ready: %1", count);
- if (count && total)
- text+=i18nc("percentages in statusbar", " (%1%)", int(100.0*count/total));
- statusBarItems.insert(ID_STATUS_FUZZY,text);
-}
-
-void LokalizeSubwindowBase::reflectUntranslatedCount(int count, int total)
-{
- QString text=i18nc("@info:status message entries","Untranslated: %1", count);
- if (count && total)
- text+=i18nc("percentages in statusbar", " (%1%)", int(100.0*count/total));
- statusBarItems.insert(ID_STATUS_UNTRANS,text);
-}
-
-void EditorTab::numberOfFuzziesChanged()
-{
- reflectNonApprovedCount(m_catalog->numberOfNonApproved(),m_catalog->numberOfEntries());
-}
-
-void EditorTab::numberOfUntranslatedChanged()
-{
- reflectUntranslatedCount(m_catalog->numberOfUntranslated(),m_catalog->numberOfEntries());
-}
-
-void EditorTab::setupActions()
-{
- //all operations that can be done after initial setup
- //(via QTimer::singleShot) go to initLater()
-
- setXMLFile("editorui.rc");
-
- KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* actionCategory;
-
- KActionCategory* file=new KActionCategory(i18nc("@title actions category","File"), ac);;
- KActionCategory* nav=new KActionCategory(i18nc("@title actions category","Navigation"), ac);
- KActionCategory* edit=new KActionCategory(i18nc("@title actions category","Editing"), ac);
- KActionCategory* sync1=new KActionCategory(i18n("Synchronization 1"), ac);
- KActionCategory* sync2=new KActionCategory(i18n("Synchronization 2"), ac);
- KActionCategory* tm=new KActionCategory(i18n("Translation Memory"), ac);
- KActionCategory* glossary=new KActionCategory(i18nc("@title actions category","Glossary"), actionCollection());
- KActionCategory* tools=new KActionCategory(i18nc("@title actions category","Tools"), actionCollection());
-
-
-
-//BEGIN dockwidgets
- int i=0;
-
- QVector<KAction*> altactions(ALTTRANS_SHORTCUTS);
- Qt::Key altlist[ALTTRANS_SHORTCUTS]=
- {
- Qt::Key_1,
- Qt::Key_2,
- Qt::Key_3,
- Qt::Key_4,
- Qt::Key_5,
- Qt::Key_6,
- Qt::Key_7,
- Qt::Key_8,
- Qt::Key_9
- };
- KAction* altaction;
- for (i=0;i<ALTTRANS_SHORTCUTS;++i)
- {
- altaction=tm->addAction(QString("alttrans_insert_%1").arg(i));
- altaction->setShortcut(Qt::ALT+altlist[i]);
- altaction->setText(i18nc("@action:inmenu","Insert alternate translation # %1",i));
- altactions[i]=altaction;
- }
-
- m_altTransView = new AltTransView(this,m_catalog,altactions);
- addDockWidget(Qt::BottomDockWidgetArea, m_altTransView);
- actionCollection()->addAction( QLatin1String("showmsgiddiff_action"), m_altTransView->toggleViewAction() );
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),m_altTransView,SLOT(slotNewEntryDisplayed(DocPosition)));
- connect (m_altTransView,SIGNAL(textInsertRequested(QString)),m_view,SLOT(insertTerm(QString)));
- connect (m_altTransView,SIGNAL(refreshRequested()),m_view,SLOT(gotoEntry()),Qt::QueuedConnection);
- connect (m_catalog,SIGNAL(signalFileLoaded()),m_altTransView,SLOT(fileLoaded()));
-
- m_syncView = new MergeView(this,m_catalog,true);
- addDockWidget(Qt::BottomDockWidgetArea, m_syncView);
- sync1->addAction( QLatin1String("showmergeview_action"), m_syncView->toggleViewAction() );
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),m_syncView,SLOT(slotNewEntryDisplayed(DocPosition)));
- connect (m_catalog,SIGNAL(signalFileLoaded()),m_syncView,SLOT(cleanup()));
- connect (m_syncView,SIGNAL(gotoEntry(DocPosition,int)),
- this,SLOT(gotoEntry(DocPosition,int)));
-
- m_syncViewSecondary = new MergeView(this,m_catalog,false);
- addDockWidget(Qt::BottomDockWidgetArea, m_syncViewSecondary);
- sync2->addAction( QLatin1String("showmergeviewsecondary_action"), m_syncViewSecondary->toggleViewAction() );
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),m_syncViewSecondary,SLOT(slotNewEntryDisplayed(DocPosition)));
- connect (m_catalog,SIGNAL(signalFileLoaded()),m_syncViewSecondary,SLOT(cleanup()));
- connect (m_catalog,SIGNAL(signalFileLoaded(KUrl)),m_syncViewSecondary,SLOT(mergeOpen(KUrl)),Qt::QueuedConnection);
- connect (m_syncViewSecondary,SIGNAL(gotoEntry(DocPosition,int)),
- this,SLOT(gotoEntry(DocPosition,int)));
-
- m_transUnitsView = new CatalogView(this,m_catalog);
- addDockWidget(Qt::LeftDockWidgetArea, m_transUnitsView);
- actionCollection()->addAction( QLatin1String("showcatalogtreeview_action"), m_transUnitsView->toggleViewAction() );
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),m_transUnitsView,SLOT(slotNewEntryDisplayed(DocPosition)));
- connect (m_transUnitsView,SIGNAL(gotoEntry(DocPosition,int)),this,SLOT(gotoEntry(DocPosition,int)));
- connect (m_transUnitsView,SIGNAL(escaped()),this,SLOT(setProperFocus()));
- connect (m_syncView,SIGNAL(mergeCatalogPointerChanged(MergeCatalog*)),
- m_transUnitsView, SLOT(setMergeCatalogPointer(MergeCatalog*)));
-
- m_notesView = new MsgCtxtView(this,m_catalog);
- addDockWidget(Qt::LeftDockWidgetArea, m_notesView);
- actionCollection()->addAction( QLatin1String("showmsgctxt_action"), m_notesView->toggleViewAction() );
- connect(m_catalog,SIGNAL(signalFileLoaded()),m_notesView,SLOT(cleanup()));
- connect(m_notesView,SIGNAL(srcFileOpenRequested(QString,int)),this,SLOT(dispatchSrcFileOpenRequest(QString,int)));
- connect(m_view, SIGNAL(signalChanged(uint)), m_notesView, SLOT(removeErrorNotes()));
- connect(m_notesView,SIGNAL(escaped()),this,SLOT(setProperFocus()));
-
- action=edit->addAction(QLatin1String("edit_addnote"),m_notesView,SLOT(addNoteUI()));
- //action->setShortcut(Qt::CTRL+glist[i]);
- action->setText(i18nc("@action:inmenu","Add a note"));
-
- QVector<KAction*> tmactions(TM_SHORTCUTS);
- Qt::Key tmlist[TM_SHORTCUTS]=
- {
- Qt::Key_1,
- Qt::Key_2,
- Qt::Key_3,
- Qt::Key_4,
- Qt::Key_5,
- Qt::Key_6,
- Qt::Key_7,
- Qt::Key_8,
- Qt::Key_9,
- Qt::Key_0
- };
- KAction* tmaction;
- for (i=0;i<TM_SHORTCUTS;++i)
- {
-// action->setVisible(false);
- tmaction=tm->addAction(QString("tmquery_insert_%1").arg(i));
- tmaction->setShortcut(Qt::CTRL+tmlist[i]);
- tmaction->setText(i18nc("@action:inmenu","Insert TM suggestion # %1",i));
- tmactions[i]=tmaction;
- }
- TM::TMView* _tmView = new TM::TMView(this,m_catalog,tmactions);
- addDockWidget(Qt::BottomDockWidgetArea, _tmView);
- tm->addAction( QLatin1String("showtmqueryview_action"), _tmView->toggleViewAction() );
- connect (_tmView,SIGNAL(refreshRequested()),m_view,SLOT(gotoEntry()),Qt::QueuedConnection);
- connect (_tmView,SIGNAL(refreshRequested()),this,SLOT(msgStrChanged()),Qt::QueuedConnection);
- connect (_tmView,SIGNAL(textInsertRequested(QString)),m_view,SLOT(insertTerm(QString)));
- connect (_tmView,SIGNAL(fileOpenRequested(KUrl,QString,QString)),this,SIGNAL(fileOpenRequested(KUrl,QString,QString)));
- connect (this,SIGNAL(fileAboutToBeClosed()),m_catalog,SLOT(flushUpdateDBBuffer()));
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),m_catalog,SLOT(flushUpdateDBBuffer()));
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),_tmView,SLOT(slotNewEntryDisplayed(DocPosition))); //do this after flushUpdateDBBuffer
-
- QVector<KAction*> gactions(GLOSSARY_SHORTCUTS);
- Qt::Key glist[GLOSSARY_SHORTCUTS]=
- {
- Qt::Key_E,
- Qt::Key_H,
- // Qt::Key_G,
- // Qt::Key_I,
- // Qt::Key_J,
- // Qt::Key_K,
- Qt::Key_K,
- Qt::Key_P,
- Qt::Key_N,
- // Qt::Key_Q,
- // Qt::Key_R,
- // Qt::Key_U,
- // Qt::Key_V,
- // Qt::Key_W,
- // Qt::Key_X,
- Qt::Key_Y,
- // Qt::Key_Z,
- Qt::Key_BraceLeft,
- Qt::Key_BraceRight,
- Qt::Key_Semicolon,
- Qt::Key_Apostrophe
- };
- KAction* gaction;
-// int i=0;
- for (i=0;i<GLOSSARY_SHORTCUTS;++i)
- {
-// action->setVisible(false);
- gaction=glossary->addAction(QString("glossary_insert_%1").arg(i));
- gaction->setShortcut(Qt::CTRL+glist[i]);
- gaction->setText(i18nc("@action:inmenu","Insert # %1 term translation",i));
- gactions[i]=gaction;
- }
-
- GlossaryNS::GlossaryView* _glossaryView = new GlossaryNS::GlossaryView(this,m_catalog,gactions);
- addDockWidget(Qt::BottomDockWidgetArea, _glossaryView);
- glossary->addAction( QLatin1String("showglossaryview_action"), _glossaryView->toggleViewAction() );
- connect (this,SIGNAL(signalNewEntryDisplayed(DocPosition)),_glossaryView,SLOT(slotNewEntryDisplayed(DocPosition)));
- connect (_glossaryView,SIGNAL(termInsertRequested(QString)),m_view,SLOT(insertTerm(QString)));
-
- gaction = glossary->addAction("glossary_define",this,SLOT(defineNewTerm()));
- gaction->setText(i18nc("@action:inmenu","Define new term"));
- _glossaryView->addAction(gaction);
- _glossaryView->setContextMenuPolicy( Qt::ActionsContextMenu);
-
-
- BinUnitsView* binUnitsView=new BinUnitsView(m_catalog,this);
- addDockWidget(Qt::BottomDockWidgetArea, binUnitsView);
- edit->addAction( QLatin1String("showbinunitsview_action"), binUnitsView->toggleViewAction() );
- connect(m_view,SIGNAL(binaryUnitSelectRequested(QString)),binUnitsView,SLOT(selectUnit(QString)));
-//END dockwidgets
-
-
-
-
- actionCategory=file;
-
-// File
- action=file->addAction(KStandardAction::Save,this, SLOT(saveFile()));
- action->setEnabled(false);
- connect (m_catalog,SIGNAL(cleanChanged(bool)),action,SLOT(setDisabled(bool)));
- connect (m_catalog,SIGNAL(cleanChanged(bool)),this,SLOT(setModificationSign(bool)));
- file->addAction(KStandardAction::SaveAs,this, SLOT(saveFileAs()));
- //action = KStandardAction::quit(qApp, SLOT(quit()), ac);
- //action->setText(i18nc("@action:inmenu","Close all Lokalize windows"));
-
- //KStandardAction::quit(kapp, SLOT(quit()), ac);
- //KStandardAction::quit(this, SLOT(deleteLater()), ac);
-
- action = actionCategory->addAction("file_phases");
- action->setText(i18nc("@action:inmenu","Phases..."));
- connect(action, SIGNAL(triggered()), SLOT(openPhasesWindow()));
-
-#define ADD_ACTION_ICON(_name,_text,_shortcut,_icon)\
- action = actionCategory->addAction(_name);\
- action->setText(_text);\
- action->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::_shortcut));\
- action->setIcon(KIcon(_icon));
-
-#define ADD_ACTION_SHORTCUT_ICON(_name,_text,_shortcut,_icon)\
- action = actionCategory->addAction(_name);\
- action->setText(_text);\
- action->setShortcut(QKeySequence( _shortcut ));\
- action->setIcon(KIcon(_icon));
-
-#define ADD_ACTION_SHORTCUT(_name,_text,_shortcut)\
- action = actionCategory->addAction(_name);\
- action->setText(_text);\
- action->setShortcut(QKeySequence( _shortcut ));\
-
-
-//Edit
- actionCategory=edit;
- action=edit->addAction(KStandardAction::Undo,this,SLOT(undo()));
- connect(m_view->viewPort(),SIGNAL(undoRequested()),this,SLOT(undo()));
- connect(m_catalog,SIGNAL(canUndoChanged(bool)),action,SLOT(setEnabled(bool)) );
- action->setEnabled(false);
-
- action=edit->addAction(KStandardAction::Redo,this,SLOT(redo()));
- connect(m_view->viewPort(),SIGNAL(redoRequested()),this,SLOT(redo()));
- connect(m_catalog,SIGNAL(canRedoChanged(bool)),action,SLOT(setEnabled(bool)) );
- action->setEnabled(false);
-
- action=nav->addAction(KStandardAction::Find,this,SLOT(find()));
- action=nav->addAction(KStandardAction::FindNext,this,SLOT(findNext()));
- action=nav->addAction(KStandardAction::FindPrev,this,SLOT(findPrev()));
- action->setText(i18nc("@action:inmenu","Change searching direction"));
- action=edit->addAction(KStandardAction::Replace,this,SLOT(replace()));
-
- connect(m_view,SIGNAL(findRequested()), this,SLOT(find()));
- connect(m_view,SIGNAL(findNextRequested()), this,SLOT(findNext()));
- connect(m_view,SIGNAL(replaceRequested()), this,SLOT(replace()));
-
-
-//
- action = actionCategory->addAction("edit_approve", new KToolBarPopupAction(KIcon("approved"),i18nc("@option:check whether message is marked as translated/reviewed/approved (depending on your role)","Approved"),this));
- action->setShortcut(QKeySequence( Qt::CTRL+Qt::Key_U ));
- action->setCheckable(true);
- connect(action, SIGNAL(triggered()), m_view,SLOT(toggleApprovement()));
- connect(m_view, SIGNAL(signalApprovedEntryDisplayed(bool)),this,SIGNAL(signalApprovedEntryDisplayed(bool)));
- connect(this, SIGNAL(signalApprovedEntryDisplayed(bool)),action,SLOT(setChecked(bool)));
- connect(this, SIGNAL(signalApprovedEntryDisplayed(bool)),this,SLOT(msgStrChanged()),Qt::QueuedConnection);
- m_approveAction=action;
- connect(Project::local(), SIGNAL(configChanged()), SLOT(setApproveActionTitle()));
- connect(m_catalog, SIGNAL(activePhaseChanged()), SLOT(setApproveActionTitle()));
- setApproveActionTitle();
- connect(action->menu(), SIGNAL(aboutToShow()),this,SLOT(showStatesMenu()));
- connect(action->menu(), SIGNAL(triggered(QAction*)),this,SLOT(setState(QAction*)));
-
-
- action = actionCategory->addAction("edit_approve_go_fuzzyUntr");
- action->setText(i18nc("@action:inmenu","Approve and go to next"));
- connect(action, SIGNAL(triggered()), SLOT(toggleApprovementGotoNextFuzzyUntr()));
-
-
- action = actionCategory->addAction("edit_nonequiv",m_view,SLOT(setEquivTrans(bool)));
- action->setText(i18nc("@action:inmenu","Equivalent translation"));
- action->setCheckable(true);
- connect(this, SIGNAL(signalEquivTranslatedEntryDisplayed(bool)),action,SLOT(setChecked(bool)));
-
-
- int copyShortcut=Qt::CTRL+Qt::Key_Space;
- QString systemLang=KGlobal::locale()->language();
- if (Q_UNLIKELY( systemLang.startsWith("ko")
- || systemLang.startsWith("ja")
- || systemLang.startsWith("zh")
- ))
- copyShortcut=Qt::ALT+Qt::Key_Space;
- ADD_ACTION_SHORTCUT_ICON("edit_msgid2msgstr",i18nc("@action:inmenu","Copy source to target"),copyShortcut,"msgid2msgstr")
- connect(action, SIGNAL(triggered(bool)), m_view->viewPort(),SLOT(source2target()));
-
- ADD_ACTION_SHORTCUT("edit_unwrap-target",i18nc("@action:inmenu","Unwrap target"),Qt::CTRL+Qt::Key_I)
- connect(action, SIGNAL(triggered(bool)), m_view,SLOT(unwrap()));
-
- action=edit->addAction("edit_clear-target",m_view->viewPort(),SLOT(removeTargetSubstring()));
- action->setShortcut(Qt::CTRL+Qt::Key_D);
- action->setText(i18nc("@action:inmenu","Clear"));
-
- action=edit->addAction("edit_completion",m_view,SIGNAL(doExplicitCompletion()));
- action->setShortcut(Qt::CTRL+Qt::ALT+Qt::Key_Space);
- action->setText(i18nc("@action:inmenu","Completion"));
-
- action=edit->addAction("edit_tagmenu",m_view->viewPort(),SLOT(tagMenu()));
- action->setShortcut(Qt::CTRL+Qt::Key_T);
- action->setText(i18nc("@action:inmenu","Insert Tag"));
-
- action=edit->addAction("edit_tagimmediate",m_view->viewPort(),SLOT(tagImmediate()));
- action->setShortcut(Qt::CTRL+Qt::Key_M);
- action->setText(i18nc("@action:inmenu","Insert Next Tag"));
-
- action=edit->addAction("edit_spellreplace",m_view->viewPort(),SLOT(spellReplace()));
- action->setShortcut(Qt::CTRL+Qt::Key_Equal);
- action->setText(i18nc("@action:inmenu","Replace with best spellcheck suggestion"));
-
-// action = ac->addAction("glossary_define",m_view,SLOT(defineNewTerm()));
-// action->setText(i18nc("@action:inmenu","Define new term"));
-
-// Go
- actionCategory=nav;
- action=nav->addAction(KStandardAction::Next,this, SLOT(gotoNext()));
- action->setText(i18nc("@action:inmenu entry","&Next"));
- connect( this, SIGNAL(signalLastDisplayed(bool)),action,SLOT(setDisabled(bool)));
- connect(m_view->viewPort(),SIGNAL(gotoNextRequested()),this,SLOT(gotoNext()));
-
- action=nav->addAction(KStandardAction::Prior,this, SLOT(gotoPrev()));
- action->setText(i18nc("@action:inmenu entry","&Previous"));
- connect( this, SIGNAL(signalFirstDisplayed(bool)), action , SLOT(setDisabled(bool)) );
- connect(m_view->viewPort(),SIGNAL(gotoPrevRequested()),this,SLOT(gotoPrev()));
-
- action=nav->addAction(KStandardAction::FirstPage,this, SLOT(gotoFirst()));
- connect(m_view->viewPort(),SIGNAL(gotoFirstRequested()),this,SLOT(gotoFirst()));
- action->setText(i18nc("@action:inmenu","&First Entry"));
- action->setShortcut(QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_Home));
- connect( this, SIGNAL(signalFirstDisplayed(bool)), action , SLOT(setDisabled(bool)) );
-
- action=nav->addAction(KStandardAction::LastPage,this, SLOT(gotoLast()));
- connect(m_view->viewPort(),SIGNAL(gotoLastRequested()),this,SLOT(gotoLast()));
- action->setText(i18nc("@action:inmenu","&Last Entry"));
- action->setShortcut(QKeySequence(Qt::CTRL+Qt::ALT+Qt::Key_End));
- connect( this, SIGNAL(signalLastDisplayed(bool)),action,SLOT(setDisabled(bool)));
-
- action=nav->addAction(KStandardAction::GotoPage,this, SLOT(gotoEntry()));
- action->setShortcut(Qt::CTRL+Qt::Key_G);
- action->setText(i18nc("@action:inmenu","Entry by number"));
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous non-empty but not ready"),Qt::CTRL+Qt::Key_PageUp,"prevfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzy()) );
- connect( m_view->viewPort(), SIGNAL(gotoPrevFuzzyRequested()), this, SLOT(gotoPrevFuzzy()) );
- connect( this, SIGNAL(signalPriorFuzzyAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next non-empty but not ready"),Qt::CTRL+Qt::Key_PageDown,"nextfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzy()) );
- connect( m_view->viewPort(), SIGNAL(gotoNextFuzzyRequested()), this, SLOT(gotoNextFuzzy()) );
- connect( this, SIGNAL(signalNextFuzzyAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_untrans",i18nc("@action:inmenu","Previous untranslated"),Qt::ALT+Qt::Key_PageUp,"prevuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevUntranslated()));
- connect( m_view->viewPort(), SIGNAL(gotoPrevUntranslatedRequested()), this, SLOT(gotoPrevUntranslated()) );
- connect( this, SIGNAL(signalPriorUntranslatedAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_untrans",i18nc("@action:inmenu","Next untranslated"),Qt::ALT+Qt::Key_PageDown,"nextuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextUntranslated()));
- connect( m_view->viewPort(), SIGNAL(gotoNextUntranslatedRequested()), this, SLOT(gotoNextUntranslated()) );
- connect( this, SIGNAL(signalNextUntranslatedAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous not ready"),Qt::CTRL+Qt::SHIFT/*ALT*/+Qt::Key_PageUp,"prevfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzyUntr()) );
- connect( m_view->viewPort(), SIGNAL(gotoPrevFuzzyUntrRequested()), this, SLOT(gotoPrevFuzzyUntr()) );
- connect( this, SIGNAL(signalPriorFuzzyOrUntrAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next not ready"),Qt::CTRL+Qt::SHIFT+Qt::Key_PageDown,"nextfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzyUntr()) );
- connect( m_view->viewPort(), SIGNAL(gotoNextFuzzyUntrRequested()), this, SLOT(gotoNextFuzzyUntr()) );
- connect( this, SIGNAL(signalNextFuzzyOrUntrAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- action=nav->addAction("go_focus_earch_line",m_transUnitsView, SLOT(setFocus()));
- action->setShortcut(Qt::CTRL+Qt::Key_L);
- action->setText(i18nc("@action:inmenu","Focus the search line of Translation Units view"));
-
-
-//Bookmarks
- action=nav->addAction(KStandardAction::AddBookmark,m_view,SLOT(toggleBookmark(bool)));
- //action = ac->addAction("bookmark_do");
- action->setText(i18nc("@option:check","Bookmark message"));
- action->setCheckable(true);
- //connect(action, SIGNAL(triggered(bool)),m_view,SLOT(toggleBookmark(bool)));
- connect( this, SIGNAL(signalBookmarkDisplayed(bool)),action,SLOT(setChecked(bool)) );
-
- action=nav->addAction("bookmark_prior",this,SLOT(gotoPrevBookmark()));
- action->setText(i18nc("@action:inmenu","Previous bookmark"));
- connect( this, SIGNAL(signalPriorBookmarkAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
- action=nav->addAction("bookmark_next",this,SLOT(gotoNextBookmark()));
- action->setText(i18nc("@action:inmenu","Next bookmark"));
- connect( this, SIGNAL(signalNextBookmarkAvailable(bool)),action,SLOT(setEnabled(bool)) );
-
-//Tools
- edit->addAction(KStandardAction::Spelling,this,SLOT(spellcheck()));
-
- actionCategory=tm;
- // xgettext: no-c-format
- ADD_ACTION_SHORTCUT("tools_tm_batch",i18nc("@action:inmenu","Fill in all exact suggestions"),Qt::CTRL+Qt::ALT+Qt::Key_B)
- connect( action, SIGNAL(triggered(bool)), _tmView, SLOT(slotBatchTranslate()) );
-
- // xgettext: no-c-format
- ADD_ACTION_SHORTCUT("tools_tm_batch_fuzzy",i18nc("@action:inmenu","Fill in all exact suggestions and mark as fuzzy"),Qt::CTRL+Qt::ALT+Qt::Key_N)
- connect( action, SIGNAL(triggered(bool)), _tmView, SLOT(slotBatchTranslateFuzzy()) );
-
- actionCategory=tools;
- ADD_ACTION_SHORTCUT("tools_wordcount",i18nc("@action:inmenu","Word count"),Qt::CTRL+Qt::ALT+Qt::Key_C)
- connect( action, SIGNAL(triggered(bool)), this, SLOT(displayWordCount()) );
-
-//MergeMode
- action = sync1->addAction("merge_open",m_syncView,SLOT(mergeOpen()));
- action->setText(i18nc("@action:inmenu","Open file for sync/merge"));
- action->setStatusTip(i18nc("@info:status","Open catalog to be merged into the current one / replicate base file changes to"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- m_syncView->addAction(action);
-
- action = sync1->addAction("merge_prev",m_syncView,SLOT(gotoPrevChanged()));
- action->setText(i18nc("@action:inmenu","Previous different"));
- action->setStatusTip(i18nc("@info:status","Previous entry which is translated differently in the file being merged, including empty translations in merge source"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- action->setShortcut(Qt::ALT+Qt::Key_Up);
- connect( m_syncView, SIGNAL(signalPriorChangedAvailable(bool)),action,SLOT(setEnabled(bool)) );
- m_syncView->addAction(action);
-
- action = sync1->addAction("merge_next",m_syncView,SLOT(gotoNextChanged()));
- action->setText(i18nc("@action:inmenu","Next different"));
- action->setStatusTip(i18nc("@info:status","Next entry which is translated differently in the file being merged, including empty translations in merge source"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- action->setShortcut(Qt::ALT+Qt::Key_Down);
- connect( m_syncView, SIGNAL(signalNextChangedAvailable(bool)),action,SLOT(setEnabled(bool)) );
- m_syncView->addAction(action);
-
- action = sync1->addAction("merge_nextapproved",m_syncView,SLOT(gotoNextChangedApproved()));
- action->setText(i18nc("@action:inmenu","Next different approved"));
- action->setShortcut(Qt::ALT+Qt::META+Qt::Key_Down);
- connect( m_syncView, SIGNAL(signalNextChangedAvailable(bool)),action,SLOT(setEnabled(bool)) );
- m_syncView->addAction(action);
-
- action = sync1->addAction("merge_accept",m_syncView,SLOT(mergeAccept()));
- action->setText(i18nc("@action:inmenu","Copy from merging source"));
- action->setShortcut(Qt::ALT+Qt::Key_Return);
- connect( m_syncView, SIGNAL(signalEntryWithMergeDisplayed(bool)),action,SLOT(setEnabled(bool)));
- m_syncView->addAction(action);
-
- action = sync1->addAction("merge_acceptnew",m_syncView,SLOT(mergeAcceptAllForEmpty()));
- action->setText(i18nc("@action:inmenu","Copy all new translations"));
- action->setStatusTip(i18nc("@info:status","This changes only empty and non-ready entries in base file"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- action->setShortcut(Qt::CTRL+Qt::ALT+Qt::Key_A);
- m_syncView->addAction(action);
- //action->setShortcut(Qt::ALT+Qt::Key_E);
-
- action = sync1->addAction("merge_back",m_syncView,SLOT(mergeBack()));
- action->setText(i18nc("@action:inmenu","Copy to merging source"));
- action->setShortcut(Qt::CTRL+Qt::ALT+Qt::Key_Return);
- m_syncView->addAction(action);
-
-
-//Secondary merge
- action = sync2->addAction("mergesecondary_open",m_syncViewSecondary,SLOT(mergeOpen()));
- action->setText(i18nc("@action:inmenu","Open file for secondary sync"));
- action->setStatusTip(i18nc("@info:status","Open catalog to be merged into the current one / replicate base file changes to"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- m_syncViewSecondary->addAction(action);
-
- action = sync2->addAction("mergesecondary_prev",m_syncViewSecondary,SLOT(gotoPrevChanged()));
- action->setText(i18nc("@action:inmenu","Previous different"));
- action->setStatusTip(i18nc("@info:status","Previous entry which is translated differently in the file being merged, including empty translations in merge source"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- connect( m_syncViewSecondary, SIGNAL(signalPriorChangedAvailable(bool)),action,SLOT(setEnabled(bool)) );
- m_syncViewSecondary->addAction(action);
-
- action = sync2->addAction("mergesecondary_next",m_syncViewSecondary,SLOT(gotoNextChanged()));
- action->setText(i18nc("@action:inmenu","Next different"));
- action->setStatusTip(i18nc("@info:status","Next entry which is translated differently in the file being merged, including empty translations in merge source"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- connect( m_syncViewSecondary, SIGNAL(signalNextChangedAvailable(bool)),action,SLOT(setEnabled(bool)) );
- m_syncViewSecondary->addAction(action);
-
- action = sync2->addAction("mergesecondary_accept",m_syncViewSecondary,SLOT(mergeAccept()));
- action->setText(i18nc("@action:inmenu","Copy from merging source"));
- connect( m_syncViewSecondary, SIGNAL(signalEntryWithMergeDisplayed(bool)),action,SLOT(setEnabled(bool)));
- m_syncViewSecondary->addAction(action);
-
- action = sync2->addAction("mergesecondary_acceptnew",m_syncViewSecondary,SLOT(mergeAcceptAllForEmpty()));
- action->setText(i18nc("@action:inmenu","Copy all new translations"));
- action->setStatusTip(i18nc("@info:status","This changes only empty entries"));
- action->setToolTip(action->statusTip());
- action->setWhatsThis(action->statusTip());
- m_syncViewSecondary->addAction(action);
-
- action = sync2->addAction("mergesecondary_back",m_syncViewSecondary,SLOT(mergeBack()));
- action->setText(i18nc("@action:inmenu","Copy to merging source"));
- m_syncViewSecondary->addAction(action);
-
-}
-
-void EditorTab::setProperFocus()
-{
- m_view->setProperFocus();
-}
-
-void EditorTab::hideDocks()
-{
- if (m_transUnitsView->isFloating())
- m_transUnitsView->hide();
-}
-
-void EditorTab::showDocks()
-{
- return;
- if (m_transUnitsView->isFloating())
- m_transUnitsView->show();
-}
-
-void EditorTab::setProperCaption(QString title, bool modified)
-{
- if (m_catalog->autoSaveRecovered()) title+=' '+i18nc("editor tab name","(recovered)");
- setWindowTitle(title+" [*]");
- setWindowModified(modified);
-}
-
-void EditorTab::setFullPathShown(bool fullPathShown)
-{
- m_fullPathShown=fullPathShown;
-
- updateCaptionPath();
- setModificationSign(m_catalog->isClean());
-}
-
-
-void EditorTab::updateCaptionPath()
-{
- KUrl url=m_catalog->url();
- if (!url.isLocalFile() || !_project->isLoaded())
- _captionPath=url.pathOrUrl();
- else
- {
- if (m_fullPathShown)
- {
- _captionPath=KUrl::relativePath(
- KUrl(_project->path()).directory()
- ,url.toLocalFile());
- if (_captionPath.contains("../.."))
- _captionPath=url.toLocalFile();
- else if (_captionPath.startsWith("./"))
- _captionPath=_captionPath.mid(2);
- }
- else
- _captionPath=url.fileName();
- }
-
-}
-
-bool EditorTab::fileOpen(KUrl url, KUrl baseUrl, bool silent)
-{
- if (!m_catalog->isClean())
- {
- switch (KMessageBox::warningYesNoCancel(SettingsController::instance()->mainWindowPtr(),
- i18nc("@info","The document contains unsaved changes.\n"
- "Do you want to save your changes or discard them?"),i18nc("@title:window","Warning"),
- KStandardGuiItem::save(),KStandardGuiItem::discard())
- )
- {
- case KMessageBox::Yes: if (!saveFile()) return false;
- case KMessageBox::Cancel: return false;
- }
- }
- if (baseUrl.isEmpty())
- baseUrl=m_catalog->url();
-
- KUrl saidUrl;
- if (url.isEmpty())
- {
- //Prevent crashes
- Project::instance()->model()->weaver()->suspend();
- url=KFileDialog::getOpenFileName(baseUrl, Catalog::supportedMimeFilters + " text/x-gettext-translation-template", SettingsController::instance()->mainWindowPtr());
- Project::instance()->model()->weaver()->resume();
- //TODO application/x-xliff, windows: just extensions
- //originalPath=url.path(); never used
- }
- else if (!QFile::exists(url.toLocalFile())&&Project::instance()->isLoaded())
- { //check if we are opening template
- QString path=url.toLocalFile();
- path.replace(Project::instance()->poDir(),Project::instance()->potDir());
- if (QFile::exists(path) || QFile::exists(path=path+'t'))
- {
- saidUrl=url;
- url.setPath(path);
- }
- }
- if (url.isEmpty())
- return false;
-
- QApplication::setOverrideCursor(Qt::WaitCursor);
-
- QString prevFilePath=currentFile();
- bool wasOpen=!m_catalog->isEmpty();
- if (wasOpen) emit fileAboutToBeClosed();
- int errorLine=m_catalog->loadFromUrl(url,saidUrl);
- if (wasOpen&&errorLine==0) {emit fileClosed();emit fileClosed(prevFilePath);}
-
- QApplication::restoreOverrideCursor();
-
- if (errorLine==0)
- {
- statusBarItems.insert(ID_STATUS_TOTAL,i18nc("@info:status message entries","Total: %1", m_catalog->numberOfEntries()));
- numberOfUntranslatedChanged();
- numberOfFuzziesChanged();
-
- m_currentPos.entry=-1;//so the signals are emitted
- DocPosition pos(0);
- //we delay gotoEntry(pos) until project is loaded;
-
-
- //TODO "test" for the name????
- m_catalog->setActivePhase("test",Project::local()->role());
-//Project
- if (url.isLocalFile() && !_project->isLoaded())
- {
-//search for it
- int i=4;
- QDir dir(url.directory());
- QStringList proj("*.ktp");
- proj.append("*.lokalize");
- dir.setNameFilters(proj);
- while (--i && !dir.isRoot() && !_project->isLoaded())
- {
- if (dir.entryList().isEmpty()) dir.cdUp();
- else _project->load(dir.absoluteFilePath(dir.entryList().first()));
- }
-
- //enforce autosync
- m_syncViewSecondary->mergeOpen(url);
-
- if (!_project->isLoaded() && _project->desirablePath().isEmpty())
- {
- _project->setDesirablePath(url.directory(KUrl::AppendTrailingSlash)+"index.lokalize");
- //_project->setLangCode(m_catalog->targetLangCode());
- }
-
- }
-
- gotoEntry(pos);
-
- updateCaptionPath();
- setModificationSign(m_catalog->isClean());
-
-//OK!!!
- emit fileOpened();
- return true;
- }
-
- if (!silent)
- {
- //KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
- if (errorLine>0) KMessageBox::error(this, i18nc("@info","Error opening the file <filename>%1</filename>, line: %2",url.pathOrUrl(),errorLine) );
- else KMessageBox::error(this, i18nc("@info","Error opening the file <filename>%1</filename>",url.pathOrUrl()) );
- }
- return false;
-}
-
-bool EditorTab::saveFileAs()
-{
- KUrl url=KFileDialog::getSaveUrl(m_catalog->url(),m_catalog->mimetype(),this);
- if (url.isEmpty()) return false;
- return saveFile(url);
-}
-
-bool EditorTab::saveFile(const KUrl& url)
-{
- if (m_catalog->saveToUrl(url))
- {
- updateCaptionPath();
- setModificationSign(/*clean*/true);
- emit fileSaved(url.toLocalFile());
- return true;
- }
-
- if ( KMessageBox::Continue==KMessageBox::warningContinueCancel(this,
- i18nc("@info","Error saving the file <filename>%1</filename>\n"
- "Do you want to save to another file or cancel?", m_catalog->url().pathOrUrl()),
- i18nc("@title","Error"),KStandardGuiItem::save())
- )
- return saveFileAs();
- return false;
-}
-
-void EditorTab::fileAutoSaveFailedWarning(const QString& fileName)
-{
- KMessageBox::information(this, i18nc("@info","Could not perform file autosaving.\n"
- "The target file was <filename>%1</filename>.", fileName) );
-}
-
-EditorState EditorTab::state()
-{
- EditorState state;
- state.dockWidgets=saveState();
- state.url=m_catalog->url();
- state.mergeUrl=m_syncView->url();
- state.entry=m_currentPos.entry;
- //state.offset=_currentPos.offset;
- return state;
-}
-
-
-bool EditorTab::queryClose()
-{
- if (m_catalog->isClean()) return true;
-
- //TODO caption
- switch (KMessageBox::warningYesNoCancel(this,
- i18nc("@info","The document contains unsaved changes.\n"
- "Do you want to save your changes or discard them?"),i18nc("@title:window","Warning"),
- KStandardGuiItem::save(),KStandardGuiItem::discard()))
- {
- case KMessageBox::Yes: return saveFile();
- case KMessageBox::No: return true;
- default: return false;
- }
-}
-
-
-void EditorTab::undo()
-{
- gotoEntry(m_catalog->undo(),0);
- msgStrChanged();
-}
-
-void EditorTab::redo()
-{
- gotoEntry(m_catalog->redo(),0);
- msgStrChanged();
-}
-
-void EditorTab::gotoEntry()
-{
- DocPosition pos=m_currentPos;
- pos.entry=KInputDialog::getInteger(
- i18nc("@title","Jump to Entry"),
- i18nc("@label:spinbox","Enter entry number:"),
- pos.entry,1,
- m_catalog->numberOfEntries(),
- 1,0,this);
- if (pos.entry)
- {
- --(pos.entry);
- gotoEntry(pos);
- }
-}
-
-void EditorTab::gotoEntry(DocPosition pos, int selection)
-{
- //specially for dbus users
- if (pos.entry>=m_catalog->numberOfEntries()||pos.entry<0)
- return;
- if (!m_catalog->isPlural(pos))
- pos.form=0;
-
- m_currentPos.part=pos.part;//for searching;
- //UndefPart => called on fuzzy toggle
-
-
- bool newEntry=m_currentPos.entry!=pos.entry || m_currentPos.form!=pos.form;
- if (newEntry||pos.part==DocPosition::Comment)
- {
- m_notesView->gotoEntry(pos,pos.part==DocPosition::Comment?selection:0);
- if (pos.part==DocPosition::Comment)
- {
- pos.form=0;
- pos.offset=0;
- selection=0;
- }
- }
-
-
- m_view->gotoEntry(pos,selection);
- if (pos.part==DocPosition::UndefPart)
- m_currentPos.part=DocPosition::Target;
-
- //QTime time; time.start();
-
- if (newEntry)
- {
- m_currentPos=pos;
- if (true)
- {
- emit signalNewEntryDisplayed(pos);
- emit entryDisplayed();
-
- emit signalFirstDisplayed(pos.entry==m_transUnitsView->firstEntry());
- emit signalLastDisplayed(pos.entry==m_transUnitsView->lastEntry());
-
- emit signalPriorFuzzyAvailable(pos.entry>m_catalog->firstFuzzyIndex());
- emit signalNextFuzzyAvailable(pos.entry<m_catalog->lastFuzzyIndex());
-
- emit signalPriorUntranslatedAvailable(pos.entry>m_catalog->firstUntranslatedIndex());
- emit signalNextUntranslatedAvailable(pos.entry<m_catalog->lastUntranslatedIndex());
-
- emit signalPriorFuzzyOrUntrAvailable(pos.entry>m_catalog->firstFuzzyIndex()
- ||pos.entry>m_catalog->firstUntranslatedIndex()
- );
- emit signalNextFuzzyOrUntrAvailable(pos.entry<m_catalog->lastFuzzyIndex()
- ||pos.entry<m_catalog->lastUntranslatedIndex());
-
- emit signalPriorBookmarkAvailable(pos.entry>m_catalog->firstBookmarkIndex());
- emit signalNextBookmarkAvailable(pos.entry<m_catalog->lastBookmarkIndex());
- emit signalBookmarkDisplayed(m_catalog->isBookmarked(pos.entry));
-
- emit signalEquivTranslatedEntryDisplayed(m_catalog->isEquivTrans(pos));
- emit signalApprovedEntryDisplayed(m_catalog->isApproved(pos));
- }
-
- }
-
- statusBarItems.insert(ID_STATUS_CURRENT,i18nc("@info:status","Current: %1", m_currentPos.entry+1));
- //kDebug()<<"ELA "<<time.elapsed();
-}
-
-void EditorTab::msgStrChanged()
-{
- bool isUntr=m_catalog->msgstr(m_currentPos).isEmpty();
- bool isApproved=m_catalog->isApproved(m_currentPos);
- if (isUntr==m_currentIsUntr && isApproved==m_currentIsApproved)
- return;
-
- QString msg;
- if (isUntr) msg=i18nc("@info:status","Untranslated");
- else if (isApproved)msg=i18nc("@info:status 'non-fuzzy' in gettext terminology","Ready");
- else msg=i18nc("@info:status 'fuzzy' in gettext terminology","Needs review");
-
- /* else
- statusBar()->changeItem("",ID_STATUS_ISFUZZY);*/
-
- statusBarItems.insert(ID_STATUS_ISFUZZY,msg);
-
- m_currentIsUntr=isUntr;
- m_currentIsApproved=isApproved;
-}
-
-void EditorTab::switchForm(int newForm)
-{
- if (m_currentPos.form==newForm) return;
-
- DocPosition pos=m_currentPos;
- pos.form=newForm;
- gotoEntry(pos);
-}
-
-void EditorTab::gotoNextUnfiltered()
-{
- DocPosition pos=m_currentPos;
-
- if (switchNext(m_catalog,pos))
- gotoEntry(pos);
-}
-
-
-void EditorTab::gotoPrevUnfiltered()
-{
- DocPosition pos=m_currentPos;
-
- if (switchPrev(m_catalog,pos))
- gotoEntry(pos);
-}
-
-void EditorTab::gotoFirstUnfiltered(){gotoEntry(DocPosition(0));}
-void EditorTab::gotoLastUnfiltered(){gotoEntry(DocPosition(m_catalog->numberOfEntries()-1));}
-
-void EditorTab::gotoFirst()
-{
- DocPosition pos=DocPosition(m_transUnitsView->firstEntry());
- if (pos.entry!=-1)
- gotoEntry(pos);
-}
-
-void EditorTab::gotoLast()
-{
- DocPosition pos=DocPosition(m_transUnitsView->lastEntry());
- if (pos.entry!=-1)
- gotoEntry(pos);
-}
-
-
-void EditorTab::gotoNext()
-{
- DocPosition pos=m_currentPos;
- if (m_catalog->isPlural(pos) && pos.form+1<m_catalog->numberOfPluralForms())
- pos.form++;
- else
- pos=DocPosition(m_transUnitsView->nextEntry());
-
- if (pos.entry!=-1)
- gotoEntry(pos);
-}
-
-void EditorTab::gotoPrev()
-{
- DocPosition pos=m_currentPos;
- if (m_catalog->isPlural(pos) && pos.form>0)
- pos.form--;
- else
- pos=DocPosition(m_transUnitsView->prevEntry());
-
- if (pos.entry!=-1)
- gotoEntry(pos);
-}
-
-void EditorTab::gotoPrevFuzzy()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->prevFuzzyIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-void EditorTab::gotoNextFuzzy()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->nextFuzzyIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-void EditorTab::gotoPrevUntranslated()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->prevUntranslatedIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-void EditorTab::gotoNextUntranslated()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->nextUntranslatedIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-void EditorTab::gotoPrevFuzzyUntr()
-{
- DocPosition pos;
-
- short fu = m_catalog->prevFuzzyIndex(m_currentPos.entry);
- short un = m_catalog->prevUntranslatedIndex(m_currentPos.entry);
-
- pos.entry=fu>un?fu:un;
- if ( pos.entry == -1)
- return;
-
- gotoEntry(pos);
-}
-
-bool EditorTab::gotoNextFuzzyUntr(const DocPosition& p)
-{
- int index=(p.entry==-1)?m_currentPos.entry:p.entry;
-
- DocPosition pos;
-
- short fu = m_catalog->nextFuzzyIndex(index);
- short un = m_catalog->nextUntranslatedIndex(index);
- if ( (fu == -1) && (un == -1) )
- return false;
-
- if (fu == -1) fu=un;
- else if (un == -1) un=fu;
-
- pos.entry=fu<un?fu:un;
- gotoEntry(pos);
- return true;
-}
-
-
-void EditorTab::toggleApprovementGotoNextFuzzyUntr()
-{
- if(!m_catalog->isApproved(m_currentPos.entry))
- m_view->toggleApprovement();
- if (!gotoNextFuzzyUntr())
- gotoNextFuzzyUntr(DocPosition(-2));//so that we don't skip the first
-}
-
-void EditorTab::setApproveActionTitle()
-{
- const char* const titles[]={
- I18N_NOOP2("@option:check trans-unit state","Translated"),
- I18N_NOOP2("@option:check trans-unit state","Signed-off"),
- I18N_NOOP2("@option:check trans-unit state","Approved")
- };
- const char* const helpText[]={
- I18N_NOOP2("@info:tooltip","Translation is done (although still may need a review)"),
- I18N_NOOP2("@info:tooltip","Translation received positive review"),
- I18N_NOOP2("@info:tooltip","Entry is fully localized (i.e. final)")
- };
-
- int role=m_catalog->activePhaseRole();
- if (role==ProjectLocal::Undefined)
- role=Project::local()->role();
- m_approveAction->setText(i18nc("@option:check trans-unit state",titles[role]));
- m_approveAction->setToolTip(i18nc("@info:tooltip",helpText[role]));
-}
-
-void EditorTab::showStatesMenu()
-{
- m_approveAction->menu()->clear();
- if (!(m_catalog->capabilities()&ExtendedStates))
- {
- QAction* a=m_approveAction->menu()->addAction(i18nc("@info:status 'fuzzy' in gettext terminology","Needs review"));
- a->setData(QVariant(-1));
- a->setCheckable(true);
- a->setChecked(!m_catalog->isApproved(m_currentPos));
-
- a=m_approveAction->menu()->addAction(i18nc("@info:status 'non-fuzzy' in gettext terminology","Ready"));
- a->setData(QVariant(-2));
- a->setCheckable(true);
- a->setChecked(m_catalog->isApproved(m_currentPos));
-
- return;
- }
-
- TargetState state=m_catalog->state(m_currentPos);
-
- const char* const* states=Catalog::states();
- for (int i=0;i<StateCount;++i)
- {
- QAction* a=m_approveAction->menu()->addAction(i18n(states[i]));
- a->setData(QVariant(i));
- a->setCheckable(true);
- a->setChecked(state==i);
-
- if (i==New || i==Translated || i==Final)
- m_approveAction->menu()->addSeparator();
- }
-}
-
-void EditorTab::setState(QAction* a)
-{
- if (!(m_catalog->capabilities()&ExtendedStates))
- m_view->toggleApprovement();
- else
- m_view->setState(TargetState(a->data().toInt()));
-
- m_approveAction->menu()->clear();
-}
-
-void EditorTab::openPhasesWindow()
-{
- PhasesWindow w(m_catalog, this);
- w.exec();
-}
-
-void EditorTab::gotoPrevBookmark()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->prevBookmarkIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-void EditorTab::gotoNextBookmark()
-{
- DocPosition pos;
-
- if ( (pos.entry=m_catalog->nextBookmarkIndex(m_currentPos.entry)) == -1)
- return;
-
- gotoEntry(pos);
-}
-
-//wrapper for cmdline handling...
-void EditorTab::mergeOpen(KUrl url)
-{
- m_syncView->mergeOpen(url);
-}
-/*
-KUrl EditorWindow::mergeFile()
-{
- return _mergeView->url();
-}
-*/
-
-//HACK to prevent redundant repaintings when widget isn't visible
-void EditorTab::paintEvent(QPaintEvent* event)
-{
- if (QMdiSubWindow* sw=qobject_cast<QMdiSubWindow*>(parent()))
- {
- if (sw->mdiArea()->currentSubWindow()!=sw)
- return;
- }
- LokalizeSubwindowBase2::paintEvent(event);
-}
-
-void EditorTab::indexWordsForCompletion()
-{
- CompletionStorage::instance()->scanCatalog(m_catalog);
-}
-
-//see also termlabel.h
-void EditorTab::defineNewTerm()
-{
- //TODO just a word under cursor?
- QString en(m_view->selectionInSource().toLower());
- if (en.isEmpty())
- en=m_catalog->msgid(m_currentPos).toLower();
-
- QString target(m_view->selectionInTarget().toLower());
- if (target.isEmpty())
- target=m_catalog->msgstr(m_currentPos).toLower();
-
- _project->defineNewTerm(en,target);
-}
-
-
-void EditorTab::reloadFile()
-{
- KUrl mergeFile=m_syncView->url();
- DocPosition p=m_currentPos;
- if (!fileOpen(currentUrl()))
- return;
-
- gotoEntry(p);
- if (!mergeFile.isEmpty())
- mergeOpen(mergeFile);
-}
-
-void EditorTab::dispatchSrcFileOpenRequest(const QString& srcPath, int line)
-{
- m_srcFileOpenRequestAccepted=false;
- emit srcFileOpenRequested(srcPath,line);
- if (!m_srcFileOpenRequestAccepted)
- KMessageBox::information(this, i18nc("@info","Cannot open source files: no scripts to do so are currently loaded. "
- "Refer to the Lokalize handbook for script examples and how to plug them into your project.") );
-}
-
-
-//BEGIN DBus interface
-#include "editoradaptor.h"
-QList<int> EditorTab::ids;
-
-QString EditorTab::dbusObjectPath()
-{
- if ( m_dbusId==-1 )
- {
- m_adaptor=new EditorAdaptor(this);
-
- int i=0;
- while(i<ids.size()&&i==ids.at(i))
- ++i;
- ids.insert(i,i);
- m_dbusId=i;
- QDBusConnection::sessionBus().registerObject("/ThisIsWhatYouWant/Editor/" + QString::number(m_dbusId), this);
- }
- return "/ThisIsWhatYouWant/Editor/" + QString::number(m_dbusId);
-}
-
-
-KUrl EditorTab::currentUrl(){return m_catalog->url();}
-QByteArray EditorTab::currentFileContents(){return m_catalog->contents();}
-QString EditorTab::currentEntryId(){return m_catalog->id(m_currentPos);}
-QString EditorTab::selectionInTarget(){return m_view->selectionInTarget();}
-QString EditorTab::selectionInSource(){return m_view->selectionInSource();}
-
-void EditorTab::lookupSelectionInTranslationMemory(){emit tmLookupRequested(selectionInSource(),selectionInTarget());}
-
-
-void EditorTab::setEntryFilteredOut(int entry, bool filteredOut){m_transUnitsView->setEntryFilteredOut(entry, filteredOut);}
-void EditorTab::setEntriesFilteredOut(bool filteredOut){m_transUnitsView->setEntriesFilteredOut(filteredOut);}
-int EditorTab::entryCount(){return m_catalog->numberOfEntries();}
-
-QString EditorTab::entrySource(int entry, int form){return m_catalog->sourceWithTags(DocPosition(entry, form)).string;}
-QString EditorTab::entryTarget(int entry, int form){return m_catalog->targetWithTags(DocPosition(entry, form)).string;}
-int EditorTab::entryPluralFormCount(int entry){return m_catalog->isPlural(entry)?m_catalog->numberOfPluralForms():1;}
-bool EditorTab::entryReady(int entry){return m_catalog->isApproved(entry);}
-QString EditorTab::sourceLangCode(){return m_catalog->sourceLangCode();}
-QString EditorTab::targetLangCode(){return m_catalog->targetLangCode();}
-void EditorTab::addEntryNote(int entry, const QString& note){m_notesView->addNote(entry, note);}
-void EditorTab::addTemporaryEntryNote(int entry, const QString& note){m_notesView->addTemporaryEntryNote(entry, note);}
-
-void EditorTab::addAlternateTranslation(int entry, const QString& translation){m_altTransView->addAlternateTranslation(entry, translation);}
-void EditorTab::addTemporaryAlternateTranslation(int entry, const QString& translation){m_altTransView->addAlternateTranslation(entry, translation);}
-void EditorTab::attachAlternateTranslationFile(const QString& path){m_altTransView->attachAltTransFile(path);}
-
-void EditorTab::setEntryTarget(int entry, int form, const QString& content)
-{
- DocPosition pos(entry,form);
- //TODO uncomment when trunk is open for new strings
- //m_catalog->beginMacro(i18nc("@item Undo action item","Set unit text"));
- removeTargetSubstring(m_catalog, pos);
- insertCatalogString(m_catalog, pos, CatalogString(content));
- //m_catalog->endMacro();
- if (m_currentPos==pos)
- m_view->gotoEntry();
-}
-
-//END DBus interface
-
-
-#include "moc_editortab.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef EDITORTAB_H
-#define EDITORTAB_H
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "lokalizesubwindowbase.h"
-#include "pos.h"
-
-#include <kapplication.h>
-#include <kmainwindow.h>
-#include <kxmlguiclient.h>
-#include <kurl.h>
-
-#include <QHash>
-namespace Sonnet{class Dialog;}
-namespace Sonnet{class BackgroundChecker;}
-
-class KFind;
-class KReplace;
-class KProgressDialog;
-class KActionCategory;
-
-class Catalog;
-class EditorView;
-class Project;
-class ProjectView;
-class MergeView;
-class CatalogView;
-class MsgCtxtView;
-class AltTransView;
-namespace GlossaryNS{class GlossaryView;}
-
-
-
-struct EditorState
-{
-public:
- EditorState(){}
- EditorState(const EditorState& ks){dockWidgets=ks.dockWidgets;url=ks.url;}
- ~EditorState(){}
-
- QByteArray dockWidgets;
- KUrl url;
- KUrl mergeUrl;
- int entry;
- //int offset;
-};
-
-
-/**
- * @short Editor tab
- *
- * This class can be called a dispatcher for one message catalog.
- *
- * It is accessible via Lokalize.currentEditor() from scripts and via
- * '/ThisIsWhatYouWant/Editor/# : org.kde.Lokalize.Editor' from qdbusviewer
- *
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class EditorTab: public LokalizeSubwindowBase2
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.Editor")
- //qdbuscpp2xml -m -s editortab.h -o org.kde.lokalize.Editor.xml
-#define qdbuscpp2xml
-
-public:
- EditorTab(QWidget* parent, bool valid=true);
- ~EditorTab();
-
-
- //interface for LokalizeMainWindow
- void hideDocks();
- void showDocks();
- KUrl currentUrl();
- void setFullPathShown(bool);
- void setProperCaption(QString,bool);//reimpl to remove ' - Lokalize'
-public slots:
- void setProperFocus();
-public:
- bool queryClose();
- EditorState state();
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
-
- //wrapper for cmdline handling
- void mergeOpen(KUrl url=KUrl());
-
- bool fileOpen(KUrl url=KUrl(), KUrl baseUrl=KUrl(), bool silent=false);
-
- QString dbusObjectPath();
- int dbusId(){return m_dbusId;}
- QObject* adaptor(){return m_adaptor;}
-public slots:
- //for undo/redo, views
- void gotoEntry(DocPosition pos,int selection=0);
-#ifdef qdbuscpp2xml
- Q_SCRIPTABLE void gotoEntry(int entry){gotoEntry(DocPosition(entry));}
- Q_SCRIPTABLE void gotoEntryForm(int entry,int form){gotoEntry(DocPosition(entry,form));}
- Q_SCRIPTABLE void gotoEntryFormOffset(int entry,int form, int offset){gotoEntry(DocPosition(entry,form,offset));}
- Q_SCRIPTABLE void gotoEntryFormOffsetSelection(int entry,int form, int offset, int selection){gotoEntry(DocPosition(entry,form,offset),selection);}
-
- Q_SCRIPTABLE QString currentEntryId();
- Q_SCRIPTABLE int currentEntry(){return m_currentPos.entry;}
- Q_SCRIPTABLE int currentForm(){return m_currentPos.form;}
- Q_SCRIPTABLE QString selectionInTarget();
- Q_SCRIPTABLE QString selectionInSource();
-
- Q_SCRIPTABLE void setEntryFilteredOut(int entry, bool filteredOut);
- Q_SCRIPTABLE void setEntriesFilteredOut(bool filteredOut);
-
- Q_SCRIPTABLE int entryCount();
- Q_SCRIPTABLE QString entrySource(int entry, int form);
- Q_SCRIPTABLE QString entryTarget(int entry, int form);
- Q_SCRIPTABLE void setEntryTarget(int entry, int form, const QString& content);
- Q_SCRIPTABLE int entryPluralFormCount(int entry);
- Q_SCRIPTABLE bool entryReady(int entry);
- Q_SCRIPTABLE void addEntryNote(int entry, const QString& note);
- Q_SCRIPTABLE void addTemporaryEntryNote(int entry, const QString& note);
-
- Q_SCRIPTABLE void addAlternateTranslation(int entry, const QString& translation);
- Q_SCRIPTABLE void addTemporaryAlternateTranslation(int entry, const QString& translation);
-
- Q_SCRIPTABLE QString currentFile(){return currentUrl().pathOrUrl();}
- Q_SCRIPTABLE QByteArray currentFileContents();
- Q_SCRIPTABLE QString sourceLangCode();
- Q_SCRIPTABLE QString targetLangCode();
-
- Q_SCRIPTABLE void attachAlternateTranslationFile(const QString& path);
- Q_SCRIPTABLE void openSyncSource(QString path){mergeOpen(KUrl(path));}
- Q_SCRIPTABLE void reloadFile();
-#endif
- Q_SCRIPTABLE bool saveFile(const KUrl& url = KUrl());
- Q_SCRIPTABLE bool saveFileAs();
- Q_SCRIPTABLE void close(){return parent()->deleteLater();}
- Q_SCRIPTABLE void gotoNextUnfiltered();
- Q_SCRIPTABLE void gotoPrevUnfiltered();
- Q_SCRIPTABLE void gotoFirstUnfiltered();
- Q_SCRIPTABLE void gotoLastUnfiltered();
- Q_SCRIPTABLE void gotoNext();
- Q_SCRIPTABLE void gotoPrev();
- Q_SCRIPTABLE void gotoFirst();
- Q_SCRIPTABLE void gotoLast();
-
-
- Q_SCRIPTABLE bool findEntryBySourceContext(const QString& source, const QString& ctxt);
-
- Q_SCRIPTABLE bool isValid(){return m_valid;}
-
- Q_SCRIPTABLE void setSrcFileOpenRequestAccepted(bool a){m_srcFileOpenRequestAccepted=a;}
-
-private slots:
- void highlightFound(const QString &,int,int);//for find/replace
- void highlightFound_(const QString &,int,int);//for find/replace
-
- void lookupSelectionInTranslationMemory();
-
- //statusbar indication
- void numberOfFuzziesChanged();
- void numberOfUntranslatedChanged();
- //fuzzy, untr [statusbar] indication
- void msgStrChanged();
- //modif [caption] indication
- void setModificationSign(bool clean){setProperCaption(_captionPath,!clean);}
- void updateCaptionPath();
-
- //gui
- void switchForm(int);
-
- void undo();
- void redo();
- void findNext();
- void findPrev();
- void find();
-
- void replace();
- void replaceNext();//internal
- void doReplace(const QString&,int,int,int);//internal
- void cleanupReplace();//internal
-
-// void selectAll();
-// void deselectAll();
-// void clear();
-// void search2msgstr();
-// void plural2msgstr();
-
- void gotoEntry();
-
- void gotoPrevFuzzyUntr();
- bool gotoNextFuzzyUntr(const DocPosition& pos=DocPosition());
- void gotoNextFuzzy();
- void gotoPrevFuzzy();
- void gotoNextUntranslated();
- void gotoPrevUntranslated();
-
- void toggleApprovementGotoNextFuzzyUntr();
- void setApproveActionTitle();
-
-
- void spellcheck();
- void spellcheckNext();
- void spellcheckShow(const QString&,int);
- void spellcheckReplace(QString,int,const QString&);
- void spellcheckStop();
- void spellcheckCancel();
-
- void gotoNextBookmark();
- void gotoPrevBookmark();
-
- void displayWordCount();
-
- void openPhasesWindow();
-
- void defineNewTerm();
-
- void initLater();
- void showStatesMenu();
- void setState(QAction*);
- void dispatchSrcFileOpenRequest(const QString& srcPath, int line);
- void indexWordsForCompletion();
-
- void fileAutoSaveFailedWarning(const QString&);
-
-protected:
- void paintEvent(QPaintEvent* event);
-
-private:
- void setupAccel();
- void setupActions();
- void setupStatusBar();
-
- void findNext(const DocPosition& startingPos);
- void replaceNext(const DocPosition&);
- bool determineStartingPos(KFind*,//search or replace
- DocPosition&);//called from find() and findNext()
-
-private:
- Project* _project;
- Catalog* m_catalog;
-
- EditorView* m_view;
- KAction* m_approveAction;
-
- DocPosition m_currentPos;
- DocPosition _searchingPos; //for find/replace
- DocPosition _replacingPos;
- DocPosition _spellcheckPos;
- DocPosition _spellcheckStartPos;
-
- Sonnet::BackgroundChecker* m_sonnetChecker;
- Sonnet::Dialog* m_sonnetDialog;
- int _spellcheckStartUndoIndex;
- bool _spellcheckStop:1;
-
- bool m_currentIsApproved:1; //for statusbar animation
- bool m_currentIsUntr:1; //for statusbar animation
-
- bool m_fullPathShown:1;
-
- bool m_doReplaceCalled:1;//used to prevent non-clean catalog status
- KFind* _find;
- KReplace* _replace;
-
- //BEGIN views
- MergeView* m_syncView;
- MergeView* m_syncViewSecondary;
- CatalogView* m_transUnitsView;
- MsgCtxtView* m_notesView;
- AltTransView* m_altTransView;
- //END views
-
-
- QString _captionPath;
-
- //BEGIN dbus
- bool m_valid;
- QObject* m_adaptor;
- int m_dbusId;
- static QList<int> ids;
- bool m_srcFileOpenRequestAccepted;
- //END dbus
-
-signals:
- void tmLookupRequested(DocPosition::Part, const QString&);
- void tmLookupRequested(const QString& source, const QString& target);
-
- Q_SCRIPTABLE void srcFileOpenRequested(const QString& srcPath, int line);
-
- void fileOpenRequested(const KUrl& path, const QString& str, const QString& ctxt);
-
- //emitted when mainwindow is closed or another file is opened
- void fileClosed();
- Q_SCRIPTABLE void fileClosed(const QString& path);
- Q_SCRIPTABLE void fileSaved(const QString& path);
- Q_SCRIPTABLE void fileAboutToBeClosed();//old catalog is still accessible
- Q_SCRIPTABLE void fileOpened();
-
- Q_SCRIPTABLE void entryDisplayed();
- void signalNewEntryDisplayed(const DocPosition&);
- void signalEntryWithMergeDisplayed(bool,const DocPosition&);
- void signalFirstDisplayed(bool);
- void signalLastDisplayed(bool);
-
- void signalEquivTranslatedEntryDisplayed(bool);
- void signalApprovedEntryDisplayed(bool);
-
- void signalFuzzyEntryDisplayed(bool);
- void signalPriorFuzzyAvailable(bool);
- void signalNextFuzzyAvailable(bool);
-
- void signalPriorUntranslatedAvailable(bool);
- void signalNextUntranslatedAvailable(bool);
-
- void signalPriorFuzzyOrUntrAvailable(bool);
- void signalNextFuzzyOrUntrAvailable(bool);
-
- // merge mode signals gone to the view
- //NOTE move these to catalog tree view?
- void signalPriorBookmarkAvailable(bool);
- void signalNextBookmarkAvailable(bool);
- void signalBookmarkDisplayed(bool);
-
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "editortab.h"
-#include "editorview.h"
-#include "catalog.h"
-#include "pos.h"
-#include "cmd.h"
-#include "project.h"
-#include "prefs_lokalize.h"
-#include "ui_kaider_findextension.h"
-#include "stemming.h"
-
-
-#include <kglobal.h>
-#include <kmessagebox.h>
-#include <klocale.h>
-#include <kdebug.h>
-#include <kurl.h>
-
-#include <kprogressdialog.h>
-
-#include <kreplacedialog.h>
-#include <kreplace.h>
-
-#include <sonnet/backgroundchecker.h>
-#include <sonnet/dialog.h>
-
-#include <QTimer>
-#include <QPointer>
-
-
-#define IGNOREACCELS KFind::MinimumUserOption
-#define INCLUDENOTES KFind::MinimumUserOption*2
-
-static long makeOptions(long options, const Ui_findExtension* ui_findExtension)
-{
- return options
- +IGNOREACCELS*ui_findExtension->m_ignoreAccelMarks->isChecked()
- +INCLUDENOTES*ui_findExtension->m_notes->isChecked();
- //bool skipMarkup(){return ui_findExtension->m_skipTags->isChecked();}
-}
-
-class EntryFindDialog: public KFindDialog
-{
-public:
- EntryFindDialog(QWidget* parent);
- ~EntryFindDialog();
- long options() const{return makeOptions(KFindDialog::options(),ui_findExtension);}
- static EntryFindDialog* instance(QWidget* parent=0);
-private:
- static QPointer<EntryFindDialog> _instance;
- static void cleanup(){delete EntryFindDialog::_instance;}
-private:
- Ui_findExtension* ui_findExtension;
-};
-
-QPointer<EntryFindDialog> EntryFindDialog::_instance=0;
-EntryFindDialog* EntryFindDialog::instance(QWidget* parent)
-{
- if (_instance==0 )
- {
- _instance=new EntryFindDialog(parent);
- qAddPostRoutine(EntryFindDialog::cleanup);
- }
- return _instance;
-}
-
-EntryFindDialog::EntryFindDialog(QWidget* parent)
- : KFindDialog(parent)
- , ui_findExtension(new Ui_findExtension)
-{
- ui_findExtension->setupUi(findExtension());
- setHasSelection(false);
-
- KConfig config;
- KConfigGroup stateGroup(&config,"FindReplace");
- setOptions(stateGroup.readEntry("FindOptions",(qlonglong)0));
- setFindHistory(stateGroup.readEntry("FindHistory",QStringList()));
-}
-
-EntryFindDialog::~EntryFindDialog()
-{
- KConfig config;
- KConfigGroup stateGroup(&config,"FindReplace");
- stateGroup.writeEntry("FindOptions",(qlonglong)options());
- stateGroup.writeEntry("FindHistory",findHistory());
-
- delete ui_findExtension;
-}
-
-//BEGIN EntryReplaceDialog
-class EntryReplaceDialog: public KReplaceDialog
-{
-public:
- EntryReplaceDialog(QWidget* parent);
- ~EntryReplaceDialog();
- long options() const{return makeOptions(KReplaceDialog::options(),ui_findExtension);}
- static EntryReplaceDialog* instance(QWidget* parent=0);
-private:
- static QPointer<EntryReplaceDialog> _instance;
- static void cleanup(){delete EntryReplaceDialog::_instance;}
-private:
- Ui_findExtension* ui_findExtension;
-};
-
-QPointer<EntryReplaceDialog> EntryReplaceDialog::_instance=0;
-EntryReplaceDialog* EntryReplaceDialog::instance(QWidget* parent)
-{
- if (_instance==0 )
- {
- _instance=new EntryReplaceDialog(parent);
- qAddPostRoutine(EntryReplaceDialog::cleanup);
- }
- return _instance;
-}
-
-EntryReplaceDialog::EntryReplaceDialog(QWidget* parent)
- : KReplaceDialog(parent)
- , ui_findExtension(new Ui_findExtension)
-{
- ui_findExtension->setupUi(findExtension());
- //ui_findExtension->m_notes->hide();
- setHasSelection(false);
-
- KConfig config;
- KConfigGroup stateGroup(&config,"FindReplace");
- setOptions(stateGroup.readEntry("ReplaceOptions",(qlonglong)0));
- setFindHistory(stateGroup.readEntry("ReplacePatternHistory",QStringList()));
- setReplacementHistory(stateGroup.readEntry("ReplacementHistory",QStringList()));
-}
-
-EntryReplaceDialog::~EntryReplaceDialog()
-{
- KConfig config;
- KConfigGroup stateGroup(&config,"FindReplace");
- stateGroup.writeEntry("ReplaceOptions",(qlonglong)options());
- stateGroup.writeEntry("ReplacePatternHistory",findHistory());
- stateGroup.writeEntry("ReplacementHistory",replacementHistory());
-
- delete ui_findExtension;
-}
-//END EntryReplaceDialog
-
-//TODO &,
-static void calcOffsetWithAccels(const QString& data, int& offset, int& length)
-{
- int i=0;
- for (;i<offset;++i)
- if (Q_UNLIKELY( data.at(i)=='&' ))
- ++offset;
-
- //if & is inside highlighted word
- int limit=offset+length;
- for (i=offset;i<limit;++i)
- if (Q_UNLIKELY( data.at(i)=='&' ))
- {
- ++length;
- limit=qMin(data.size(),offset+length);//just safety
- }
-}
-
-void EditorTab::find()
-{
- //QWidget* p=0; QWidget* next=qobject_cast<QWidget*>(parent()); while(next) { p=next; next=qobject_cast<QWidget*>(next->parent()); }
- EntryFindDialog::instance(nativeParentWidget());
-
- QString sel=selectionInTarget();
- if (!(sel.isEmpty()&&selectionInSource().isEmpty()))
- {
- if (sel.isEmpty())
- sel=selectionInSource();
- if (_find&&_find->options()&IGNOREACCELS)
- sel.remove('&');
- EntryFindDialog::instance()->setPattern(sel);
- }
-
- if ( EntryFindDialog::instance()->exec() != QDialog::Accepted )
- return;
-
- if (_find)
- {
- _find->resetCounts();
- _find->setPattern(EntryFindDialog::instance()->pattern());
- _find->setOptions(EntryFindDialog::instance()->options());
-
- }
- else // This creates a find-next-prompt dialog if needed.
- {
- _find = new KFind(EntryFindDialog::instance()->pattern(),EntryFindDialog::instance()->options(),this,EntryFindDialog::instance());
- connect(_find,SIGNAL(highlight(QString,int,int)),this, SLOT(highlightFound(QString,int,int)) );
- connect(_find,SIGNAL(findNext()),this,SLOT(findNext()));
- _find->closeFindNextDialog();
- }
-
- DocPosition pos;
- if (_find->options() & KFind::FromCursor)
- pos=m_currentPos;
- else if (!determineStartingPos(_find,pos))
- return;
-
-
- findNext(pos);
-}
-
-bool EditorTab::determineStartingPos(KFind* find,
- DocPosition& pos)
-{
- if (find->options() & KFind::FindBackwards)
- {
- pos.entry=m_catalog->numberOfEntries()-1;
- pos.form=(m_catalog->isPlural(pos.entry))?
- m_catalog->numberOfPluralForms()-1:0;
- }
- else
- {
- pos.entry=0;
- pos.form=0;
- }
- return true;
-}
-
-void EditorTab::findNext(const DocPosition& startingPos)
-{
- Catalog& catalog=*m_catalog;
- KFind& find=*_find;
-
- if (Q_UNLIKELY( catalog.numberOfEntries()<=startingPos.entry ))
- return;//for the case when app wasn't able to process event before file close
-
- bool anotherEntry=_searchingPos.entry!=m_currentPos.entry;
- _searchingPos=startingPos;
-
- if (anotherEntry)
- _searchingPos.offset=0;
-
-
- QRegExp rx("[^(\\\\n)>]\n");
- QTime a;a.start();
- //_searchingPos.part=DocPosition::Source;
- bool ignoreaccels=_find->options()&IGNOREACCELS;
- bool includenotes=_find->options()&INCLUDENOTES;
- int switchOptions=DocPosition::Source|DocPosition::Target|(includenotes*DocPosition::Comment);
- int flag=1;
- while (flag)
- {
-
- flag=0;
- KFind::Result res = KFind::NoMatch;
- while (true)
- {
- if (find.needData()||anotherEntry||m_view->m_modifiedAfterFind)
- {
- anotherEntry=false;
- m_view->m_modifiedAfterFind=false;
-
- QString data;
- if (_searchingPos.part==DocPosition::Comment)
- data=catalog.notes(_searchingPos).at(_searchingPos.form).content;
- else
- data=catalog.catalogString(_searchingPos).string;
-
- if (ignoreaccels)
- data.remove('&');
- find.setData(data);
- }
-
- res = find.find();
- //offset=-1;
- if (res!=KFind::NoMatch)
- break;
-
- if (!(
- (find.options()&KFind::FindBackwards)?
- switchPrev(m_catalog,_searchingPos,switchOptions):
- switchNext(m_catalog,_searchingPos,switchOptions)
- ))
- break;
- }
-
- if (res==KFind::NoMatch)
- {
- //file-wide search
- if(find.shouldRestart(true,true))
- {
- flag=1;
- determineStartingPos(_find,_searchingPos);
- }
- find.resetCounts();
- }
- }
-}
-
-void EditorTab::findNext()
-{
- if (_find)
- {
- findNext((m_currentPos.entry==_searchingPos.entry&&_searchingPos.part==DocPosition::Comment)?
- _searchingPos:m_currentPos);
- }
- else
- find();
-
-}
-
-void EditorTab::findPrev()
-{
-
- if (_find)
- {
- _find->setOptions(_find->options() ^ KFind::FindBackwards);
- findNext(m_currentPos);
- }
- else
- {
- find();
- }
-
-}
-
-void EditorTab::highlightFound(const QString &,int matchingIndex,int matchedLength)
-{
- if (_find->options()&IGNOREACCELS && _searchingPos.part!=DocPosition::Comment)
- {
- QString data=m_catalog->catalogString(_searchingPos).string;
- calcOffsetWithAccels(data, matchingIndex, matchedLength);
- }
-
- _searchingPos.offset=matchingIndex;
- gotoEntry(_searchingPos,matchedLength);
-}
-
-void EditorTab::replace()
-{
- EntryReplaceDialog::instance(nativeParentWidget());
-
- if (!m_view->selectionInTarget().isEmpty())
- {
- if (_replace&&_replace->options()&IGNOREACCELS)
- {
- QString tmp(m_view->selectionInTarget());
- tmp.remove('&');
- EntryReplaceDialog::instance()->setPattern(tmp);
- }
- else
- EntryReplaceDialog::instance()->setPattern(m_view->selectionInTarget());
- }
-
-
- if ( EntryReplaceDialog::instance()->exec() != QDialog::Accepted )
- return;
-
-
- if (_replace) _replace->deleteLater();// _replace=0;
-
- // This creates a find-next-prompt dialog if needed.
- {
- _replace = new KReplace(EntryReplaceDialog::instance()->pattern(),EntryReplaceDialog::instance()->replacement(),EntryReplaceDialog::instance()->options(),this,EntryReplaceDialog::instance());
- connect(_replace,SIGNAL(highlight(QString,int,int)), this,SLOT(highlightFound_(QString,int,int)));
- connect(_replace,SIGNAL(findNext()), this,SLOT(replaceNext()));
- connect(_replace,SIGNAL(replace(QString,int,int,int)), this,SLOT(doReplace(QString,int,int,int)));
- connect(_replace,SIGNAL(dialogClosed()), this,SLOT(cleanupReplace()));
-// _replace->closeReplaceNextDialog();
- }
-// else
-// {
-// _replace->resetCounts();
-// _replace->setPattern(EntryReplaceDialog::instance()->pattern());
-// _replace->setOptions(EntryReplaceDialog::instance()->options());
-// }
-
- //m_catalog->beginMacro(i18nc("@item Undo action item","Replace"));
- m_doReplaceCalled=false;
-
- if (_replace->options() & KFind::FromCursor)
- replaceNext(m_currentPos);
- else
- {
- DocPosition pos;
- if (!determineStartingPos(_replace,pos)) return;
- replaceNext(pos);
- }
-
-}
-
-
-void EditorTab::replaceNext(const DocPosition& startingPos)
-{
- bool anotherEntry=_replacingPos.entry!=_replacingPos.entry;
- _replacingPos=startingPos;
-
- if (anotherEntry)
- _replacingPos.offset=0;
-
-
- int flag=1;
- bool ignoreaccels=_replace->options()&IGNOREACCELS;
- bool includenotes=_replace->options()&INCLUDENOTES;
- kWarning()<<"includenotes"<<includenotes;
- int switchOptions=DocPosition::Target|(includenotes*DocPosition::Comment);
- while (flag)
- {
- flag=0;
- KFind::Result res=KFind::NoMatch;
- while (1)
- {
- if (_replace->needData()||anotherEntry/*||m_view->m_modifiedAfterFind*/)
- {
- anotherEntry=false;
- //m_view->m_modifiedAfterFind=false;//NOTE TEST THIS
-
- QString data;
- if (_replacingPos.part==DocPosition::Comment)
- data=m_catalog->notes(_replacingPos).at(_replacingPos.form).content;
- else
- {
- data=m_catalog->targetWithTags(_replacingPos).string;
- if (ignoreaccels) data.remove('&');
- }
- _replace->setData(data);
- }
- res = _replace->replace();
- if (res!=KFind::NoMatch)
- break;
-
- if (!(
- (_replace->options()&KFind::FindBackwards)?
- switchPrev(m_catalog,_replacingPos,switchOptions):
- switchNext(m_catalog,_replacingPos,switchOptions)
- ))
- break;
- }
-
- if (res==KFind::NoMatch)
- {
- if((_replace->options()&KFind::FromCursor)
- &&_replace->shouldRestart(true))
- {
- flag=1;
- determineStartingPos(_replace,_replacingPos);
- }
- else
- {
- if(!(_replace->options() & KFind::FromCursor))
- _replace->displayFinalDialog();
-
- _replace->closeReplaceNextDialog();
- cleanupReplace();
- }
- _replace->resetCounts();
- }
- }
-}
-
-void EditorTab::cleanupReplace()
-{
- if(m_doReplaceCalled)
- {
- m_doReplaceCalled=false;
- m_catalog->endMacro();
- }
-}
-
-void EditorTab::replaceNext()
-{
- replaceNext(m_currentPos);
-}
-
-void EditorTab::highlightFound_(const QString &,int matchingIndex,int matchedLength)
-{
- if (_replace->options()&IGNOREACCELS)
- {
- QString data=m_catalog->targetWithTags(_replacingPos).string;
- calcOffsetWithAccels(data,matchingIndex,matchedLength);
- }
-
- _replacingPos.offset=matchingIndex;
- gotoEntry(_replacingPos,matchedLength);
-}
-
-
-void EditorTab::doReplace(const QString &newStr,int offset,int newLen,int remLen)
-{
- if(!m_doReplaceCalled)
- {
- m_doReplaceCalled=true;
- m_catalog->beginMacro(i18nc("@item Undo action item","Replace"));
- }
- DocPosition pos=_replacingPos;
- if (_replacingPos.part==DocPosition::Comment)
- m_catalog->push(new SetNoteCmd(m_catalog,pos,newStr));
- else
- {
- QString oldStr=m_catalog->target(_replacingPos);
-
- if (_replace->options()&IGNOREACCELS)
- calcOffsetWithAccels(oldStr,offset,remLen);
-
- pos.offset=offset;
- m_catalog->push(new DelTextCmd(m_catalog,pos,oldStr.mid(offset,remLen)));
-
- if (newLen)
- m_catalog->push(new InsTextCmd(m_catalog,pos,newStr.mid(offset,newLen)));
- }
- if (pos.entry==m_currentPos.entry)
- {
- pos.offset+=newLen;
- m_view->gotoEntry(pos);
- }
-}
-
-
-
-
-
-
-
-
-
-
-void EditorTab::spellcheck()
-{
- if (!m_sonnetDialog)
- {
- m_sonnetChecker=new Sonnet::BackgroundChecker(this);
- m_sonnetChecker->changeLanguage(enhanceLangCode(Project::instance()->langCode()));
- m_sonnetDialog=new Sonnet::Dialog(m_sonnetChecker,this);
- connect(m_sonnetDialog,SIGNAL(done(QString)),this,SLOT(spellcheckNext()));
- connect(m_sonnetDialog,SIGNAL(replace(QString,int,QString)),
- this,SLOT(spellcheckReplace(QString,int,QString)));
- connect(m_sonnetDialog,SIGNAL(stop()),this,SLOT(spellcheckStop()));
- connect(m_sonnetDialog,SIGNAL(cancel()),this,SLOT(spellcheckCancel()));
-
- connect(m_sonnetDialog/*m_sonnetChecker*/,SIGNAL(misspelling(QString,int)),
- this,SLOT(spellcheckShow(QString,int)));
-// disconnect(/*m_sonnetDialog*/m_sonnetChecker,SIGNAL(misspelling(QString,int)),
-// m_sonnetDialog,SLOT(slotMisspelling(QString,int)));
-//
-// connect( d->checker, SIGNAL(misspelling(const QString&, int)),
-// SLOT(slotMisspelling(const QString&, int)) );
- }
-
- QString text=m_catalog->msgstr(m_currentPos);
- if (!m_view->selectionInTarget().isEmpty())
- text=m_view->selectionInTarget();
- text.remove('&');
- m_sonnetDialog->setBuffer(text);
-
- _spellcheckPos=m_currentPos;
- _spellcheckStartPos=m_currentPos;
- _spellcheckStop=false;
- //m_catalog->beginMacro(i18n("Spellcheck"));
- _spellcheckStartUndoIndex=m_catalog->index();
- m_sonnetDialog->show();
-
-}
-
-
-void EditorTab::spellcheckNext()
-{
- if (_spellcheckStop)
- return;
-
- do
- {
- if (!switchNext(m_catalog,_spellcheckPos))
- {
- kWarning()<<_spellcheckStartPos.entry;
- kWarning()<<_spellcheckStartPos.form;
- bool continueFromStart=
- !(_spellcheckStartPos.entry==0 && _spellcheckStartPos.form==0)
- && KMessageBox::questionYesNo(this,i18n("Lokalize has reached end of document. Do you want to continue from start?"), i18nc("@title", "Spellcheck"))==KMessageBox::Yes;
- if (continueFromStart)
- {
- _spellcheckStartPos.entry=0;
- _spellcheckStartPos.form=0;
- _spellcheckPos=_spellcheckStartPos;
- }
- else
- {
- KMessageBox::information(this,i18n("Lokalize has finished spellchecking"), i18nc("@title", "Spellcheck"));
- return;
- }
- }
- }
- while (m_catalog->msgstr(_spellcheckPos).isEmpty() || !m_catalog->isApproved(_spellcheckPos.entry));
-
- QString text=m_catalog->msgstr(_spellcheckPos);
- text.remove('&');
- m_sonnetDialog->setBuffer(text);
-}
-
-void EditorTab::spellcheckStop()
-{
- _spellcheckStop=true;
-}
-
-void EditorTab::spellcheckCancel()
-{
- m_catalog->setIndex(_spellcheckStartUndoIndex);
- gotoEntry(_spellcheckPos);
-}
-
-void EditorTab::spellcheckShow(const QString &word, int offset)
-{
- QString source=m_catalog->source(_spellcheckPos);
- source.remove('&');
- if (source.contains(word))
- {
- m_sonnetDialog->setUpdatesEnabled(false);
- m_sonnetChecker->continueChecking();
- return;
- }
- m_sonnetDialog->setUpdatesEnabled(true);
-
- show();
-
- DocPosition pos=_spellcheckPos;
- int length=word.length();
- calcOffsetWithAccels(m_catalog->target(pos),offset,length);
- pos.offset=offset;
-
- gotoEntry(pos,length);
-}
-
-void EditorTab::spellcheckReplace(QString oldWord, int offset, const QString &newWord)
-{
- DocPosition pos=_spellcheckPos;
- int length=oldWord.length();
- calcOffsetWithAccels(m_catalog->target(pos),offset,length);
- pos.offset=offset;
- if (length>oldWord.length())//replaced word contains accel mark
- oldWord=m_catalog->target(pos).mid(offset,length);
-
- m_catalog->push(new DelTextCmd(m_catalog,pos,oldWord));
- m_catalog->push(new InsTextCmd(m_catalog,pos,newWord));
-
-
- gotoEntry(pos,newWord.length());
-}
-
-
-
-
-
-
-
-
-
-
-
-bool EditorTab::findEntryBySourceContext(const QString& source, const QString& ctxt)
-{
- DocPosition pos(0);
- do
- {
- if (m_catalog->source(pos)==source && m_catalog->context(pos.entry)==QStringList(ctxt))
- {
- gotoEntry(pos);
- return true;
- }
- }
- while (switchNext(m_catalog,pos));
- return false;
-}
-
-
-void EditorTab::displayWordCount()
-{
- //TODO in trans and fuzzy separately
- int sourceCount=0;
- int targetCount=0;
- QRegExp rxClean(Project::instance()->markup()+'|'+Project::instance()->accel());//cleaning regexp; NOTE isEmpty()?
- QRegExp rxSplit("\\W|\\d");//splitting regexp
- DocPosition pos(0);
- do
- {
- QString msg=m_catalog->source(pos);
- msg.remove(rxClean);
- QStringList words=msg.split(rxSplit,QString::SkipEmptyParts);
- sourceCount+=words.size();
-
- msg=m_catalog->target(pos);
- msg.remove(rxClean);
- words=msg.split(rxSplit,QString::SkipEmptyParts);
- targetCount+=words.size();
- }
- while (switchNext(m_catalog,pos));
-
- KMessageBox::information(this, i18nc("@info words count",
- "Source text words: %1<br/>Target text words: %2",
- sourceCount,targetCount),i18nc("@title","Word Count"));
-}
-
-
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="Editor" version="10">
-<MenuBar>
- <Menu name="file"><text>&File</text>
- <Action name="file_new"/>
- <MergeLocal name="new_merge"/>
- <Action name="file_open"/>
- <Action name="file_open_recent"/>
- <MergeLocal name="open_merge"/>
- <Separator/>
- <Action name="file_save"/>
- <Action name="file_save_as"/>
- <Action name="file_save_all"/>
- <MergeLocal name="save_merge"/>
- <Action name="file_revert"/>
- <Action name="file_revert_all"/>
- <MergeLocal name="revert_merge"/>
- <Separator/>
- <Action name="file_print"/>
- <Action name="file_print_preview"/>
- <MergeLocal name="print_merge"/>
- <Action name="file_mail"/>
- <MergeLocal name="mail_merge"/>
- <Separator/>
- <Action name="file_phases"/>
- <MergeLocal/>
- <Separator/>
- <Action name="file_close"/>
- <Action name="file_close_all"/>
- <MergeLocal name="close_merge"/>
- </Menu>
- <Menu name="edit"><text>&Edit</text>
- <Action name="edit_undo"/>
- <Action name="edit_redo"/>
- <MergeLocal name="edit_undo_merge"/>
- <Separator/>
- <Action name="edit_cut"/>
- <Action name="edit_copy"/>
- <Action name="edit_paste"/>
- <MergeLocal name="edit_paste_merge"/>
- <Action name="edit_clear"/>
- <Separator/>
- <Action name="edit_select_all"/>
- <Action name="edit_deselect"/>
- <MergeLocal name="edit_select_merge"/>
- <Separator/>
- <Action name="edit_find"/>
- <Action name="edit_find_next"/>
- <Action name="edit_find_prev"/>
- <Action name="edit_replace"/>
- <MergeLocal name="edit_find_merge"/>
- <Separator/>
- <MergeLocal/>
- <Action name="edit_approve"/>
- <Action name="edit_nonequiv"/>
- <Action name="edit_msgid2msgstr"/>
- <Action name="edit_unwrap-target"/>
- <Action name="edit_clear-target"/>
- <Action name="edit_completion"/>
- <Action name="edit_tagmenu"/>
- <Action name="edit_tagimmediate"/>
- <Action name="edit_spellreplace"/>
- <Action name="edit_addnote"/>
- <Menu name="glossary"><text>&Glossary</text>
- <Action name="glossary_define"/>
- <Separator/>
- <Action name="glossary_insert_0"/>
- <Action name="glossary_insert_1"/>
- <Action name="glossary_insert_2"/>
- <Action name="glossary_insert_3"/>
- <Action name="glossary_insert_4"/>
- <Action name="glossary_insert_5"/>
- <Action name="glossary_insert_6"/>
- <Action name="glossary_insert_7"/>
- <Action name="glossary_insert_8"/>
- <Action name="glossary_insert_9"/>
- <Action name="glossary_insert_10"/>
- <Action name="glossary_insert_11"/>
- <Action name="glossary_insert_12"/>
- <Action name="glossary_insert_13"/>
- <Action name="glossary_insert_14"/>
- <Action name="glossary_insert_15"/>
- <Action name="glossary_insert_16"/>
- <Action name="glossary_insert_17"/>
- <Action name="glossary_insert_18"/>
- <Action name="glossary_insert_19"/>
- <Action name="glossary_insert_20"/>
- </Menu>
- <Menu name="tmquery"><text>Translation &Memory</text>
- <Action name="tmquery_do"/>
- <Separator/>
- <Action name="tmquery_insert_0"/>
- <Action name="tmquery_insert_1"/>
- <Action name="tmquery_insert_2"/>
- <Action name="tmquery_insert_3"/>
- <Action name="tmquery_insert_4"/>
- <Action name="tmquery_insert_5"/>
- <Action name="tmquery_insert_6"/>
- <Action name="tmquery_insert_7"/>
- <Action name="tmquery_insert_8"/>
- <Action name="tmquery_insert_9"/>
- <Action name="tmquery_insert_10"/>
- <Action name="tmquery_insert_11"/>
- <Action name="tmquery_insert_12"/>
- </Menu>
- <Menu name="alttrans"><text>Alternative Translations</text>
- <Action name="alttrans_attach"/>
- <Separator/>
- <Action name="alttrans_insert_0"/>
- <Action name="alttrans_insert_1"/>
- <Action name="alttrans_insert_2"/>
- <Action name="alttrans_insert_3"/>
- <Action name="alttrans_insert_4"/>
- <Action name="alttrans_insert_5"/>
- <Action name="alttrans_insert_6"/>
- <Action name="alttrans_insert_7"/>
- <Action name="alttrans_insert_8"/>
- <Action name="alttrans_insert_9"/>
- <Action name="alttrans_insert_10"/>
- <Action name="alttrans_insert_11"/>
- <Action name="alttrans_insert_12"/>
- </Menu>
- </Menu>
- <Menu name="go"><text>&Go</text>
- <Action name="go_up"/>
- <Action name="go_back"/>
- <Action name="go_forward"/>
- <Action name="go_home"/>
- <Separator/>
- <Action name="go_previous"/>
- <Action name="go_next"/>
- <Action name="go_goto_page"/>
- <Action name="go_goto_line"/>
- <Action name="go_goto"/>
- <Separator/>
- <Action name="go_first"/>
- <Action name="go_last"/>
- <Separator/>
- <Action name="go_document_back"/>
- <Action name="go_document_forward"/>
- <Separator/>
- <MergeLocal/>
- <Action name="go_goto"/>
- <Separator/>
- <Action name="go_first"/>
- <Action name="go_last"/>
- <Separator/>
- <Action name="go_prev_fuzzyUntr"/>
- <Action name="go_next_fuzzyUntr"/>
- <Action name="go_prev_fuzzy"/>
- <Action name="go_next_fuzzy"/>
- <Action name="go_prev_untrans"/>
- <Action name="go_next_untrans"/>
- <Menu name="bookmarks"><text>&Bookmarks</text>
- <Action name="bookmark_prior"/>
- <Action name="bookmark_next"/>
- <Action name="bookmark_add"/>
- <Action name="bookmark_edit"/>
- </Menu>
- </Menu>
- <Menu name="merge"><text>S&ync</text>
- <Action name="merge_open"/>
- <Separator/>
- <Action name="merge_prev"/>
- <Action name="merge_next"/>
- <Action name="merge_nextapproved"/>
- <Separator/>
- <Action name="merge_accept"/>
- <Action name="merge_acceptnew"/>
- <Separator/>
- <Menu name="mergesecondary"><text>&Secondary sync source</text>
- <Action name="mergesecondary_open"/>
- <Separator/>
- <Action name="mergesecondary_prev"/>
- <Action name="mergesecondary_next"/>
- <Separator/>
- <Action name="mergesecondary_accept"/>
- <Action name="mergesecondary_acceptnew"/>
- <Separator/>
- </Menu>
- </Menu>
- <Menu name="tools">
- <Separator/>
- <Action name="tools_tm_batch"/>
- <Action name="tools_tm_batch_fuzzy"/>
- <Separator/>
- <Action name="tools_spelling"/>
- <Separator/>
- <Action name="tools_wordcount"/>
- <Separator/>
- </Menu>
- <Menu name="settings">
- <Menu name="toolviews"><text>Tool&views</text>
- <Action name="showmsgiddiff_action" />
- <Action name="showprojectview_action" />
- <Action name="showmergeview_action" />
- <Action name="showmergeviewsecondary_action" />
- <Action name="showmsgctxt_action" />
- <Action name="showcatalogtreeview_action" />
- <Action name="showglossaryview_action" />
- <Action name="showtmqueryview_action" />
- <Action name="showbinunitsview_action" />
- </Menu>
- <MergeLocal/>
- </Menu>
-</MenuBar>
-<!--<State name="po" >
- <disable>
- </disable>
-</State>
-<State name="xliff" >
- <enable>
- </enable>
-</State>-->
-<ToolBar name="mainToolBar"><text>Main Toolbar</text>
- <Action name="file_new"/>
- <Action name="file_open"/>
- <Action name="file_save"/>
- <Action name="file_print"/>
- <Action name="file_mail"/>
- <Separator/>
- <Action name="edit_undo"/>
- <Action name="edit_redo"/>
- <Action name="edit_cut"/>
- <Action name="edit_copy"/>
- <Action name="edit_paste"/>
- <Separator/>
- <Action name="edit_find"/>
- <Action name="view_zoom"/>
- <Separator/>
- <Action name="go_previous"/>
- <Action name="go_next"/>
- <Action name="go_home"/>
- <Separator/>
- <Action name="edit_approve"/>
-</ToolBar>
-</kpartgui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize (some bits of KBabel code were reused)
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 1999-2000 by Matthias Kiefer <matthias.kiefer@gmx.de>
- 2001-2004 by Stanislav Visnovsky <visnovsky@kde.org>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "editorview.h"
-#include "xlifftextedit.h"
-#include "project.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "prefs_lokalize.h"
-#include "prefs.h"
-
-#include <QTimer>
-#include <QMenu>
-#include <QtGui/qevent.h>
-
-#include <QLabel>
-#include <QHBoxLayout>
-
-
-#include <ktabbar.h>
-#include <kled.h>
-#include <kmessagebox.h>
-#include <klocale.h>
-#include <kdebug.h>
-#include <kurl.h>
-#include <kstandardshortcut.h>
-#include <kcolorscheme.h>
-
-
-//parent is set on qsplitter insertion
-
-LedsWidget::LedsWidget(QWidget* parent): QWidget(parent)
-{
- KColorScheme colorScheme(QPalette::Normal);
-
- QHBoxLayout* layout=new QHBoxLayout(this);
- layout->addStretch();
- layout->addWidget(new QLabel(i18nc("@label whether entry is fuzzy","Not ready:"),this));
- layout->addWidget(ledFuzzy=new KLed(colorScheme.foreground(KColorScheme::NeutralText).color()/*Qt::green*/,KLed::Off,KLed::Sunken,KLed::Rectangular));
- layout->addWidget(new QLabel(i18nc("@label whether entry is untranslated","Untranslated:"),this));
- layout->addWidget(ledUntr=new KLed(colorScheme.foreground(KColorScheme::NegativeText).color()/*Qt::red*/,KLed::Off,KLed::Sunken,KLed::Rectangular));
- layout->addSpacing(1);
- layout->addWidget(lblColumn=new QLabel(this));
- layout->addStretch();
- setMaximumHeight(minimumSizeHint().height());
-}
-
-void LedsWidget::contextMenuEvent(QContextMenuEvent* event)
-{
- QMenu menu;
- menu.addAction(i18nc("@action","Hide"));
- if (!menu.exec(event->globalPos()))
- return; //NOTE the config doesn't seem to work
- Settings::setLeds(false);
- SettingsController::instance()->dirty=true;
- hide();
-}
-
-void LedsWidget::cursorPositionChanged(int column)
-{
- lblColumn->setText(i18nc("@info:label cursor position", "Column: %1", column));
-}
-
-
-
-EditorView::EditorView(QWidget *parent,Catalog* catalog/*,keyEventHandler* kh*/)
- : QSplitter(Qt::Vertical,parent)
- , m_catalog(catalog)
- , m_sourceTextEdit(new TranslationUnitTextEdit(catalog,DocPosition::Source,this))
- , m_targetTextEdit(new TranslationUnitTextEdit(catalog,DocPosition::Target,this))
- , m_pluralTabBar(new KTabBar(this))
- , _leds(0)
- , m_modifiedAfterFind(false)
-{
- m_pluralTabBar->hide();
- m_sourceTextEdit->setWhatsThis(i18n("<qt><p><b>Original String</b></p>\n"
- "<p>This part of the window shows the original message\n"
- "of the currently displayed entry.</p></qt>"));
-
- connect (m_targetTextEdit, SIGNAL(contentsModified(DocPosition)), this, SLOT(resetFindForCurrent(DocPosition)));
- connect (m_targetTextEdit, SIGNAL(toggleApprovementRequested()), this, SLOT(toggleApprovement()));
- connect (this, SIGNAL(signalApprovedEntryDisplayed(bool)), m_targetTextEdit, SLOT(reflectApprovementState()));
- connect (m_sourceTextEdit, SIGNAL(tagInsertRequested(InlineTag)), m_targetTextEdit, SLOT(insertTag(InlineTag)));
-
- connect (m_sourceTextEdit, SIGNAL(binaryUnitSelectRequested(QString)), this, SIGNAL(binaryUnitSelectRequested(QString)));
- connect (m_targetTextEdit, SIGNAL(binaryUnitSelectRequested(QString)), this, SIGNAL(binaryUnitSelectRequested(QString)));
- connect (m_sourceTextEdit, SIGNAL(gotoEntryRequested(DocPosition)), this, SIGNAL(gotoEntryRequested(DocPosition)));
- connect (m_targetTextEdit, SIGNAL(gotoEntryRequested(DocPosition)), this, SIGNAL(gotoEntryRequested(DocPosition)));
-
- connect (m_sourceTextEdit, SIGNAL(tmLookupRequested(DocPosition::Part,QString)), this, SIGNAL(tmLookupRequested(DocPosition::Part,QString)));
- connect (m_targetTextEdit, SIGNAL(tmLookupRequested(DocPosition::Part,QString)), this, SIGNAL(tmLookupRequested(DocPosition::Part,QString)));
-
- connect (m_sourceTextEdit, SIGNAL(findRequested()), this, SIGNAL(findRequested()));
- connect (m_targetTextEdit, SIGNAL(findRequested()), this, SIGNAL(findRequested()));
- connect (m_sourceTextEdit, SIGNAL(findNextRequested()), this, SIGNAL(findNextRequested()));
- connect (m_targetTextEdit, SIGNAL(findNextRequested()), this, SIGNAL(findNextRequested()));
- connect (m_sourceTextEdit, SIGNAL(replaceRequested()), this, SIGNAL(replaceRequested()));
- connect (m_targetTextEdit, SIGNAL(replaceRequested()), this, SIGNAL(replaceRequested()));
-
- connect (this, SIGNAL(doExplicitCompletion()), m_targetTextEdit, SLOT(doExplicitCompletion()));
-
- addWidget(m_pluralTabBar);
- addWidget(m_sourceTextEdit);
- addWidget(m_targetTextEdit);
-
- QWidget::setTabOrder(m_targetTextEdit,m_sourceTextEdit);
- QWidget::setTabOrder(m_sourceTextEdit,m_targetTextEdit);
- setFocusProxy(m_targetTextEdit);
-// QTimer::singleShot(3000,this,SLOT(setupWhatsThis()));
- settingsChanged();
-}
-
-EditorView::~EditorView()
-{
-}
-
-
-void EditorView::resetFindForCurrent(const DocPosition& pos)
-{
- m_modifiedAfterFind=true;
- emit signalChanged(pos.entry);
-}
-
-
-void EditorView::settingsChanged()
-{
- //Settings::self()->config()->setGroup("Editor");
- m_sourceTextEdit->document()->setDefaultFont(Settings::msgFont());
- m_targetTextEdit->document()->setDefaultFont(Settings::msgFont());
- if (_leds) _leds->setVisible(Settings::leds());
- else if (Settings::leds())
- {
- _leds=new LedsWidget(this);
- insertWidget(2,_leds);
- connect (m_targetTextEdit, SIGNAL(cursorPositionChanged(int)), _leds, SLOT(cursorPositionChanged(int)));
- connect (m_targetTextEdit, SIGNAL(nonApprovedEntryDisplayed()),_leds->ledFuzzy, SLOT(on()));
- connect (m_targetTextEdit, SIGNAL(approvedEntryDisplayed()), _leds->ledFuzzy, SLOT(off()));
- connect (m_targetTextEdit, SIGNAL(untranslatedEntryDisplayed()),_leds->ledUntr, SLOT(on()));
- connect (m_targetTextEdit, SIGNAL(translatedEntryDisplayed()), _leds->ledUntr, SLOT(off()));
- m_targetTextEdit->showPos(m_targetTextEdit->currentPos());
- }
-}
-
-
-//main function in this file :)
-void EditorView::gotoEntry(DocPosition pos, int selection)
-{
- setUpdatesEnabled(false);
-
- bool refresh=(pos.entry==-1);
- if (refresh) pos=m_targetTextEdit->currentPos();
- //kWarning()<<"refresh"<<refresh;
- //kWarning()<<"offset"<<pos.offset;
- //TODO trigger refresh directly via Catalog signal
-
- if (Q_UNLIKELY( m_catalog->isPlural(pos.entry)))
- {
- if (Q_UNLIKELY( m_catalog->numberOfPluralForms()!=m_pluralTabBar->count() ))
- {
- int i=m_pluralTabBar->count();
- if (m_catalog->numberOfPluralForms()>m_pluralTabBar->count())
- while (i<m_catalog->numberOfPluralForms())
- m_pluralTabBar->addTab(i18nc("@title:tab","Plural Form %1",++i));
- else
- while (i>m_catalog->numberOfPluralForms())
- m_pluralTabBar->removeTab(i--);
- }
- m_pluralTabBar->show();
- m_pluralTabBar->blockSignals(true);
- m_pluralTabBar->setCurrentIndex(pos.form);
- m_pluralTabBar->blockSignals(false);
- }
- else
- m_pluralTabBar->hide();
-
- //bool keepCursor=DocPos(pos)==DocPos(_msgidEdit->currentPos());
- bool keepCursor=false;
- CatalogString sourceWithTags=m_sourceTextEdit->showPos(pos,CatalogString(),keepCursor);
-
- //kWarning()<<"calling showPos";
- QString targetString=m_targetTextEdit->showPos(pos,sourceWithTags,keepCursor).string;
- //kWarning()<<"ss"<<_msgstrEdit->textCursor().anchor()<<_msgstrEdit->textCursor().position();
- m_sourceTextEdit->cursorToStart();
- m_targetTextEdit->cursorToStart();
-
- bool untrans=targetString.isEmpty();
- //kWarning()<<"ss1"<<_msgstrEdit->textCursor().anchor()<<_msgstrEdit->textCursor().position();
-
- if (pos.offset || selection)
- {
- TranslationUnitTextEdit* msgEdit=(pos.part==DocPosition::Source?m_sourceTextEdit:m_targetTextEdit);
- QTextCursor t=msgEdit->textCursor();
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,pos.offset);
- //NOTE this was kinda bug due to on-the-fly msgid wordwrap
- if (selection)
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor,selection);
- msgEdit->setTextCursor(t);
- }
- else if (!untrans)
- {
- QTextCursor t=m_targetTextEdit->textCursor();
- //what if msg starts with a tag?
- if (Q_UNLIKELY( targetString.startsWith('<') ))
- {
- int offset=targetString.indexOf(QRegExp(">[^<]"));
- if ( offset!=-1 )
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,offset+1);
- }
- else if (Q_UNLIKELY( targetString.startsWith(TAGRANGE_IMAGE_SYMBOL) ))
- {
- int offset=targetString.indexOf(QRegExp("[^"+TAGRANGE_IMAGE_SYMBOL+']'));
- if ( offset!=-1 )
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,offset+1);
- }
- m_targetTextEdit->setTextCursor(t);
- }
- //kWarning()<<"set-->"<<_msgstrEdit->textCursor().anchor()<<_msgstrEdit->textCursor().position();
- //kWarning()<<"anchor"<<t.anchor()<<"pos"<<t.position();
- m_targetTextEdit->setFocus();
- setUpdatesEnabled(true);
-}
-/*
-void KAiderView::dragEnterEvent(QDragEnterEvent* event)
-{
- if(event->mimeData()->hasUrls() && event->mimeData()->urls().first().path().endsWith(".po"))
- event->acceptProposedAction();
-}
-
-void KAiderView::dropEvent(QDropEvent *event)
-{
- emit fileOpenRequested(KUrl(event->mimeData()->urls().first()));
- event->acceptProposedAction();
-}
-
-*/
-
-
-//BEGIN edit actions that are easier to do in this class
-void EditorView::unwrap(TranslationUnitTextEdit* editor)
-{
- if (!editor)
- editor=m_targetTextEdit;
-
- QTextCursor t=editor->document()->find(QRegExp("[^(\\\\n)]$"));
- if (t.isNull())
- return;
-
- if (editor==m_targetTextEdit)
- m_catalog->beginMacro(i18nc("@item Undo action item","Unwrap"));
- t.movePosition(QTextCursor::EndOfLine);
- if (!t.atEnd())
- t.deleteChar();
-
- QRegExp rx("[^(\\\\n)>]$");
- //remove '\n's skipping "\\\\n"
- while (!(t=editor->document()->find(rx,t)).isNull())
- {
- t.movePosition(QTextCursor::EndOfLine);
- if (!t.atEnd())
- t.deleteChar();
- }
- if (editor==m_targetTextEdit)
- m_catalog->endMacro();
-}
-
-void EditorView::insertTerm(const QString& term)
-{
- m_targetTextEdit->insertPlainText(term);
- m_targetTextEdit->setFocus();
-}
-
-
-QString EditorView::selectionInTarget() const
-{
- //TODO remove IMAGES
- return m_targetTextEdit->textCursor().selectedText();
-}
-
-QString EditorView::selectionInSource() const
-{
- //TODO remove IMAGES
- return m_sourceTextEdit->textCursor().selectedText();
-}
-
-void EditorView::setProperFocus()
-{
- m_targetTextEdit->setFocus();
-}
-
-
-//END edit actions that are easier to do in this class
-
-
-
-QObject* EditorView::viewPort()
-{
- return m_targetTextEdit;
-}
-
-void EditorView::toggleBookmark(bool checked)
-{
- if (Q_UNLIKELY( m_targetTextEdit->currentPos().entry==-1 ))
- return;
-
- m_catalog->setBookmark(m_targetTextEdit->currentPos().entry,checked);
-}
-
-void EditorView::toggleApprovement()
-{
- //kWarning()<<"called";
- if (Q_UNLIKELY( m_targetTextEdit->currentPos().entry==-1 ))
- return;
-
- bool newState=!m_catalog->isApproved(m_targetTextEdit->currentPos().entry);
- SetStateCmd::push(m_catalog,m_targetTextEdit->currentPos(),newState);
- emit signalApprovedEntryDisplayed(newState);
-}
-
-void EditorView::setState(TargetState state)
-{
- if (Q_UNLIKELY( m_targetTextEdit->currentPos().entry==-1
- || m_catalog->state(m_targetTextEdit->currentPos())==state))
- return;
-
- SetStateCmd::instantiateAndPush(m_catalog,m_targetTextEdit->currentPos(),state);
- emit signalApprovedEntryDisplayed(m_catalog->isApproved(m_targetTextEdit->currentPos()));
-}
-
-void EditorView::setEquivTrans(bool equivTrans)
-{
- m_catalog->push(new SetEquivTransCmd(m_catalog, m_targetTextEdit->currentPos(), equivTrans));
-}
-
-
-#include "moc_editorview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef EDITORVIEW_H
-#define EDITORVIEW_H
-
-#include "pos.h"
-#include "state.h"
-#include "catalogstring.h"
-
-#include <QSplitter>
-#include <KUrl>
-
-class Catalog;
-class LedsWidget;
-class TranslationUnitTextEdit;
-class KTabBar;
-#include <QContextMenuEvent>
-#include <QDragEnterEvent>
-
-/**
- * This is the main view class for Lokalize Editor.
- * Most of the non-menu, non-toolbar, non-statusbar,
- * and non-dockview editing GUI code should go here.
- *
- * There are several ways (for views) to modify current msg:
- * -modify KTextEdit and changes will be applied to catalog automatically (plus you need to care of fuzzy indication etc)
- * -modify catalog directly, then call EditorWindow::gotoEntry slot
- * I used both :)
- *
- * @short Main editor view: source and target textedits
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-
-class EditorView: public QSplitter
-{
- Q_OBJECT
-public:
- EditorView(QWidget *,Catalog*);
- virtual ~EditorView();
-
- KTabBar* tabBar(){return m_pluralTabBar;}//to connect tabbar signals to controller (EditorWindow) slots
- QString selectionInTarget() const;//for non-batch replace
- QString selectionInSource() const;
-
- QObject* viewPort();
- void setProperFocus();
-
-public slots:
- void gotoEntry(DocPosition pos=DocPosition(),int selection=0/*, bool updateHistory=true*/);
- void toggleApprovement();
- void setState(TargetState);
- void setEquivTrans(bool);
-
-/*
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent*);
-*/
-private:
- Catalog* m_catalog;
-
- TranslationUnitTextEdit * m_sourceTextEdit;
- TranslationUnitTextEdit * m_targetTextEdit
-;
-
- KTabBar* m_pluralTabBar;
- LedsWidget* _leds;
-
-public:
- bool m_modifiedAfterFind;//for F3-search reset
-
-signals:
- void signalEquivTranslatedEntryDisplayed(bool);
- void signalApprovedEntryDisplayed(bool);
- void signalChangeStatusbar(const QString&);
- void signalChanged(uint index); //esp for mergemode...
- //void fileOpenRequested(KUrl);
- void binaryUnitSelectRequested(const QString& id);
- void gotoEntryRequested(const DocPosition&);
- void tmLookupRequested(DocPosition::Part, const QString&);
- //void tmLookupRequested(const QString& source, const QString& target);
- void findRequested();
- void findNextRequested();
- void replaceRequested();
- void doExplicitCompletion();
-
-
-private slots:
- void settingsChanged();
- void resetFindForCurrent(const DocPosition& pos);
-
- //Edit menu
- void unwrap(TranslationUnitTextEdit* editor=0);
- void toggleBookmark(bool);
- void insertTerm(const QString&);
-
-//workaround for qt ctrl+z bug
-};
-
-
-class KLed;
-#include <QLabel>
-class LedsWidget:public QWidget
-{
-Q_OBJECT
-public:
- LedsWidget(QWidget* parent);
-private:
- void contextMenuEvent(QContextMenuEvent* event);
-
-public slots:
- void cursorPositionChanged(int column);
-
-public:
- KLed* ledFuzzy;
- KLed* ledUntr;
- //KLed* ledErr;
- QLabel* lblColumn;
-};
-
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>FileSearchOptions</class>
- <widget class="QWidget" name="FileSearchOptions">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>600</width>
- <height>278</height>
- </rect>
- </property>
- <layout class="QVBoxLayout">
- <item>
- <layout class="QHBoxLayout" name="queryLayout">
- <item>
- <widget class="QLabel" name="querySourceLabel">
- <property name="text">
- <string>Source:</string>
- </property>
- <property name="buddy">
- <cstring>querySource</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="KLineEdit" name="querySource">
- <property name="toolTip">
- <string>Search expression for source language part.
-Press Ctrl+L to go to this control.
-Press Enter to start the search.
-Press Esc to stop the search.</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="queryTargetLabel">
- <property name="text">
- <string>Target:</string>
- </property>
- <property name="buddy">
- <cstring>queryTarget</cstring>
- </property>
- </widget>
- </item>
- <item>
- <widget class="KLineEdit" name="queryTarget">
- <property name="toolTip">
- <string>Search expression for target language part.
-Press Enter to start the search.</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="regEx">
- <property name="text">
- <string>Regular expressions</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="doFind">
- <property name="text">
- <string>&Search</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QTreeView" name="treeView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KLineEdit</class>
- <extends>QLineEdit</extends>
- <header>klineedit.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "filesearchtab.h"
-#include "ui_filesearchoptions.h"
-#include "ui_massreplaceoptions.h"
-#include "project.h"
-
-#include "tmscanapi.h" //TODO separate some decls into new header
-#include "state.h"
-#include "qaview.h"
-
-#include "catalog.h"
-#include "fastsizehintitemdelegate.h"
-//#include "flowlayout.h"
-
-#include <QApplication>
-#include <QDesktopWidget>
-#include <QTreeView>
-#include <QClipboard>
-#include <QShortcut>
-#include <QtGui/qevent.h>
-#include <QSortFilterProxyModel>
-#include <QStyledItemDelegate>
-#include <QPainter>
-#include <QTextDocument>
-#include <QHeaderView>
-#include <QStringListModel>
-#include <QBoxLayout>
-
-#include <KColorScheme>
-#include <kactioncategory.h>
-#include <kaction.h>
-#include <klocale.h>
-#include <kstandarddirs.h>
-#include <kxmlguifactory.h>
-#include <threadweaver/Job.h>
-#include <threadweaver/JobCollection.h>
-#include <threadweaver/ThreadWeaver.h>
-#include <threadweaver/Thread.h>
-
-
-static QStringList doScanRecursive(const QDir& dir);
-
-
-
-class FileListModel: public QStringListModel
-{
-public:
- FileListModel(QObject* parent): QStringListModel(parent){}
- QVariant data(const QModelIndex& item, int role=Qt::DisplayRole) const;
-};
-
-QVariant FileListModel::data(const QModelIndex& item, int role) const
-{
- if (role==Qt::DisplayRole)
- return shorterFilePath(stringList().at(item.row()));
- return QVariant();
-}
-
-SearchFileListView::SearchFileListView(QWidget* parent)
- : QDockWidget( i18nc("@title:window","File List"), parent)
- , m_browser(new QTreeView(this))
- , m_background(new QLabel(i18n("Drop translation files here..."), this))
- , m_model(new FileListModel(this))
-{
- setWidget(m_background);
- m_background->setMinimumWidth(QApplication::desktop()->width()/4);
- m_background->setAlignment(Qt::AlignCenter);
- m_browser->hide();
- m_browser->setModel(m_model);
- m_browser->setRootIsDecorated(false);
- m_browser->setHeaderHidden(true);
- m_browser->setUniformRowHeights(true);
- m_browser->setAlternatingRowColors(true);
-
-
- m_browser->setContextMenuPolicy(Qt::ActionsContextMenu);
-
- QAction* action=new QAction(i18nc("@action:inmenu", "Clear"), m_browser);
- connect(action, SIGNAL(triggered()), this, SLOT(clear()));
- m_browser->addAction(action);
-}
-
-void SearchFileListView::addFiles(const QStringList& files)
-{
- if (files.isEmpty())
- return;
-
- m_background->hide();
- setWidget(m_browser);
- m_browser->show();
-
- //ensure unquiness, sorting the list along the way
- QMap<QString, bool> map;
- foreach(const QString& filepath, m_model->stringList())
- map[filepath]=true;
- foreach(const QString& filepath, files)
- map[filepath]=true;
-
- m_model->setStringList(map.keys());
-}
-
-void SearchFileListView::addFilesFast(const QStringList& files)
-{
- if (files.size())
- m_model->setStringList(m_model->stringList()+files);
-}
-
-void SearchFileListView::clear()
-{
- m_model->setStringList(QStringList());
-}
-
-
-QStringList SearchFileListView::files() const
-{
- return m_model->stringList();
-}
-
-void SearchFileListView::scrollTo(const QString& file)
-{
- if (file.isEmpty())
- {
- m_browser->scrollToTop();
- return;
- }
- int idx=m_model->stringList().indexOf(file);
- if (idx!=-1)
- m_browser->scrollTo(m_model->index(idx, 0), QAbstractItemView::PositionAtCenter);
-}
-
-
-struct SearchParams
-{
- QRegExp sourcePattern;
- QRegExp targetPattern;
- QRegExp notesPattern;
-
- bool states[StateCount];
-
- bool isEmpty() const;
-};
-
-bool SearchParams::isEmpty() const
-{
- return sourcePattern.pattern().isEmpty()
- && targetPattern.pattern().isEmpty();
-}
-
-
-
-/// @short scan one file
-class SearchJob: public ThreadWeaver::Job
-{
-public:
- explicit SearchJob(const QStringList& f,
- const SearchParams& sp,
- const QVector<Rule>& r,
- int sn,
- QObject* parent=0);
- ~SearchJob(){}
-
-protected:
- void run ();
-public:
- QStringList files;
- SearchParams searchParams;
- QVector<Rule> rules;
- int searchNumber;
-
- //QMap<QString, QVector<FileSearchResult> > results; //filepath -> results
- SearchResults results; //plain
-
- int m_size;
-};
-
-SearchJob::SearchJob(const QStringList& f, const SearchParams& sp, const QVector<Rule>& r, int sn, QObject* parent)
- : ThreadWeaver::Job(parent)
- , files(f)
- , searchParams(sp)
- , rules(r)
- , searchNumber(sn)
-{
-}
-
-void SearchJob::run()
-{
- QTime a;a.start();
- foreach(const QString& path, files)
- {
- Catalog catalog(thread());
- if (Q_UNLIKELY(catalog.loadFromUrl(KUrl::fromPath(path), KUrl(), &m_size)!=0))
- continue;
-
- //QVector<FileSearchResult> catalogResults;
- int numberOfEntries=catalog.numberOfEntries();
- DocPosition pos(0);
- for (;pos.entry<numberOfEntries;pos.entry++)
- {
- //if (!searchParams.states[catalog.state(pos)])
- // return false;
- int lim=catalog.isPlural(pos.entry)?catalog.numberOfPluralForms():1;
- for (pos.form=0;pos.form<lim;pos.form++)
- {
- int sp=0;
- int tp=0;
- if (!searchParams.sourcePattern.isEmpty())
- sp=searchParams.sourcePattern.indexIn(catalog.source(pos));
- if (!searchParams.targetPattern.isEmpty())
- tp=searchParams.targetPattern.indexIn(catalog.target(pos));
- //int np=searchParams.notesPattern.indexIn(catalog.notes(pos));
-
- if (sp!=-1 && tp!=-1)
- {
- //TODO handle multiple results in same column
- //FileSearchResult r;
- SearchResult r;
- r.filepath=path;
- r.docPos=pos;
- if (!searchParams.sourcePattern.isEmpty())
- r.sourcePositions<<StartLen(searchParams.sourcePattern.pos(), searchParams.sourcePattern.matchedLength());
- if (!searchParams.targetPattern.isEmpty())
- r.targetPositions<<StartLen(searchParams.targetPattern.pos(), searchParams.targetPattern.matchedLength());
- r.source=catalog.source(pos);
- r.target=catalog.target(pos);
- r.state=catalog.state(pos);
- r.isApproved=catalog.isApproved(pos);
- //r.activePhase=catalog.activePhase();
- if (rules.size())
- {
- QVector<StartLen> positions(2);
- int matchedQaRule=findMatchingRule(rules, r.source, r.target, positions);
- if (matchedQaRule==-1)
- continue;
- if (positions.at(0).len)
- r.sourcePositions<<positions.at(0);
- if (positions.at(1).len)
- r.targetPositions<<positions.at(1);
- }
-
- r.sourcePositions.squeeze();
- r.targetPositions.squeeze();
- //catalogResults<<r;
- results<<r;
- }
- }
- }
- //if (catalogResults.size())
- // results[path]=catalogResults;
- }
- qDebug()<<"done in"<<a.elapsed();
-}
-
-/// @short replace in files
-class MassReplaceJob: public ThreadWeaver::Job
-{
-public:
- explicit MassReplaceJob(const SearchResults& srs,
- int pos,
- const QRegExp& s,
- const QString& r,
- //int sn,
- QObject* parent=0);
- ~MassReplaceJob(){}
-
-protected:
- void run ();
-public:
- SearchResults searchResults;
- int globalPos;
- QRegExp replaceWhat;
- QString replaceWith;
-};
-
-MassReplaceJob::MassReplaceJob(const SearchResults& srs, int pos, const QRegExp& s, const QString& r, QObject* parent)
- : ThreadWeaver::Job(parent)
- , searchResults(srs)
- , globalPos(pos)
- , replaceWhat(s)
- , replaceWith(r)
-{
-}
-
-void MassReplaceJob::run()
-{
- QMultiHash<QString, int> map;
- for (int i=0;i<searchResults.count();++i)
- map.insertMulti(searchResults.at(i).filepath, i);
-
- foreach(const QString& filepath, map.keys())
- {
- Catalog catalog(thread());
- if (catalog.loadFromUrl(KUrl::fromPath(filepath), KUrl())!=0)
- continue;
-
- foreach(int index, map.values(filepath))
- {
- SearchResult& sr=searchResults[index];
- if (catalog.target(sr.docPos.toDocPosition())!=sr.target)
- continue;
-
- CatalogString s=catalog.targetWithTags(sr.docPos.toDocPosition());
- s.string.replace(replaceWhat, replaceWith);
- catalog.setTarget(sr.docPos.toDocPosition(), s);
- }
-
- catalog.save();
- }
-}
-
-
-//BEGIN FileSearchModel
-FileSearchModel::FileSearchModel(QObject* parent)
- : QAbstractListModel(parent)
-{
-}
-
-QVariant FileSearchModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
- switch (section)
- {
- case FileSearchModel::Source: return i18nc("@title:column Original text","Source");
- case FileSearchModel::Target: return i18nc("@title:column Text in target language","Target");
- //case FileSearchModel::Context: return i18nc("@title:column","Context");
- case FileSearchModel::Filepath: return i18nc("@title:column","File");
- case FileSearchModel::TranslationStatus: return i18nc("@title:column","Translation Status");
- }
- return QVariant();
-}
-
-void FileSearchModel::appendSearchResults(const SearchResults& results)
-{
- beginInsertRows(QModelIndex(), m_searchResults.size(), m_searchResults.size()+results.size()-1);
- m_searchResults+=results;
- endInsertRows();
-}
-
-void FileSearchModel::clear()
-{
- beginResetModel();
- m_searchResults.clear();;
- endResetModel();
-}
-
-QVariant FileSearchModel::data(const QModelIndex& item, int role) const
-{
- bool doHtml=(role==FastSizeHintItemDelegate::HtmlDisplayRole);
- if (doHtml)
- role=Qt::DisplayRole;
-
- if (role==Qt::DisplayRole)
- {
- QString result;
- const SearchResult& sr=m_searchResults.at(item.row());
- if (item.column()==Source)
- result=sr.source;
- if (item.column()==Target)
- result=sr.target;
- if (item.column()==Filepath)
- result=shorterFilePath(sr.filepath);
-
- if (doHtml && item.column()<=FileSearchModel::Target)
- {
- if (result.isEmpty())
- return result;
-
- static QString startBld="_ST_";
- static QString endBld="_END_";
- static QString startBldTag="<b >";
- static QString endBldTag="</b >";
-
- if (item.column()==FileSearchModel::Target && !m_replaceWhat.isEmpty())
- {
- result.replace(m_replaceWhat, m_replaceWith);
- QString escaped=convertToHtml(result, !sr.isApproved);
- escaped.replace(startBld, startBldTag);
- escaped.replace(endBld, endBldTag);
- return escaped;
- }
-
- const QVector<StartLen>& occurences=item.column()==FileSearchModel::Source?sr.sourcePositions:sr.targetPositions;
- int occ=occurences.count();
- while (--occ>=0)
- {
- const StartLen& sl=occurences.at(occ);
- result.insert(sl.start+sl.len, endBld);
- result.insert(sl.start, startBld);
- }
- /* !isApproved(sr.state, Project::instance()->local()->role()) */
- QString escaped=convertToHtml(result, item.column()==FileSearchModel::Target && !sr.isApproved);
-
- escaped.replace(startBld, startBldTag);
- escaped.replace(endBld, endBldTag);
- return escaped;
- }
- return result;
-
- }
-
- if (role==Qt::UserRole)
- {
- const SearchResult& sr=m_searchResults.at(item.row());
- if (item.column()==Filepath)
- return sr.filepath;
- }
-
- return QVariant();
-}
-
-void FileSearchModel::setReplacePreview(const QRegExp& s, const QString& r)
-{
- m_replaceWhat=s;
- m_replaceWith="_ST_" + r + "_END_";
-
- emit dataChanged(index(0, Target), index(rowCount()-1, Target));
-}
-
-
-//END FileSearchModel
-
-//BEGIN FileSearchTab
-FileSearchTab::FileSearchTab(QWidget *parent)
- : LokalizeSubwindowBase2(parent)
-// , m_proxyModel(new TMResultsSortFilterProxyModel(this))
- , m_model(new FileSearchModel(this))
- , m_lastSearchNumber(0)
- , m_dbusId(-1)
-{
- setWindowTitle(i18nc("@title:window","Search and replace in files"));
- setAcceptDrops(true);
-
- QWidget* w=new QWidget(this);
- ui_fileSearchOptions=new Ui_FileSearchOptions;
- ui_fileSearchOptions->setupUi(w);
- setCentralWidget(w);
-
-
- QShortcut* sh=new QShortcut(Qt::CTRL+Qt::Key_L, this);
- connect(sh,SIGNAL(activated()),ui_fileSearchOptions->querySource,SLOT(setFocus()));
- setFocusProxy(ui_fileSearchOptions->querySource);
-
- sh=new QShortcut(Qt::Key_Escape,this,SLOT(stopSearch()),0,Qt::WidgetWithChildrenShortcut);
-
- QTreeView* view=ui_fileSearchOptions->treeView;
-
- QVector<bool> singleLineColumns(FileSearchModel::ColumnCount, false);
- singleLineColumns[FileSearchModel::Filepath]=true;
- singleLineColumns[FileSearchModel::TranslationStatus]=true;
- //singleLineColumns[TMDBModel::Context]=true;
-
- QVector<bool> richTextColumns(FileSearchModel::ColumnCount, false);
- richTextColumns[FileSearchModel::Source]=true;
- richTextColumns[FileSearchModel::Target]=true;
- view->setItemDelegate(new FastSizeHintItemDelegate(this,singleLineColumns,richTextColumns));
- connect(m_model,SIGNAL(modelReset()),view->itemDelegate(),SLOT(reset()));
- connect(m_model,SIGNAL(dataChanged(QModelIndex,QModelIndex)),view->itemDelegate(),SLOT(reset()));
- //connect(m_model,SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),view->itemDelegate(),SLOT(reset()));
- //connect(m_proxyModel,SIGNAL(layoutChanged()),view->itemDelegate(),SLOT(reset()));
- //connect(m_proxyModel,SIGNAL(layoutChanged()),this,SLOT(displayTotalResultCount()));
-
- view->setContextMenuPolicy(Qt::ActionsContextMenu);
-
- QAction* a=new QAction(i18n("Copy source to clipboard"),view);
- a->setShortcut(Qt::CTRL + Qt::Key_S);
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(copySource()));
- view->addAction(a);
-
- a=new QAction(i18n("Copy target to clipboard"),view);
- a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(copyTarget()));
- view->addAction(a);
-
- a=new QAction(i18n("Open file"),view);
- a->setShortcut(QKeySequence(Qt::Key_Return));
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(openFile()));
- connect(view,SIGNAL(activated(QModelIndex)), this, SLOT(openFile()));
- view->addAction(a);
-
- connect(ui_fileSearchOptions->querySource,SIGNAL(returnPressed()),this,SLOT(performSearch()));
- connect(ui_fileSearchOptions->queryTarget,SIGNAL(returnPressed()),this,SLOT(performSearch()));
- connect(ui_fileSearchOptions->doFind,SIGNAL(clicked()), this,SLOT(performSearch()));
-
-// m_proxyModel->setDynamicSortFilter(true);
-// m_proxyModel->setSourceModel(m_model);
- view->setModel(m_model);
-// view->setModel(m_proxyModel);
-// view->sortByColumn(FileSearchModel::Filepath,Qt::AscendingOrder);
-// view->setSortingEnabled(true);
-// view->setItemDelegate(new FastSizeHintItemDelegate(this));
-// connect(m_model,SIGNAL(resultsFetched()),view->itemDelegate(),SLOT(reset()));
-// connect(m_model,SIGNAL(modelReset()),view->itemDelegate(),SLOT(reset()));
-// connect(m_proxyModel,SIGNAL(layoutChanged()),view->itemDelegate(),SLOT(reset()));
-// connect(m_proxyModel,SIGNAL(layoutChanged()),this,SLOT(displayTotalResultCount()));
-
-
-//BEGIN resizeColumnToContents
- static const int maxInitialWidths[]={QApplication::desktop()->availableGeometry().width()/3,QApplication::desktop()->availableGeometry().width()/3};
- int column=sizeof(maxInitialWidths)/sizeof(int);
- while (--column>=0)
- view->setColumnWidth(column, maxInitialWidths[column]);
-//END resizeColumnToContents
-
- int i=6;
- while (--i>ID_STATUS_PROGRESS)
- statusBarItems.insert(i,QString());
-
- setXMLFile("filesearchtabui.rc",true);
- dbusObjectPath();
-
-
- //KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* srf=new KActionCategory(i18nc("@title actions category","Search and replace in files"), ac);
-
- m_searchFileListView = new SearchFileListView(this);
- //m_searchFileListView->hide();
- addDockWidget(Qt::RightDockWidgetArea, m_searchFileListView);
- srf->addAction( QLatin1String("showfilelist_action"), m_searchFileListView->toggleViewAction() );
-
- m_massReplaceView = new MassReplaceView(this);
- addDockWidget(Qt::RightDockWidgetArea, m_massReplaceView);
- srf->addAction( QLatin1String("showmassreplace_action"), m_massReplaceView->toggleViewAction() );
- connect(m_massReplaceView, SIGNAL(previewRequested(QRegExp,QString)), m_model, SLOT(setReplacePreview(QRegExp ,QString)));
- connect(m_massReplaceView, SIGNAL(replaceRequested(QRegExp,QString)), this, SLOT(massReplace(QRegExp,QString)));
- //m_massReplaceView->hide();
-
- m_qaView = new QaView(this);
- m_qaView->hide();
- addDockWidget(Qt::RightDockWidgetArea, m_qaView);
- srf->addAction( QLatin1String("showqa_action"), m_qaView->toggleViewAction() );
-
- connect(m_qaView, SIGNAL(rulesChanged()), this, SLOT(performSearch()));
- connect(m_qaView->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(performSearch()), Qt::QueuedConnection);
-
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- view->header()->restoreState(QByteArray::fromBase64( cg.readEntry("FileSearchResultsHeaderState", QByteArray()) ));
-}
-
-FileSearchTab::~FileSearchTab()
-{
- stopSearch();
-
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- cg.writeEntry("FileSearchResultsHeaderState",ui_fileSearchOptions->treeView->header()->saveState().toBase64());
-
- ids.removeAll(m_dbusId);
-}
-
-void FileSearchTab::performSearch()
-{
- if (m_searchFileListView->files().isEmpty())
- {
- addFilesToSearch(doScanRecursive(QDir(Project::instance()->poDir())));
- if (m_searchFileListView->files().isEmpty())
- return;
- }
-
- m_model->clear();
- statusBarItems.insert(1,QString());
- m_searchFileListView->scrollTo();
-
- m_lastSearchNumber++;
-
- SearchParams sp;
- sp.sourcePattern.setPattern(ui_fileSearchOptions->querySource->text());
- sp.targetPattern.setPattern(ui_fileSearchOptions->queryTarget->text());
-
- QVector<Rule> rules=m_qaView->isVisible()?m_qaView->rules():QVector<Rule>();
-
- if (sp.isEmpty() && rules.isEmpty())
- return;
-
- if (!ui_fileSearchOptions->regEx->isChecked())
- {
- sp.sourcePattern.setPatternSyntax(QRegExp::FixedString);
- sp.targetPattern.setPatternSyntax(QRegExp::FixedString);
- }
-/*
- else
- {
- sp.sourcePattern.setMinimal(true);
- sp.targetPattern.setMinimal(true);
- }
-*/
- stopSearch();
-
- m_massReplaceView->deactivatePreview();
-
- QStringList files=m_searchFileListView->files();
- for(int i=0; i<files.size();i+=100)
- {
- QStringList batch;
- int lim=qMin(files.size(), i+100);
- for(int j=i; j<lim;j++)
- batch.append(files.at(j));
-
- SearchJob* job=new SearchJob(batch, sp, rules, m_lastSearchNumber);
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(searchJobDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- m_runningJobs.append(job);
- }
-}
-
-void FileSearchTab::stopSearch()
-{
- QVector<ThreadWeaver::Job*>::const_iterator it;
- for (it = m_runningJobs.constBegin(); it != m_runningJobs.constEnd(); ++it)
- ThreadWeaver::Weaver::instance()->dequeue(*it);
- m_runningJobs.clear();
-}
-
-
-void FileSearchTab::massReplace(const QRegExp &what, const QString& with)
-{
-#define BATCH_SIZE 20
-
- SearchResults searchResults=m_model->searchResults();
-
- for (int i=0;i<searchResults.count();i+=BATCH_SIZE)
- {
- int last=qMin(i+BATCH_SIZE, searchResults.count()-1);
- QString filepath=searchResults.at(last).filepath;
- while (last+1<searchResults.count() && filepath==searchResults.at(last+1).filepath)
- ++last;
-
- MassReplaceJob* job=new MassReplaceJob(searchResults.mid(i, last+1-i), i, what, with);
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(replaceJobDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- m_runningJobs.append(job);
- }
-}
-
-
-static void copy(QTreeView* view, int column)
-{
- QApplication::clipboard()->setText( view->currentIndex().sibling(view->currentIndex().row(),column).data().toString());
-}
-
-void FileSearchTab::copySource()
-{
- copy(ui_fileSearchOptions->treeView, FileSearchModel::Source);
-}
-
-void FileSearchTab::copyTarget()
-{
- copy(ui_fileSearchOptions->treeView, FileSearchModel::Target);
-}
-
-void FileSearchTab::openFile()
-{
- QModelIndex item=ui_fileSearchOptions->treeView->currentIndex();
- SearchResult sr=m_model->searchResult(item);
- DocPosition docPos=sr.docPos.toDocPosition();
- int selection=0;
- if (sr.targetPositions.size())
- {
- docPos.offset=sr.targetPositions.first().start;
- selection =sr.targetPositions.first().len;
- }
- kDebug()<<"fileOpenRequest"<<docPos.offset<<selection;
- emit fileOpenRequested(sr.filepath, docPos, selection);
-}
-
-void FileSearchTab::fileSearchNext()
-{
- QModelIndex item=ui_fileSearchOptions->treeView->currentIndex();
- int row=item.row();
- int rowCount=m_model->rowCount();
-
- if (++row>=rowCount) //ok if row was -1 (no solection)
- return;
-
- ui_fileSearchOptions->treeView->setCurrentIndex(item.sibling(row, item.column()));
- openFile();
-}
-
-
-QStringList scanRecursive(const QList<QUrl>& urls)
-{
- QStringList result;
-
- int i=urls.size();
- while(--i>=0)
- {
- if (urls.at(i).isEmpty() || urls.at(i).path().isEmpty() ) //NOTE is this a Qt bug?
- continue;
- QString path=urls.at(i).toLocalFile();
- if (Catalog::extIsSupported(path))
- result.append(path);
- else
- result+=doScanRecursive(QDir(path));
- }
-
- return result;
-}
-
-//returns gross number of jobs started
-static QStringList doScanRecursive(const QDir& dir)
-{
- QStringList result;
- QStringList subDirs(dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Readable));
- int i=subDirs.size();
- while(--i>=0)
- result+=doScanRecursive(QDir(dir.filePath(subDirs.at(i))));
-
- QStringList filters=Catalog::supportedExtensions();
- i=filters.size();
- while(--i>=0)
- filters[i].prepend('*');
- QStringList files(dir.entryList(filters,QDir::Files|QDir::NoDotAndDotDot|QDir::Readable));
- i=files.size();
-
- while(--i>=0)
- result.append(dir.filePath(files.at(i)));
-
- return result;
-}
-
-
-void FileSearchTab::dragEnterEvent(QDragEnterEvent* event)
-{
- if(dragIsAcceptable(event->mimeData()->urls()))
- event->acceptProposedAction();
-}
-
-void FileSearchTab::dropEvent(QDropEvent *event)
-{
- event->acceptProposedAction();
- addFilesToSearch(scanRecursive(event->mimeData()->urls()));
-}
-
-void FileSearchTab::addFilesToSearch(const QStringList& files)
-{
- m_searchFileListView->addFiles(files);
- performSearch();
-}
-
-void FileSearchTab::searchJobDone(ThreadWeaver::Job* job)
-{
- SearchJob* j=static_cast<SearchJob*>(job);
- if (j->searchNumber!=m_lastSearchNumber)
- return;
-
-/*
- SearchResults searchResults;
-
- FileSearchResults::const_iterator i = j->results.constBegin();
- while (i != j->results.constEnd())
- {
- foreach(const FileSearchResult& fsr, i.value())
- {
- SearchResult sr(fsr);
- sr.filepath=i.key();
- searchResults<<sr;
- }
- ++i;
- }
-
- m_model->appendSearchResults(searchResults);
-*/
- if (j->results.size())
- {
- m_model->appendSearchResults(j->results);
- m_searchFileListView->scrollTo(j->results.last().filepath);
- }
-
- statusBarItems.insert(1,i18nc("@info:status message entries","Total: %1", m_model->rowCount()));
- //ui_fileSearchOptions->treeView->setFocus();
-}
-
-void FileSearchTab::replaceJobDone(ThreadWeaver::Job* job)
-{
- MassReplaceJob* j=static_cast<MassReplaceJob*>(job);
- ui_fileSearchOptions->treeView->scrollTo(m_model->index(j->globalPos+j->searchResults.count(), 0));
-
-}
-
-
-//END FileSearchTab
-
-//BEGIN MASS REPLACE
-
-MassReplaceView::MassReplaceView(QWidget* parent)
- : QDockWidget(i18nc("@title:window","Mass replace"), parent)
- , ui(new Ui_MassReplaceOptions)
-{
- QWidget* base=new QWidget(this);
- setWidget(base);
- ui->setupUi(base);
-
- connect(ui->doPreview, SIGNAL(toggled(bool)), this, SLOT(requestPreview(bool)));
- connect(ui->doReplace, SIGNAL(clicked(bool)), this, SLOT(requestReplace()));
-/*
- QLabel* rl=new QLabel(i18n("Replace:"), base);
- KLineEdit* searchEdit=new KLineEdit(base);
- QHBoxLayout* searchL=new QHBoxLayout();
- searchL->addWidget(rl);
- searchL->addWidget(searchEdit);
-
- QLabel* wl=new QLabel(i18n("With:"), base);
- wl->setAlignment(Qt::AlignRight);
- wl->setMinimumSize(rl->minimumSizeHint());
- KLineEdit* replacementEdit=new KLineEdit(base);
- QHBoxLayout* replacementL=new QHBoxLayout();
- replacementL->addWidget(wl);
- replacementL->addWidget(replacementEdit);
-
- FlowLayout* fl=new FlowLayout();
- fl->addItem(searchL);
- fl->addItem(replacementL);
- base->setLayout(fl);
- */
-}
-
-MassReplaceView::~MassReplaceView()
-{
- delete ui;
-}
-
-void MassReplaceView::requestPreview(bool enable)
-{
- QString s, r;
- if (enable)
- {
- s=ui->searchText->text();
- r=ui->replaceText->text();
-
- if (s.length())
- ui->doReplace->setEnabled(true);
- }
-
- emit previewRequested(QRegExp(s), r);
-}
-
-void MassReplaceView::requestReplace()
-{
- QString s=ui->searchText->text();
- QString r=ui->replaceText->text();
-
- if (s.isEmpty())
- return;
-
- emit replaceRequested(QRegExp(s), r);
-}
-
-void MassReplaceView::deactivatePreview()
-{
- ui->doPreview->setChecked(false);
- ui->doReplace->setEnabled(false);
-}
-
-
-#include "filesearchadaptor.h"
-#include <qdbusconnection.h>
-
-QList<int> FileSearchTab::ids;
-
-//BEGIN DBus interface
-
-QString FileSearchTab::dbusObjectPath()
-{
- if ( m_dbusId==-1 )
- {
- new FileSearchAdaptor(this);
-
- int i=0;
- while(i<ids.size()&&i==ids.at(i))
- ++i;
- ids.insert(i,i);
- m_dbusId=i;
- QDBusConnection::sessionBus().registerObject("/ThisIsWhatYouWant/FileSearch/" + QString::number(m_dbusId), this);
- }
-
- return "/ThisIsWhatYouWant/FileSearch/" + QString::number(m_dbusId);
-}
-
-
-//END DBus interface
-
-#include "moc_filesearchtab.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef FILESEARCHTAB_H
-#define FILESEARCHTAB_H
-
-#include "lokalizesubwindowbase.h"
-#include "pos.h"
-#include "rule.h"
-
-#include <KMainWindow>
-#include <KXMLGUIClient>
-#include <KUrl>
-
-#include <QDockWidget>
-#include <QtCore/qabstractitemmodel.h>
-#include <state.h>
-#include <phase.h>
-
-#include <QLabel>
-#include <QStringListModel>
-#include <QComboBox>
-#include <QTreeView>
-#include <QSortFilterProxyModel>
-
-namespace ThreadWeaver{class Job;}
-namespace ThreadWeaver{class JobCollection;}
-
-class QaView;
-class FileSearchModel;
-class SearchFileListView;
-class MassReplaceView;
-
-QT_BEGIN_NAMESPACE
-class Ui_FileSearchOptions;
-QT_END_NAMESPACE
-
-/**
- * Global file search/repalce tab
- */
-class FileSearchTab: public LokalizeSubwindowBase2
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.FileSearch")
- //qdbuscpp2xml -m -s filesearch/filesearchtab.h -o filesearch/org.kde.lokalize.FileSearch.xml
-
-public:
- FileSearchTab(QWidget *parent);
- ~FileSearchTab();
-
- void hideDocks(){};
- void showDocks(){};
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
- QString dbusObjectPath();
- int dbusId(){return m_dbusId;}
-
-
-public slots:
- void copySource();
- void copyTarget();
- void openFile();
- Q_SCRIPTABLE void performSearch();
- Q_SCRIPTABLE void addFilesToSearch(const QStringList&);
- void fileSearchNext();
- void stopSearch();
- void massReplace(const QRegExp &what, const QString& with);
-
-private slots:
- void searchJobDone(ThreadWeaver::Job*);
- void replaceJobDone(ThreadWeaver::Job*);
-
-signals:
- void fileOpenRequested(const KUrl& url, DocPosition docPos, int selection);
-
-private:
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent*);
-
-
-private:
- Ui_FileSearchOptions* ui_fileSearchOptions;
-
- FileSearchModel* m_model;
- //TMResultsSortFilterProxyModel *m_proxyModel;
- SearchFileListView* m_searchFileListView;
- MassReplaceView* m_massReplaceView;
- QaView* m_qaView;
-
- QVector<ThreadWeaver::Job*> m_runningJobs;
-
- //to avoid results from previous search showing up in the new one
- int m_lastSearchNumber;
-
- //QString m_dbusObjectPath;
- int m_dbusId;
- static QList<int> ids;
-};
-
-struct FileSearchResult
-{
- DocPos docPos;
-
- QString source;
- QString target;
-
- bool isApproved;
- TargetState state;
- //Phase activePhase;
-
- QVector<StartLen> sourcePositions;
- QVector<StartLen> targetPositions;
-
- //int matchedQaRule;
- //short notePos;
- //char noteindex;
-};
-
-typedef QMap<QString, QVector<FileSearchResult> > FileSearchResults;
-
-struct SearchResult: public FileSearchResult
-{
- QString filepath;
-
- SearchResult(const FileSearchResult& fsr):FileSearchResult(fsr){}
- SearchResult(){}
-};
-
-typedef QVector<SearchResult> SearchResults;
-
-class FileSearchModel: public QAbstractListModel
-{
- Q_OBJECT
-public:
-
- enum FileSearchModelColumns
- {
- Source=0,
- Target,
- //Context,
- Filepath,
- TranslationStatus,
- //Notes,
- ColumnCount
- };
-
- enum Roles
- {
- FullPathRole=Qt::UserRole,
- TransStateRole=Qt::UserRole+1,
- HtmlDisplayRole=Qt::UserRole+2
- };
-
- FileSearchModel(QObject* parent);
- ~FileSearchModel(){}
-
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- QVariant data(const QModelIndex& item, int role=Qt::DisplayRole) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const {Q_UNUSED(parent) return ColumnCount;}
- int rowCount(const QModelIndex& parent = QModelIndex()) const {Q_UNUSED(parent) return m_searchResults.size();}
-
- SearchResults searchResults()const {return m_searchResults;}
- SearchResult searchResult(const QModelIndex& item) const {return m_searchResults.at(item.row());}
- void appendSearchResults(const SearchResults&);
- void clear();
-
-public slots:
- void setReplacePreview(const QRegExp&, const QString&);
-
-private:
- SearchResults m_searchResults;
- QRegExp m_replaceWhat;
- QString m_replaceWith;
-};
-
-class SearchFileListView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- SearchFileListView(QWidget*);
- ~SearchFileListView(){}
-
- void addFiles(const QStringList& files);
- void addFilesFast(const QStringList& files);
-
- QStringList files()const;
-
- void scrollTo(const QString& file=QString());
-
-public slots:
- void clear();
-
-private:
- QTreeView* m_browser;
- QLabel* m_background;
- QStringListModel* m_model;
-};
-
-QT_BEGIN_NAMESPACE
-class Ui_MassReplaceOptions;
-QT_END_NAMESPACE
-
-class MassReplaceView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- MassReplaceView(QWidget*);
- ~MassReplaceView();
-
- void deactivatePreview();
-
-signals:
- void previewRequested(const QRegExp&, const QString&);
- void replaceRequested(const QRegExp&, const QString&);
-
-private slots:
- void requestPreview(bool);
- void requestReplace();
-
-private:
- Ui_MassReplaceOptions* ui;
-};
-
-//const QString& sourceRefine, const QString& targetRefine
-
-
-
-
-#endif
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="FileSearch" version="0">
-<MenuBar>
- <Menu name="tools">
- <Action name="showfilelist_action"/>
- <Separator/>
- <MergeLocal/>
- </Menu>
-</MenuBar>
-<ToolBar name="mainToolBar"><text>Main Toolbar</text>
- <Separator/>
- <Action name="showfilelist_action"/>
- <Action name="showmassreplace_action"/>
- <Action name="showqa_action"/>
-</ToolBar>
-</kpartgui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>MassReplaceOptions</class>
- <widget class="QWidget" name="MassReplaceOptions">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>370</width>
- <height>278</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="0" column="1">
- <widget class="QLineEdit" name="searchText"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>With:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLineEdit" name="replaceText"/>
- </item>
- <item row="2" column="1">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Replace:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="2">
- <widget class="QPushButton" name="doPreview">
- <property name="text">
- <string>Preview</string>
- </property>
- <property name="checkable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QPushButton" name="doReplace">
- <property name="enabled">
- <bool>false</bool>
- </property>
- <property name="text">
- <string>Mass Replace</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.FileSearch">
- <method name="performSearch">
- </method>
- <method name="addFilesToSearch">
- <arg type="as" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "glossary.h"
-
-#include "stemming.h"
-// #include "tbxparser.h"
-#include "project.h"
-#include "prefs_lokalize.h"
-#include "domroutines.h"
-
-#include <kdebug.h>
-
-#include <QFile>
-#include <QtXml/qxml.h>
-#include <qxmlstream.h>
-#include <QBuffer>
-#include <QApplication>
-
-using namespace GlossaryNS;
-
-static const QString defaultLang="en_US";
-static const QString xmlLang="xml:lang";
-static const QString ntig="ntig";
-static const QString tig="tig";
-static const QString termGrp="termGrp";
-static const QString langSet="langSet";
-static const QString term="term";
-static const QString id="id";
-
-
-
-QList<QByteArray> Glossary::idsForLangWord(const QString& lang, const QString& word) const
-{
- return idsByLangWord[lang].values(word);
-}
-
-
-Glossary::Glossary(QObject* parent)
- : QObject(parent)
-{
-}
-
-
-//BEGIN DISK
-bool Glossary::load(const QString& newPath)
-{
- QTime a;a.start();
-//BEGIN NEW
- QIODevice* device=new QFile(newPath);
- if (!device->open(QFile::ReadOnly | QFile::Text))
- {
- delete device;
- //return;
- device=new QBuffer();
- static_cast<QBuffer*>(device)->setData(QByteArray(
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<!DOCTYPE martif PUBLIC \"ISO 12200:1999A//DTD MARTIF core (DXFcdV04)//EN\" \"TBXcdv04.dtd\">\n"
-"<martif type=\"TBX\" xml:lang=\"en_US\">\n"
-" <text>\n"
-" <body>\n"
-" </body>\n"
-" </text>\n"
-"</martif>\n"
-));
- }
-
- QXmlSimpleReader reader;
- //reader.setFeature("http://qtsoftware.com/xml/features/report-whitespace-only-CharData",true);
- reader.setFeature("http://xml.org/sax/features/namespaces",false);
- QXmlInputSource source(device);
-
- QDomDocument newDoc;
- QString errorMsg;
- int errorLine;//+errorColumn;
- bool success=newDoc.setContent(&source, &reader, &errorMsg, &errorLine/*,errorColumn*/);
-
- delete device;
-
- if (!success)
- {
- kWarning()<<errorMsg;
- return false; //errorLine+1;
- }
- clear();//does setClean(true);
- m_path=newPath;
- m_doc=newDoc;
-
- //QDomElement file=m_doc.elementsByTagName("file").at(0).toElement();
- m_entries=m_doc.elementsByTagName("termEntry");
- for(int i=0;i<m_entries.size();i++)
- hashTermEntry(m_entries.at(i).toElement());
- m_idsForEntriesById=m_entriesById.keys();
-
-//END NEW
-#if 0
- TbxParser parser(this);
- QXmlSimpleReader reader1;
- reader1.setContentHandler(&parser);
-
- QFile file(p);
- if (!file.open(QFile::ReadOnly | QFile::Text))
- return;
- QXmlInputSource xmlInputSource(&file);
- if (!reader1.parse(xmlInputSource))
- kWarning() << "failed to load "<< path;
-#endif
- emit loaded();
-
- qDebug()<<"glossary loaded in"<<a.elapsed();
-
- return true;
-}
-
-bool Glossary::save()
-{
- if (m_path.isEmpty())
- return false;
-
- QFile* device=new QFile(m_path);
- if (!device->open(QFile::WriteOnly | QFile::Truncate))
- {
- device->deleteLater();
- return false;
- }
- QTextStream stream(device);
- m_doc.save(stream,2);
-
- device->deleteLater();
-
- setClean(true);
- return true;
-}
-
-void Glossary::setClean(bool clean)
-{
- m_clean=clean;
- emit changed();//may be emitted multiple times in a row. so what? :)
-}
-
-//END DISK
-
-//BEGIN MODEL
-#define FETCH_SIZE 128
-
-void GlossarySortFilterProxyModel::setFilterRegExp(const QString& s)
-{
- if (!sourceModel())
- return;
-
- //static const QRegExp lettersOnly("^[a-z]");
- QSortFilterProxyModel::setFilterRegExp(s);
-
- fetchMore(QModelIndex());
-}
-
-void GlossarySortFilterProxyModel::fetchMore(const QModelIndex& parent)
-{
- int expectedCount=rowCount()+FETCH_SIZE/2;
- while (rowCount(QModelIndex())<expectedCount && sourceModel()->canFetchMore(QModelIndex()))
- {
- sourceModel()->fetchMore(QModelIndex());
- //qDebug()<<"filter:"<<rowCount(QModelIndex())<<"/"<<sourceModel()->rowCount();
- qApp->processEvents();
- }
-}
-
-GlossaryModel::GlossaryModel(QObject* parent)
- : QAbstractListModel(parent)
- , m_visibleCount(0)
- , m_glossary(Project::instance()->glossary())
-{
- connect(m_glossary, SIGNAL(loaded()), this, SLOT(forceReset()));
-}
-
-void GlossaryModel::forceReset()
-{
- beginResetModel();
- m_visibleCount=0;
- endResetModel();
-}
-
-bool GlossaryModel::canFetchMore(const QModelIndex& parent) const
-{
- return false;//!parent.isValid() && m_glossary->size()!=m_visibleCount;
-}
-
-void GlossaryModel::fetchMore(const QModelIndex& parent)
-{
- int newVisibleCount=qMin(m_visibleCount+FETCH_SIZE,m_glossary->size());
- beginInsertRows(parent, m_visibleCount, newVisibleCount-1);
- m_visibleCount=newVisibleCount;
- endInsertRows();
-}
-
-int GlossaryModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return m_glossary->size();//m_visibleCount;
-}
-
-QVariant GlossaryModel::headerData( int section, Qt::Orientation /*orientation*/, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- //case ID: return i18nc("@title:column","ID");
- case English: return i18nc("@title:column Original text","Source");;
- case Target: return i18nc("@title:column Text in target language","Target");
- case SubjectField: return i18nc("@title:column","Subject Field");
- }
- return QVariant();
-}
-
-QVariant GlossaryModel::data(const QModelIndex& index, int role) const
-{
- //if (role==Qt::SizeHintRole)
- // return QVariant(QSize(50, 30));
-
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- static const QString nl=QString(" ")+QChar(0x00B7)+' ';
- static Project* project=Project::instance();
- Glossary* glossary=m_glossary;
-
- QByteArray id=glossary->id(index.row());
- switch (index.column())
- {
- case ID: return id;
- case English: return glossary->terms(id, project->sourceLangCode()).join(nl);
- case Target: return glossary->terms(id, project->targetLangCode()).join(nl);
- case SubjectField: return glossary->subjectField(id);
- }
- return QVariant();
-}
-
-/*
-QModelIndex GlossaryModel::index (int row,int column,const QModelIndex& parent) const
-{
- return createIndex (row, column);
-}
-*/
-
-int GlossaryModel::columnCount(const QModelIndex&) const
-{
- return GlossaryModelColumnCount;
-}
-
-/*
-Qt::ItemFlags GlossaryModel::flags ( const QModelIndex & index ) const
-{
- return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
- //if (index.column()==FuzzyFlag)
- // return Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled;
- //return QAbstractItemModel::flags(index);
-}
-*/
-
-
-//END MODEL general (GlossaryModel continues below)
-
-//BEGIN EDITING
-
-QByteArray Glossary::generateNewId()
-{
- // generate unique ID
- int idNumber=0;
- QList<int> busyIdNumbers;
-
- QString authorId(Settings::authorName().toLower());
- authorId.replace(' ','_');
- QRegExp rx('^'+authorId+"\\-([0-9]*)$");
-
-
- foreach(const QByteArray& id, m_idsForEntriesById)
- {
- if (rx.exactMatch(QString::fromLatin1(id)))
- busyIdNumbers.append(rx.cap(1).toInt());
- }
-
- int i=removedIds.size();
- while(--i>=0)
- {
- if (rx.exactMatch(QString::fromLatin1(removedIds.at(i))))
- busyIdNumbers.append(rx.cap(1).toInt());
- }
-
- if (!busyIdNumbers.isEmpty())
- {
- qSort(busyIdNumbers);
- while (busyIdNumbers.contains(idNumber))
- ++idNumber;
- }
-
- return QString(authorId+"-%1").arg(idNumber).toLatin1();
-}
-
-QStringList Glossary::subjectFields() const
-{
- QSet<QString> result;
- foreach(const QByteArray& id, m_idsForEntriesById)
- result.insert(subjectField(id));
- return result.toList();
-}
-
-QByteArray Glossary::id(int index) const
-{
- if (index<m_idsForEntriesById.size())
- return m_idsForEntriesById.at(index);
- return QByteArray();
-}
-
-QStringList Glossary::terms(const QByteArray& id, const QString& language) const
-{
- QString minusLang=language; minusLang.replace('_', '-');
- QStringRef soleLang=language.leftRef(2);
- QStringList result;
- QDomElement n = m_entriesById.value(id).firstChildElement(langSet);
- while (!n.isNull())
- {
- QString lang=n.attribute(xmlLang, defaultLang);
-
- if (language==lang || minusLang==lang || soleLang==lang)
- {
- QDomElement ntigElem=n.firstChildElement(ntig);
- while (!ntigElem.isNull())
- {
- result<<ntigElem.firstChildElement(termGrp).firstChildElement(term).text();
- ntigElem=ntigElem.nextSiblingElement(ntig);
- }
- QDomElement tigElem=n.firstChildElement(tig);
- while (!tigElem.isNull())
- {
- result<<tigElem.firstChildElement(term).text();
- tigElem=tigElem.nextSiblingElement(tig);
- }
- }
-
- n = n.nextSiblingElement(langSet);
- }
-
- return result;
-}
-
-// QDomElement ourLangSetElement will reference the lang tag we want (if it exists)
-static void getElementsForTermLangIndex(QDomElement termEntry, QString& lang, int index,
- QDomElement& ourLangSetElement,
- QDomElement& tigElement, //<-- can point to <ntig> as well
- QDomElement& termElement)
-{
- QString minusLang=lang; minusLang.replace('_', '-');
- QStringRef soleLang=lang.leftRef(2);
-
- //qDebug()<<"started walking over"<<lang<<index;
- QDomElement n = termEntry.firstChildElement(langSet);
- QDomDocument document=n.ownerDocument();
- int i=0;
- while (!n.isNull())
- {
- QString nLang=n.attribute(xmlLang, defaultLang);
-
- if (lang==nLang || minusLang==nLang || soleLang==nLang)
- {
- ourLangSetElement=n;
- QDomElement ntigElem=n.firstChildElement(ntig);
- while(!ntigElem.isNull())
- {
- //qDebug()<<i<<ntigElem.firstChildElement(termGrp).firstChildElement(term).text();
- if (i==index)
- {
- tigElement=ntigElem;
- termElement=ntigElem.firstChildElement(termGrp).firstChildElement(term);
- return;
- }
- ntigElem = ntigElem.nextSiblingElement(ntig);
- i++;
- }
- QDomElement tigElem=n.firstChildElement(tig);
- while(!tigElem.isNull())
- {
- //qDebug()<<i<<tigElem.firstChildElement(term).text();
- if (i==index)
- {
- tigElement=tigElem;
- termElement=tigElem.firstChildElement(term);
- return;
- }
- tigElem = tigElem.nextSiblingElement(tig);
- i++;
- }
- }
- n = n.nextSiblingElement(langSet);
- }
-}
-
-
-void Glossary::setTerm(const QByteArray& id, QString lang, int index, const QString& termText)
-{
- setClean(false);
-
- QDomElement ourLangSetElement; //will reference the lang we want if it exists
- QDomElement tigElement;
- QDomElement termElement;
- getElementsForTermLangIndex(m_entriesById.value(id), lang, index,
- ourLangSetElement, tigElement, termElement);
-
- if (!termElement.isNull())
- {
- setText(termElement,termText);
- return;
- }
- QDomElement entry=m_entriesById.value(id);
- QDomDocument document=entry.ownerDocument();
- if (ourLangSetElement.isNull())
- {
- ourLangSetElement=entry.appendChild( document.createElement(langSet)).toElement();
- lang.replace('_', '-');
- ourLangSetElement.setAttribute(xmlLang,lang);
- }
-/*
- QDomElement ntigElement=ourLangSetElement.appendChild( document.createElement(ntig)).toElement();
- QDomElement termGrpElement=ntigElement.appendChild( document.createElement(termGrp)).toElement();
- termElement=termGrpElement.appendChild( document.createElement(term)).toElement();
- termElement.appendChild( document.createTextNode(termText));
-*/
- tigElement=ourLangSetElement.appendChild( document.createElement(tig)).toElement();
- termElement=tigElement.appendChild( document.createElement(term)).toElement();
- termElement.appendChild( document.createTextNode(termText));
-}
-
-void Glossary::rmTerm(const QByteArray& id, QString lang, int index)
-{
- setClean(false);
-
- QDomElement ourLangSetElement; //will reference the lang we want if it exists
- QDomElement tigElement;
- QDomElement termElement;
- getElementsForTermLangIndex(m_entriesById.value(id), lang, index,
- ourLangSetElement, tigElement, termElement);
-
- if (!tigElement.isNull())
- ourLangSetElement.removeChild(tigElement);
-}
-
-
-static QDomElement firstDescripElemForLang(QDomElement termEntry, const QString& lang)
-{
- if (lang.isEmpty())
- return termEntry.firstChildElement("descrip");
-
- QString minusLang=lang;
- minusLang.replace('_', '-');
-
- //disable this for now
- //bool enUSLangGiven=defaultLang==lang; //treat en_US and en as equal
- //bool enLangGiven="en"==lang; //treat en_US and en as equal
-
- QDomElement n=termEntry.firstChildElement(langSet);
- while (!n.isNull())
- {
- const QString& curLang=n.attribute(xmlLang);
- if (curLang==lang || curLang==minusLang
- //|| (enUSLangGiven && curLang=="en")
- //|| (enLangGiven && curLang==defaultLang)
- )
- return n.firstChildElement("descrip");
-
- n = n.nextSiblingElement(langSet);
- }
- return QDomElement();
-}
-
-
-QString Glossary::descrip(const QByteArray& id, const QString& lang, const QString& type) const
-{
- QDomElement n = firstDescripElemForLang(m_entriesById.value(id), lang);
- if (n.isNull())
- return QString();
-
- while (!n.isNull())
- {
- if (n.attribute("type")==type)
- return n.text();
-
- n = n.nextSiblingElement("descrip");
- }
- return QString();
-}
-
-void Glossary::setDescrip(const QByteArray& id, QString lang, const QString& type, const QString& value)
-{
- setClean(false);
-
- QDomElement descripElem = firstDescripElemForLang(m_entriesById.value(id), lang);
-
- QDomDocument document=descripElem.ownerDocument();
- while (!descripElem.isNull())
- {
- if (descripElem.attribute("type")==type)
- return setText(descripElem,value);;
-
- descripElem = descripElem.nextSiblingElement("descrip");
- }
-
- //create new descrip element
- QDomElement parentForDescrip = m_entriesById.value(id);
- if (!lang.isEmpty())
- {
- //find/create a langSet elem that should be parent of the new descrip
- QDomElement langSetElem = m_entriesById.value(id).firstChildElement(langSet);
- while (!langSetElem.isNull())
- {
- QString nLang=langSetElem.attribute(xmlLang, defaultLang);
- nLang.replace('-','_');
- if (lang=="en") //NOTE COMPAT
- {
- lang=defaultLang;
- nLang.replace('_','-');
- langSetElem.setAttribute(xmlLang, defaultLang);
- }
-
- if (lang==nLang)
- break;
-
- langSetElem = langSetElem.nextSiblingElement(langSet);
- }
- if (!langSetElem.isNull())
- parentForDescrip=langSetElem;
- else
- {
- parentForDescrip=parentForDescrip.appendChild( document.createElement(langSet)).toElement();
- lang.replace('_', '-');
- parentForDescrip.setAttribute(xmlLang,lang);
- }
- }
- QDomElement descrip=parentForDescrip.insertBefore( document.createElement("descrip"), parentForDescrip.firstChild() ).toElement();
- descrip.setAttribute("type",type);
- descrip.appendChild( document.createTextNode(value));
-}
-
-QString Glossary::subjectField(const QByteArray& id, const QString& lang) const
-{
- return descrip(id, lang, "subjectField");
-}
-
-QString Glossary::definition(const QByteArray& id, const QString& lang) const
-{
- return descrip(id, lang, "definition");
-}
-
-void Glossary::setSubjectField(const QByteArray& id, const QString& lang, const QString& value)
-{
- setDescrip(id, lang, "subjectField", value);
-}
-
-void Glossary::setDefinition(const QByteArray& id, const QString& lang, const QString& value)
-{
- setDescrip(id, lang, "definition", value);
-}
-
-
-
-//add words to the hash
-// static void addToHash(const QMultiHash<QString,int>& wordHash,
-// const QString& what,
-// int index)
-void Glossary::hashTermEntry(const QDomElement& termEntry)
-{
- QByteArray entryId=termEntry.attribute(::id).toLatin1();
- if (entryId.isEmpty())
- return;
-
- m_entriesById.insert(entryId,termEntry);
-
- QString sourceLangCode=Project::instance()->sourceLangCode();
- foreach(const QString& termText, terms(entryId, sourceLangCode))
- {
- foreach(const QString& word, termText.split(' ',QString::SkipEmptyParts))
- idsByLangWord[sourceLangCode].insert(stem(sourceLangCode,word),entryId);
- }
-}
-
-void Glossary::unhashTermEntry(const QDomElement& termEntry)
-{
- QByteArray entryId=termEntry.attribute(::id).toLatin1();
- m_entriesById.remove(entryId);
-
- QString sourceLangCode=Project::instance()->sourceLangCode();
- foreach(const QString& termText, terms(entryId, sourceLangCode))
- {
- foreach(const QString& word, termText.split(' ',QString::SkipEmptyParts))
- idsByLangWord[sourceLangCode].remove(stem(sourceLangCode,word),entryId);
- }
-}
-
-#if 0
-void Glossary::hashTermEntry(int index)
-{
- Q_ASSERT(index<termList.size());
- foreach(const QString& term, termList_.at(index).english)
- {
- foreach(const QString& word, term.split(' ',QString::SkipEmptyParts))
- wordHash_.insert(stem(Project::instance()->sourceLangCode(),word),index);
- }
-}
-
-void Glossary::unhashTermEntry(int index)
-{
- Q_ASSERT(index<termList.size());
- foreach(const QString& term, termList_.at(index).english)
- {
- foreach(const QString& word, term.split(' ',QString::SkipEmptyParts))
- wordHash_.remove(stem(Project::instance()->sourceLangCode(),word),index);
- }
-}
-#endif
-
-void Glossary::removeEntry(const QByteArray& id)
-{
- if (!m_entriesById.contains(id))
- return;
-
- QDomElement entry = m_entriesById.value(id);
- if (entry.nextSibling().isCharacterData())
- entry.parentNode().removeChild(entry.nextSibling()); //nice formatting
- entry.parentNode().removeChild(entry);
- m_entriesById.remove(id);
-
- unhashTermEntry(entry);
- m_idsForEntriesById=m_entriesById.keys();
- removedIds.append(id); //for new id generation goodness
-
- setClean(false);
-}
-
-static void appendTerm(QDomElement langSetElem, const QString& termText)
-{
- QDomDocument doc=langSetElem.ownerDocument();
-/*
- QDomElement ntigElement=doc.createElement(ntig); langSetElem.appendChild(ntigElement);
- QDomElement termGrpElement=doc.createElement(termGrp); ntigElement.appendChild(termGrpElement);
- QDomElement termElement=doc.createElement(term); termGrpElement.appendChild(termElement);
- termElement.appendChild(doc.createTextNode(termText));
-*/
- QDomElement tigElement=doc.createElement(tig); langSetElem.appendChild(tigElement);
- QDomElement termElement=doc.createElement(term); tigElement.appendChild(termElement);
- termElement.appendChild(doc.createTextNode(termText));
-}
-
-QByteArray Glossary::append(const QStringList& sourceTerms, const QStringList& targetTerms)
-{
- if (!m_doc.elementsByTagName("body").count())
- return QByteArray();
-
- setClean(false);
- QDomElement termEntry=m_doc.createElement("termEntry");
- m_doc.elementsByTagName("body").at(0).appendChild(termEntry);
-
- //m_entries=m_doc.elementsByTagName("termEntry");
-
- QByteArray newId=generateNewId();
- termEntry.setAttribute(::id, QString::fromLatin1(newId));
-
- QDomElement sourceElem=m_doc.createElement(langSet); termEntry.appendChild(sourceElem);
- sourceElem.setAttribute(xmlLang, Project::instance()->sourceLangCode().replace('_','-'));
- foreach (QString sourceTerm, sourceTerms)
- appendTerm(sourceElem, sourceTerm);
-
- QDomElement targetElem=m_doc.createElement(langSet); termEntry.appendChild(targetElem);
- targetElem.setAttribute(xmlLang, Project::instance()->targetLangCode().replace('_', '-'));
- foreach (QString targetTerm, targetTerms)
- appendTerm(targetElem, targetTerm);
-
- hashTermEntry(termEntry);
- m_idsForEntriesById=m_entriesById.keys();
-
- return newId;
-}
-
-void Glossary::append(const QString& _english, const QString& _target)
-{
- append(QStringList(_english), QStringList(_target));
-}
-
-void Glossary::clear()
-{
- setClean(true);
- //path.clear();
- idsByLangWord.clear();
- m_entriesById.clear();
- m_idsForEntriesById.clear();
-
- removedIds.clear();
- changedIds_.clear();
- addedIds_.clear();
- wordHash_.clear();
- termList_.clear();
- langWordEntry_.clear();
- subjectFields_=QStringList(QLatin1String(""));
-
- m_doc.clear();
-}
-
-
-bool GlossaryModel::removeRows(int row, int count, const QModelIndex& parent)
-{
- beginRemoveRows(parent,row,row+count-1);
-
- Glossary* glossary=Project::instance()->glossary();
- int i=row+count;
- while (--i>=row)
- glossary->removeEntry(glossary->id(i));
-
- endRemoveRows();
- return true;
-}
-
-// bool GlossaryModel::insertRows(int row,int count,const QModelIndex& parent)
-// {
-// if (row!=rowCount())
-// return false;
-QByteArray GlossaryModel::appendRow(const QString& _english, const QString& _target)
-{
- bool notify=!canFetchMore(QModelIndex());
- if (notify)
- beginInsertRows(QModelIndex(),rowCount(),rowCount());
-
- QByteArray id=m_glossary->append(QStringList(_english), QStringList(_target));
-
- if (notify)
- {
- m_visibleCount++;
- endInsertRows();
- }
- return id;
-}
-
-//END EDITING
-
-#include "moc_glossary.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef GLOSSARY_H
-#define GLOSSARY_H
-
-#include <QStringList>
-#include <QMultiHash>
-#include <QtCore/qabstractitemmodel.h>
-#include <QSortFilterProxyModel>
-#include <QList>
-#include <QSet>
-
-#include <QtXml/qdom.h>
-
-/**
- * Classes for TBX Glossary handling
- */
-namespace GlossaryNS {
-
-/**
- * struct that contains types data we work with.
- * this data can also be added to the TBX file
- *
- * the entry represents term, not word(s),
- * so there can be only one subjectField.
- *
- * @short Contains parts of 'entry' tag in TBX that we support
- */
-struct TermEntry
-{
- QStringList english;
- QStringList target;
- QString definition;
- int subjectField; //index in global Glossary's subjectFields list
- QString id; //used to identify entry on edit action
- //TODO <descrip type="context"></descrip>
-
- TermEntry(const QStringList& _english,
- const QStringList& _target,
- const QString& _definition,
- int _subjectField,
- const QString& _id=QString()
- )
- : english(_english)
- , target(_target)
- , definition(_definition)
- , subjectField(_subjectField)
- , id(_id)
- {}
-
- TermEntry()
- : subjectField(0)
- {}
-
- void clear()
- {
- english.clear();
- target.clear();
- definition.clear();
- subjectField=0;
- }
-};
-
-
-
-/**
- * Internal representation of glossary.
- *
- * We store only data we need (i.e. only subset of TBX format)
- *
- * @short Internal representation of glossary
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class Glossary: public QObject
-{
- Q_OBJECT
-
-public:
-
- Glossary(QObject* parent);
- ~Glossary(){}
-
- QString path() const{return m_path;}
- bool isClean() {return m_clean;}
-
- QList<QByteArray> idsForLangWord(const QString& lang, const QString& word) const;
-
- QByteArray id(int index) const;
- QStringList terms(const QByteArray& id, const QString& lang) const;
- void setTerm(const QByteArray& id, QString lang, int i, const QString& term);
- void rmTerm(const QByteArray& id, QString lang, int i);
- QString subjectField(const QByteArray& id, const QString& lang=QString()) const;
- void setSubjectField(const QByteArray& id, const QString& lang, const QString& value);
- QString definition(const QByteArray& id, const QString& lang=QString()) const;
- void setDefinition(const QByteArray& id, const QString& lang, const QString& value);
-
-private:
- QString descrip(const QByteArray& id, const QString& lang, const QString& type) const;
- void setDescrip(const QByteArray& id, QString lang, const QString& type, const QString& value);
-
-public:
- QStringList subjectFields() const;
-
- int size() const{return m_entries.size();}
-
- void clear();
-
- //disk
- bool load(const QString&);
- bool save();
-
- //in-memory changing
- QByteArray generateNewId();
- void append(const QString& _english,const QString& _target);
- void removeEntry(const QByteArray& id);
- void forceChangeSignal(){emit changed();}
- void setClean(bool );
-
-
- QByteArray append(const QStringList& sourceTerms, const QStringList& targetTerms);
-
- //general
- void hashTermEntry(const QDomElement&);
- void unhashTermEntry(const QDomElement&);
-
-signals:
- void changed();
- void loaded();
-
-private:
- QString m_path;
-
- mutable QDomDocument m_doc;
- QDomNodeList m_entries;
-
- QMap<QByteArray, QDomElement> m_entriesById;
- QList<QByteArray> m_idsForEntriesById;
-
-
- QMap< QString, QMultiHash<QString,QByteArray> > idsByLangWord;
-
- QMultiHash<QString,int> wordHash_;
- QList<TermEntry> termList_;
- QMap< QString, QMultiHash<QString,int> > langWordEntry_;
- QStringList subjectFields_;//first entry should be empty
-
- //for delayed saving
- QStringList addedIds_;
- QStringList changedIds_;
- QList<QByteArray> removedIds;
-
- bool m_clean;
-};
-
-
-/**
- * @short MVC wrapper around Glossary
- */
-class GlossaryModel: public QAbstractListModel
-{
- Q_OBJECT
-public:
-
- enum Columns
- {
- ID = 0,
- English,
- Target,
- SubjectField,
- GlossaryModelColumnCount
- };
-
- GlossaryModel(QObject* parent/*, Glossary* glossary*/);
- ~GlossaryModel(){}
-
- //QModelIndex index (int row, int column, const QModelIndex & parent = QModelIndex() ) const;
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const;
- QVariant data(const QModelIndex&, int role=Qt::DisplayRole) const;
- QVariant headerData(int section,Qt::Orientation, int role = Qt::DisplayRole ) const;
- //Qt::ItemFlags flags(const QModelIndex&) const;
-
- bool canFetchMore(const QModelIndex& parent) const;
- void fetchMore(const QModelIndex& parent);
-
- bool removeRows(int row, int count, const QModelIndex& parent=QModelIndex());
- //bool insertRows(int row,int count,const QModelIndex& parent=QModelIndex());
- QByteArray appendRow(const QString& _english, const QString& _target);
-
-public slots:
- void forceReset();
-
-private:
- int m_visibleCount;
- Glossary* m_glossary; //taken from Project::instance()->glossary()
-};
-
-
-class GlossarySortFilterProxyModel: public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- GlossarySortFilterProxyModel(QObject* parent=0)
- : QSortFilterProxyModel(parent)
- {}
- Qt::ItemFlags flags(const QModelIndex&) const {return Qt::ItemIsSelectable|Qt::ItemIsEnabled;}
- void fetchMore(const QModelIndex& parent);
-
-public slots:
- void setFilterRegExp(const QString& s);
-
-};
-
-
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "glossaryview.h"
-#include "glossary.h"
-#include "project.h"
-#include "catalog.h"
-#include "flowlayout.h"
-
-#include "glossarywindow.h"
-#include "stemming.h"
-
-#include <klineedit.h>
-#include <kdialog.h>
-#include <klocale.h>
-#include <kdebug.h>
-#include <kurl.h>
-#include <kaction.h>
-
-#include <QtGui/qevent.h>
-#include <QtCore/qdatetime.h>
-#include <QSet>
-#include <QScrollArea>
-//
-#include <QPushButton>
-
-
-
-using namespace GlossaryNS;
-
-GlossaryView::GlossaryView(QWidget* parent,Catalog* catalog,const QVector<KAction*>& actions)
- : QDockWidget ( i18nc("@title:window","Glossary"), parent)
- , m_browser(new QScrollArea(this))
- , m_catalog(catalog)
- , m_flowLayout(new FlowLayout(FlowLayout::glossary,/*who gets signals*/this,actions,0,10))
- , m_glossary(Project::instance()->glossary())
- , m_rxClean(Project::instance()->markup()+'|'+Project::instance()->accel())//cleaning regexp; NOTE isEmpty()?
- , m_rxSplit("\\W|\\d")//splitting regexp
- , m_currentIndex(-1)
- , m_normTitle(i18nc("@title:window","Glossary"))
- , m_hasInfoTitle(m_normTitle+" [*]")
- , m_hasInfo(false)
-
-{
- setObjectName("glossaryView");
- QWidget* w=new QWidget(m_browser);
- m_browser->setWidget(w);
- m_browser->setWidgetResizable(true);
- w->setLayout(m_flowLayout);
- w->show();
-
- setToolTip(i18nc("@info:tooltip","<p>Translations for common terms appear here.</p>"
- "<p>Press shortcut displayed near the term to insert its translation.</p>"
- "<p>Use context menu to add new entry (tip: select words in original and translation fields before calling <interface>Define new term</interface>).</p>"));
-
- setWidget(m_browser);
- m_browser->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
- m_browser->setAutoFillBackground(true);
- m_browser->setBackgroundRole(QPalette::Background);
-
- m_rxClean.setMinimal(true);
- connect (m_glossary,SIGNAL(changed()),this,SLOT(slotNewEntryDisplayed()),Qt::QueuedConnection);
-}
-
-GlossaryView::~GlossaryView()
-{
-}
-
-
-//TODO define new term by dragging some text.
-// void GlossaryView::dragEnterEvent(QDragEnterEvent* event)
-// {
-// /* if(event->mimeData()->hasUrls() && event->mimeData()->urls().first().path().endsWith(".po"))
-// {
-// event->acceptProposedAction();
-// };*/
-// }
-//
-// void GlossaryView::dropEvent(QDropEvent *event)
-// {
-// event->acceptProposedAction();*/
-// }
-
-void GlossaryView::slotNewEntryDisplayed(DocPosition pos)
-{
- //kWarning()<<"\n\n\n\nstart"<<pos.entry<<m_currentIndex;
- QTime time;time.start();
- if (pos.entry==-1)
- pos.entry=m_currentIndex;
- else
- m_currentIndex=pos.entry;
-
- if (pos.entry==-1 || m_catalog->numberOfEntries()<=pos.entry)
- return;//because of Qt::QueuedConnection
- //if (!toggleViewAction()->isChecked())
- // return;
-
- Glossary& glossary=*m_glossary;
-
-
- QString source=m_catalog->source(pos);
- QString sourceLowered=source.toLower();
- QString msg=sourceLowered;
- msg.remove(m_rxClean);
- QString msgStemmed;
-
-// QRegExp accel(Project::instance()->accel());
-// kWarning()<<endl<<endl<<"valvalvalvalval " <<Project::instance()->accel()<<endl;
-// int pos=0;
-// while ((pos=accel.indexIn(msg,pos))!=-1)
-// {
-// msg.remove(accel.pos(1),accel.cap(1).size());
-// pos=accel.pos(1);
-// }
-
- QString sourceLangCode=Project::instance()->sourceLangCode();
- QList<QByteArray> termIds;
- foreach (const QString& w, msg.split(m_rxSplit,QString::SkipEmptyParts))
- {
- QString word=stem(sourceLangCode,w);
- QList<QByteArray> indexes=glossary.idsForLangWord(sourceLangCode,word);
- //if (indexes.size())
- //kWarning()<<"found entry for:" <<word;
- termIds+=indexes;
- msgStemmed+=word+' ';
- }
- if (termIds.isEmpty())
- return clear();
-
- // we found entries that contain words from msgid
- setUpdatesEnabled(false);
-
- if (m_hasInfo)
- m_flowLayout->clearTerms();
-
- bool found=false;
- //m_flowLayout->setEnabled(false);
- foreach (const QByteArray& termId, termIds.toSet())
- {
- // now check which of them are really hits...
- foreach (const QString& enTerm, glossary.terms(termId, sourceLangCode))
- {
- // ...and if so, which part of termEn list we must thank for match ...
- bool ok=msg.contains(enTerm);//,//Qt::CaseInsensitive //we lowered terms on load
- if (!ok)
- {
- QString enTermStemmed;
- foreach (const QString& word, enTerm.split(m_rxSplit,QString::SkipEmptyParts))
- enTermStemmed+=stem(sourceLangCode,word)+' ';
- ok=msgStemmed.contains(enTermStemmed);
- }
- if (ok)
- {
- //insert it into label
- found=true;
- int pos=sourceLowered.indexOf(enTerm);
- m_flowLayout->addTerm(enTerm,termId,/*uppercase*/pos!=-1 && source.at(pos).isUpper());
- break;
- }
- }
- }
- //m_flowLayout->setEnabled(true);
-
- if (!found)
- clear();
- else if (!m_hasInfo)
- {
- m_hasInfo=true;
- setWindowTitle(m_hasInfoTitle);
- }
-
- setUpdatesEnabled(true);
-}
-
-void GlossaryView::clear()
-{
- if (m_hasInfo)
- {
- m_flowLayout->clearTerms();
- m_hasInfo=false;
- setWindowTitle(m_normTitle);
- }
-}
-
-#include "moc_glossaryview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef GLOSSARYVIEW_H
-#define GLOSSARYVIEW_H
-
-#include <pos.h>
-#include <QRegExp>
-#include <QDockWidget>
-//#include <QList>
-class Catalog;
-class FlowLayout;
-#include <QDragEnterEvent>
-#include <QDropEvent>
-#include <QEvent>
-class KAction;
-#include <QFrame>
-#include <QScrollArea>
-#include <QVector>
-
-namespace GlossaryNS {
-class Glossary;
-
-#define GLOSSARY_SHORTCUTS 11
-class GlossaryView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- GlossaryView(QWidget*,Catalog*,const QVector<KAction*>&);
- ~GlossaryView();
-
-
-// void dragEnterEvent(QDragEnterEvent* event);
-// void dropEvent(QDropEvent*);
-// bool event(QEvent*);
-public slots:
- //plural messages usually contain the same words...
- void slotNewEntryDisplayed(DocPosition pos=DocPosition());//a little hacky, but... :)
-
-signals:
- void termInsertRequested(const QString&);
-
-private:
- void clear();
-
-private:
- QScrollArea* m_browser;
- Catalog* m_catalog;
- FlowLayout *m_flowLayout;
- Glossary* m_glossary;
- QRegExp m_rxClean;
- QRegExp m_rxSplit;
- int m_currentIndex;
-
- QString m_normTitle;
- QString m_hasInfoTitle;
- bool m_hasInfo;
-
-};
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "glossarywindow.h"
-#include "glossary.h"
-#include "project.h"
-#include "languagelistmodel.h"
-
-#include "ui_termedit.h"
-
-#include <kdebug.h>
-#include <klineedit.h>
-#include <kpushbutton.h>
-#include <kguiitem.h>
-#include <kmessagebox.h>
-
-
-#include <QApplication>
-#include <QSplitter>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QSortFilterProxyModel>
-#include <QAbstractItemModel>
-#include <QStringListModel>
-#include <QShortcut>
-
-using namespace GlossaryNS;
-
-//BEGIN GlossaryTreeView
-
-GlossaryTreeView::GlossaryTreeView(QWidget *parent)
- : QTreeView(parent)
-{
- setSortingEnabled(true);
- sortByColumn(GlossaryModel::English, Qt::AscendingOrder);
- setItemsExpandable(false);
- setAllColumnsShowFocus(true);
-
-/*
- setSelectionMode(QAbstractItemView::ExtendedSelection);
- setSelectionBehavior(QAbstractItemView::SelectRows);*/
-
-}
-
-static QByteArray modelIndexToId(const QModelIndex& item)
-{
- return item.sibling(item.row(),0).data(Qt::DisplayRole).toByteArray();
-}
-
-void GlossaryTreeView::currentChanged(const QModelIndex& current, const QModelIndex&/* previous*/)
-{
- if (current.isValid())
- {
- //QModelIndex item=static_cast<QSortFilterProxyModel*>(model())->mapToSource(current);
- //emit currentChanged(item.row());
- emit currentChanged(modelIndexToId(current));
- scrollTo(current);
- }
-}
-
-void GlossaryTreeView::selectRow(int i)
-{
- QSortFilterProxyModel* proxyModel=static_cast<QSortFilterProxyModel*>(model());
- GlossaryModel* sourceModel=static_cast<GlossaryModel*>(proxyModel->sourceModel());
-
- //sourceModel->forceReset();
- setCurrentIndex(proxyModel->mapFromSource(sourceModel->index(i,0)));
-}
-
-
-//END GlossaryTreeView
-
-
-//BEGIN SubjectFieldModel
-//typedef QStringListModel SubjectFieldModel;
-
-#if 0
-class SubjectFieldModel: public QAbstractItemModel
-{
-public:
-
- //Q_OBJECT
-
- SubjectFieldModel(QObject* parent);
- ~SubjectFieldModel(){}
-
- QModelIndex index (int row, int column, const QModelIndex& parent=QModelIndex()) const;
- QModelIndex parent(const QModelIndex&) const;
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const;
- QVariant data(const QModelIndex&,int role=Qt::DisplayRole) const;
- bool setData (const QModelIndex&,const QVariant&,int role=Qt::EditRole);
- bool setItemData(const QModelIndex& index, const QMap<int,QVariant>& roles);
- bool insertRows(int row, int count, const QModelIndex& parent=QModelIndex());
- Qt::ItemFlags flags(const QModelIndex&) const;
-
-/*private:
- Catalog* m_catalog;*/
-};
-
-inline
-SubjectFieldModel::SubjectFieldModel(QObject* parent)
- : QAbstractItemModel(parent)
-// , m_catalog(catalog)
-{
-}
-
-QModelIndex SubjectFieldModel::index (int row,int column,const QModelIndex& /*parent*/) const
-{
- return createIndex (row, column);
-}
-
-Qt::ItemFlags SubjectFieldModel::flags(const QModelIndex&) const
-{
- return Qt::ItemIsSelectable|Qt::ItemIsEditable|Qt::ItemIsEnabled;
-}
-
-QModelIndex SubjectFieldModel::parent(const QModelIndex& /*index*/) const
-{
- return QModelIndex();
-}
-
-int SubjectFieldModel::columnCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return 1;
-}
-/*
-inline
-Qt::ItemFlags SubjectFieldModel::flags ( const QModelIndex & index ) const
-{
- if (index.column()==FuzzyFlag)
- return Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled;
- return QAbstractItemModel::flags(index);
-}*/
-
-int SubjectFieldModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return Project::instance()->glossary()->subjectFields.size();
-}
-
-QVariant SubjectFieldModel::data(const QModelIndex& index,int role) const
-{
- if (role==Qt::DisplayRole||role==Qt::EditRole)
- return Project::instance()->glossary()->subjectFields.at(index.row());
- return QVariant();
-}
-
-bool SubjectFieldModel::insertRows(int row, int count, const QModelIndex& parent)
-{
- beginInsertRows(parent,row,row+count-1);
-
- QStringList& subjectFields=Project::instance()->glossary()->subjectFields;
-
- while (--count>=0)
- subjectFields.insert(row+count,QString());
-
- endInsertRows();
- return true;
-}
-
-bool SubjectFieldModel::setData(const QModelIndex& index, const QVariant& value, int role)
-{
- kDebug()<<role;
- QStringList& subjectFields=Project::instance()->glossary()->subjectFields;
- subjectFields[index.row()]=value.toString();
- return true;
-}
-
-bool SubjectFieldModel::setItemData(const QModelIndex& index, const QMap<int,QVariant>& roles)
-{
- if (roles.contains(Qt::EditRole))
- {
- QStringList& subjectFields=Project::instance()->glossary()->subjectFields;
- subjectFields[index.row()]=roles.value(Qt::EditRole).toString();
- }
- return true;
-}
-#endif
-//END SubjectFieldModel
-
-//BEGIN GlossaryWindow
-
-GlossaryWindow::GlossaryWindow(QWidget *parent)
- : KMainWindow(parent)
- , m_browser(new GlossaryTreeView(this))
- , m_proxyModel(new GlossarySortFilterProxyModel(this))
- , m_reactOnSignals(true)
-{
- //setAttribute(Qt::WA_DeleteOnClose, true);
- setAttribute(Qt::WA_DeleteOnClose, false);
-
- QSplitter* splitter=new QSplitter(Qt::Horizontal,this);
- setCentralWidget(splitter);
-
- m_proxyModel->setFilterKeyColumn(-1);
- m_proxyModel->setDynamicSortFilter(true);;
- GlossaryModel* model=new GlossaryModel(this);
- m_proxyModel->setSourceModel(model);
- m_browser->setModel(m_proxyModel);
-
- m_browser->setUniformRowHeights(true);
- m_browser->setAutoScroll(true);
- m_browser->setColumnHidden(GlossaryModel::ID,true);
- m_browser->setColumnWidth(GlossaryModel::English, m_browser->columnWidth(GlossaryModel::English)*2); //man this is HACK y
- m_browser->setColumnWidth(GlossaryModel::Target, m_browser->columnWidth(GlossaryModel::Target)*2);
- m_browser->setAlternatingRowColors(true);
-
- //left
- QWidget* w=new QWidget(splitter);
- QVBoxLayout* layout=new QVBoxLayout(w);
- m_filterEdit=new KLineEdit(w);
- m_filterEdit->setClearButtonShown(true);
- m_filterEdit->setClickMessage(i18n("Quick search..."));
- m_filterEdit->setFocus();
- m_filterEdit->setToolTip(i18nc("@info:tooltip","Activated by Ctrl+L.")+" "+i18nc("@info:tooltip","Accepts regular expressions"));
- new QShortcut(Qt::CTRL+Qt::Key_L,this,SLOT(setFocus()),0,Qt::WidgetWithChildrenShortcut);
- connect (m_filterEdit,SIGNAL(textChanged(QString)),
- m_proxyModel,SLOT(setFilterRegExp(QString)));
-
- layout->addWidget(m_filterEdit);
- layout->addWidget(m_browser);
- {
- KPushButton* addBtn=new KPushButton(KStandardGuiItem::add(),w);
- connect(addBtn,SIGNAL(clicked()), this,SLOT(newTermEntry()));
-
- KPushButton* rmBtn=new KPushButton(KStandardGuiItem::remove(),w);
- connect(rmBtn,SIGNAL(clicked()), this,SLOT(rmTermEntry()));
-
- KPushButton* restoreBtn=new KPushButton(i18nc("@action:button reloads glossary from disk","Restore from disk"),w);
- restoreBtn->setToolTip(i18nc("@info:tooltip","Reload glossary from disk, discarding any changes"));
- connect(restoreBtn,SIGNAL(clicked()), this,SLOT(restore()));
-
- QWidget* btns=new QWidget(w);
- QHBoxLayout* btnsLayout=new QHBoxLayout(btns);
- btnsLayout->addWidget(addBtn);
- btnsLayout->addWidget(rmBtn);
- btnsLayout->addWidget(restoreBtn);
-
- layout->addWidget(btns);
- //QWidget::setTabOrder(m_browser,addBtn);
- QWidget::setTabOrder(addBtn,rmBtn);
- QWidget::setTabOrder(rmBtn,restoreBtn);
- QWidget::setTabOrder(restoreBtn,m_filterEdit);
- }
- QWidget::setTabOrder(m_filterEdit,m_browser);
-
- splitter->addWidget(w);
-
- //right
- m_editor=new QWidget(splitter);
- m_editor->hide();
- Ui_TermEdit ui_termEdit;
- ui_termEdit.setupUi(m_editor);
- splitter->addWidget(m_editor);
-
-
- Project* project=Project::instance();
- m_sourceTermsModel=new TermsListModel(project->glossary(), project->sourceLangCode(), this);
- m_targetTermsModel=new TermsListModel(project->glossary(), project->targetLangCode(), this);
-
- ui_termEdit.sourceTermsView->setModel(m_sourceTermsModel);
- ui_termEdit.targetTermsView->setModel(m_targetTermsModel);
-
- connect(ui_termEdit.addEngTerm, SIGNAL(clicked(bool)), ui_termEdit.sourceTermsView, SLOT(addTerm()));
- connect(ui_termEdit.remEngTerm, SIGNAL(clicked(bool)), ui_termEdit.sourceTermsView, SLOT(rmTerms()));
- connect(ui_termEdit.addTargetTerm, SIGNAL(clicked(bool)), ui_termEdit.targetTermsView, SLOT(addTerm()));
- connect(ui_termEdit.remTargetTerm, SIGNAL(clicked(bool)), ui_termEdit.targetTermsView, SLOT(rmTerms()));
-
- m_sourceTermsView=ui_termEdit.sourceTermsView;
- m_targetTermsView=ui_termEdit.targetTermsView;
- m_subjectField=ui_termEdit.subjectField;
- m_definition=ui_termEdit.definition;
- m_definitionLang=ui_termEdit.definitionLang;
-
- //connect (m_english,SIGNAL(textChanged()), this,SLOT(applyEntryChange()));
- //connect (m_target,SIGNAL(textChanged()), this,SLOT(applyEntryChange()));
- //connect (m_definition,SIGNAL(editingFinished()),this,SLOT(applyEntryChange()));
- //connect (m_definition,SIGNAL(textChanged()),this,SLOT(applyEntryChange()));
- //connect (m_subjectField,SIGNAL(editTextChanged(QString)),this,SLOT(applyEntryChange()));
- connect (m_subjectField->lineEdit(),SIGNAL(editingFinished()),this,SLOT(applyEntryChange()));
-
-
- //m_subjectField->addItems(Project::instance()->glossary()->subjectFields());
- //m_subjectField->setModel(new SubjectFieldModel(this));
- QStringList subjectFields=Project::instance()->glossary()->subjectFields();
- qSort(subjectFields);
- QStringListModel* subjectFieldsModel=new QStringListModel(this);
- subjectFieldsModel->setStringList(subjectFields);
- m_subjectField->setModel(subjectFieldsModel);
- connect(m_browser,SIGNAL(currentChanged(int)), this,SLOT(currentChanged(int)));
- connect(m_browser,SIGNAL(currentChanged(QByteArray)), this,SLOT(showEntryInEditor(QByteArray)));
-
- connect(m_definitionLang, SIGNAL(activated(int)), this, SLOT(showDefinitionForLang(int)));
- m_definitionLang->setModel(LanguageListModel::emptyLangInstance()->sortModel());
- m_definitionLang->setCurrentIndex(LanguageListModel::emptyLangInstance()->sortModelRowForLangCode(m_defLang));//empty lang
-
- //TODO
- //connect(m_targetTermsModel,SIGNAL(dataChanged(QModelIndex,QModelIndex)),m_browser,SLOT(setFocus()));
-
- setAutoSaveSettings(QLatin1String("GlossaryWindow"),true);
- //Glossary* glossary=Project::instance()->glossary();
- /*setCaption(i18nc("@title:window","Glossary"),
- !glossary->changedIds.isEmpty()||!glossary->addedIds.isEmpty()||!glossary->removedIds.isEmpty());
- */
-}
-
-GlossaryWindow::~GlossaryWindow()
-{
-}
-
-void GlossaryWindow::setFocus()
-{
- m_filterEdit->setFocus();
- m_filterEdit->selectAll();
-}
-
-
-void GlossaryWindow::showEntryInEditor(const QByteArray& id)
-{
- if (m_editor->isVisible())
- applyEntryChange();
- else
- m_editor->show();
-
- m_id=id;
-
- m_reactOnSignals=false;
-
- Project* project=Project::instance();
- Glossary* glossary=project->glossary();
- m_subjectField->setCurrentItem(glossary->subjectField(id),/*insert*/true);
-
- QStringList langsToTry=QStringList(m_defLang)<<"en"<<"en_US"<<project->targetLangCode();
- foreach (const QString& lang, langsToTry)
- {
- QString d=glossary->definition(m_id, lang);
- if (!d.isEmpty())
- {
- if (m_defLang!=lang)
- m_definitionLang->setCurrentIndex(LanguageListModel::emptyLangInstance()->sortModelRowForLangCode(lang));
- m_defLang=lang;
- break;
- }
- }
- m_definition->setPlainText(glossary->definition(m_id, m_defLang));
-
-
- m_sourceTermsModel->setEntry(id);
- m_targetTermsModel->setEntry(id);
-
- //m_sourceTermsModel->setStringList(glossary->terms(id,project->sourceLangCode()));
- //m_targetTermsModel->setStringList(glossary->terms(id,project->targetLangCode()));
-
- m_reactOnSignals=true;
-}
-
-void GlossaryWindow::currentChanged(int i)
-{
- Q_UNUSED(i);
- m_reactOnSignals=false;
- m_editor->show();
- m_reactOnSignals=true;
-}
-
-void GlossaryWindow::showDefinitionForLang(int langModelIndex)
-{
- applyEntryChange();
- m_defLang=LanguageListModel::emptyLangInstance()->langCodeForSortModelRow(langModelIndex);
- m_definition->setPlainText(Project::instance()->glossary()->definition(m_id, m_defLang));
-}
-
-void GlossaryWindow::applyEntryChange()
-{
- if (!m_reactOnSignals || !m_browser->currentIndex().isValid())
- return;
-
- QByteArray id=m_id;//modelIndexToId(m_browser->currentIndex());
-
- Project* project=Project::instance();
- Glossary* glossary=project->glossary();
-
- if (m_subjectField->currentText()!=glossary->subjectField(id))
- glossary->setSubjectField(id, QString(), m_subjectField->currentText());
-
- if (m_definition->toPlainText()!=glossary->definition(id, m_defLang))
- glossary->setDefinition(id, m_defLang, m_definition->toPlainText());
-
- //HACK to force finishing of the listview editing
- QWidget* prevFocusWidget=QApplication::focusWidget();
- m_browser->setFocus();
- if (prevFocusWidget)
- prevFocusWidget->setFocus();
-
-// QSortFilterProxyModel* proxyModel=static_cast<QSortFilterProxyModel*>(model());
- //GlossaryModel* sourceModel=static_cast<GlossaryModel*>(m_proxyModel->sourceModel());
- const QModelIndex& idx=m_proxyModel->mapToSource( m_browser->currentIndex() );
- if (!idx.isValid())
- return;
-
-
- //TODO display filename, optionally stripped like for filetab names
- setCaption(i18nc("@title:window","Glossary"),!glossary->isClean());
-}
-
-
-void GlossaryWindow::selectEntry(const QByteArray& id)
-{
- qApp->processEvents(); //let it fetch the rows
-
- QModelIndexList items=m_proxyModel->match(m_proxyModel->index(0,0),Qt::DisplayRole,QVariant(id),1,0);
- if (items.count())
- {
- m_browser->setCurrentIndex(items.first());
- m_browser->scrollTo(items.first(),QAbstractItemView::PositionAtCenter);
- //kDebug()<<id<<items<<items.first().row();
- }
- else
- {
- //the row is probably not fetched yet
- m_browser->setCurrentIndex(QModelIndex());
- showEntryInEditor(id);
- //kDebug()<<id<<0;
- }
-}
-
-void GlossaryWindow::newTermEntry(QString _english, QString _target)
-{
- setCaption(i18nc("@title:window","Glossary"),true);
-
- GlossaryModel* sourceModel=static_cast<GlossaryModel*>(m_proxyModel->sourceModel());
- QByteArray id=sourceModel->appendRow(_english,_target);
-
- selectEntry(id);
-}
-
-void GlossaryWindow::rmTermEntry(int i)
-{
- setCaption(i18nc("@title:window","Glossary"),true);
-
- //QSortFilterProxyModel* proxyModel=static_cast<QSortFilterProxyModel*>(model());
- GlossaryModel* sourceModel=static_cast<GlossaryModel*>(m_proxyModel->sourceModel());
-
- if (i==-1)
- {
- //NOTE actually we should remove selected items, not current one
- const QModelIndex& current=m_browser->currentIndex();
- if (!current.isValid())
- return;
- i=m_proxyModel->mapToSource(current).row();
- }
-
- sourceModel->removeRow(i);
-}
-
-void GlossaryWindow::restore()
-{
- setCaption(i18nc("@title:window","Glossary"),false);
-
- Glossary* glossary=Project::instance()->glossary();
- glossary->load(glossary->path());
- m_reactOnSignals=false;
- showEntryInEditor(m_id);
- m_reactOnSignals=true;
-}
-
-bool GlossaryWindow::save()
-{
- //TODO add error message
- return Project::instance()->glossary()->save();
-}
-
-bool GlossaryWindow::queryClose()
-{
- Glossary* glossary=Project::instance()->glossary();
-
- applyEntryChange();
- if (glossary->isClean())
- return true;
-
- switch(KMessageBox::warningYesNoCancel(this,
- i18nc("@info","The glossary contains unsaved changes.\n\
-Do you want to save your changes or discard them?"),i18nc("@title:window","Warning"),
- KStandardGuiItem::save(),KStandardGuiItem::discard()))
- {
- case KMessageBox::Yes:
- return save();
- case KMessageBox::No:
- restore();
- return true;
- default:
- return false;
- }
-}
-
-
-//END GlossaryWindow
-
-void TermsListModel::setEntry(const QByteArray& id)
-{
- m_id=id;
- QStringList terms=m_glossary->terms(m_id,m_lang);
- terms.append(QString()); //allow adding new terms
- setStringList(terms);
-}
-
-bool TermsListModel::setData(const QModelIndex& index, const QVariant& value, int role)
-{
- Q_UNUSED(role);
- m_glossary->setTerm(m_id,m_lang,index.row(),value.toString());
- setEntry(m_id); //allow adding new terms
- return true;
-}
-
-
-bool TermsListModel::removeRows(int row, int count, const QModelIndex& parent)
-{
- if (row==rowCount()-1)
- return false;// cannot delete non-existing item
-
- m_glossary->rmTerm(m_id,m_lang,row);
- return QStringListModel::removeRows(row, 1, parent);
-}
-
-
-void TermListView::addTerm()
-{
- setCurrentIndex(model()->index(model()->rowCount()-1, 0));
- edit(currentIndex());
-}
-
-void TermListView::rmTerms()
-{
- foreach(const QModelIndex& row, selectionModel()->selectedRows())
- model()->removeRow(row.row());
-}
-
-
-#include "moc_glossarywindow.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef GLOSSARYWINDOW_H
-#define GLOSSARYWINDOW_H
-
-#include <kmainwindow.h>
-#include <ktextedit.h>
-#include <QTreeView>
-#include <QListView>
-#include <QStringListModel>
-
-#include <QListView>
-//class KTextEdit;
-class KLineEdit;
-class KComboBox;
-//#include <QStringListModel>
-
-
-class AuxTextEdit: public KTextEdit
-{
- Q_OBJECT
-public:
- AuxTextEdit(QWidget* parent=0): KTextEdit(parent){}
-
- void focusOutEvent(QFocusEvent* e){Q_UNUSED(e); emit editingFinished();}
-signals:
- void editingFinished();
-};
-
-class TermListView: public QListView
-{
- Q_OBJECT
-public:
- explicit TermListView(QWidget* parent = 0):QListView(parent){}
-
-public slots:
- void rmTerms();
- void addTerm();
-};
-
-
-namespace GlossaryNS {
-class GlossaryTreeView;
-class Glossary;
-class TermsListModel;
-class GlossarySortFilterProxyModel;
-
-class GlossaryWindow: public KMainWindow
-{
-Q_OBJECT
-public:
- GlossaryWindow(QWidget *parent = 0);
- ~GlossaryWindow();
- bool queryClose();
-
-public slots:
- void currentChanged(int);
- void showEntryInEditor(const QByteArray& id);
- void showDefinitionForLang(int);
- void newTermEntry(QString _english=QString(), QString _target=QString());
- void rmTermEntry(int i=-1);
- void restore();
- bool save();
- void applyEntryChange();
- void selectEntry(const QByteArray& id);
- void setFocus();
-
-private:
- QWidget* m_editor;
- GlossaryTreeView* m_browser;
- TermsListModel* m_sourceTermsModel;
- TermsListModel* m_targetTermsModel;
- GlossarySortFilterProxyModel* m_proxyModel;
- KLineEdit* m_filterEdit;
-
- KComboBox* m_subjectField;
- KTextEdit* m_definition;
- KComboBox* m_definitionLang;
- QListView* m_sourceTermsView;
- QListView* m_targetTermsView;
-
- bool m_reactOnSignals;
- QByteArray m_id;
- QString m_defLang;
-};
-
-class GlossaryTreeView: public QTreeView
-{
-Q_OBJECT
-public:
- GlossaryTreeView(QWidget *parent = 0);
- ~GlossaryTreeView(){}
-
- void currentChanged(const QModelIndex& current, const QModelIndex& previous);
- void selectRow(int i);
-
-signals:
- void currentChanged(int);
- void currentChanged(const QByteArray&);
- void currentChanged(const QByteArray& prev, const QByteArray& current);
-};
-
-
-class TermsListModel: public QStringListModel
-{
- Q_OBJECT
-public:
- TermsListModel(Glossary* glossary, const QString& lang, QObject* parent=0): QStringListModel(parent), m_glossary(glossary), m_lang(lang){}
-
- bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex());
-
-public slots:
- void setEntry(const QByteArray& id);
-
-private:
- Glossary* m_glossary;
- QString m_lang;
- QByteArray m_id;
-};
-
-
-
-
-/*
-class GlossaryItemDelegate : public QItemDelegate//KFileItemDelegate
-{
- Q_OBJECT
-
-public:
- GlossaryItemDelegate(QObject *parent=0)
- : QItemDelegate(parent)
- {}
- ~GlossaryItemDelegate(){}
- bool editorEvent (QEvent* event,QAbstractItemModel* model,const QStyleOptionViewItem& option,const QModelIndex& index);
-signals:
- void selected(const KUrl&);
- void newWindowOpenRequested(const KUrl&);
-
-};
-
-*/
-
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "tbxparser.h"
-
-#include "glossary.h"
-#include "project.h"
-#include <kdebug.h>
-
-using namespace GlossaryNS;
-
-bool TbxParser::startDocument()
-{
- m_state=null;
- m_lang=langNull;
- return true;
-}
-
-
-
-bool TbxParser::startElement( const QString&, const QString&,
- const QString& qName,
- const QXmlAttributes& attr)
-{
- if (qName=="langSet")
- {
- if (attr.value("xml:lang").startsWith("en"))
- m_lang=langEn;
- else if (attr.value("xml:lang")==Project::instance()->langCode())
- m_lang=langTarget;
- else
- m_lang=langNull;
- }
- else if (qName=="term")
- {
- m_state=term;
- }
- else if (qName=="termEntry")
- {
- m_termEn.clear();
- m_termOther.clear();
- m_entry.clear();
- m_entry.id=attr.value("id");
- }
- else if (qName=="descrip")
- {
- if (attr.value("type")=="definition")
- m_state=descripDefinition;
- else if (attr.value("type")=="subjectField")
- m_state=descripSubjectField;
- }
- return true;
-}
-
-bool TbxParser::endElement(const QString&,const QString&,const QString& qName)
-{
- if (qName=="term")
- {
- if (m_lang==langEn)
- {
- m_entry.english << m_termEn;
- m_termEn.clear();
- m_entry.english.last().squeeze();
- }
- else if (m_lang==langTarget)
- {
- m_entry.target << m_termOther;
- m_termOther.clear();
- m_entry.target.last().squeeze();
- }
-
- }
- else if (qName=="descrip")
- {
- if (m_state==descripSubjectField && !m_subjectField.isEmpty())
- {
- m_entry.subjectField=Project::instance()->glossary()->subjectFields.indexOf(m_subjectField);
- if (m_entry.subjectField==-1)//got this field value for the first time
- {
- m_entry.subjectField=Project::instance()->glossary()->subjectFields.size();
- Project::instance()->glossary()->subjectFields << m_subjectField;
- }
- m_subjectField.clear();
- }
-
- }
- else if (qName=="termEntry")
- {
- //sanity check --maybe this entry is only for another language?
- if (m_entry.target.isEmpty()||m_entry.english.isEmpty())
- return true;
-
- int index=m_glossary->termList.count();
- m_glossary->termList.append(m_entry);
- m_glossary->hashTermEntry(index);
-
- m_entry.clear();
- }
- m_state=null;
- return true;
-}
-
-
-
-bool TbxParser::characters ( const QString & ch )
-{
- if(m_state==term)
- {
- if (m_lang==langEn)
- m_termEn+=ch.toLower();//this is important
- else if (m_lang==langTarget)
- m_termOther+=ch;
- }
- else if (m_state==descripDefinition)
- m_entry.definition+=ch;
- else if (m_state==descripSubjectField)
- m_subjectField+=ch;
-
-
- return true;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef TBXPARSER_H
-#define TBXPARSER_H
-
-#include <QtXml/qxml.h>
-
-#include "glossary.h"
-
-namespace GlossaryNS {
-
-/**
- * loads only data we need to store in memory
- * e.g. skips entries for languages other than en
- * and current project's target language
- *
- * @short TBX glossary parser
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class TbxParser : public QXmlDefaultHandler
-{
- enum State //localstate for getting chars into right place
- {
- null=0,
-// termGrp,
- term,
- descripDefinition,
- descripSubjectField
- };
-
- enum Lang
- {
- langNull=0,
- langEn,
- langTarget
- };
-
-public:
- TbxParser(Glossary* glossary)
- : QXmlDefaultHandler()
- , m_glossary(glossary)
- {}
-
- ~TbxParser(){}
-
- bool startDocument();
- bool startElement(const QString&,const QString&,const QString&,const QXmlAttributes&);
- bool endElement(const QString&,const QString&,const QString&);
- bool characters(const QString&);
-
-private:
-// bool inTermTag:1;
- State m_state:8;
- Lang m_lang:8;
- QString m_termEn;
- QString m_termOther;
- TermEntry m_entry;
- QString m_subjectField;
- Glossary* m_glossary;
-
-};
-}
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>TermEdit</class>
- <widget class="QWidget" name="TermEdit">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>534</width>
- <height>536</height>
- </rect>
- </property>
- <layout class="QVBoxLayout">
- <item>
- <layout class="QHBoxLayout" name="engTermHL">
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>English synonyms (double-click to edit):</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="addEngTerm">
- <property name="text">
- <string>+</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="remEngTerm">
- <property name="text">
- <string>-</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="TermListView" name="sourceTermsView"/>
- </item>
- <item>
- <layout class="QHBoxLayout" name="targetTermHL">
- <item>
- <widget class="QLabel" name="l2">
- <property name="text">
- <string>Corresponding target language synonyms:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="addTargetTerm">
- <property name="text">
- <string>+</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="remTargetTerm">
- <property name="text">
- <string>-</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="TermListView" name="targetTermsView"/>
- </item>
- <item>
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Subject field:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="KComboBox" name="subjectField">
- <property name="toolTip">
- <string comment="@info:tooltip">When adding a new item, press enter after you have typed its name for changes to take effect</string>
- </property>
- <property name="editable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Definition:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="KComboBox" name="definitionLang"/>
- </item>
- </layout>
- </item>
- <item>
- <widget class="KTextEdit" name="definition">
- <property name="tabChangesFocus">
- <bool>true</bool>
- </property>
- <property name="acceptRichText">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Note: one glossary entry corresponds exactly to one term, not word/word sequence.
-
-That is, there may be several entries with the same word/word sequence expressing different meanings.</string>
- </property>
- <property name="alignment">
- <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- <customwidget>
- <class>KTextEdit</class>
- <extends>QTextEdit</extends>
- <header>ktextedit.h</header>
- </customwidget>
- <customwidget>
- <class>TermListView</class>
- <extends>QListView</extends>
- <header>glossarywindow.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<ui version="4.0" >
- <class>findExtension</class>
- <widget class="QWidget" name="findExtension" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>300</width>
- <height>60</height>
- </rect>
- </property>
- <layout class="QHBoxLayout" name="horizontalLayout" >
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>4</number>
- </property>
- <property name="rightMargin" >
- <number>4</number>
- </property>
- <property name="bottomMargin" >
- <number>0</number>
- </property>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
- <item>
- <widget class="QCheckBox" name="m_skipTags" >
- <property name="whatsThis" >
- <string>Skip tags</string>
- </property>
- <property name="text" >
- <string comment="@option:check" >Skip markup</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="m_ignoreAccelMarks" >
- <property name="whatsThis" >
- <string>Ignore accelerator marks</string>
- </property>
- <property name="text" >
- <string comment="@option:check" >Ignore accelerator marks</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout" >
- <item>
- <widget class="QCheckBox" name="m_notes" >
- <property name="text" >
- <string>Include notes</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef LISTS_H
-#define LISTS_H
-
-#include <QString>
-#include <klocale.h>
-#include <kglobal.h>
-
-static inline QString getMailingList()
-{
- QString lang(KGlobal::locale()->language());
- if(lang.startsWith("ca"))
- return "kde-i18n-ca@kde.org";
- if(lang.startsWith("de"))
- return "kde-i18n-de@kde.org";
- if(lang.startsWith("hu"))
- return "kde-l10n-hu@kde.org";
- if(lang.startsWith("tr"))
- return "kde-l10n-tr@kde.org";
- if(lang.startsWith("it"))
- return "kde-i18n-it@kde.org";
- if(lang.startsWith("lt"))
- return "kde-i18n-lt@kde.org";
- if(lang.startsWith("nb"))
- return "i18n-nb@lister.ping.uio.no";
- if(lang.startsWith("nn"))
- return "i18n-nn@lister.ping.uio.no";
- if(lang.startsWith("pt_BR"))
- return "kde-i18n-pt_BR@kde.org";
- if(lang.startsWith("ru"))
- return "kde-russian@lists.kde.ru";
- if(lang.startsWith("se"))
- return "i18n-sme@lister.ping.uio.no";
- if(lang.startsWith("sl"))
- return "lugos-slo@lugos.si";
-
- return "kde-i18n-doc@kde.org";
-}
-
-#endif
+++ /dev/null
-[Desktop Entry]
-Name=Lokalize
-Name[ar]=لوكالايز
-Name[ast]=Lokalize
-Name[bg]=Lokalize
-Name[bs]=Lokalize
-Name[ca]=Lokalize
-Name[ca@valencia]=Lokalize
-Name[cs]=Lokalize
-Name[da]=Lokalize
-Name[de]=Lokalize
-Name[el]=Lokalize
-Name[en_GB]=Lokalize
-Name[eo]=Lokalize
-Name[es]=Lokalize
-Name[et]=Lokalize
-Name[fi]=Lokalize
-Name[fr]=Lokalize
-Name[ga]=Lokalize
-Name[gl]=Lokalize
-Name[hu]=Lokalize
-Name[is]=Lokalize
-Name[it]=Lokalize
-Name[ja]=Lokalize
-Name[kk]=Lokalize
-Name[km]=Lokalize
-Name[ko]=Lokalize
-Name[lt]=Lokalize
-Name[lv]=Lokalize
-Name[mr]=लोकलाइझ
-Name[nb]=Lokalize
-Name[nds]=Lokalize
-Name[nl]=Lokalize
-Name[nn]=Lokalize
-Name[pa]=ਲੋਕਾਲਾਈਜ਼
-Name[pl]=Lokalize
-Name[pt]=Lokalize
-Name[pt_BR]=Lokalize
-Name[ro]=Lokalize
-Name[ru]=Lokalize
-Name[sk]=Lokalize
-Name[sl]=Lokalize
-Name[sr]=Локализуј
-Name[sr@ijekavian]=Локализуј
-Name[sr@ijekavianlatin]=Lokalizuj
-Name[sr@latin]=Lokalizuj
-Name[sv]=Lokalize
-Name[tr]=Lokalize
-Name[ug]=Lokalize
-Name[uk]=Lokalize
-Name[wa]=Lokalize
-Name[x-test]=xxLokalizexx
-Name[zh_CN]=Lokalize
-Name[zh_TW]=Lokalize
-Exec=lokalize --icon '%i' --caption '%c' %u
-Icon=lokalize
-Type=Application
-Categories=Qt;KDE;Development;Office;Translation;
-MimeType=application/x-xliff;text/x-gettext-translation;application/x-lokalize-project;
-X-DocPath=lokalize/index.html
-GenericName=Computer-Aided Translation System
-GenericName[ar]=برنامج ترجمة بمساعدة الحاسوب.
-GenericName[ast]=Sistema de traducción asistíu por computadora
-GenericName[bs]=Sistem za prevođenje pomoću računara
-GenericName[ca]=Sistema de traducció assistida per ordinador
-GenericName[ca@valencia]=Sistema de traducció assistida per ordinador
-GenericName[cs]=Systém pro překlad pomocí počítače
-GenericName[da]=Computerassisteret oversættelsessystem (CAT)
-GenericName[de]=Computergestütztes Übersetzungssystem
-GenericName[el]=Σύστημα μετάφρασης υποβοηθούμενο από τον υπολογιστή
-GenericName[en_GB]=Computer-Aided Translation System
-GenericName[es]=Sistema de traducción asistida por computadora
-GenericName[et]=Tõlkemäluga tõlkimisrakendus
-GenericName[fi]=Tietokoneavusteinen käännösjärjestelmä
-GenericName[fr]=Outil de traduction assistée par ordinateur
-GenericName[ga]=Córas Aistriúcháin Ríomhchuidithe
-GenericName[gl]=Sistema de tradución asistida por ordenador
-GenericName[hu]=Számítógéppel támogatott fordítórendszer
-GenericName[it]=Sistema di traduzione assistito dal computer
-GenericName[ja]=コンピュータの力を利用した翻訳システム
-GenericName[kk]=Компьютер демеуімен тәржімелеу жүйесі
-GenericName[km]=ប្រព័ន្ធបកប្រែដែលមានជំនួយដោយកុំព្យូទ័រ
-GenericName[ko]=컴퓨터 보조 번역 시스템
-GenericName[lt]=Kompiuterizuota vertimo sistema
-GenericName[lv]=Datorizēta tulkošanas sistēma
-GenericName[mr]=संगणकाच्या मदतीवरील भाषांतर प्रणाली
-GenericName[nb]=Dataassistert oversettelsessystem
-GenericName[nds]=Reeknerünnerstütt Översettensysteem
-GenericName[nl]=Computerondersteund vertaalsysteem
-GenericName[nn]=Dataassistert omsetjing
-GenericName[pa]=ਕੰਪਿਊਟਰ ਅਨੁਵਾਦ ਸਿਸਟਮ
-GenericName[pl]=System tłumaczeń wspomaganych komputerowo
-GenericName[pt]=Sistema de Traduções Auxiliado pelo Computador
-GenericName[pt_BR]=Sistema de tradução auxiliado pelo computador
-GenericName[ru]=Система автоматизированного перевода
-GenericName[sk]=Počítačom podporovaný prekladový systém
-GenericName[sl]=Računalniško podprt prevajalni sistem
-GenericName[sr]=Систем за превођење помоћу рачунара
-GenericName[sr@ijekavian]=Систем за превођење помоћу рачунара
-GenericName[sr@ijekavianlatin]=Sistem za prevođenje pomoću računara
-GenericName[sr@latin]=Sistem za prevođenje pomoću računara
-GenericName[sv]=Datorstött översättningssystem
-GenericName[tr]=Bilgisayar Destekli Çeviri Sistemi
-GenericName[ug]=كومپيۇتېر تەرجىمە ياردەمچى سىستېمىسى
-GenericName[uk]=Комп’ютерна система допомоги у перекладі
-GenericName[x-test]=xxComputer-Aided Translation Systemxx
-GenericName[zh_CN]=计算机辅助翻译系统
-GenericName[zh_TW]=電腦協助翻譯系統
-Terminal=false
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
- <kcfgfile name="lokalizerc"/>
- <include>kglobalsettings.h</include>
- <include>klocale.h</include>
- <include>kemailsettings.h</include>
- <include>kde-i18n-lists.h</include>
- <group name="Identity">
- <entry key="authorName" type="String">
-<!--
- <label>Translator's name</label>
- <whatsthis>Translator's name in English</whatsthis>
--->
- <default code="true">KEMailSettings().getSetting(KEMailSettings::RealName)</default>
- </entry>
- <entry key="authorLocalizedName" type="String">
-<!--
- <label>Localized name</label>
- <whatsthis>Translator's name in target language</whatsthis>
--->
- <default code="true">KEMailSettings().getSetting(KEMailSettings::RealName)</default>
- </entry>
- <entry key="authorEmail" type="String">
-<!--
- <whatsthis>Translator's email</whatsthis>
--->
- <default code="true">KEMailSettings().getSetting(KEMailSettings::EmailAddress)</default>
- </entry>
- <entry key="DefaultLangCode" type="String">
-<!--
- <label>Default language code for new projects</label>
- <whatsthis>Default language code for new projects</whatsthis>
--->
- <default code="true">KGlobal::locale()->language()</default>
- </entry>
- <entry key="DefaultMailingList" type="String">
-<!--
- <label>Default mailing list for new projects</label>
- <whatsthis>Default mailing list for new projects</whatsthis>
--->
- <default code="true">getMailingList()</default>
- </entry>
- </group>
- <group name="Appearance">
- <entry name="AddColor" type="Color">
- <default>#99CCFF</default>
- </entry>
- <entry name="DelColor" type="Color">
- <default>#FF9999</default>
- </entry>
- <entry name="HighlightSpaces" type="Bool">
- <default>true</default>
- </entry>
-
-<!--
- <entry name="CleverEditing" type="Bool">
- <label>
- </label>
- <default>true</default>
- </entry>
--->
- <entry name="MsgFont" type="Font">
-<!--
- <label>Font for Messages</label>
--->
- <default code="true">KGlobalSettings::generalFont()</default>
- </entry>
- <entry name="Leds" type="Bool">
- <default>false</default>
- </entry>
-<!--
- <entry name="OnFlySpellCheck" type="Bool">
- <label>
- </label>
- <default>true</default>
- </entry>
- <entry name="WhitespacePoints" type="Bool">
- <label>
- </label>
- <default>true</default>
- </entry>
--->
- </group>
- <group name="Editor">
- <entry name="AutoApprove" type="Bool">
- <default>true</default>
- </entry>
- <entry name="AutoSpellcheck" type="Bool">
- <default>true</default>
- </entry>
- <entry name="MouseWheelGo" type="Bool">
- <default>false</default>
- </entry>
- <entry name="WordCompletionLength" type="Int">
- <default>4</default>
- </entry>
- </group>
- <group name="TM">
- <entry name="PrefetchTM" type="Bool">
- <default>false</default>
- </entry>
- <entry name="SuggCount" type="Int">
- <default>7</default>
- </entry>
- <entry name="AutoaddTM" type="Bool">
- <default>true</default>
- </entry>
- <entry name="ScanToTMOnOpen" type="Bool">
- <default>false</default>
- </entry>
- </group>
-</kcfg>
+++ /dev/null
-[Global]
-IconName=lokalize
-Comment=Computer-aided translation system
-Comment[ar]=برنامج ترجمة بمساعدة الحاسوب.
-Comment[bs]=Sistem za prevođenje pomoću računara
-Comment[ca]=Sistema de traducció assistida per ordinador
-Comment[ca@valencia]=Sistema de traducció assistida per ordinador
-Comment[cs]=Systém pro překlad pomocí počítače
-Comment[da]=Computerassisteret oversættelsessystem (CAT)
-Comment[de]=Computergestütztes Übersetzungssystem
-Comment[el]=Σύστημα μετάφρασης υποβοηθούμενο από τον υπολογιστή
-Comment[en_GB]=Computer-aided translation system
-Comment[es]=Sistema de traducción asistida por computadora
-Comment[et]=Tõlkemäluga tõlkimisrakendus
-Comment[fi]=Tietokoneavusteinen käännösjärjestelmä
-Comment[fr]=Outil de traduction assistée par ordinateur
-Comment[ga]=Córas Aistriúcháin Ríomhchuidithe
-Comment[gl]=Sistema de tradución asistida por computador.
-Comment[hu]=Számítógéppel támogatott fordítórendszer
-Comment[it]=Sistema di traduzione assistito dal computer
-Comment[kk]=Компьютер демеуімен тәржімелеу жүйесі
-Comment[ko]=컴퓨터 보조 번역 시스템
-Comment[lt]=Kompiuterizuota vertimo sistema
-Comment[mr]=संगणकाच्या मदतीवरील भाषांतर प्रणाली
-Comment[nb]=Dataassistert oversettelsessystem
-Comment[nds]=Reeknerünnerstütt Översettensysteem
-Comment[nl]=Computerondersteund vertaalsysteem
-Comment[pa]=ਕੰਪਿਊਟਰ-ਸਹਾਇਕ ਅਨੁਵਾਦ ਸਿਸਟਮ
-Comment[pl]=System tłumaczeń wspomaganych komputerowo
-Comment[pt]=Sistema de traduções auxiliado pelo computador
-Comment[pt_BR]=Sistema de tradução auxiliado pelo computador
-Comment[ru]=Система автоматизированного перевода
-Comment[sk]=Počítačom podporovaný prekladový systém
-Comment[sl]=Računalniško podprt prevajalni sistem
-Comment[sr]=Систем за превођење помоћу рачунара
-Comment[sr@ijekavian]=Систем за превођење помоћу рачунара
-Comment[sr@ijekavianlatin]=Sistem za prevođenje pomoću računara
-Comment[sr@latin]=Sistem za prevođenje pomoću računara
-Comment[sv]=Datorstött översättningssystem
-Comment[tr]=Bilgisayar destekli çeviri sistemi
-Comment[uk]=Комп’ютерна система допомоги у перекладі
-Comment[x-test]=xxComputer-aided translation systemxx
-Comment[zh_CN]=计算机辅助翻译系统
-Comment[zh_TW]=電腦協助翻譯系統
-Name=Lokalize
-Name[ar]=لوكالايز
-Name[ast]=Lokalize
-Name[bg]=Lokalize
-Name[bs]=Lokalize
-Name[ca]=Lokalize
-Name[ca@valencia]=Lokalize
-Name[cs]=Lokalize
-Name[da]=Lokalize
-Name[de]=Lokalize
-Name[el]=Lokalize
-Name[en_GB]=Lokalize
-Name[eo]=Lokalize
-Name[es]=Lokalize
-Name[et]=Lokalize
-Name[fi]=Lokalize
-Name[fr]=Lokalize
-Name[ga]=Lokalize
-Name[gl]=Lokalize
-Name[hu]=Lokalize
-Name[is]=Lokalize
-Name[it]=Lokalize
-Name[ja]=Lokalize
-Name[kk]=Lokalize
-Name[km]=Lokalize
-Name[ko]=Lokalize
-Name[lt]=Lokalize
-Name[lv]=Lokalize
-Name[mr]=लोकलाइझ
-Name[nb]=Lokalize
-Name[nds]=Lokalize
-Name[nl]=Lokalize
-Name[nn]=Lokalize
-Name[pa]=ਲੋਕਾਲਾਈਜ਼
-Name[pl]=Lokalize
-Name[pt]=Lokalize
-Name[pt_BR]=Lokalize
-Name[ro]=Lokalize
-Name[ru]=Lokalize
-Name[sk]=Lokalize
-Name[sl]=Lokalize
-Name[sr]=Локализуј
-Name[sr@ijekavian]=Локализуј
-Name[sr@ijekavianlatin]=Lokalizuj
-Name[sr@latin]=Lokalizuj
-Name[sv]=Lokalize
-Name[tr]=Lokalize
-Name[ug]=Lokalize
-Name[uk]=Lokalize
-Name[wa]=Lokalize
-Name[x-test]=xxLokalizexx
-Name[zh_CN]=Lokalize
-Name[zh_TW]=Lokalize
-
-[Event/FilesOpenError]
-Name=Error opening files
-Name[ar]=خطأ في فتح الملفات
-Name[bs]=Greška u otvaranju datoteka
-Name[ca]=S'ha produït un error en obrir els fitxers
-Name[ca@valencia]=S'ha produït un error en obrir els fitxers
-Name[cs]=Chyba při otevírání souborů
-Name[da]=Fejl ved åbning af filer
-Name[de]=Fehler beim Öffnen von Dateien
-Name[el]=Σφάλμα στο άνοιγμα αρχείων
-Name[en_GB]=Error opening files
-Name[es]=Error abriendo archivos
-Name[et]=Tõrge failide avamisel
-Name[fi]=Virhe avattaessa tiedostoja
-Name[fr]=Problème lors de l'ouverture des fichiers
-Name[gl]=Erro ao abrir os ficheiros
-Name[hu]=Hiba a fájlok megnyitásakor
-Name[it]=Errore nell'apertura dei file
-Name[kk]=Файлдарды ашу қатесі
-Name[ko]=파일 열기 오류
-Name[lt]=Klaida atidarant failus
-Name[mr]=फाईल उघडतेवेळी त्रुटी आढळली
-Name[nb]=Feil ved åpning av filer
-Name[nds]=Fehler bi't Opmaken vun Dateien
-Name[nl]=Fout bij openen van bestanden
-Name[pa]=ਫਾਇਲਾਂ ਖੋਲ੍ਹਣ ਦੌਰਾਨ ਗਲਤੀ
-Name[pl]=Błąd otwierania plików
-Name[pt]=Erro ao aceder aos ficheiros
-Name[pt_BR]=Erro ao abrir arquivos
-Name[ru]=Ошибка открытия файлов
-Name[sk]=Chyba pri otváraní súborov
-Name[sl]=Napaka med odpiranjem datotek
-Name[sr]=Грешка при отварању фајлова
-Name[sr@ijekavian]=Грешка при отварању фајлова
-Name[sr@ijekavianlatin]=Greška pri otvaranju fajlova
-Name[sr@latin]=Greška pri otvaranju fajlova
-Name[sv]=Fel när filer skulle öppnas
-Name[tr]=Dosyalar açılamadı
-Name[uk]=Помилка під час відкриття файлів
-Name[x-test]=xxError opening filesxx
-Name[zh_CN]=打开文件出错
-Name[zh_TW]=開啟檔案時發生錯誤
-Action=Popup
-
-[Event/MergeFilesOpenError]
-Name=Error opening files for synchronization
-Name[bs]=Greška u otvaranju datoteka za sinhronizaciju
-Name[ca]=S'ha produït un error en obrir els fitxers a sincronitzar
-Name[ca@valencia]=S'ha produït un error en obrir els fitxers a sincronitzar
-Name[cs]=Chyba při otevírání souborů pro synchronizaci
-Name[da]=Fejl ved åbning af filer til synkronisering
-Name[de]=Fehler beim Öffnen von Dateien zum Abgleich
-Name[el]=Σφάλμα στο άνοιγμα αρχείων για συγχρονισμό
-Name[en_GB]=Error opening files for synchronization
-Name[es]=Error abriendo archivos para sincronización
-Name[et]=Tõrge failide avamisel sünkroonimiseks
-Name[fi]=Virhe avattaessa tiedostoja synkronoitavaksi
-Name[fr]=Problème lors de l'ouverture des fichiers pour une synchronisation
-Name[gl]=Erro ao abrir os ficheiros para sincronizalos
-Name[hu]=Hiba a fájlok megnyitásakor a szinkronizációhoz
-Name[it]=Errore nell'apertura dei file per la sincronizzazione
-Name[kk]=Файлдарды қадамдастыруға ашқандағы қате
-Name[ko]=동기화를 위한 파일 열기 오류
-Name[lt]=Klaida atidarant failus sinchronizavimui
-Name[nb]=Feil ved åpning av filer for synkronisering
-Name[nds]=Fehler bi't Opmaken vun Dateien för't Synkroniseren
-Name[nl]=Fout bij openen van bestanden voor synchronisatie
-Name[pa]=ਸੈਕਰੋਨਾਈਜ਼ੇਸ਼ਨ ਲਈ ਫਾਇਲਾਂ ਖੋਲ੍ਹਣ ਦੌਰਾਨ ਗਲਤੀ
-Name[pl]=Błąd otwierania plików do synchronizacji
-Name[pt]=Erro ao aceder aos ficheiros para a sincronização
-Name[pt_BR]=Erro ao abrir arquivos para sincronização
-Name[ru]=Ошибка открытия файлов для синхронизации
-Name[sk]=Chyba otvárania súborov pre synchronizáciu
-Name[sl]=Napaka med odpiranjem datotek za uskladitev
-Name[sr]=Грешка при отварању фајлова ради синхронизације
-Name[sr@ijekavian]=Грешка при отварању фајлова ради синхронизације
-Name[sr@ijekavianlatin]=Greška pri otvaranju fajlova radi sinhronizacije
-Name[sr@latin]=Greška pri otvaranju fajlova radi sinhronizacije
-Name[sv]=Fel när filer skulle öppnas för synkronisering
-Name[tr]=Eşzamanlama için dosyalar açılamadı
-Name[uk]=Помилка під час відкриття файлів для синхронізації
-Name[x-test]=xxError opening files for synchronizationxx
-Name[zh_CN]=打开文件同步出错
-Name[zh_TW]=開啟檔案以同步時發生錯誤
-Action=Popup
-
-[Event/NoSqlModulesAvailable]
-Name=No Qt Sql modules were found
-Name[bs]=Nema Qt Sql modula
-Name[ca]=No s'ha trobat cap mòdul Qt Sql
-Name[ca@valencia]=No s'ha trobat cap mòdul Qt Sql
-Name[cs]=Nebyly nalezeny žádné moduly Qt Sql
-Name[da]=Der blev ikke fundet nogen Qt sql-moduler
-Name[de]=Keine Qt-SQL-Module gefunden
-Name[el]=Δεν βρέθηκαν αρθρώματα Qt Sql
-Name[en_GB]=No Qt Sql modules were found
-Name[es]=No se han encontrado módulos SQL para Qt
-Name[et]=Qt Sql moodulit ei leitud.
-Name[fi]=Qt Sql -moduuleja ei löytynyt
-Name[fr]=Aucun module « Qt Sql » n'a été trouvé
-Name[gl]=Non se atoparon módulos de Qt SQL
-Name[hu]=Nem találhatók Qt SQL modulok
-Name[it]=Non è stato trovato nessun modulo Qt Sql
-Name[kk]=Qt Sql модульдері табылмаған
-Name[ko]=Qt SQL 모듈을 찾을 수 없음
-Name[lt]=Nerasta Qt Sql modulių
-Name[nb]=Fant ingen Qt SQL-moduler
-Name[nds]=Keen SQLite-Modulen för Qt funnen
-Name[nl]=Geen Qt-Sql-modules gevonden
-Name[pa]=ਕੋਈ Qt Sql ਮੋਡੀਊਲ ਨਹੀਂ ਲੱਭਿਆ
-Name[pl]=Nie znaleziono żadnych modułów Qt Sql
-Name[pt]=Não foram encontrados módulos de SQL do Qt
-Name[pt_BR]=Nenhum módulo Qt SQL foi encontrado
-Name[ru]=Модули Qt Sql не найдены.
-Name[sk]=Nenájdené žiadne moduly Qt Sql
-Name[sl]=Ni bilo najdenih modulov Qt SQL
-Name[sr]=Није нађен ниједан СКуЛ модул за КуТ
-Name[sr@ijekavian]=Није нађен ниједан СКуЛ модул за КуТ
-Name[sr@ijekavianlatin]=Nije nađen nijedan SQL modul za Qt
-Name[sr@latin]=Nije nađen nijedan SQL modul za Qt
-Name[sv]=Inga Qt SQL-moduler hittades
-Name[tr]=Hiç Qt Sql modülü bulunamadı
-Name[uk]=Не знайдено модулів SQL Qt
-Name[x-test]=xxNo Qt Sql modules were foundxx
-Name[zh_CN]=未找到 Qt SQL 模块
-Name[zh_TW]=找不到 Qt Sql 模組
-Action=Popup
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "lokalizemainwindow.h"
-#include "actionproxy.h"
-#include "editortab.h"
-#include "projecttab.h"
-#include "tmtab.h"
-#include "jobs.h"
-#include "filesearchtab.h"
-#include "prefs_lokalize.h"
-#include "project.h"
-#include "projectmodel.h"
-#include "projectlocal.h"
-#include "prefs.h"
-
-#include "tools/widgettextcaptureconfig.h"
-
-#include <kglobal.h>
-#include <kstandarddirs.h>
-#include <klocale.h>
-#include <kicon.h>
-#include <kstatusbar.h>
-#include <kdebug.h>
-#include <kmessagebox.h>
-#include <knotification.h>
-#include <kapplication.h>
-#include <kio/netaccess.h>
-#include <kaction.h>
-#include <kactioncollection.h>
-#include <kactioncategory.h>
-#include <kstandardaction.h>
-#include <kstandardshortcut.h>
-#include <krecentfilesaction.h>
-#include <kxmlguifactory.h>
-#include <kurl.h>
-#include <kmenu.h>
-#include <kfiledialog.h>
-#include <kdialog.h>
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QTimer>
-#include <QActionGroup>
-#include <QMdiArea>
-#include <QMdiSubWindow>
-
-
-LokalizeMainWindow::LokalizeMainWindow()
- : KXmlGuiWindow()
- , m_mdiArea(new QMdiArea)
- , m_prevSubWindow(0)
- , m_projectSubWindow(0)
- , m_translationMemorySubWindow(0)
- , m_editorActions(new QActionGroup(this))
- , m_managerActions(new QActionGroup(this))
-{
- m_mdiArea->setViewMode(QMdiArea::TabbedView);
- m_mdiArea->setActivationOrder(QMdiArea::ActivationHistoryOrder);
- m_mdiArea->setDocumentMode(true);
-#if QT_VERSION >= 0x040800
- m_mdiArea->setTabsMovable(true);
-#endif
-
- setCentralWidget(m_mdiArea);
- connect(m_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),this,SLOT(slotSubWindowActivated(QMdiSubWindow*)));
- setupActions();
-
- //prevent relayout of dockwidgets
- m_mdiArea->setOption(QMdiArea::DontMaximizeSubWindowOnActivation,true);
-
- connect(Project::instance(), SIGNAL(configChanged()), this, SLOT(projectSettingsChanged()));
- showProjectOverview();
-
- QString tmp=" ";
- statusBar()->insertItem(tmp,ID_STATUS_CURRENT);
- statusBar()->insertItem(tmp,ID_STATUS_TOTAL);
- statusBar()->insertItem(tmp,ID_STATUS_FUZZY);
- statusBar()->insertItem(tmp,ID_STATUS_UNTRANS);
- statusBar()->insertItem(tmp,ID_STATUS_ISFUZZY);
-
-
-
-
- setAttribute(Qt::WA_DeleteOnClose,true);
-
-
- if (!qApp->isSessionRestored())
- {
- KConfig config;
- KConfigGroup stateGroup(&config,"State");
- readProperties(stateGroup);
- }
-
- registerDBusAdaptor();
-
- QTimer::singleShot(0,this,SLOT(initLater()));
-}
-void LokalizeMainWindow::initLater()
-{
- if(!m_prevSubWindow && m_projectSubWindow)
- slotSubWindowActivated(m_projectSubWindow);
-
- if(!Project::instance()->isTmSupported())
- {
- KNotification* notification=new KNotification("NoSqlModulesAvailable", this);
- notification->setText( i18nc("@info","No Qt Sql modules were found. Translation memory will not work.") );
- notification->sendEvent();
- }
-}
-
-LokalizeMainWindow::~LokalizeMainWindow()
-{
- KConfig config;
- KConfigGroup stateGroup(&config,"State");
- saveProjectState(stateGroup);
-}
-
-void LokalizeMainWindow::slotSubWindowActivated(QMdiSubWindow* w)
-{
- //QTime aaa;aaa.start();
- if (!w || m_prevSubWindow==w)
- return;
-
- w->setUpdatesEnabled(true); //QTBUG-23289
-
- if (m_prevSubWindow)
- {
- m_prevSubWindow->setUpdatesEnabled(false);
- LokalizeSubwindowBase* prevEditor=static_cast<LokalizeSubwindowBase2*>( m_prevSubWindow->widget() );
- prevEditor->hideDocks();
- guiFactory()->removeClient( prevEditor->guiClient() );
- prevEditor->statusBarItems.unregisterStatusBar();
-
- if (qobject_cast<EditorTab*>(prevEditor))
- {
- EditorTab* w=static_cast<EditorTab*>( prevEditor );
- EditorState state=w->state();
- m_lastEditorState=state.dockWidgets.toBase64();
- }
- }
- LokalizeSubwindowBase* editor=static_cast<LokalizeSubwindowBase2*>( w->widget() );
- if (qobject_cast<EditorTab*>(editor))
- {
- EditorTab* w=static_cast<EditorTab*>( editor );
- w->setProperFocus();
-
- EditorState state=w->state();
- m_lastEditorState=state.dockWidgets.toBase64();
-
- QTabBar* tw = m_mdiArea->findChild<QTabBar*>();
- if(tw) tw->setTabToolTip(tw->currentIndex(), w->currentUrl().toLocalFile());
-
- emit editorActivated();
- }
- else if (w==m_projectSubWindow && m_projectSubWindow)
- {
- QTabBar* tw = m_mdiArea->findChild<QTabBar*>();
- if(tw) tw->setTabToolTip(tw->currentIndex(), Project::instance()->path());
- }
-
- editor->showDocks();
- editor->statusBarItems.registerStatusBar(statusBar());
- guiFactory()->addClient( editor->guiClient() );
-
- m_prevSubWindow=w;
-
- //kWarning()<<"finished"<<aaa.elapsed();
-}
-
-
-bool LokalizeMainWindow::queryClose()
-{
- QList<QMdiSubWindow*> editors=m_mdiArea->subWindowList();
- int i=editors.size();
- while (--i>=0)
- {
- //if (editors.at(i)==m_projectSubWindow)
- if (!qobject_cast<EditorTab*>(editors.at(i)->widget()))
- continue;
- if (!static_cast<EditorTab*>( editors.at(i)->widget() )->queryClose())
- return false;
- }
-
- bool ok=Project::instance()->queryCloseForAuxiliaryWindows();
-
- if (ok)
- {
- TM::cancelAllJobs(); //this shit works l)
- Project::instance()->model()->weaver()->dequeue();
- }
- return ok;
-}
-
-EditorTab* LokalizeMainWindow::fileOpen(KUrl url, int entry, bool setAsActive, const QString& mergeFile, bool silent)
-{
- if (!url.isEmpty()&&m_fileToEditor.contains(url)&&m_fileToEditor.value(url))
- {
- kWarning()<<"already opened";
- QMdiSubWindow* sw=m_fileToEditor.value(url);
- m_mdiArea->setActiveSubWindow(sw);
- return static_cast<EditorTab*>(sw->widget());
- }
-
- QByteArray state=m_lastEditorState;
- EditorTab* w=new EditorTab(this);
- QMdiSubWindow* sw=0;
- if (!url.isEmpty())//create QMdiSubWindow BEFORE fileOpen() because it causes some strange QMdiArea behaviour otherwise
- sw=m_mdiArea->addSubWindow(w);
-
- KUrl baseUrl;
- QMdiSubWindow* activeSW=m_mdiArea->currentSubWindow();
- if (activeSW && qobject_cast<LokalizeSubwindowBase*>(activeSW->widget()))
- baseUrl=static_cast<LokalizeSubwindowBase*>(activeSW->widget())->currentUrl();
-
- if (!w->fileOpen(url,baseUrl,silent))
- {
- if (sw)
- {
- m_mdiArea->removeSubWindow(sw);
- sw->deleteLater();
- }
- w->deleteLater();
- return 0;
- }
-
- if (!sw)
- sw=m_mdiArea->addSubWindow(w);
- w->showMaximized();
- sw->showMaximized();
-
- if (!state.isEmpty())
- w->restoreState(QByteArray::fromBase64(state));
-
- if (entry/* || offset*/)
- w->gotoEntry(DocPosition(entry/*, DocPosition::Target, 0, offset*/));
- if (setAsActive)
- {
- m_toBeActiveSubWindow=sw;
- QTimer::singleShot(0,this,SLOT(applyToBeActiveSubWindow()));
- }
- else
- sw->setUpdatesEnabled(false); //QTBUG-23289
-
- if (!mergeFile.isEmpty())
- w->mergeOpen(mergeFile);
-
- m_openRecentFileAction->addUrl(w->currentUrl());
- connect(sw, SIGNAL(destroyed(QObject*)),this,SLOT(editorClosed(QObject*)));
- connect(w, SIGNAL(fileOpenRequested(KUrl,QString,QString)),this,SLOT(fileOpen(KUrl,QString,QString)));
- connect(w, SIGNAL(tmLookupRequested(QString,QString)),this,SLOT(lookupInTranslationMemory(QString,QString)));
-
- QString fn=url.fileName();
- FileToEditor::const_iterator i = m_fileToEditor.constBegin();
- while (i != m_fileToEditor.constEnd())
- {
- if (i.key().fileName()==fn)
- {
- static_cast<EditorTab*>(i.value()->widget())->setFullPathShown(true);
- w->setFullPathShown(true);
- }
- ++i;
- }
- m_fileToEditor.insert(w->currentUrl(),sw);
-
- sw->setAttribute(Qt::WA_DeleteOnClose,true);
- emit editorAdded();
- return w;
-}
-
-void LokalizeMainWindow::editorClosed(QObject* obj)
-{
- m_fileToEditor.remove(m_fileToEditor.key(static_cast<QMdiSubWindow*>(obj)));
-}
-
-EditorTab* LokalizeMainWindow::fileOpen(const KUrl& url, const QString& source, const QString& ctxt)
-{
- EditorTab* w=fileOpen(url, 0, true);
- if (!w)
- return 0;//TODO message
- w->findEntryBySourceContext(source,ctxt);
- return w;
-}
-
-EditorTab* LokalizeMainWindow::fileOpen(const KUrl& url, DocPosition docPos, int selection)
-{
- EditorTab* w=fileOpen(url, 0, true);
- if (!w)
- return 0;//TODO message
- w->gotoEntry(docPos, selection);
- return w;
-}
-
-QObject* LokalizeMainWindow::projectOverview()
-{
- if (!m_projectSubWindow)
- {
- ProjectTab* w=new ProjectTab(this);
- m_projectSubWindow=m_mdiArea->addSubWindow(w);
- w->showMaximized();
- m_projectSubWindow->showMaximized();
- connect(w, SIGNAL(fileOpenRequested(KUrl)),this,SLOT(fileOpen(KUrl)));
- connect(w, SIGNAL(projectOpenRequested(QString)),this,SLOT(openProject(QString)));
- connect(w, SIGNAL(searchRequested(QStringList)),this,SLOT(addFilesToSearch(QStringList)));
- }
- if (m_mdiArea->currentSubWindow()==m_projectSubWindow)
- return m_projectSubWindow->widget();
- return 0;
-}
-
-void LokalizeMainWindow::showProjectOverview()
-{
- projectOverview();
- m_mdiArea->setActiveSubWindow(m_projectSubWindow);
-}
-
-TM::TMTab* LokalizeMainWindow::showTM()
-{
- if (!Project::instance()->isTmSupported())
- {
- KMessageBox::information(0, i18n("TM facility requires SQLite Qt module."), i18n("No SQLite module available"));
- return 0;
- }
-
- if (!m_translationMemorySubWindow)
- {
- TM::TMTab* w=new TM::TMTab(this);
- m_translationMemorySubWindow=m_mdiArea->addSubWindow(w);
- w->showMaximized();
- m_translationMemorySubWindow->showMaximized();
- connect(w, SIGNAL(fileOpenRequested(KUrl,QString,QString)),this,SLOT(fileOpen(KUrl,QString,QString)));
- }
-
- m_mdiArea->setActiveSubWindow(m_translationMemorySubWindow);
- return static_cast<TM::TMTab*>(m_translationMemorySubWindow->widget());
-}
-
-FileSearchTab* LokalizeMainWindow::showFileSearch(bool activate)
-{
- if (!m_fileSearchSubWindow)
- {
- FileSearchTab* w=new FileSearchTab(this);
- m_fileSearchSubWindow=m_mdiArea->addSubWindow(w);
- w->showMaximized();
- m_fileSearchSubWindow->showMaximized();
- connect(w, SIGNAL(fileOpenRequested(KUrl,DocPosition,int)),this,SLOT(fileOpen(KUrl,DocPosition,int)));
- }
-
- if (activate)
- m_mdiArea->setActiveSubWindow(m_fileSearchSubWindow);
- return static_cast<FileSearchTab*>(m_fileSearchSubWindow->widget());
-}
-
-void LokalizeMainWindow::fileSearchNext()
-{
- FileSearchTab* w=showFileSearch(/*activate=*/false);
- //TODO fill search params based on current selection
- w->fileSearchNext();
-}
-
-void LokalizeMainWindow::addFilesToSearch(const QStringList& files)
-{
- FileSearchTab* w=showFileSearch();
- w->addFilesToSearch(files);
-}
-
-
-void LokalizeMainWindow::applyToBeActiveSubWindow()
-{
- m_mdiArea->setActiveSubWindow(m_toBeActiveSubWindow);
-}
-
-
-void LokalizeMainWindow::setupActions()
-{
- //all operations that can be done after initial setup
- //(via QTimer::singleShot) go to initLater()
-
- QTime aaa;aaa.start();
-
- setStandardToolBarMenuEnabled(true);
-
- KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* actionCategory;
- KActionCategory* file=new KActionCategory(i18nc("@title actions category","File"), ac);
- //KActionCategory* config=new KActionCategory(i18nc("@title actions category","Configuration"), ac);
- KActionCategory* glossary=new KActionCategory(i18nc("@title actions category","Glossary"), ac);
- KActionCategory* tm=new KActionCategory(i18nc("@title actions category","Translation Memory"), ac);
- KActionCategory* proj=new KActionCategory(i18nc("@title actions category","Project"), ac);
-
- actionCategory=file;
-
-// File
- //KStandardAction::open(this, SLOT(fileOpen()), ac);
- file->addAction(KStandardAction::Open,this, SLOT(fileOpen()));
- m_openRecentFileAction = KStandardAction::openRecent(this,SLOT(fileOpen(KUrl)),ac);
-
- file->addAction(KStandardAction::Quit,KApplication::kApplication(), SLOT(closeAllWindows()));
-
-
-//Settings
- SettingsController* sc=SettingsController::instance();
- KStandardAction::preferences(sc, SLOT(showSettingsDialog()),ac);
-
-#define ADD_ACTION_ICON(_name,_text,_shortcut,_icon)\
- action = actionCategory->addAction(_name);\
- action->setText(_text);\
- action->setShortcuts(KStandardShortcut::shortcut(KStandardShortcut::_shortcut));\
- action->setIcon(KIcon(_icon));
-
-#define ADD_ACTION_SHORTCUT_ICON(_name,_text,_shortcut,_icon)\
- action = actionCategory->addAction(_name);\
- action->setText(_text);\
- action->setShortcut(QKeySequence( _shortcut ));\
- action->setIcon(KIcon(_icon));
-
-#define ADD_ACTION_SHORTCUT(_name,_text,_shortcut)\
- action = actionCategory->addAction(_name);\
- action->setShortcut(QKeySequence( _shortcut ));\
- action->setText(_text);
-
-
-//Window
- //documentBack
- //KStandardAction::close(m_mdiArea, SLOT(closeActiveSubWindow()), ac);
-
- actionCategory=file;
- ADD_ACTION_SHORTCUT("next-tab",i18n("Next tab"),Qt::CTRL+Qt::Key_BracketRight)
- connect(action,SIGNAL(triggered()),m_mdiArea,SLOT(activateNextSubWindow()));
-
- ADD_ACTION_SHORTCUT("prev-tab",i18n("Previous tab"),Qt::CTRL+Qt::Key_BracketLeft)
- connect(action,SIGNAL(triggered()),m_mdiArea,SLOT(activatePreviousSubWindow()));
-
-//Tools
- actionCategory=glossary;
- Project* project=Project::instance();
- ADD_ACTION_SHORTCUT("tools_glossary",i18nc("@action:inmenu","Glossary"),Qt::CTRL+Qt::ALT+Qt::Key_G)
- connect(action,SIGNAL(triggered()),project,SLOT(showGlossary()));
-
- actionCategory=tm;
- ADD_ACTION_SHORTCUT("tools_tm",i18nc("@action:inmenu","Translation memory"),Qt::Key_F7)
- connect(action,SIGNAL(triggered()),this,SLOT(showTM()));
-
- action = tm->addAction("tools_tm_manage",project,SLOT(showTMManager()));
- action->setText(i18nc("@action:inmenu","Manage translation memories"));
-
-//Project
- actionCategory=proj;
- ADD_ACTION_SHORTCUT("project_overview",i18nc("@action:inmenu","Project overview"),Qt::Key_F4)
- connect(action,SIGNAL(triggered()),this,SLOT(showProjectOverview()));
-
- action = proj->addAction("project_configure",sc,SLOT(projectConfigure()));
- action->setText(i18nc("@action:inmenu","Configure project"));
-
- action = proj->addAction("project_create",sc,SLOT(projectCreate()));
- action->setText(i18nc("@action:inmenu","Create new project"));
-
- action = proj->addAction("project_open",this,SLOT(openProject()));
- action->setText(i18nc("@action:inmenu","Open project"));
- action->setIcon(KIcon("project-open"));
-
- m_openRecentProjectAction=new KRecentFilesAction(i18nc("@action:inmenu","Open recent project"),this);
- action = proj->addAction("project_open_recent",m_openRecentProjectAction);
- connect(m_openRecentProjectAction,SIGNAL(urlSelected(KUrl)),this,SLOT(openProject(KUrl)));
-
- //Qt::QueuedConnection: defer until event loop is running to eliminate QWidgetPrivate::showChildren(bool) startup crash
- connect(Project::instance(),SIGNAL(loaded()), this,SLOT(projectLoaded()), Qt::QueuedConnection);
-
-
- ADD_ACTION_SHORTCUT("tools_filesearch",i18nc("@action:inmenu","Search and replace in files"),Qt::Key_F6)
- connect(action,SIGNAL(triggered()),this,SLOT(showFileSearch()));
-
- ADD_ACTION_SHORTCUT("tools_filesearch_next",i18nc("@action:inmenu","Find next in files"),Qt::META+Qt::Key_F3)
- connect(action,SIGNAL(triggered()),this,SLOT(fileSearchNext()));
-
- action = ac->addAction("tools_widgettextcapture",this,SLOT(widgetTextCapture()));
- action->setText(i18nc("@action:inmenu","Widget text capture"));
-
- setupGUI(Default,"lokalizemainwindowui.rc");
-
- kWarning()<<"finished"<<aaa.elapsed();
-}
-
-bool LokalizeMainWindow::closeProject()
-{
- if (!queryClose())
- return false;
-
- KConfigGroup emptyGroup; //don't save which project to reopen
- saveProjectState(emptyGroup);
- //close files from previous project
- foreach (QMdiSubWindow* subwindow, m_mdiArea->subWindowList())
- {
- if (subwindow==m_translationMemorySubWindow && m_translationMemorySubWindow)
- subwindow->deleteLater();
- else if (qobject_cast<EditorTab*>(subwindow->widget()))
- {
- m_fileToEditor.remove(static_cast<EditorTab*>(subwindow->widget())->currentUrl());//safety
- m_mdiArea->removeSubWindow(subwindow);
- subwindow->deleteLater();
- }
- }
- Project::instance()->load(QString());
- //TODO scripts
- return true;
-}
-
-void LokalizeMainWindow::openProject(QString path)
-{
- path=SettingsController::instance()->projectOpen(path, false);//dry run
-
- if (path.isEmpty())
- return;
-
- if (closeProject())
- SettingsController::instance()->projectOpen(path, true);//really open
-}
-
-void LokalizeMainWindow::saveProperties(KConfigGroup& stateGroup)
-{
- saveProjectState(stateGroup);
-}
-
-void LokalizeMainWindow::saveProjectState(KConfigGroup& stateGroup)
-{
- QList<QMdiSubWindow*> editors=m_mdiArea->subWindowList();
-
- QStringList files;
- QStringList mergeFiles;
- QList<QByteArray> dockWidgets;
- //QList<int> offsets;
- QList<int> entries;
- QMdiSubWindow* activeSW=m_mdiArea->currentSubWindow();
- int activeSWIndex=-1;
- int i=editors.size();
- while (--i>=0)
- {
- //if (editors.at(i)==m_projectSubWindow)
- if (!editors.at(i) || !qobject_cast<EditorTab*>(editors.at(i)->widget()))
- continue;
- if (editors.at(i)==activeSW)
- activeSWIndex=files.size();
- EditorState state=static_cast<EditorTab*>( editors.at(i)->widget() )->state();
- files.append(state.url.pathOrUrl());
- mergeFiles.append(state.mergeUrl.pathOrUrl());
- dockWidgets.append(state.dockWidgets.toBase64());
- entries.append(state.entry);
- //offsets.append(state.offset);
- //kWarning()<<static_cast<EditorWindow*>(editors.at(i)->widget() )->state().url;
- }
- //if (activeSWIndex==-1 && activeSW==m_projectSubWindow)
-
- if (files.size() == 0 && !m_lastEditorState.isEmpty())
- dockWidgets.append(m_lastEditorState); // save last state if no editor open
-
- if (stateGroup.isValid())
- stateGroup.writeEntry("Project",Project::instance()->path());
-
-
- KConfig config;
- KConfigGroup projectStateGroup(&config,"State-"+Project::instance()->path());
- projectStateGroup.writeEntry("Active",activeSWIndex);
- projectStateGroup.writeEntry("Files",files);
- projectStateGroup.writeEntry("MergeFiles",mergeFiles);
- projectStateGroup.writeEntry("DockWidgets",dockWidgets);
- //stateGroup.writeEntry("Offsets",offsets);
- projectStateGroup.writeEntry("Entries",entries);
- if (m_projectSubWindow)
- {
- ProjectTab *w = static_cast<ProjectTab*>(m_projectSubWindow->widget());
- if (w->unitsCount()>0)
- projectStateGroup.writeEntry("UnitsCount", w->unitsCount());
- }
-
-
- QString nameSpecifier=Project::instance()->path();
- if (!nameSpecifier.isEmpty()) nameSpecifier.prepend('-');
- KConfig* c=stateGroup.isValid()?stateGroup.config():&config;
- m_openRecentFileAction->saveEntries(KConfigGroup(c,"RecentFiles"+nameSpecifier));
-
- m_openRecentProjectAction->saveEntries(KConfigGroup(&config,"RecentProjects"));
-}
-
-void LokalizeMainWindow::readProperties(const KConfigGroup& stateGroup)
-{
- KConfig config;
- const KConfig* c=stateGroup.isValid()?stateGroup.config():&config;
- m_openRecentProjectAction->loadEntries(KConfigGroup(c,"RecentProjects"));
-
- QString path=stateGroup.readEntry("Project",QString());
- if (Project::instance()->isLoaded() || path.isEmpty())
- {
- //1. we weren't existing yet when the signal was emitted
- //2. defer until event loop is running to eliminate QWidgetPrivate::showChildren(bool) startup crash
- QTimer::singleShot(0, this, SLOT(projectLoaded()));
- }
- else
- Project::instance()->load(path);
-}
-
-void LokalizeMainWindow::projectLoaded()
-{
- QString projectPath=Project::instance()->path();
- kDebug()<<projectPath;
- m_openRecentProjectAction->addUrl( KUrl::fromPath(projectPath) );
-
- KConfig config;
-
- QString nameSpecifier=projectPath;
- if (!nameSpecifier.isEmpty()) nameSpecifier.prepend('-');
- m_openRecentFileAction->loadEntries(KConfigGroup(&config,"RecentFiles"+nameSpecifier));
-
-
- //if project isn't loaded, still restore opened files from "State-"
- KConfigGroup projectStateGroup(&config,"State-"+projectPath);
-
- QStringList files;
- QStringList mergeFiles;
- QList<QByteArray> dockWidgets;
- //QList<int> offsets;
- QList<int> entries;
-
- if (m_projectSubWindow)
- {
- ProjectTab *w = static_cast<ProjectTab*>(m_projectSubWindow->widget());
- w->setLegacyUnitsCount(projectStateGroup.readEntry("UnitsCount", 0));
-
- QTabBar* tw = m_mdiArea->findChild<QTabBar*>();
- if(tw) for(int i=0;i<tw->count();i++)
- if (tw->tabText(i)==w->windowTitle())
- tw->setTabToolTip(i, Project::instance()->path());
- }
-
- entries=projectStateGroup.readEntry("Entries",entries);
-
- files=projectStateGroup.readEntry("Files",files);
- mergeFiles=projectStateGroup.readEntry("MergeFiles",mergeFiles);
- dockWidgets=projectStateGroup.readEntry("DockWidgets",dockWidgets);
- int i=files.size();
- int activeSWIndex=projectStateGroup.readEntry("Active",-1);
- QStringList failedFiles;
- while (--i>=0)
- {
- if (i<dockWidgets.size())
- m_lastEditorState=dockWidgets.at(i);
- if (!fileOpen(files.at(i), entries.at(i)/*, offsets.at(i)*//*,&activeSW11*/,activeSWIndex==i,mergeFiles.at(i),/*silent*/true))
- failedFiles.append(files.at(i));
- }
- if (!failedFiles.isEmpty())
- {
- kDebug()<<"failedFiles"<<failedFiles;
-// KMessageBox::error(this, i18nc("@info","Error opening the following files:")+
-// "<br><il><li><filename>"+failedFiles.join("</filename></li><li><filename>")+"</filename></li></il>" );
- KNotification* notification=new KNotification("FilesOpenError", this);
- notification->setText( i18nc("@info","Error opening the following files:\n\n")+"<filename>"+failedFiles.join("</filename><br><filename>")+"</filename>" );
- notification->sendEvent();
- }
-
- if (files.isEmpty() && dockWidgets.size() > 0)
- m_lastEditorState=dockWidgets.first(); // restore last state if no editor open
-
- if (activeSWIndex==-1)
- {
- m_toBeActiveSubWindow=m_projectSubWindow;
- QTimer::singleShot(0,this,SLOT(applyToBeActiveSubWindow()));
- }
-
- projectSettingsChanged();
-}
-
-void LokalizeMainWindow::projectSettingsChanged()
-{
- //TODO show langs
- setCaption(Project::instance()->projectID());
-}
-
-void LokalizeMainWindow::widgetTextCapture()
-{
- WidgetTextCaptureConfig* w=new WidgetTextCaptureConfig(this);
- w->show();
-}
-
-
-//BEGIN DBus interface
-
-//#include "plugin.h"
-#include "mainwindowadaptor.h"
-
-/*
-void LokalizeMainWindow::checkForProjectAlreadyOpened()
-{
-
- QStringList services=QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
- int i=services.size();
- while(--i>=0)
- {
- if (services.at(i).startsWith("org.kde.lokalize"))
- //QDBusReply<uint> QDBusConnectionInterface::servicePid ( const QString & serviceName ) const;
- QDBusConnection::callWithCallback(QDBusMessage::createMethodCall(services.at(i),"/ThisIsWhatYouWant","org.kde.Lokalize.MainWindow","currentProject"),
- this, SLOT(), const char * errorMethod);
- }
-
-}
-*/
-
-void LokalizeMainWindow::registerDBusAdaptor()
-{
- new MainWindowAdaptor(this);
- QDBusConnection::sessionBus().registerObject("/ThisIsWhatYouWant", this);
- QDBusConnection::sessionBus().unregisterObject("/KDebug",QDBusConnection::UnregisterTree);
-
- //kWarning()<<QDBusConnection::sessionBus().interface()->registeredServiceNames().value();
-
-/*
- KActionCollection* actionCollection = mWindow->actionCollection();
- actionCollection->action("file_save")->setEnabled(canSave);
- actionCollection->action("file_save_as")->setEnabled(canSave);
-*/
-}
-
-int LokalizeMainWindow::lookupInTranslationMemory(DocPosition::Part part, const QString& text)
-{
- TM::TMTab* w=showTM();
- if (!text.isEmpty())
- w->lookup(part==DocPosition::Source?text:QString(),part==DocPosition::Target?text:QString());
- return w->dbusId();
-}
-
-int LokalizeMainWindow::lookupInTranslationMemory(const QString& source, const QString& target)
-{
- TM::TMTab* w=showTM();
- w->lookup(source, target);
- return w->dbusId();
-}
-
-
-int LokalizeMainWindow::showTranslationMemory()
-{
- /*activateWindow();
- raise();
- show();*/
- return lookupInTranslationMemory(DocPosition::UndefPart,QString());
-}
-
-int LokalizeMainWindow::openFileInEditorAt(const QString& path, const QString& source, const QString& ctxt)
-{
- EditorTab* w=fileOpen(KUrl(path),source,ctxt);
- if (!w) return -1;
- return w->dbusId();
-}
-
-int LokalizeMainWindow::openFileInEditor(const QString& path)
-{
- return openFileInEditorAt(path,QString(),QString());
-}
-
-QObject* LokalizeMainWindow::activeEditor()
-{
- QList<QMdiSubWindow*> editors=m_mdiArea->subWindowList();
- QMdiSubWindow* activeSW=m_mdiArea->currentSubWindow();
- if (!activeSW || !qobject_cast<EditorTab*>(activeSW->widget()))
- return 0;
- return activeSW->widget();
-}
-
-QObject* LokalizeMainWindow::editorForFile(const QString& path)
-{
- if (!m_fileToEditor.contains(KUrl(path))) return 0;
- QMdiSubWindow* w=m_fileToEditor.value(KUrl(path));
- if (!w) return 0;
- return static_cast<EditorTab*>(w->widget());
-}
-
-int LokalizeMainWindow::editorIndexForFile(const QString& path)
-{
- EditorTab* editor=static_cast<EditorTab*>(editorForFile(path));
- if (!editor) return -1;
- return editor->dbusId();
-}
-
-
-QString LokalizeMainWindow::currentProject(){return Project::instance()->path();}
-
-#include <unistd.h>
-int LokalizeMainWindow::pid(){return getpid();}
-QString LokalizeMainWindow::dbusName(){return QString("org.kde.lokalize-%1").arg(pid());}
-void LokalizeMainWindow::busyCursor(bool busy){busy?QApplication::setOverrideCursor(Qt::WaitCursor):QApplication::restoreOverrideCursor();}
-// void LokalizeMainWindow::processEvents(){QCoreApplication::processEvents();}
-
-//END DBus interface
-
-
-
-DelayedFileOpener::DelayedFileOpener(const KUrl::List& urls, LokalizeMainWindow* lmw)
- : QObject()
- , m_urls(urls)
- , m_lmw(lmw)
-{
- //do the work just after project load handlind is finished
- //(i.e. all the files from previous project session are loaded)
- QTimer::singleShot(1,this,SLOT(doOpen()));
-}
-
-void DelayedFileOpener::doOpen()
-{
- int lastIndex=m_urls.count()-1;
- for (int i=0;i<=lastIndex;i++)
- m_lmw->fileOpen(m_urls.at(i), 0, /*set as active*/i==lastIndex);
- deleteLater();
-}
-
-
-#include "moc_lokalizemainwindow.cpp"
- //these have to be included somewhere ;)
-#include "moc_lokalizesubwindowbase.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef LOKALIZEMAINWINDOW_H
-#define LOKALIZEMAINWINDOW_H
-
-#include "pos.h"
-
-#include <kxmlguiwindow.h>
-#include <kurl.h>
-#include <kconfiggroup.h>
-
-#include <QPointer>
-#include <QMap>
-#include <QtDBus/qdbusextratypes.h>
-
-
-#include <QMdiSubWindow>
-#include <QMdiArea>
-#include <QActionGroup>
-class KAction;
-class KRecentFilesAction;
-class EditorTab;
-namespace TM {class TMTab;}
-class FileSearchTab;
-
-/**
- * @short Lokalize MDI (tabbed) window.
- *
- * Sets up actions, and maintains their connection with active subwindow via ActionProxy
- * As such, it handles the menus, toolbars, and status bars.
- *
- * It is known as Lokalize in scripts and as
- * '/ThisIsWhatYouWant : org.kde.Lokalize.MainWindow' in qdbusviewer
- *
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class LokalizeMainWindow: public KXmlGuiWindow
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.MainWindow")
- //qdbuscpp2xml -m -s lokalizemainwindow.h -o org.kde.lokalize.MainWindow.xml
-
-public:
- LokalizeMainWindow();
- ~LokalizeMainWindow();
-
-protected:
- void saveProjectState(KConfigGroup&);
- void saveProperties(KConfigGroup& stateGroup);
- bool queryClose();
- void readProperties(const KConfigGroup& stateGroup);
- void registerDBusAdaptor();
- void setupActions();
-
-private slots:
- void slotSubWindowActivated(QMdiSubWindow*);
- void initLater();
- void applyToBeActiveSubWindow();
- void projectLoaded();
- void projectSettingsChanged();
-
- void editorClosed(QObject* obj);
-
- void openProject(const KUrl& url){openProject(url.path());}//convenience overload for recent projects action
- void openProject(){openProject(QString());}
-
-
-public slots:
- /**
- * Adds new editor with @param path loaded,
- * or just activates already existing editor with this file.
- */
- Q_SCRIPTABLE int openFileInEditor(const QString& path);
- Q_SCRIPTABLE int openFileInEditorAt(const QString& path, const QString& source, const QString& ctxt);
- int lookupInTranslationMemory(DocPosition::Part part, const QString& text);
- Q_SCRIPTABLE int lookupInTranslationMemory(const QString& source, const QString& target);
- Q_SCRIPTABLE int showTranslationMemory();
- Q_SCRIPTABLE void showProjectOverview();
- Q_SCRIPTABLE QObject* projectOverview();
-
- Q_SCRIPTABLE bool closeProject();
- Q_SCRIPTABLE void openProject(QString path);
- Q_SCRIPTABLE QString currentProject();
-
- /// @returns 0 if current tab is not of Editor type
- Q_SCRIPTABLE QObject* activeEditor();
-
- /// @returns editor with @param path loaded or 0 if there is no such editor.
- Q_SCRIPTABLE QObject* editorForFile(const QString& path);
- /**
- * # part of editor DBus path: /ThisIsWhatYouWant/Editor/#
- * @returns -1 if there is no such editor
- */
- Q_SCRIPTABLE int editorIndexForFile(const QString& path);
-
- /// @returns Unix process ID
- Q_SCRIPTABLE int pid();
-
- /// @returns smth like 'org.kde.lokalize-####' where #### is pid()
- Q_SCRIPTABLE QString dbusName();
-
- Q_SCRIPTABLE void busyCursor(bool busy);
- //Q_SCRIPTABLE void processEvents();
-
- //returns 0 if error
- EditorTab* fileOpen(KUrl url=KUrl(),int entry=0, bool setAsActive=true, const QString& mergeFile=QString(), bool silent=false);
- EditorTab* fileOpen(const KUrl& url, const QString& source, const QString& ctxt);
- EditorTab* fileOpen(const KUrl& url, DocPosition docPos, int selection);
- TM::TMTab* showTM();
- FileSearchTab* showFileSearch(bool activate=true);
- void fileSearchNext();
- void addFilesToSearch(const QStringList&);
-
- void widgetTextCapture();
-signals:
- Q_SCRIPTABLE void editorAdded();
- Q_SCRIPTABLE void editorActivated();
-
-private:
- QMdiArea* m_mdiArea;
- QPointer<QMdiSubWindow> m_prevSubWindow;
- QPointer<QMdiSubWindow> m_projectSubWindow;
- QPointer<QMdiSubWindow> m_translationMemorySubWindow;
- QPointer<QMdiSubWindow> m_fileSearchSubWindow;
- QPointer<QMdiSubWindow> m_toBeActiveSubWindow;//used during session restore
-
- QActionGroup* m_editorActions;
- QActionGroup* m_managerActions;
- KRecentFilesAction* m_openRecentFileAction;
- KRecentFilesAction* m_openRecentProjectAction;
-
- QByteArray m_lastEditorState;
-
- //using QPointer switches it.value() to 0 before we get to destroyed() handler
- //typedef QMap<KUrl, QPointer<QMdiSubWindow> > FileToEditor;
- typedef QMap<KUrl, QMdiSubWindow*> FileToEditor;
- FileToEditor m_fileToEditor;
-};
-
-class DelayedFileOpener: public QObject
-{
-Q_OBJECT
-public:
- DelayedFileOpener(const KUrl::List& urls, LokalizeMainWindow* lmw);
-
-private slots:
- void doOpen();
-
-private:
- KUrl::List m_urls;
- LokalizeMainWindow* m_lmw;
-};
-
-
-#endif
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="LokalizeMainWindow" version="7">
-<MenuBar>
- <Menu name="file"><text>&File</text>
- <Action name="file_new"/>
- <MergeLocal name="new_merge"/>
- <Action name="file_open"/>
- <Action name="file_open_recent"/>
- <MergeLocal name="open_merge"/>
- <Separator/>
- <Merge/>
- <Separator/>
- <Action name="file_quit"/>
- </Menu>
-
- <Merge/>
- <Menu name="project"><text>&Project</text>
- <Action name="project_overview"/>
- <Action name="project_configure"/>
- <Separator/>
- <Action name="project_open"/>
- <Action name="project_open_recent"/>
- <Action name="project_create"/>
- <Merge/>
- </Menu>
- <Menu name="tools">
- <MergeLocal name="tools_spelling_merge"/>
- <Separator/>
- <Action name="tools_glossary"/>
- <Separator/>
- <Action name="tools_tm"/>
- <Action name="tools_tm_manage"/>
- <Separator/>
- <Action name="tools_filesearch"/>
- <Action name="tools_filesearch_next"/>
- <Separator/>
- <Action name="tools_widgettextcapture"/>
- <Merge/>
- </Menu>
- <Menu name="settings">
- <Menu name="toolviews"><text>Tool&views</text>
- </Menu>
- <Merge/>
- </Menu>
-</MenuBar>
-<!--<State name="po" >
- <disable>
- </disable>
-</State>
-<State name="xliff" >
- <enable>
- </enable>
-</State>-->
-</kpartgui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef LOKALIZESUBWINDOWBASE_H
-#define LOKALIZESUBWINDOWBASE_H
-
-#include <QHash>
-#include <QString>
-#include <KMainWindow>
-#include <KXMLGUIClient>
-
-#include <kurl.h>
-#include "actionproxy.h"
-
-
-/**
- * Interface for LokalizeMainWindow
- */
-class LokalizeSubwindowBase: public KMainWindow
-{
-Q_OBJECT
-public:
- LokalizeSubwindowBase(QWidget* parent):KMainWindow(parent){}
- virtual ~LokalizeSubwindowBase(){emit aboutToBeClosed();}
- virtual KXMLGUIClient* guiClient()=0;
-
- //interface for LokalizeMainWindow
- virtual void hideDocks()=0;
- virtual void showDocks()=0;
- //bool queryClose();
-
- virtual KUrl currentUrl(){return KUrl();}
-
-protected:
- void reflectNonApprovedCount(int count, int total);
- void reflectUntranslatedCount(int count, int total);
-
-signals:
- void aboutToBeClosed();
-
-public:
- //QHash<QString,ActionProxy*> supportedActions;
- StatusBarProxy statusBarItems;
-
-};
-
-/**
- * C++ casting workaround
- */
-class LokalizeSubwindowBase2: public LokalizeSubwindowBase, public KXMLGUIClient
-{
-public:
- LokalizeSubwindowBase2(QWidget* parent): LokalizeSubwindowBase(parent),KXMLGUIClient(){}
- virtual ~LokalizeSubwindowBase2(){};
-
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#include "version.h"
-#include "prefs_lokalize.h"
-#include "prefs.h"
-#include "project.h"
-#include "jobs.h"
-#include "projectmodel.h"
-
-#include "lokalizemainwindow.h"
-#include "projecttab.h"
-
-#include "stemming.h"
-
-#include "catalogstring.h"
-#include "pos.h"
-#include <QMetaType>
-#include <QString>
-#include <QFileInfo>
-
-#include <kapplication.h>
-#include <kaboutdata.h>
-#include <kcmdlineargs.h>
-#include <klocale.h>
-#include <threadweaver/ThreadWeaver.h>
-
-static const char version[] = LOKALIZE_VERSION;
-static const char description[] =
- I18N_NOOP("Computer-aided translation system.\nDo not translate what had already been translated.");
-
-int main(int argc, char **argv)
-{
- KAboutData about("lokalize", 0, ki18nc("@title", "Lokalize"), version, ki18n(description),
- KAboutData::License_GPL, ki18nc("@info:credit", "(c) 2007-2013 Nick Shaforostoff\n(c) 1999-2006 The KBabel developers") /*, KLocalizedString(), 0, "shafff@ukr.net"*/);
- about.addAuthor( ki18n("Nick Shaforostoff"), KLocalizedString(), "shaforostoff@kde.ru" );
- about.addCredit (ki18n("Google Inc."), ki18n("sponsored development as part of Google Summer Of Code program"), QByteArray(), "http://google.com");
- about.addCredit (ki18n("Translate-toolkit"), ki18n("provided excellent cross-format converting scripts"), QByteArray(), "http://translate.sourceforge.net");
- about.addCredit (ki18n("Viesturs Zarins"), ki18n("project tree merging translation+templates"), "viesturs.zarins@mii.lu.lv", QByteArray());
- about.addCredit (ki18n("Stephan Johach"), ki18n("bug fixing patches"), "hunsum@gmx.de");
- about.addCredit (ki18n("Chusslove Illich"), ki18n("bug fixing patches"), "caslav.ilic@gmx.net");
- about.addCredit (ki18n("Jure Repinc"), ki18n("testing and bug fixing"), "jlp@holodeck1.com");
- about.addCredit (ki18n("Stefan Asserhall"), ki18n("patches"), "stefan.asserhall@comhem.se");
- about.addCredit (ki18n("Papp Laszlo"), ki18n("bug fixing patches"), "djszapi@archlinux.us");
- about.addCredit (ki18n("Albert Astals Cid"), ki18n("XLIFF improvements"), "aacid@kde.org");
-
- KCmdLineArgs::init(argc, argv, &about);
-
- KCmdLineOptions options;
- //options.add("merge-source <URL>", ki18n( "Source for the merge mode" ));
- options.add("noprojectscan", ki18n( "Do not scan files of the project."));
- options.add("project <filename>", ki18n( "Load specified project."));
- options.add("+[URL]", ki18n( "Document to open" ));
- KCmdLineArgs::addCmdLineOptions(options);
-
- KApplication app;
-
- //qDebug() is important as it aviods compile 'optimization'.
- qDebug()<<qRegisterMetaType<DocPosition>();
- qDebug()<<qRegisterMetaType<DocPos>();
- qDebug()<<qRegisterMetaType<InlineTag>();
- qDebug()<<qRegisterMetaType<CatalogString>();
- qRegisterMetaTypeStreamOperators<InlineTag>("InlineTag");
- qRegisterMetaTypeStreamOperators<CatalogString>("CatalogString");
- qAddPostRoutine(&cleanupSpellers);
-
- // see if we are starting with session management
- if (app.isSessionRestored()) {
- kRestoreMainWindows<LokalizeMainWindow>();
- }
- else
- {
- // no session.. just start up normally
- KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
-
- if (!args->getOption("project").isEmpty())
- {
- // load needs an absolute path
- // FIXME: I do not know how to handle urls here
- // bug 245546 regarding symlinks
- QFileInfo projectFileInfo(args->getOption("project").toUtf8());
- QString projectFilePath=projectFileInfo.canonicalFilePath();
- if (projectFilePath.isEmpty())
- projectFilePath=projectFileInfo.absoluteFilePath();
- Project::instance()->load( projectFilePath );
- }
- LokalizeMainWindow* lmw=new LokalizeMainWindow;
- SettingsController::instance()->setMainWindowPtr(lmw);
- lmw->show();
-
- KUrl::List urls;
- for (int j=0; j<args->count(); j++)
- urls << args->url(j);
- if (urls.size())
- new DelayedFileOpener(urls, lmw);
-
- Project::instance()->model()->setCompleteScan(args->isSet("projectscan"));
- args->clear();
- }
-
- int code=app.exec();
-
- ThreadWeaver::Weaver::instance()->dequeue();
- Project::instance()->model()->weaver()->dequeue();
-
- if (SettingsController::instance()->dirty) //for config changes done w/o config dialog
- Settings::self()->writeConfig();
-
- if (Project::instance()->isLoaded())
- Project::instance()->save();
-
- qWarning()<<"QCoreApplication::processEvents()...";
- QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0,0);
-
- qWarning()<<"Finishing Project jobs...";
- //Project::instance()->model()->weaver()->finish();
- // HACK due to deadlock with libstreamanalyzer.so.0 -> libxml2.so.2 -> etree.so -> libpython2.5.so.1.0 -> PyThread_acquire_lock
- while (!Project::instance()->model()->weaver()->isIdle())
- {
- QCoreApplication::processEvents();
- QCoreApplication::sendPostedEvents(0,0);
- }
-
- qWarning()<<"Finishing TM jobs...";
- ThreadWeaver::Weaver::instance()->finish();
-
- return code;
-}
-
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "mergecatalog.h"
-#include "catalog_private.h"
-#include "catalogstorage.h"
-#include "cmd.h"
-#include <kdebug.h>
-#include <klocalizedstring.h>
-#include <QMultiHash>
-#include <QtCore/qalgorithms.h>
-
-
-
-MergeCatalog::MergeCatalog(QObject* parent, Catalog* baseCatalog, bool saveChanges)
- : Catalog(parent)
- , m_baseCatalog(baseCatalog)
- , m_modified(false)
-{
- setActivePhase(baseCatalog->activePhase(),baseCatalog->activePhaseRole());
- if (saveChanges)
- {
- connect (baseCatalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(copyFromBaseCatalogIfInDiffIndex(DocPosition)));
- connect (baseCatalog,SIGNAL(signalFileSaved()),this,SLOT(save()));
- }
-}
-
-void MergeCatalog::copyFromBaseCatalog(const DocPosition& pos, int options)
-{
- bool a=m_mergeDiffIndex.contains(pos.entry);
- if (options&EvenIfNotInDiffIndex || !a)
- {
- //sync changes
- DocPosition ourPos=pos;
- if ( (ourPos.entry=m_map.at(ourPos.entry)) == -1)
- return;
-
- //note the explicit use of map...
- if (m_storage->isApproved(ourPos)!=m_baseCatalog->isApproved(pos))
- //kWarning()<<ourPos.entry<<"SHIT";
- m_storage->setApproved(ourPos, m_baseCatalog->isApproved(pos));
- DocPos p(pos);
- if (!m_originalHashes.contains(p))
- m_originalHashes[p]=qHash(m_storage->target(ourPos));
- m_storage->setTarget(ourPos,m_baseCatalog->target(pos));
- setModified(ourPos, true);
-
- if (options&EvenIfNotInDiffIndex && a)
- m_mergeDiffIndex.removeAll(pos.entry);
-
- m_modified=true;
- emit signalEntryModified(pos);
- }
-}
-
-QString MergeCatalog::msgstr(const DocPosition& pos) const
-{
- DocPosition us=pos;
- us.entry=m_map.at(pos.entry);
-
- return (us.entry==-1)?QString():Catalog::msgstr(us);
-}
-
-bool MergeCatalog::isApproved(uint index) const
-{
- return (m_map.at(index)==-1)?false:Catalog::isApproved(m_map.at(index));
-}
-
-TargetState MergeCatalog::state(const DocPosition& pos) const
-{
- DocPosition us=pos;
- us.entry=m_map.at(pos.entry);
-
- return (us.entry==-1)?New:Catalog::state(us);
-}
-
-
-bool MergeCatalog::isPlural(uint index) const
-{
- //sanity
- if (m_map.at(index) == -1)
- {
- kWarning()<<"!!! index"<<index<<"m_map.at(index)"<<m_map.at(index)<<"numberOfEntries()"<<numberOfEntries();
- return false;
- }
-
- return Catalog::isPlural(m_map.at(index));
-}
-
-bool MergeCatalog::isPresent(const short int& entry) const
-{
- return m_map.at(entry)!=-1;
-}
-
-MatchItem MergeCatalog::calcMatchItem(const DocPosition& basePos,const DocPosition& mergePos)
-{
- CatalogStorage& baseStorage=*(m_baseCatalog->m_storage);
- CatalogStorage& mergeStorage=*(m_storage);
-
- MatchItem item(mergePos.entry, basePos.entry, true);
- //TODO make more robust, perhaps after XLIFF?
- QStringList baseMatchData=baseStorage.matchData(basePos);
- QStringList mergeMatchData=mergeStorage.matchData(mergePos);
-
- //compare ids
- item.score+=40*((baseMatchData.isEmpty()&&mergeMatchData.isEmpty())?baseStorage.id(basePos)==mergeStorage.id(mergePos)
- :baseMatchData==mergeMatchData);
-
- //TODO look also for changed/new <note>s
-
- //translation isn't changed
- if (baseStorage.targetAllForms(basePos, true)==mergeStorage.targetAllForms(mergePos, true))
- {
- item.translationIsDifferent=baseStorage.isApproved(basePos)!=mergeStorage.isApproved(mergePos);
- item.score+=29+1*item.translationIsDifferent;
- }
-#if 0
- if (baseStorage.source(basePos)=="%1 (%2)")
- {
- qDebug()<<"BASE";
- qDebug()<<m_baseCatalog->url();
- qDebug()<<basePos.entry;
- qDebug()<<baseStorage.source(basePos);
- qDebug()<<baseMatchData.first();
- qDebug()<<"MERGE";
- qDebug()<<url();
- qDebug()<<mergePos.entry;
- qDebug()<<mergeStorage.source(mergePos);
- qDebug()<<mergeStorage.matchData(mergePos).first();
- qDebug()<<item.score;
- qDebug()<<"";
- }
-#endif
- return item;
-}
-
-static QString strip(QString source)
-{
- source.remove('\n');
- return source;
-}
-
-int MergeCatalog::loadFromUrl(const KUrl& url)
-{
- int errorLine=Catalog::loadFromUrl(url);
- if (Q_UNLIKELY( errorLine!=0 ))
- return errorLine;
-
- //now calc the entry mapping
-
- CatalogStorage& baseStorage=*(m_baseCatalog->m_storage);
- CatalogStorage& mergeStorage=*(m_storage);
-
- DocPosition i(0);
- int size=baseStorage.size();
- int mergeSize=mergeStorage.size();
- m_map.fill(-1,size);
- QMultiMap<int,int> backMap; //will be used to maintain one-to-one relation
-
-
- //precalc for fast lookup
- QMultiHash<QString, int> mergeMap;
- while (i.entry<mergeSize)
- {
- mergeMap.insert(strip(mergeStorage.source(i)),i.entry);
- ++(i.entry);
- }
-
- i.entry=0;
- while (i.entry<size)
- {
- QString key=strip(baseStorage.source(i));
- const QList<int>& entries=mergeMap.values(key);
- QList<MatchItem> scores;
- int k=entries.size();
- if (k)
- {
- while(--k>=0)
- scores<<calcMatchItem(i,DocPosition( entries.at(k) ));
-
- qSort(scores.begin(), scores.end(), qGreater<MatchItem>());
-
- m_map[i.entry]=scores.first().mergeEntry;
- backMap.insert(scores.first().mergeEntry, i.entry);
-
- if (scores.first().translationIsDifferent)
- m_mergeDiffIndex.append(i.entry);
-
- }
- ++i.entry;
- }
-
-
- //maintain one-to-one relation
- const QList<int>& mergePositions=backMap.uniqueKeys();
- foreach(int mergePosition, mergePositions)
- {
- const QList<int>& basePositions=backMap.values(mergePosition);
- if (basePositions.size()==1)
- continue;
-
- //qDebug()<<"kv"<<mergePosition<<basePositions;
- QList<MatchItem> scores;
- foreach(int value, basePositions)
- scores<<calcMatchItem(DocPosition(value), mergePosition);
-
- qSort(scores.begin(), scores.end(), qGreater<MatchItem>());
- int i=scores.size();
- while(--i>0)
- {
- //qDebug()<<"erasing"<<scores.at(i).baseEntry<<m_map[scores.at(i).baseEntry]<<",m_map["<<scores.at(i).baseEntry<<"]=-1";
- m_map[scores.at(i).baseEntry]=-1;
- }
- }
-
- //fuzzy match unmatched entries?
-/* QMultiHash<QString, int>::iterator it = mergeMap.begin();
- while (it != mergeMap.end())
- {
- //kWarning()<<it.value()<<it.key();
- ++it;
- }*/
- m_unmatchedCount=numberOfEntries()-mergePositions.count();
- m_modified=false;
- m_originalHashes.clear();
-
- return 0;
-}
-
-bool MergeCatalog::isModified(DocPos pos) const
-{
- return Catalog::isModified(pos) && m_originalHashes.value(pos)!=qHash(target(pos.toDocPosition()));
-}
-
-bool MergeCatalog::save()
-{
- bool ok = !m_modified || Catalog::save();
- if (ok) m_modified=false;
- m_originalHashes.clear();
- return ok;
-}
-
-void MergeCatalog::copyToBaseCatalog(DocPosition& pos)
-{
- bool changeContents=m_baseCatalog->msgstr(pos)!=msgstr(pos);
-
- m_baseCatalog->beginMacro(i18nc("@item Undo action item","Accept change in translation"));
-
- if ( m_baseCatalog->state(pos) != state(pos))
- SetStateCmd::instantiateAndPush(m_baseCatalog,pos,state(pos));
-
- if (changeContents)
- {
- pos.offset=0;
- if (!m_baseCatalog->msgstr(pos).isEmpty())
- m_baseCatalog->push(new DelTextCmd(m_baseCatalog,pos,m_baseCatalog->msgstr(pos)));
-
- m_baseCatalog->push(new InsTextCmd(m_baseCatalog,pos,msgstr(pos)));
- }
- ////////this is NOT done automatically by BaseCatalogEntryChanged slot
- bool remove=true;
- if (isPlural(pos.entry))
- {
- DocPosition p=pos;
- p.form=qMin(m_baseCatalog->numberOfPluralForms(),numberOfPluralForms());//just sanity check
- p.form=qMax((int)p.form,1);//just sanity check
- while ((--(p.form))>=0 && remove)
- remove=m_baseCatalog->msgstr(p)==msgstr(p);
- }
- if (remove)
- removeFromDiffIndex(pos.entry);
-
- m_baseCatalog->endMacro();
-}
-
-void MergeCatalog::copyToBaseCatalog(int options)
-{
- DocPosition pos;
- pos.offset=0;
- bool insHappened=false;
- QLinkedList<int> changed=differentEntries();
- foreach(int entry, changed)
- {
- pos.entry=entry;
- if (options&EmptyOnly&&!m_baseCatalog->isEmpty(entry))
- continue;
- if (options&HigherOnly&&!m_baseCatalog->isEmpty(entry)&&m_baseCatalog->state(pos)>=state(pos))
- continue;
-
- int formsCount=(m_baseCatalog->isPlural(entry))?m_baseCatalog->numberOfPluralForms():1;
- pos.form=0;
- while (pos.form<formsCount)
- {
- //m_baseCatalog->push(new DelTextCmd(m_baseCatalog,pos,m_baseCatalog->msgstr(pos.entry,0))); ?
- //some forms may still contain translation...
- if (!(options&EmptyOnly && !m_baseCatalog->isEmpty(pos)) /*&&
- !(options&HigherOnly && !m_baseCatalog->isEmpty(pos) && m_baseCatalog->state(pos)>=state(pos))*/)
- {
- if (!insHappened)
- {
- //stop basecatalog from sending signalEntryModified to us
- //when we are the ones who does the modification
- disconnect (m_baseCatalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(copyFromBaseCatalogIfInDiffIndex(DocPosition)));
- insHappened=true;
- m_baseCatalog->beginMacro(i18nc("@item Undo action item","Accept all new translations"));
- }
-
- copyToBaseCatalog(pos);
- /// ///
- /// m_baseCatalog->push(new InsTextCmd(m_baseCatalog,pos,mergeCatalog.msgstr(pos)));
- /// ///
- }
- ++(pos.form);
- }
- /// ///
- /// removeFromDiffIndex(m_pos.entry);
- /// ///
- }
-
- if (insHappened)
- {
- m_baseCatalog->endMacro();
- //reconnect to catch all modifications coming from outside
- connect (m_baseCatalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(copyFromBaseCatalogIfInDiffIndex(DocPosition)));
- }
-}
-
-#include "moc_mergecatalog.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef MERGECATALOG_H
-#define MERGECATALOG_H
-
-#include "catalog.h"
-
-#include <QVector>
-#include <QLinkedList>
-
-struct MatchItem
-{
- short mergeEntry:16;
- short baseEntry:16;
- short score:16;
- short translationIsDifferent:16;
-
- MatchItem()
- : mergeEntry(0)
- , baseEntry(0)
- , score(0)
- , translationIsDifferent(false)
- {}
-
- MatchItem(short m, short b, bool d)
- : mergeEntry(m)
- , baseEntry(b)
- , score(0)
- , translationIsDifferent(d)
- {}
-
- bool operator<(const MatchItem& other) const
- {
- return score<other.score;
- }
-
-};
-
-
-/**
- * Merge source container.
- * Parallel editing is available.
- * What this subclass does is creating the map (to provide main-file entry order) and index for fast changed entry lookup
- * So order of entries the same as of main-file
- *
- * TODO index of ch - on-the-fly
- * @short Merge source container
- * @author Nick Shaforostoff <shafff@ukr.net>
- */
-class MergeCatalog: public Catalog
-{
- Q_OBJECT
-public:
- MergeCatalog(QObject* parent, Catalog* baseCatalog, bool saveChanges=true);
- ~MergeCatalog(){};
-
- int loadFromUrl(const KUrl& url);
-
- int firstChangedIndex() const {return m_mergeDiffIndex.isEmpty()?numberOfEntries():m_mergeDiffIndex.first();}
- int lastChangedIndex() const {return m_mergeDiffIndex.isEmpty()?-1:m_mergeDiffIndex.last();}
- int nextChangedIndex(uint index) const {return findNextInList(m_mergeDiffIndex,index);}
- int prevChangedIndex(uint index) const {return findPrevInList(m_mergeDiffIndex,index);}
- int isDifferent(uint index) const {return m_mergeDiffIndex.contains(index);}
- QLinkedList<int> differentEntries()const {return m_mergeDiffIndex;}
-
- //override to use map
- QString msgstr(const DocPosition&) const;
- bool isApproved(uint index) const;
- bool isPlural(uint index) const;
- TargetState state(const DocPosition& pos) const;
-
- int unmatchedCount()const{return m_unmatchedCount;}
-
- /// whether 'merge source' has entry with such msgid
- bool isPresent(const short int& entry) const;
- bool isModified(DocPos)const;
-
- ///@arg pos in baseCatalog's coordinates
- void copyToBaseCatalog(DocPosition& pos);
- enum CopyToBaseOptions {EmptyOnly=1, HigherOnly=2};
- void copyToBaseCatalog(int options=0);
-
- inline void removeFromDiffIndex(uint index){m_mergeDiffIndex.removeAll(index);}
- enum CopyFromBaseOptions {EvenIfNotInDiffIndex=1};
- void copyFromBaseCatalog(const DocPosition&, int options);
- void copyFromBaseCatalog(const DocPosition& pos){copyFromBaseCatalog(pos, EvenIfNotInDiffIndex);}
-public slots:
- void copyFromBaseCatalogIfInDiffIndex(const DocPosition& pos){copyFromBaseCatalog(pos, 0);}
-
- bool save(); //reimplement to do save only when changes were actually done to this catalog
-
-private:
- MatchItem calcMatchItem(const DocPosition& basePos,const DocPosition& mergePos);
- KAutoSaveFile* checkAutoSave(const KUrl&){return 0;}//rely on basecatalog restore
-
-
-private:
- QVector<int> m_map; //maps entries: m_baseCatalog -> this
- Catalog* m_baseCatalog;
- QLinkedList<int> m_mergeDiffIndex;//points to baseCatalog entries
- QMap<DocPos, uint> m_originalHashes; //for modified units only
- int m_unmatchedCount;
- bool m_modified; //need own var here cause we don't use qundostack system for merging
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "mergeview.h"
-
-#include "cmd.h"
-#include "mergecatalog.h"
-#include "project.h"
-#include "diff.h"
-#include "projectmodel.h"
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <kurl.h>
-#include <kfiledialog.h>
-#include <kmessagebox.h>
-#include <knotification.h>
-#include <ktextedit.h>
-#include <kaction.h>
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QtGui/qevent.h>
-#include <QFile>
-#include <QToolTip>
-
-MergeView::MergeView(QWidget* parent, Catalog* catalog, bool primary)
- : QDockWidget ( primary?i18nc("@title:window that displays difference between current file and 'merge source'","Primary Sync"):i18nc("@title:window that displays difference between current file and 'merge source'","Secondary Sync"), parent)
- , m_browser(new KTextEdit(this))
- , m_baseCatalog(catalog)
- , m_mergeCatalog(0)
- , m_normTitle(primary?
- i18nc("@title:window that displays difference between current file and 'merge source'","Primary Sync"):
- i18nc("@title:window that displays difference between current file and 'merge source'","Secondary Sync"))
- , m_hasInfoTitle(m_normTitle+" [*]")
- , m_hasInfo(false)
- , m_primary(primary)
-{
- setObjectName(primary?"mergeView-primary":"mergeView-secondary");
- setWidget(m_browser);
- setToolTip(i18nc("@info:tooltip","Drop file to be merged into / synced with the current one here"));
-
- hide();
-
- setAcceptDrops(true);
- m_browser->setReadOnly(true);
- m_browser->setContextMenuPolicy(Qt::NoContextMenu);
- setContextMenuPolicy(Qt::ActionsContextMenu);
-}
-
-MergeView::~MergeView()
-{
- delete m_mergeCatalog;
- emit mergeCatalogPointerChanged(NULL);
-}
-
-KUrl MergeView::url()
-{
- if (m_mergeCatalog)
- return m_mergeCatalog->url();
- return KUrl();
-}
-
-void MergeView::dragEnterEvent(QDragEnterEvent* event)
-{
- if(event->mimeData()->hasUrls() && Catalog::extIsSupported(event->mimeData()->urls().first().path()))
- event->acceptProposedAction();
-}
-
-void MergeView::dropEvent(QDropEvent *event)
-{
- mergeOpen(KUrl(event->mimeData()->urls().first()));
- event->acceptProposedAction();
-}
-
-void MergeView::slotUpdate(const DocPosition& pos)
-{
- if (pos.entry==m_pos.entry)
- slotNewEntryDisplayed(pos);
-}
-
-void MergeView::slotNewEntryDisplayed(const DocPosition& pos)
-{
- m_pos=pos;
-
- if (!m_mergeCatalog)
- return;
-
- emit signalPriorChangedAvailable((pos.entry>m_mergeCatalog->firstChangedIndex())
- ||(pluralFormsAvailableBackward()!=-1));
- emit signalNextChangedAvailable((pos.entry<m_mergeCatalog->lastChangedIndex())
- ||(pluralFormsAvailableForward()!=-1));
-
- if (!m_mergeCatalog->isPresent(pos.entry))
- {
- //i.e. no corresponding entry, whether changed or not
- if (m_hasInfo)
- {
- m_hasInfo=false;
- setWindowTitle(m_normTitle);
- m_browser->clear();
-// m_browser->viewport()->setBackgroundRole(QPalette::Base);
- }
- emit signalEntryWithMergeDisplayed(false);
-
- /// no editing at all! ////////////
- return;
- }
- if (!m_hasInfo)
- {
- m_hasInfo=true;
- setWindowTitle(m_hasInfoTitle);
- }
-
- emit signalEntryWithMergeDisplayed(m_mergeCatalog->isDifferent(pos.entry));
-
- QString result=userVisibleWordDiff(m_baseCatalog->msgstr(pos),
- m_mergeCatalog->msgstr(pos),
- Project::instance()->accel(),
- Project::instance()->markup(),
- Html);
-#if 0
- int i=-1;
- bool inTag=false;
- while(++i<result.size())//dynamic
- {
- if (!inTag)
- {
- if (result.at(i)=='<')
- inTag=true;
- else if (result.at(i)==' ')
- result.replace(i,1,"&sp;");
- }
- else if (result.at(i)=='>')
- inTag=false;
- }
-#endif
-
- if (!m_mergeCatalog->isApproved(pos.entry))
- {
- result.prepend("<i>");
- result.append("</i>");
- }
-
- if (m_mergeCatalog->isModified(pos))
- {
- result.prepend("<b>");
- result.append("</b>");
- }
-
- m_browser->setHtml(result);
-// kWarning()<<"ELA "<<time.elapsed();
-}
-
-void MergeView::cleanup()
-{
- delete m_mergeCatalog;
- m_mergeCatalog=0;
- emit mergeCatalogPointerChanged(m_mergeCatalog);
- m_pos=DocPosition();
-
- emit signalPriorChangedAvailable(false);
- emit signalNextChangedAvailable(false);
-
- m_browser->clear();
-}
-
-void MergeView::mergeOpen(KUrl url)
-{
- if (Q_UNLIKELY( !m_baseCatalog->numberOfEntries() ))
- return;
-
- if (url==m_baseCatalog->url())
- {
- //(we are likely to be _mergeViewSecondary)
- //special handling: open corresponding file in the branch
- //for AutoSync
-
- QString path=QFileInfo(url.toLocalFile()).canonicalFilePath(); //bug 245546 regarding symlinks
- QString oldPath=path;
- path.replace(Project::instance()->poDir(),Project::instance()->branchDir());
-
- if (oldPath==path) //if file doesn't exist both are empty
- {
- cleanup();
- return;
- }
-
- url=KUrl(path);
- }
-
- if (url.isEmpty())
- {
- Project::instance()->model()->weaver()->suspend();
- url=KFileDialog::getOpenUrl(KUrl("kfiledialog:///merge-source") /*m_baseCatalog->url()*/ , Catalog::supportedMimeFilters, this);
- Project::instance()->model()->weaver()->resume();
- }
- if (url.isEmpty())
- return;
-
- delete m_mergeCatalog;
- m_mergeCatalog=new MergeCatalog(this,m_baseCatalog);
- emit mergeCatalogPointerChanged(m_mergeCatalog);
- int errorLine=m_mergeCatalog->loadFromUrl(url);
- if (Q_LIKELY( errorLine==0 ))
- {
- if (m_pos.entry>0)
- emit signalPriorChangedAvailable(m_pos.entry>m_mergeCatalog->firstChangedIndex());
-
- emit signalNextChangedAvailable(m_pos.entry<m_mergeCatalog->lastChangedIndex());
-
- //a bit hacky :)
- connect (m_mergeCatalog,SIGNAL(signalEntryModified(DocPosition)),this,SLOT(slotUpdate(DocPosition)));
-
- if (m_pos.entry!=-1)
- slotNewEntryDisplayed(m_pos);
- show();
- }
- else
- {
- //KMessageBox::error(this, KIO::NetAccess::lastErrorString() );
- cleanup();
- if (errorLine>0)
- KMessageBox::error(this, i18nc("@info","Error opening the file <filename>%1</filename> for synchronization, error line: %2",url.pathOrUrl(),errorLine) );
- else
- {
- /* disable this as requested by bug 272587
- KNotification* notification=new KNotification("MergeFilesOpenError", this);
- notification->setText( i18nc("@info %1 is full filename","Error opening the file <filename>%1</filename> for synchronization",url.pathOrUrl()) );
- notification->sendEvent();
- */
- }
- //i18nc("@info %1 is w/o path","No branch counterpart for <filename>%1</filename>",url.fileName()),
- }
-
-}
-
-int MergeView::pluralFormsAvailableForward()
-{
- if(Q_LIKELY( m_pos.entry==-1 || !m_mergeCatalog->isPlural(m_pos.entry) ))
- return -1;
-
- int formLimit=qMin(m_baseCatalog->numberOfPluralForms(),m_mergeCatalog->numberOfPluralForms());//just sanity check
- DocPosition pos=m_pos;
- while (++(pos.form)<formLimit)
- {
- if (m_baseCatalog->msgstr(pos)!=m_mergeCatalog->msgstr(pos))
- return pos.form;
- }
- return -1;
-}
-
-int MergeView::pluralFormsAvailableBackward()
-{
- if(Q_LIKELY( m_pos.entry==-1 || !m_mergeCatalog->isPlural(m_pos.entry) ))
- return -1;
-
- DocPosition pos=m_pos;
- while (--(pos.form)>=0)
- {
- if (m_baseCatalog->msgstr(pos)!=m_mergeCatalog->msgstr(pos))
- return pos.form;
- }
- return -1;
-}
-
-void MergeView::gotoPrevChanged()
-{
- if (Q_UNLIKELY( !m_mergeCatalog ))
- return;
-
- DocPosition pos;
-
- //first, check if there any plural forms waiting to be synced
- int form=pluralFormsAvailableBackward();
- if (Q_UNLIKELY( form!=-1 ))
- {
- pos=m_pos;
- pos.form=form;
- }
- else if(Q_UNLIKELY( (pos.entry=m_mergeCatalog->prevChangedIndex(m_pos.entry)) == -1 ))
- return;
-
- if (Q_UNLIKELY( m_mergeCatalog->isPlural(pos.entry)&&form==-1 ))
- pos.form=qMin(m_baseCatalog->numberOfPluralForms(),m_mergeCatalog->numberOfPluralForms())-1;
-
- emit gotoEntry(pos,0);
-}
-
-void MergeView::gotoNextChangedApproved()
-{
- gotoNextChanged(true);
-}
-
-void MergeView::gotoNextChanged(bool approvedOnly)
-{
- if (Q_UNLIKELY( !m_mergeCatalog ))
- return;
-
- DocPosition pos=m_pos;
-
- //first, check if there any plural forms waiting to be synced
- int form=pluralFormsAvailableForward();
- if (Q_UNLIKELY( form!=-1 ))
- {
- pos=m_pos;
- pos.form=form;
- }
- else if(Q_UNLIKELY( (pos.entry=m_mergeCatalog->nextChangedIndex(m_pos.entry)) == -1 ))
- return;
-
- while (approvedOnly && !m_mergeCatalog->isApproved(pos.entry))
- {
- if(Q_UNLIKELY( (pos.entry=m_mergeCatalog->nextChangedIndex(pos.entry)) == -1 ))
- return;
- }
-
- emit gotoEntry(pos,0);
-}
-
-void MergeView::mergeBack()
-{
- if(m_pos.entry==-1 ||!m_mergeCatalog ||m_baseCatalog->msgstr(m_pos).isEmpty())
- return;
-
- m_mergeCatalog->copyFromBaseCatalog(m_pos);
-}
-
-void MergeView::mergeAccept()
-{
- if(m_pos.entry==-1
- ||!m_mergeCatalog
- //||m_baseCatalog->msgstr(m_pos)==m_mergeCatalog->msgstr(m_pos)
- ||m_mergeCatalog->msgstr(m_pos).isEmpty())
- return;
-
- m_mergeCatalog->copyToBaseCatalog(m_pos);
-
- emit gotoEntry(m_pos,0);
-}
-
-void MergeView::mergeAcceptAllForEmpty()
-{
- if(Q_UNLIKELY(!m_mergeCatalog)) return;
-
- bool update=m_mergeCatalog->differentEntries().contains(m_pos.entry);
-
- m_mergeCatalog->copyToBaseCatalog(/*MergeCatalog::EmptyOnly*/MergeCatalog::HigherOnly);
-
- if (update!=m_mergeCatalog->differentEntries().contains(m_pos.entry))
- emit gotoEntry(m_pos,0);
-}
-
-
-bool MergeView::event(QEvent *event)
-{
- if (event->type()==QEvent::ToolTip && m_mergeCatalog)
- {
- QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
- QString text="<b>" + url().prettyUrl() + "</b>\n" + i18nc("@info:tooltip","Different entries: %1\nUnmatched entries: %2",
- m_mergeCatalog->differentEntries().count(),m_mergeCatalog->unmatchedCount());
- text.replace('\n',"<br />");
- QToolTip::showText(helpEvent->globalPos(),text);
- return true;
- }
- return QWidget::event(event);
-}
-
-#include "moc_mergeview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef MERGEVIEW_H
-#define MERGEVIEW_H
-
-#include "pos.h"
-#include "mergecatalog.h"
-
-#include <kurl.h>
-
-#include <QDockWidget>
-class KTextEdit;
-class Catalog;
-class MergeCatalog;
-#include <QDragEnterEvent>
-#include <QDropEvent>
-
-
-
-class MergeView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- MergeView(QWidget*,Catalog*,bool primary);
- virtual ~MergeView();
-
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent*);
- KUrl url();
-
-private:
- /**
- * checks if there are any other plural forms waiting to be synced for current pos
- * @returns number of form or -1
- */
- int pluralFormsAvailableForward();
- int pluralFormsAvailableBackward();
-
- bool event(QEvent *event);
-
-public slots:
- void mergeOpen(KUrl url=KUrl());
- void cleanup();
- void slotNewEntryDisplayed(const DocPosition&);
- void slotUpdate(const DocPosition&);
-
- void gotoNextChanged(bool approvedOnly=false);
- void gotoNextChangedApproved();
- void gotoPrevChanged();
- void mergeAccept();
- void mergeAcceptAllForEmpty();
- void mergeBack();
-
-signals:
-// //we connect it to our internal mergeCatalog to remove entry from index
-// void entryModified(uint);
-
- void signalPriorChangedAvailable(bool);
- void signalNextChangedAvailable(bool);
- void signalEntryWithMergeDisplayed(bool);
-
- void gotoEntry(const DocPosition&,int);
-
- void mergeCatalogPointerChanged(MergeCatalog* mergeCatalog);
-
-private:
- KTextEdit* m_browser;
- Catalog* m_baseCatalog;
- MergeCatalog* m_mergeCatalog;
- DocPosition m_pos;
- QString m_normTitle;
- QString m_hasInfoTitle;
- bool m_hasInfo;
- bool m_primary;
-
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#define KDE_NO_DEBUG_OUTPUT
-
-#include "msgctxtview.h"
-
-#include "noteeditor.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "prefs_lokalize.h"
-
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <ktextedit.h>
-#include <kcombobox.h>
-#include <kpushbutton.h>
-
-#include <QDateTime>
-#include <QTimer>
-#include <QBoxLayout>
-#include <QStackedLayout>
-#include <QLabel>
-#include <QStringListModel>
-#include <QLineEdit>
-#include <QTextBrowser>
-
-MsgCtxtView::MsgCtxtView(QWidget* parent, Catalog* catalog)
- : QDockWidget (i18nc("@title toolview name","Unit metadata"), parent)
- , m_browser(new QTextBrowser(this))
- , m_editor(0)
- , m_catalog(catalog)
- , m_hasInfo(false)
- , m_hasErrorNotes(false)
-{
- setObjectName("msgCtxtView");
- QWidget* main=new QWidget(this);
- setWidget(main);
- m_stackedLayout = new QStackedLayout(main);
- m_stackedLayout->addWidget(m_browser);
-
- m_browser->viewport()->setBackgroundRole(QPalette::Background);
- m_browser->setOpenLinks(false);
- connect(m_browser,SIGNAL(anchorClicked(QUrl)),this,SLOT(anchorClicked(QUrl)));
-}
-
-MsgCtxtView::~MsgCtxtView()
-{
-}
-
-void MsgCtxtView::cleanup()
-{
- m_unfinishedNotes.clear();
- m_tempNotes.clear();
-}
-
-void MsgCtxtView::gotoEntry(const DocPosition& pos, int selection)
-{
- m_entry=DocPos(pos);
- m_selection=selection;
- m_offset=pos.offset;
- QTimer::singleShot(0,this,SLOT(process()));
-}
-
-void MsgCtxtView::process()
-{
- if (m_catalog->numberOfEntries()<=m_entry.entry)
- return;//because of Qt::QueuedConnection
-
- if (m_stackedLayout->currentIndex())
- m_unfinishedNotes[m_prevEntry]=qMakePair(m_editor->note(),m_editor->noteIndex());
-
-
- if (m_unfinishedNotes.contains(m_entry))
- {
- addNoteUI();
- m_editor->setNote(m_unfinishedNotes.value(m_entry).first,m_unfinishedNotes.value(m_entry).second);
- }
- else
- m_stackedLayout->setCurrentIndex(0);
-
-
- m_prevEntry=m_entry;
- m_browser->clear();
-
- if (m_tempNotes.contains(m_entry.entry))
- {
- QString html=i18nc("@info notes to translation unit which expire when the catalog is closed", "<b>Temporary notes:</b>");
- html+="<br>";
- foreach(const QString& note, m_tempNotes.values(m_entry.entry))
- html+=Qt::escape(note)+"<br>";
- html+="<br>";
- m_browser->insertHtml(html.replace('\n',"<br>"));
- }
-
- QString phaseName=m_catalog->phase(m_entry.toDocPosition());
- if (!phaseName.isEmpty())
- {
- Phase phase=m_catalog->phase(phaseName);
- QString html=i18nc("@info translation unit metadata","<b>Phase:</b><br>");
- if (phase.date.isValid())
- html+=QString("%1: ").arg(phase.date.toString(Qt::ISODate));
- html+=Qt::escape(phase.process);
- if (!phase.contact.isEmpty())
- html+=QString(" (%1)").arg(Qt::escape(phase.contact));
- m_browser->insertHtml(html+"<br>");
- }
-
- const QVector<Note> notes=m_catalog->notes(m_entry.toDocPosition());
- m_hasErrorNotes=false;
- foreach (const Note& note, notes)
- m_hasErrorNotes=m_hasErrorNotes||note.content.contains("[ERROR]");
-
- int realOffset=displayNotes(m_browser, m_catalog->notes(m_entry.toDocPosition()), m_entry.form, m_catalog->capabilities()&MultipleNotes);
-
- QString html;
- foreach(const Note& note, m_catalog->developerNotes(m_entry.toDocPosition()))
- html+="<br>"+Qt::escape(note.content);
-
- QStringList sourceFiles=m_catalog->sourceFiles(m_entry.toDocPosition());
- if (!sourceFiles.isEmpty())
- {
- html+=i18nc("@info PO comment parsing","<br><b>Files:</b><br>");
- foreach(const QString &sourceFile, sourceFiles)
- html+=QString("<a href=\"src:/%1\">%2</a><br />").arg(sourceFile).arg(sourceFile);
- html.chop(6);
- }
-
- QString msgctxt=m_catalog->context(m_entry.entry).first();
- if (!msgctxt.isEmpty())
- html+=i18nc("@info PO comment parsing","<br><b>Context:</b><br>")+Qt::escape(msgctxt);
-
- QTextCursor t=m_browser->textCursor();
- t.movePosition(QTextCursor::End);
- m_browser->setTextCursor(t);
- m_browser->insertHtml(html);
-
- t.movePosition(QTextCursor::Start);
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,realOffset+m_offset);
- t.movePosition(QTextCursor::NextCharacter,QTextCursor::KeepAnchor,m_selection);
- m_browser->setTextCursor(t);
-}
-
-
-void MsgCtxtView::addNoteUI()
-{
- anchorClicked(QUrl("note:/add"));
-}
-
-void MsgCtxtView::anchorClicked(const QUrl& link)
-{
- QString path=link.path().mid(1);// minus '/'
-
- if (link.scheme()=="note")
- {
- int capabilities=m_catalog->capabilities();
- if (!m_editor)
- {
- m_editor=new NoteEditor(this);
- m_stackedLayout->addWidget(m_editor);
- connect(m_editor,SIGNAL(accepted()),this,SLOT(noteEditAccepted()));
- connect(m_editor,SIGNAL(rejected()),this,SLOT(noteEditRejected()));
- }
- m_editor->setNoteAuthors(m_catalog->noteAuthors());
- QVector<Note> notes=m_catalog->notes(m_entry.toDocPosition());
- int noteIndex=-1;//means add new note
- Note note;
- if (!path.endsWith("add"))
- {
- noteIndex=path.toInt();
- note=notes.at(noteIndex);
- }
- else if (!(capabilities&MultipleNotes) && notes.size())
- {
- noteIndex=0; //so we don't overwrite the only possible note
- note=notes.first();
- }
- m_editor->setNote(note,noteIndex);
- m_editor->setFromFieldVisible(capabilities&KeepsNoteAuthors);
- m_stackedLayout->setCurrentIndex(1);
- }
- else if (link.scheme()=="src")
- {
- int pos=path.lastIndexOf(':');
- emit srcFileOpenRequested(path.left(pos),path.mid(pos+1).toInt());
- }
-}
-
-void MsgCtxtView::noteEditAccepted()
-{
- DocPosition pos=m_entry.toDocPosition();
- pos.form=m_editor->noteIndex();
- m_catalog->push(new SetNoteCmd(m_catalog,pos,m_editor->note()));
-
- m_prevEntry.entry=-1; process();
- //m_stackedLayout->setCurrentIndex(0);
- //m_unfinishedNotes.remove(m_entry);
- noteEditRejected();
-}
-void MsgCtxtView::noteEditRejected()
-{
- m_stackedLayout->setCurrentIndex(0);
- m_unfinishedNotes.remove(m_entry);
- emit escaped();
-}
-
-void MsgCtxtView::addNote(DocPosition p, const QString& text)
-{
- p.form=-1;
- m_catalog->push(new SetNoteCmd(m_catalog,p,Note(text)));
- if (m_entry.entry==p.entry) {m_prevEntry.entry=-1; process();}
-}
-
-void MsgCtxtView::addTemporaryEntryNote(int entry, const QString& text)
-{
- m_tempNotes.insertMulti(entry,text);
- m_prevEntry.entry=-1; process();
-}
-
-void MsgCtxtView::removeErrorNotes()
-{
- if (!m_hasErrorNotes) return;
-
- DocPosition p=m_entry.toDocPosition();
- const QVector<Note> notes=m_catalog->notes(p);
- p.form=notes.size();
- while(--(p.form)>=0)
- {
- if (notes.at(p.form).content.contains("[ERROR]"))
- m_catalog->push(new SetNoteCmd(m_catalog,p,Note()));
- }
-
- m_prevEntry.entry=-1; process();
-}
-
-
-#include "moc_msgctxtview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef MSGCTXTVIEW_H
-#define MSGCTXTVIEW_H
-
-#include "pos.h"
-#include "note.h"
-
-#include <QMap>
-#include <QDockWidget>
-
-#include <QTextBrowser>
-class Catalog;
-class NoteEditor;
-#include <QStackedLayout>
-
-class MsgCtxtView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- MsgCtxtView(QWidget*,Catalog*);
- ~MsgCtxtView();
-
- void gotoEntry(const DocPosition&, int selection=0);
- void addNote(DocPosition, const QString& text);
- void addTemporaryEntryNote(int entry, const QString& text);
-public slots:
- void removeErrorNotes();
- void cleanup();
-
- void addNoteUI();
-private slots:
- void anchorClicked(const QUrl& link);
- void noteEditAccepted();
- void noteEditRejected();
- void process();
-
-signals:
- void srcFileOpenRequested(const QString& srcPath, int line);
- void escaped();
-
-private:
- QTextBrowser* m_browser;
- NoteEditor* m_editor;
- QStackedLayout* m_stackedLayout;
-
- Catalog* m_catalog;
- QMap< DocPos,QPair<Note,int> > m_unfinishedNotes;//note and its index
- QMap< int,QString > m_tempNotes;
- char m_selection;
- char m_offset;
- bool m_hasInfo;
- bool m_hasErrorNotes;
- DocPos m_entry;
- DocPos m_prevEntry;
-};
-
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "noteeditor.h"
-
-#include "catalog.h"
-#include "cmd.h"
-#include "prefs_lokalize.h"
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <ktextedit.h>
-#include <kcombobox.h>
-#include <kpushbutton.h>
-
-#include <QBoxLayout>
-#include <QStackedLayout>
-#include <QLabel>
-#include <QStringListModel>
-#include <QLineEdit>
-#include <QEvent>
-#include <QTextBrowser>
-
-void TextEdit::keyPressEvent(QKeyEvent* keyEvent)
-{
- if (keyEvent->modifiers()& Qt::ControlModifier
- && keyEvent->key()==Qt::Key_Return)
- emit accepted();
- else if (keyEvent->key()==Qt::Key_Escape)
- emit rejected();
- else
- QPlainTextEdit::keyPressEvent(keyEvent);
-}
-
-NoteEditor::NoteEditor(QWidget* parent)
- : QWidget(parent)
- , m_from(new KComboBox(this))
- , m_fromLabel(new QLabel(i18nc("@info:label","From:"),this))
- , m_authors(new QStringListModel(this))
- , m_edit(new TextEdit(this))
-{
- setToolTip(i18nc("@info:tooltip","Save empty note to remove it"));
- m_from->setToolTip(i18nc("@info:tooltip","Author of this note"));
- m_from->setEditable(true);
- m_from->setModel(m_authors);
- m_from->setAutoCompletion(true);
- m_from->completionObject(true);
-
- QVBoxLayout* main=new QVBoxLayout(this);
- QHBoxLayout* prop=new QHBoxLayout;
- main->addLayout(prop);
- prop->addWidget(m_fromLabel);
- prop->addWidget(m_from,42);
- main->addWidget(m_edit);
-
- KPushButton* ok=new KPushButton(KStandardGuiItem::save(), this);
- KPushButton* cancel=new KPushButton(KStandardGuiItem::discard(), this);
- ok->setToolTip(i18n("Ctrl+Enter"));
- cancel->setToolTip(i18n("Esc"));
-
- connect(m_edit,SIGNAL(accepted()),this,SIGNAL(accepted()));
- connect(m_edit,SIGNAL(rejected()),this,SIGNAL(rejected()));
- connect(ok,SIGNAL(clicked()),this,SIGNAL(accepted()));
- connect(cancel,SIGNAL(clicked()),this,SIGNAL(rejected()));
-
- QHBoxLayout* btns=new QHBoxLayout;
- main->addLayout(btns);
- btns->addStretch(42);
- btns->addWidget(ok);
- btns->addWidget(cancel);
-}
-
-void NoteEditor::setFromFieldVisible(bool v)
-{
- m_fromLabel->setVisible(v);
- m_from->setVisible(v);
-}
-
-Note NoteEditor::note()
-{
- m_note.content=m_edit->toPlainText();
- m_note.from=m_from->currentText();
- return m_note;
-}
-
-void NoteEditor::setNote(const Note& note, int idx)
-{
- m_note=note;
- m_edit->setPlainText(note.content);
- QString from=note.from;
- if (from.isEmpty()) from=Settings::authorName();
- m_from->setCurrentItem(from,/*insert*/true);
- m_idx=idx;
- m_edit->setFocus();
-}
-
-void NoteEditor::setNoteAuthors(const QStringList& authors)
-{
- m_authors->setStringList(authors);
- m_from->completionObject()->insertItems(authors);
-}
-
-
-int displayNotes(QTextBrowser* browser, const QVector<Note>& notes, int active, bool multiple)
-{
- QTextCursor t=browser->textCursor();
- t.movePosition(QTextCursor::End);
- int realOffset=0;
-
- if (!notes.isEmpty())
- {
- t.insertHtml(i18nc("@info XLIFF notes representation","<b>Notes:</b>")+"<br />");
- int i=0;
- foreach(const Note& note, notes)
- {
- if (!note.from.isEmpty())
- t.insertHtml("<i>"+note.from+":</i> ");
-
- if (i==active)
- realOffset=t.position();
- QString content=Qt::escape(note.content);
- if (!multiple && content.contains('\n')) content+='\n';
- content.replace('\n',"<br />");
- content+=QString(" (<a href=\"note:/%1\">").arg(i)+i18nc("link to edit note","edit...")+"</a>)<br />";
- t.insertHtml(content);
- i++;
- }
- if (multiple)
- t.insertHtml("<a href=\"note:/add\">"+i18nc("link to add a note","Add...")+"</a> ");
- }
- else
- browser->insertHtml("<a href=\"note:/add\">"+i18nc("link to add a note","Add a note...")+"</a> ");
-
- return realOffset;
-}
-
-#include "moc_noteeditor.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef NOTEEDITOR_H
-#define NOTEEDITOR_H
-
-#include "note.h"
-
-#include <KTextEdit>
-#include <QPlainTextEdit>
-#include <QStringListModel>
-#include <QLabel>
-class KComboBox;
-#include <QTextBrowser>
-class TextEdit;
-
-int displayNotes(QTextBrowser* m_browser, const QVector<Note>& notes, int active=0, bool multiple=true);
-
-class NoteEditor: public QWidget
-{
-Q_OBJECT
-public:
- NoteEditor(QWidget* parent);
- ~NoteEditor(){}
-
- Note note();
- void setNote(const Note&, int idx);
- int noteIndex(){return m_idx;}
-
- void setNoteAuthors(const QStringList&);
- void setFromFieldVisible(bool);
-
-signals:
- void accepted();
- void rejected();
-
-private:
- KComboBox* m_from;
- QLabel* m_fromLabel;
- QStringListModel* m_authors;
- TextEdit* m_edit;
- int m_idx;
- Note m_note;
-};
-
-
-class TextEdit: public QPlainTextEdit
-{
-Q_OBJECT
-public:
- TextEdit(QWidget* parent): QPlainTextEdit(parent){}
- void keyPressEvent(QKeyEvent* e);
-signals:
- void accepted();
- void rejected();
-};
-
-#endif
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.Editor">
- <signal name="srcFileOpenRequested">
- <arg name="srcPath" type="s" direction="out"/>
- <arg name="line" type="i" direction="out"/>
- </signal>
- <signal name="fileClosed">
- <arg name="path" type="s" direction="out"/>
- </signal>
- <signal name="fileSaved">
- <arg name="path" type="s" direction="out"/>
- </signal>
- <signal name="fileAboutToBeClosed">
- </signal>
- <signal name="fileOpened">
- </signal>
- <signal name="entryDisplayed">
- </signal>
- <method name="gotoEntry">
- <arg name="entry" type="i" direction="in"/>
- </method>
- <method name="gotoEntryForm">
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- </method>
- <method name="gotoEntryFormOffset">
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- <arg name="offset" type="i" direction="in"/>
- </method>
- <method name="gotoEntryFormOffsetSelection">
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- <arg name="offset" type="i" direction="in"/>
- <arg name="selection" type="i" direction="in"/>
- </method>
- <method name="currentEntryId">
- <arg type="s" direction="out"/>
- </method>
- <method name="currentEntry">
- <arg type="i" direction="out"/>
- </method>
- <method name="currentForm">
- <arg type="i" direction="out"/>
- </method>
- <method name="selectionInTarget">
- <arg type="s" direction="out"/>
- </method>
- <method name="selectionInSource">
- <arg type="s" direction="out"/>
- </method>
- <method name="setEntryFilteredOut">
- <arg name="entry" type="i" direction="in"/>
- <arg name="filteredOut" type="b" direction="in"/>
- </method>
- <method name="setEntriesFilteredOut">
- <arg name="filteredOut" type="b" direction="in"/>
- </method>
- <method name="entryCount">
- <arg type="i" direction="out"/>
- </method>
- <method name="entrySource">
- <arg type="s" direction="out"/>
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- </method>
- <method name="entryTarget">
- <arg type="s" direction="out"/>
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- </method>
- <method name="setEntryTarget">
- <arg name="entry" type="i" direction="in"/>
- <arg name="form" type="i" direction="in"/>
- <arg name="content" type="s" direction="in"/>
- </method>
- <method name="entryPluralFormCount">
- <arg type="i" direction="out"/>
- <arg name="entry" type="i" direction="in"/>
- </method>
- <method name="entryReady">
- <arg type="b" direction="out"/>
- <arg name="entry" type="i" direction="in"/>
- </method>
- <method name="addEntryNote">
- <arg name="entry" type="i" direction="in"/>
- <arg name="note" type="s" direction="in"/>
- </method>
- <method name="addTemporaryEntryNote">
- <arg name="entry" type="i" direction="in"/>
- <arg name="note" type="s" direction="in"/>
- </method>
- <method name="addAlternateTranslation">
- <arg name="entry" type="i" direction="in"/>
- <arg name="translation" type="s" direction="in"/>
- </method>
- <method name="addTemporaryAlternateTranslation">
- <arg name="entry" type="i" direction="in"/>
- <arg name="translation" type="s" direction="in"/>
- </method>
- <method name="currentFile">
- <arg type="s" direction="out"/>
- </method>
- <method name="currentFileContents">
- <arg type="ay" direction="out"/>
- </method>
- <method name="sourceLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="targetLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="attachAlternateTranslationFile">
- <arg name="path" type="s" direction="in"/>
- </method>
- <method name="openSyncSource">
- <arg name="path" type="s" direction="in"/>
- </method>
- <method name="reloadFile">
- </method>
- <method name="saveFile">
- <arg type="b" direction="out"/>
- </method>
- <method name="saveFileAs">
- <arg type="b" direction="out"/>
- </method>
- <method name="close">
- </method>
- <method name="gotoNextUnfiltered">
- </method>
- <method name="gotoPrevUnfiltered">
- </method>
- <method name="gotoFirstUnfiltered">
- </method>
- <method name="gotoLastUnfiltered">
- </method>
- <method name="gotoNext">
- </method>
- <method name="gotoPrev">
- </method>
- <method name="gotoFirst">
- </method>
- <method name="gotoLast">
- </method>
- <method name="findEntryBySourceContext">
- <arg type="b" direction="out"/>
- <arg name="source" type="s" direction="in"/>
- <arg name="ctxt" type="s" direction="in"/>
- </method>
- <method name="isValid">
- <arg type="b" direction="out"/>
- </method>
- <method name="setSrcFileOpenRequestAccepted">
- <arg name="a" type="b" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.MainWindow">
- <signal name="editorAdded">
- </signal>
- <signal name="editorActivated">
- </signal>
- <method name="openFileInEditor">
- <arg type="i" direction="out"/>
- <arg name="path" type="s" direction="in"/>
- </method>
- <method name="openFileInEditorAt">
- <arg type="i" direction="out"/>
- <arg name="path" type="s" direction="in"/>
- <arg name="source" type="s" direction="in"/>
- <arg name="ctxt" type="s" direction="in"/>
- </method>
- <method name="showTranslationMemory">
- <arg type="i" direction="out"/>
- </method>
- <method name="showProjectOverview">
- </method>
- <method name="openProject">
- <arg name="path" type="s" direction="in"/>
- </method>
- <method name="currentProject">
- <arg type="s" direction="out"/>
- </method>
- <method name="editorIndexForFile">
- <arg type="i" direction="out"/>
- <arg name="path" type="s" direction="in"/>
- </method>
- <method name="pid">
- <arg type="i" direction="out"/>
- </method>
- <method name="dbusName">
- <arg type="s" direction="out"/>
- </method>
- <method name="busyCursor">
- <arg name="busy" type="b" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.Project">
- <signal name="loaded">
- </signal>
- <method name="translationsRoot">
- <arg type="s" direction="out"/>
- </method>
- <method name="templatesRoot">
- <arg type="s" direction="out"/>
- </method>
- <method name="targetLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="sourceLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="init">
- <arg name="path" type="s" direction="in"/>
- <arg name="kind" type="s" direction="in"/>
- <arg name="id" type="s" direction="in"/>
- <arg name="sourceLang" type="s" direction="in"/>
- <arg name="targetLang" type="s" direction="in"/>
- </method>
- <method name="kind">
- <arg type="s" direction="out"/>
- </method>
- <method name="absolutePath">
- <arg type="s" direction="out"/>
- <arg type="s" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.ProjectOverview">
- <method name="setCurrentItem">
- <arg name="url" type="s" direction="in"/>
- </method>
- <method name="currentItem">
- <arg type="s" direction="out"/>
- </method>
- <method name="selectedItems">
- <arg type="as" direction="out"/>
- </method>
- <method name="currentItemIsTranslationFile">
- <arg type="b" direction="out"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "phaseswindow.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "noteeditor.h"
-
-#include <klocale.h>
-#include <KPushButton>
-#include <KComboBox>
-
-#include <QTextBrowser>
-#include <QTreeView>
-#include <QStringListModel>
-#include <QVBoxLayout>
-#include <QFormLayout>
-#include <QApplication>
-
-
-//BEGIN PhasesModel
-#include <QtCore/qabstractitemmodel.h>
-#include <QSplitter>
-#include <QStackedLayout>
-
-class PhasesModel: public QAbstractListModel
-{
-public:
- enum PhasesModelColumns
- {
- Date=0,
- Process,
- Company,
- Contact,
- ToolName,
- ColumnCount
- };
-
- PhasesModel(Catalog* catalog, QObject* parent);
- ~PhasesModel(){}
- QModelIndex addPhase(const Phase& phase);
- QModelIndex activePhaseIndex()const{return index(m_activePhase);}
- QList<Phase> addedPhases()const;
-
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const{Q_UNUSED(parent); return ColumnCount;}
- QVariant data(const QModelIndex&,int role=Qt::DisplayRole) const;
- QVariant headerData(int section, Qt::Orientation, int role=Qt::DisplayRole) const;
-
-
-private:
- Catalog* m_catalog;
- QList<Phase> m_phases;
- QMap<QString,Tool> m_tools;
- int m_activePhase;
-};
-
-PhasesModel::PhasesModel(Catalog* catalog, QObject* parent)
- : QAbstractListModel(parent)
- , m_catalog(catalog)
- , m_phases(catalog->allPhases())
- , m_tools(catalog->allTools())
-{
- m_activePhase=m_phases.size();
- while (--m_activePhase>=0 && m_phases.at(m_activePhase).name!=catalog->activePhase())
- ;
-}
-
-QModelIndex PhasesModel::addPhase(const Phase& phase)
-{
- m_activePhase=m_phases.size();
- beginInsertRows(QModelIndex(),m_activePhase,m_activePhase);
- m_phases.append(phase);
- endInsertRows();
- return index(m_activePhase);
-}
-
-QList<Phase> PhasesModel::addedPhases()const
-{
- QList<Phase> result;
- for (int i=m_catalog->allPhases().size();i<m_phases.size();++i)
- result.append(m_phases.at(i));
-
- return result;
-}
-
-int PhasesModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return m_phases.size();
-}
-
-QVariant PhasesModel::data(const QModelIndex& index, int role) const
-{
- if (role==Qt::FontRole && index.row()==m_activePhase)
- {
- QFont font=QApplication::font();
- font.setBold(true);
- return font;
- }
- if (role==Qt::UserRole)
- return m_phases.at(index.row()).name;
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- const Phase& phase=m_phases.at(index.row());
- switch (index.column())
- {
- case Date: return phase.date.toString();
- case Process: return phase.process;
- case Company: return phase.company;
- case Contact: return QString(phase.contact
- +(phase.email.isEmpty()?"":QString(" <%1> ").arg(phase.email))
- +(phase.phone.isEmpty()?"":QString(", %1").arg(phase.phone)));
- case ToolName: return m_tools.value(phase.tool).name;
- }
- return QVariant();
-}
-
-QVariant PhasesModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- case Date: return i18nc("@title:column","Date");
- case Process: return i18nc("@title:column","Process");
- case Company: return i18nc("@title:column","Company");
- case Contact: return i18nc("@title:column","Person");
- case ToolName: return i18nc("@title:column","Tool");
- }
- return QVariant();
-}
-//END PhasesModel
-
-
-//BEGIN PhaseEditDialog
-class PhaseEditDialog: public KDialog
-{
-public:
- PhaseEditDialog(QWidget *parent);
- ~PhaseEditDialog(){}
-
- Phase phase()const;
-private:
- KComboBox* m_process;
-};
-
-
-PhaseEditDialog::PhaseEditDialog(QWidget *parent)
- : KDialog(parent)
- , m_process(new KComboBox(this))
-{
- QStringList processes;
- processes<<i18n("Translation")<<i18n("Review")<<i18n("Approval");
- m_process->setModel(new QStringListModel(processes,this));
-
- QFormLayout* l=new QFormLayout(mainWidget());
- l->addRow(i18n("Process"), m_process);
-}
-
-Phase PhaseEditDialog::phase() const
-{
- Phase phase;
- phase.process=processes()[m_process->currentIndex()];
- return phase;
-}
-
-PhasesWindow::PhasesWindow(Catalog* catalog, QWidget *parent)
- : KDialog(parent)
- , m_catalog(catalog)
- , m_model(new PhasesModel(catalog, this))
- , m_view(new MyTreeView(this))
- , m_browser(new QTextBrowser(this))
- , m_editor(0)
-{
- connect(this, SIGNAL(accepted()), SLOT(handleResult()));
- //setAttribute(Qt::WA_DeleteOnClose, true);
- QVBoxLayout* l=new QVBoxLayout(mainWidget());
- QHBoxLayout* btns=new QHBoxLayout;
- l->addLayout(btns);
-
- KPushButton* add=new KPushButton(KStandardGuiItem::add(),this);
- connect(add, SIGNAL(clicked()),this,SLOT(addPhase()));
- btns->addWidget(add);
- btns->addStretch(5);
-/*
- KPushButton* add=new KPushButton(i18nc("@action:button",""),this);
- btns->addWidget(activate);
-*/
- QSplitter* splitter=new QSplitter(this);
- l->addWidget(splitter);
-
- m_view->setRootIsDecorated(false);
- m_view->setModel(m_model);
- splitter->addWidget(m_view);
- int column=m_model->columnCount();
- while (--column>=0)
- m_view->resizeColumnToContents(column);
- if (m_model->rowCount())
- m_view->setCurrentIndex(m_model->activePhaseIndex());
- connect(m_view, SIGNAL(currentIndexChanged(QModelIndex)), SLOT(displayPhaseNotes(QModelIndex)));
-
-
- m_noteView=new QWidget(this);
- m_noteView->hide();
- splitter->addWidget(m_noteView);
- m_stackedLayout = new QStackedLayout(m_noteView);
- m_stackedLayout->addWidget(m_browser);
-
- m_browser->viewport()->setBackgroundRole(QPalette::Background);
- m_browser->setOpenLinks(false);
- connect(m_browser,SIGNAL(anchorClicked(QUrl)),this,SLOT(anchorClicked(QUrl)));
-
- splitter->setStretchFactor(0,15);
- splitter->setStretchFactor(1,5);
- setInitialSize(QSize(700,400));
-}
-
-void PhasesWindow::handleResult()
-{
- m_catalog->beginMacro(i18nc("@item Undo action item", "Edit phases"));
-
- Phase last;
- foreach(const Phase& phase, m_model->addedPhases())
- static_cast<QUndoStack*>(m_catalog)->push(new UpdatePhaseCmd(m_catalog, last=phase));
- m_catalog->setActivePhase(last.name,roleForProcess(last.process));
-
- QMapIterator<QString, QVector<Note> > i(m_phaseNotes);
- while (i.hasNext())
- {
- i.next();
- m_catalog->setPhaseNotes(i.key(),i.value());
- }
-
- m_catalog->endMacro();
-}
-
-void PhasesWindow::addPhase()
-{
- PhaseEditDialog d(this);
- if (!d.exec())
- return;
-
- Phase phase=d.phase();
- initPhaseForCatalog(m_catalog, phase, ForceAdd);
- m_view->setCurrentIndex(m_model->addPhase(phase));
- m_phaseNotes.insert(phase.name, QVector<Note>());
-}
-
-static QString phaseNameFromView(QTreeView* view)
-{
- return view->currentIndex().data(Qt::UserRole).toString();
-}
-
-void PhasesWindow::anchorClicked(QUrl link)
-{
- QString path=link.path().mid(1);// minus '/'
-
- if (link.scheme()=="note")
- {
- if (!m_editor)
- {
- m_editor=new NoteEditor(this);
- m_stackedLayout->addWidget(m_editor);
- connect(m_editor,SIGNAL(accepted()),this,SLOT(noteEditAccepted()));
- connect(m_editor,SIGNAL(rejected()),this,SLOT(noteEditRejected()));
- }
- m_editor->setNoteAuthors(m_catalog->noteAuthors());
- if (path.endsWith("add"))
- m_editor->setNote(Note(),-1);
- else
- {
- int pos=path.toInt();
- QString phaseName=phaseNameFromView(m_view);
- QVector<Note> notes=m_phaseNotes.contains(phaseName)?
- m_phaseNotes.value(phaseName)
- :m_catalog->phaseNotes(phaseName);
- m_editor->setNote(notes.at(pos),pos);
- }
- m_stackedLayout->setCurrentIndex(1);
- }
-}
-
-void PhasesWindow::noteEditAccepted()
-{
- QString phaseName=phaseNameFromView(m_view);
- if (!m_phaseNotes.contains(phaseName))
- m_phaseNotes.insert(phaseName, m_catalog->phaseNotes(phaseName));
-
- QVector<Note> notes=m_phaseNotes.value(phaseName);
- if (m_editor->noteIndex()==-1)
- m_phaseNotes[phaseName].append(m_editor->note());
- else
- m_phaseNotes[phaseName][m_editor->noteIndex()]=m_editor->note();
-
- m_stackedLayout->setCurrentIndex(0);
- displayPhaseNotes(m_view->currentIndex());
-}
-
-void PhasesWindow::noteEditRejected()
-{
- m_stackedLayout->setCurrentIndex(0);
-}
-
-void PhasesWindow::displayPhaseNotes(const QModelIndex& current)
-{
- m_browser->clear();
- QString phaseName=current.data(Qt::UserRole).toString();
- QVector<Note> notes=m_phaseNotes.contains(phaseName)?
- m_phaseNotes.value(phaseName)
- :m_catalog->phaseNotes(phaseName);
- kWarning()<<notes.size();
- displayNotes(m_browser, notes);
- m_noteView->show();
- m_stackedLayout->setCurrentIndex(0);
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PHASESWINDOW_H
-#define PHASESWINDOW_H
-
-
-#include "phase.h"
-#include "note.h"
-
-#include <KDialog>
-#include <QtCore/qabstractitemmodel.h>
-#include <QVector>
-#include <QMap>
-
-#include <QStackedLayout>
-class NoteEditor;
-class PhasesModel;
-class MyTreeView;
-#include <QTextBrowser>
-class PhasesWindow: public KDialog
-{
-Q_OBJECT
-public:
- PhasesWindow(Catalog* catalog, QWidget *parent);
- ~PhasesWindow(){}
-
-private slots:
- void displayPhaseNotes(const QModelIndex& current);
- void addPhase();
- void handleResult();
- void anchorClicked(QUrl);
- void noteEditAccepted();
- void noteEditRejected();
-
-private:
- Catalog* m_catalog;
- PhasesModel* m_model;
- MyTreeView* m_view;
- QTextBrowser* m_browser;
- NoteEditor* m_editor;
- QWidget* m_noteView;
- QStackedLayout* m_stackedLayout;
-
- QMap<QString, QVector<Note> > m_phaseNotes;
-};
-
-
-#include <QTreeView>
-
-class MyTreeView: public QTreeView
-{
-Q_OBJECT
-public:
- MyTreeView(QWidget* parent):QTreeView(parent){}
- ~MyTreeView(){}
-
-signals:
- void currentIndexChanged(const QModelIndex& current);
-private:
- void currentChanged(const QModelIndex& current, const QModelIndex&){emit currentIndexChanged(current);}
-};
-
-
-
-
-#endif
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "prefs.h"
-#include "prefs_lokalize.h"
-#include "project.h"
-#include "projectlocal.h"
-#include "projectmodel.h"
-#include "languagelistmodel.h"
-#include "dbfilesmodel.h"
-
-#include "ui_prefs_identity.h"
-#include "ui_prefs_editor.h"
-#include "ui_prefs_appearance.h"
-#include "ui_prefs_tm.h"
-#include "ui_prefs_projectmain.h"
-#include "ui_prefs_project_advanced.h"
-#include "ui_prefs_project_local.h"
-
-#include <kconfigdialog.h>
-#include <kglobal.h>
-#include <kstandarddirs.h>
-#include <klocale.h>
-#include <kicon.h>
-#include <kstatusbar.h>
-#include <kdebug.h>
-#include <kurl.h>
-#include <kfiledialog.h>
-#include <kmessagebox.h>
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QBoxLayout>
-#include <QtGui/qevent.h>
-
-#include <QTimer>
-
-//#include <sonnet/configwidget.h>
-
-SettingsController* SettingsController::_instance=0;
-void SettingsController::cleanupSettingsController()
-{
- delete SettingsController::_instance;
- SettingsController::_instance = 0;
-}
-
-SettingsController* SettingsController::instance()
-{
- if (_instance==0){
- _instance=new SettingsController;
- qAddPostRoutine(SettingsController::cleanupSettingsController);
- }
-
- return _instance;
-}
-
-SettingsController::SettingsController()
- : QObject(Project::instance())
- , dirty(false)
- , m_mainWindowPtr(0)
-{}
-
-SettingsController::~SettingsController()
-{}
-
-
-void SettingsController::showSettingsDialog()
-{
- if (KConfigDialog::showDialog("lokalize_settings"))
- return;
-
- KConfigDialog *dialog = new KConfigDialog(m_mainWindowPtr, "lokalize_settings", Settings::self());
- dialog->setFaceType(KPageDialog::List);
-
-// Identity
- QWidget *w = new QWidget(dialog);
- Ui_prefs_identity ui_prefs_identity;
- ui_prefs_identity.setupUi(w);
-
-
- KConfigGroup grp = Settings::self()->config()->group("Identity");
-
- ui_prefs_identity.DefaultLangCode->setModel(LanguageListModel::instance()->sortModel());
- ui_prefs_identity.DefaultLangCode->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode( grp.readEntry("DefaultLangCode",KGlobal::locale()->language()) ));
-
- connect(ui_prefs_identity.DefaultLangCode,SIGNAL(activated(int)),ui_prefs_identity.kcfg_DefaultLangCode,SLOT(setLangCode(int)));
- ui_prefs_identity.kcfg_DefaultLangCode->hide();
-
- dialog->addPage(w, i18nc("@title:tab","Identity"), "preferences-desktop-user");
-
-//Editor
- w = new QWidget(dialog);
- Ui_prefs_editor ui_prefs_editor;
- ui_prefs_editor.setupUi(w);
- dialog->addPage(w, i18nc("@title:tab","Editing"), "accessories-text-editor");
-
-//Font
- w = new QWidget(dialog);
- Ui_prefs_appearance ui_prefs_appearance;
- ui_prefs_appearance.setupUi(w);
- dialog->addPage(w, i18nc("@title:tab","Appearance"), "preferences-desktop-font");
-
-//TM
- w = new QWidget(dialog);
- Ui_prefs_tm ui_prefs_tm;
- ui_prefs_tm.setupUi(w);
- dialog->addPage(w, i18nc("@title:tab","Translation Memory"), "configure");
-
- connect(dialog,SIGNAL(settingsChanged(QString)),this,SIGNAL(generalSettingsChanged()));
-
-
-//Spellcheck
-#if 0
- w = new Sonnet::ConfigWidget(Settings::self()->config(),dialog);
- w->setParent(this);
- dialog->addPage(w, i18nc("@title:tab","Spellcheck"), "spellcheck_setting");
- connect(dialog,SIGNAL(okClicked()),w,SLOT(save()));
- connect(dialog,SIGNAL(applyClicked()),w,SLOT(save()));
- connect(dialog,SIGNAL(defaultClicked()),w,SLOT(slotDefault()));
-#endif
-
-
-
-
- //connect(dialog,SIGNAL(settingsChanged(const QString&)),m_view, SLOT(settingsChanged()));
-
- dialog->show();
-// dialog->addPage(new General(0, "General"), i18n("General") );
-// dialog->addPage(new Appearance(0, "Style"), i18n("Appearance") );
-// connect(dialog, SIGNAL(settingsChanged(const QString&)), mainWidget, SLOT(loadSettings()));
-// connect(dialog, SIGNAL(settingsChanged(const QString&)), this, SLOT(loadSettings()));
-
-}
-
-
-
-bool SettingsController::ensureProjectIsLoaded()
-{
- if (Project::instance()->isLoaded())
- return true;
-
- int answer=KMessageBox::questionYesNoCancel(m_mainWindowPtr, i18n("You have accessed a feature that requires a project to be loaded. Do you want to create a new project or open an existing project?"),
- QString(), KGuiItem(i18nc("@action","New"),KIcon("document-new")), KGuiItem(i18nc("@action","Open"),KIcon("project-open"))
- );
- if (answer==KMessageBox::Yes)
- return projectCreate();
- if (answer==KMessageBox::No)
- return !projectOpen().isEmpty();
- return false;
-}
-
-QString SettingsController::projectOpen(QString path, bool doOpen)
-{
- if (path.isEmpty())
- {
- Project::instance()->model()->weaver()->suspend();
- path=KFileDialog::getOpenFileName(KUrl()/*_catalog->url().directory()*/,
- i18n("*.lokalize *.ktp|Lokalize translation project")/*"text/x-lokalize-project"*/,
- m_mainWindowPtr);
- Project::instance()->model()->weaver()->resume();
- }
-
- if (!path.isEmpty() && doOpen)
- Project::instance()->load(path);
-
- return path;
-}
-
-bool SettingsController::projectCreate()
-{
- Project::instance()->model()->weaver()->suspend();
- QString desirablePath=Project::instance()->desirablePath();
- if (desirablePath.isEmpty())
- desirablePath=QDir::homePath()+"/index.lokalize";
- QString path=KFileDialog::getSaveFileName(KUrl(desirablePath), i18n("*.lokalize|Lokalize translation project") /*"text/x-lokalize-project"*/,m_mainWindowPtr);
- Project::instance()->model()->weaver()->resume();
- if (path.isEmpty())
- return false;
-
- //TODO ask-n-save
- Project::instance()->load(path);
- Project::instance()->setDefaults(); //NOTE will this be an obstacle?
-
- QTimer::singleShot(500, this, SLOT(projectConfigure()));
- return true;
-}
-
-void SettingsController::projectConfigure()
-{
- if (KConfigDialog::showDialog("project_settings"))
- {
- return;
- }
-
- KConfigDialog *dialog = new KConfigDialog(m_mainWindowPtr, "project_settings", Project::instance());
- dialog->setFaceType(KPageDialog::List);
-
-
-// Main
- QWidget *w = new QWidget(dialog);
- Ui_prefs_projectmain ui_prefs_projectmain;
- ui_prefs_projectmain.setupUi(w);
- dialog->addPage(w, i18nc("@title:tab","General"), "preferences-desktop-locale");
-
- ui_prefs_projectmain.kcfg_LangCode->hide();
- ui_prefs_projectmain.kcfg_PoBaseDir->hide();
- ui_prefs_projectmain.kcfg_GlossaryTbx->hide();
-
- Project& p=*(Project::instance());
- ui_prefs_projectmain.LangCode->setModel(LanguageListModel::instance()->sortModel());
- ui_prefs_projectmain.LangCode->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode(p.langCode()));
- connect(ui_prefs_projectmain.LangCode,SIGNAL(activated(int)),
- ui_prefs_projectmain.kcfg_LangCode,SLOT(setLangCode(int)));
-
- ui_prefs_projectmain.poBaseDir->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
- ui_prefs_projectmain.glossaryTbx->setMode(KFile::File|KFile::ExistingOnly|KFile::LocalOnly);
- ui_prefs_projectmain.glossaryTbx->setFilter("*.tbx\n*.xml");
- connect(ui_prefs_projectmain.poBaseDir,SIGNAL(textChanged(QString)),
- ui_prefs_projectmain.kcfg_PoBaseDir,SLOT(setText(QString)));
- connect(ui_prefs_projectmain.glossaryTbx,SIGNAL(textChanged(QString)),
- ui_prefs_projectmain.kcfg_GlossaryTbx,SLOT(setText(QString)));
- ui_prefs_projectmain.poBaseDir->setUrl(p.poDir());
- ui_prefs_projectmain.glossaryTbx->setUrl(p.glossaryPath());
-
-
-
-
-
- // RegExps
- w = new QWidget(dialog);
- Ui_project_advanced ui_project_advanced;
- ui_project_advanced.setupUi(w);
- ui_project_advanced.kcfg_PotBaseDir->hide();
- ui_project_advanced.kcfg_BranchDir->hide();
- ui_project_advanced.kcfg_AltDir->hide();
- ui_project_advanced.potBaseDir->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
- ui_project_advanced.branchDir->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
- ui_project_advanced.altDir->setMode(KFile::Directory|KFile::ExistingOnly|KFile::LocalOnly);
- connect(ui_project_advanced.potBaseDir,SIGNAL(textChanged(QString)), ui_project_advanced.kcfg_PotBaseDir,SLOT(setText(QString)));
- connect(ui_project_advanced.branchDir,SIGNAL(textChanged(QString)), ui_project_advanced.kcfg_BranchDir,SLOT(setText(QString)));
- connect(ui_project_advanced.altDir,SIGNAL(textChanged(QString)), ui_project_advanced.kcfg_AltDir,SLOT(setText(QString)));
- ui_project_advanced.potBaseDir->setUrl(p.potDir());
- ui_project_advanced.branchDir->setUrl(p.branchDir());
- ui_project_advanced.altDir->setUrl(p.altTransDir());
- dialog->addPage(w, i18nc("@title:tab","Advanced"), "applications-development-translation");
-
- w = new QWidget(dialog);
- Ui_prefs_project_local ui_prefs_project_local;
- ui_prefs_project_local.setupUi(w);
- dialog->addPage(w, Project::local(), i18nc("@title:tab","Personal"), "preferences-desktop-user");
-
-
- connect(dialog, SIGNAL(settingsChanged(QString)),Project::instance(), SLOT(populateGlossary()));
- connect(dialog, SIGNAL(settingsChanged(QString)),Project::instance(), SLOT(populateDirModel()));
- connect(dialog, SIGNAL(settingsChanged(QString)),TM::DBFilesModel::instance(), SLOT( updateProjectTmIndex()));
- connect(dialog, SIGNAL(settingsChanged(QString)),this, SLOT(reflectProjectConfigChange()));
-
- dialog->show();
-}
-
-void SettingsController::reflectProjectConfigChange()
-{
- //TODO check target language change: reflect changes in TM and glossary
- TM::DBFilesModel::instance()->openDB(Project::instance()->projectID());
-}
-
-void LangCodeSaver::setLangCode(int index)
-{
- setText(LanguageListModel::instance()->langCodeForSortModelRow(index));
-}
-
-void RelPathSaver::setText (const QString& txt)
-{
- QLineEdit::setText(KUrl::relativePath(Project::instance()->projectDir(),
- txt));
-}
-
-
-
-
-#include "moc_prefs.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PREFS_H
-#define PREFS_H
-
-#include <QLineEdit>
-class KLienEdit;
-
-/**
- * Singleton that manages cfgs for Lokalize and projects
- */
-class SettingsController: public QObject
-{
- Q_OBJECT
-
-public:
- SettingsController();
- ~SettingsController();
-
- bool dirty;
-
- void setMainWindowPtr(QWidget* w){m_mainWindowPtr=w;}
- QWidget* mainWindowPtr(){return m_mainWindowPtr;}
-
-public slots:
- void showSettingsDialog();
-
- bool ensureProjectIsLoaded();
- QString projectOpen(QString path=QString(), bool doOpen=true);
- bool projectCreate();
- void projectConfigure();
-
- void reflectProjectConfigChange();
-
-signals:
- void generalSettingsChanged();
-
-private:
- QWidget* m_mainWindowPtr;
-
-private:
- static SettingsController* _instance;
- static void cleanupSettingsController();
-public:
- static SettingsController* instance();
-};
-
-/**
- * helper widget to save relative paths in project file,
- * thus allowing its publishing in e.g. svn
- */
-class RelPathSaver: public QLineEdit
-{
-Q_OBJECT
-public:
- RelPathSaver(QWidget* p):QLineEdit(p){}
-public slots:
- void setText(const QString&);
-};
-
-
-/**
- * helper widget to save lang code text values
- * identified by LanguageListModel string index internally
- */
-class LangCodeSaver: public QLineEdit
-{
-Q_OBJECT
-public:
- LangCodeSaver(QWidget* p):QLineEdit(p){}
-public slots:
- void setLangCode(int);
-};
-
-#endif
+++ /dev/null
-<ui version="4.0" >
- <class>prefs_appearance</class>
- <widget class="QWidget" name="prefs_appearance" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>508</width>
- <height>515</height>
- </rect>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>9</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="0" >
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Editor font:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="KFontRequester" name="kcfg_MsgFont" >
- <property name="toolTip" >
- <string>Change the font for the editor</string>
- </property>
- <property name="whatsThis" >
- <string>Choose a new font for the area where you write the translated message.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" colspan="2" >
- <widget class="QCheckBox" name="kcfg_Leds" >
- <property name="toolTip" >
- <string>Display LEDS for message status</string>
- </property>
- <property name="whatsThis" >
- <string>If checked, LEDS will be shown to display the message status: Fuzzy, Untranslated or Error. If unchecked, no LEDs will be displayed.</string>
- </property>
- <property name="text" >
- <string>LEDs to indicate Fuzzy and Untranslated status as well as cursor column number</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="3" column="0" >
- <widget class="QGroupBox" name="groupBox" >
- <property name="whatsThis" >
- <string>Text colors for the changes in the message.</string>
- </property>
- <property name="title" >
- <string>String Matching</string>
- </property>
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string comment="@label:chooser" >Text added in the newer string:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="KColorButton" name="kcfg_AddColor" >
- <property name="toolTip" >
- <string>Change the color for the new text added</string>
- </property>
- <property name="whatsThis" >
- <string>You can set another color for viewing the text that was added to the string.</string>
- </property>
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_3" >
- <property name="text" >
- <string comment="@label:chooser" >Text removed in the newer string:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="KColorButton" name="kcfg_DelColor" >
- <property name="toolTip" >
- <string>Change the color for the text removed</string>
- </property>
- <property name="whatsThis" >
- <string>You can set another color for viewing the text that was removed from the string.</string>
- </property>
- <property name="text" >
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="4" column="0" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="0" >
- <widget class="QCheckBox" name="kcfg_HighlightSpaces" >
- <property name="toolTip" >
- <string>Check to see if a string ends in a space (which is often important when displaying it in the user interface, or when it gets concatenated with others).</string>
- </property>
- <property name="text" >
- <string>Highlight spaces at the end</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KColorButton</class>
- <extends>QPushButton</extends>
- <header>kcolorbutton.h</header>
- </customwidget>
- <customwidget>
- <class>KFontRequester</class>
- <extends>QWidget</extends>
- <header>kfontrequester.h</header>
- <container>1</container>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>prefs_editor</class>
- <widget class="QWidget" name="prefs_editor">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>612</width>
- <height>375</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <property name="margin">
- <number>11</number>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="3" column="0" colspan="2">
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="0">
- <widget class="QCheckBox" name="kcfg_AutoApprove">
- <property name="text">
- <string>Set 'approved' status automatically when editing started</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QCheckBox" name="kcfg_MouseWheelGo">
- <property name="toolTip">
- <string>If set, mouse wheel goes to previous or next unit, otherwise it scrolls text</string>
- </property>
- <property name="whatsThis">
- <string><html>When this option is enabled, the mouse wheel is used to go to the previous or next translation unit (without modifier keys). Modifier keys can be used to change this behavior. Use:<ul><li><b>Shift</b> to scroll within the text of the current unit,</li><li><b>Ctrl+Shift</b> to go to previous or next non-ready unit,</li><li><b>Ctrl</b> to go to previous or next non-ready not empty unit,</li><li><b>Alt</b> to go to previous or next untranslated unit.</li></ul>When the option is disabled, the mouse wheel scrolls within the text of the current translation unit.</html></string>
- </property>
- <property name="text">
- <string>Mouse wheel goes to previous or next translation unit</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="l1">
- <property name="toolTip">
- <string>Set to 2 to disable word completion</string>
- </property>
- <property name="text">
- <string>Minimum word length for word completion</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QSpinBox" name="kcfg_WordCompletionLength">
- <property name="toolTip">
- <string>Set to 2 to disable word completion</string>
- </property>
- <property name="specialValueText">
- <string>Disable word completion</string>
- </property>
- <property name="minimum">
- <number>2</number>
- </property>
- <property name="maximum">
- <number>20</number>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>prefs_identity</class>
- <widget class="QWidget" name="prefs_identity">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>612</width>
- <height>375</height>
- </rect>
- </property>
- <property name="whatsThis">
- <string>Fill in your identity and information about your translation team. This information is used when updating the header of a file.</string>
- </property>
- <layout class="QGridLayout">
- <property name="margin">
- <number>11</number>
- </property>
- <property name="spacing">
- <number>6</number>
- </property>
- <item row="2" column="0">
- <widget class="QLabel" name="textLabel1">
- <property name="text">
- <string comment="@label:chooser">Default language:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="textLabel2">
- <property name="text">
- <string comment="@label:textbox">Email:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="buddy">
- <cstring>kcfg_authorEmail</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="textLabel2_2">
- <property name="text">
- <string comment="@label:textbox">Name:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- <property name="buddy">
- <cstring>kcfg_authorName</cstring>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="KLineEdit" name="kcfg_authorName">
- <property name="toolTip">
- <string>Your name, in English</string>
- </property>
- <property name="whatsThis">
- <string>Please enter here your name and surname written in English</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string comment="@label:textbox">Default mailing list:</string>
- </property>
- <property name="buddy">
- <cstring>kcfg_DefaultMailingList</cstring>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="KLineEdit" name="kcfg_DefaultMailingList">
- <property name="toolTip">
- <string>The email of your team mailing list</string>
- </property>
- <property name="whatsThis">
- <string>Write the email of your translating team mailing list</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="KComboBox" name="DefaultLangCode">
- <property name="toolTip">
- <string>Language you translate to</string>
- </property>
- <property name="whatsThis">
- <string>Set the default language you are going to translate to</string>
- </property>
- </widget>
- </item>
- <item row="7" column="0" colspan="2">
- <spacer>
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="1" column="1">
- <widget class="KLineEdit" name="kcfg_authorEmail">
- <property name="toolTip">
- <string>Write your email</string>
- </property>
- <property name="whatsThis">
- <string>Write your email here so it will appear in the po file header with your name</string>
- </property>
- </widget>
- </item>
- <item row="5" column="1">
- <widget class="LangCodeSaver" name="kcfg_DefaultLangCode">
- <property name="enabled">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="KLineEdit" name="kcfg_authorLocalizedName">
- <property name="toolTip">
- <string>Your name in your own language</string>
- </property>
- <property name="whatsThis">
- <string>Write your name and surname in your language with your language alphabet.</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string comment="@label:textbox">Localized name:</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KLineEdit</class>
- <extends>QLineEdit</extends>
- <header>klineedit.h</header>
- </customwidget>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- <customwidget>
- <class>LangCodeSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>kcfg_authorName</tabstop>
- <tabstop>kcfg_authorEmail</tabstop>
- <tabstop>DefaultLangCode</tabstop>
- <tabstop>kcfg_DefaultMailingList</tabstop>
- <tabstop>kcfg_authorLocalizedName</tabstop>
- <tabstop>kcfg_DefaultLangCode</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-# Code generation options for kconfig_compiler
-File=lokalize.kcfg
-ClassName=Settings
-Singleton=true
-Mutators=Leds,AutoSpellcheck
-ItemAccessors=true
-SetUserTexts=true
-# will create the necessary code for setting those variables
+++ /dev/null
-<ui version="4.0" >
- <class>project_advanced</class>
- <widget class="QWidget" name="project_advanced" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>419</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QGroupBox" name="groupBox" >
- <property name="title" >
- <string>Syntax</string>
- </property>
- <layout class="QFormLayout" name="formLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="l0" >
- <property name="text" >
- <string comment="@label:textbox" >Accelerator:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="kcfg_Accel" >
- <property name="toolTip" >
- <string>Usually '&', but may also be '_' for GTK apps.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="l1" >
- <property name="text" >
- <string comment="@label:textbox" >Markup:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QLineEdit" name="kcfg_Markup" >
- <property name="toolTip" >
- <string>Regular expression of markup. It is used for translation memory matching and for 'Insert tag' feature.
-
-A default value (suitable for XML-based texts) is:
-(<[^>]+>)+|(&[A-Za-z_:][A-Za-z0-9_\.:-]*;)+
-
-It is only used for gettext PO files, as XLIFF format has its own way of specifying where markup is.</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2" >
- <property name="title" >
- <string>Paths</string>
- </property>
- <layout class="QFormLayout" name="formLayout_2" >
- <property name="fieldGrowthPolicy" >
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="l2" >
- <property name="text" >
- <string comment="@label:textbox" >Template files folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="KUrlRequester" name="potBaseDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string>Usually your translation project will be a subproject of a project
-for translating same texts into multiple languages.
-
-Set this to path of a folder containing empty translation files
-(i.e. files without translation into any language)
-shared among all subprojects.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="l3" >
- <property name="text" >
- <string comment="@label:textbox" >Branch folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="KUrlRequester" name="branchDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string comment="this message contains text from documentation, so use its translation when you're translating docs" >This setting is for Sync Mode.
-
-Sync Mode may be used to make changes to translation
-for two branches simultaneously.
-
-Set this to path that corresponds to root folder of the branch project,
-and Secondary Sync view will automatically open files from branch.
-Then, each time you make changes in files of your main branch,
-they will automatically be replicated to the branch
-(of course, if it contains the same English string).
-
-See documentation for more details.</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="l4" >
- <property name="text" >
- <string comment="@label:textbox" >Alternate translations folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="KUrlRequester" name="altDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string comment="this message contains text from documentation, so use its translation when you're translating docs" >Set this to path of a folder with structure similar to Root Folder.
-
-On each translation file open, a corresponding file in Alternate translations directory will be looked up and,
-if it is found, it will be used for Alternate Translations view.
-
-You will likely want to use translations of another target language (i.e. another subproject), which is close to yours.
-Also, you can use other subproject's translations either immediately, or have them pretranslated to your language by machine.
-
-See documentation for more details.</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_PotBaseDir" />
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_BranchDir" />
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_AltDir" />
- </item>
- <item>
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KUrlRequester</class>
- <extends>QFrame</extends>
- <header>kurlrequester.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>RelPathSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<ui version="4.0" >
- <class>prefs_project_local</class>
- <widget class="QWidget" name="prefs_project_local" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>439</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <layout class="QFormLayout" name="formLayout" >
- <property name="fieldGrowthPolicy" >
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="l0" >
- <property name="text" >
- <string>Role:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QComboBox" name="kcfg_Role" >
- <item>
- <property name="text" >
- <string>Translator</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Reviewer</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Approver</string>
- </property>
- </item>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>prefs_projectmain</class>
- <widget class="QWidget" name="prefs_projectmain">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>340</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="6" column="1">
- <widget class="RelPathSaver" name="kcfg_PoBaseDir"/>
- </item>
- <item row="7" column="1">
- <widget class="RelPathSaver" name="kcfg_GlossaryTbx"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="l0">
- <property name="text">
- <string comment="@label:textbox">Target language:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="KComboBox" name="LangCode">
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Target language of the project.</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="KUrlRequester" name="poBaseDir">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>16</height>
- </size>
- </property>
- <property name="toolTip">
- <string>This is main setting. Set this to path of a folder with translation files
-for your project (or a subproject for your target language).</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="KUrlRequester" name="glossaryTbx">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>16</height>
- </size>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="l1">
- <property name="text">
- <string comment="@label:textbox">Root folder:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="l2">
- <property name="text">
- <string comment="@label:textbox">Glossary:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="kcfg_ProjectID">
- <property name="toolTip">
- <string>Project ID is used to differentiate translation memories of absolutely different projects and languages.
-
-For example, if you have several projects for translating KDE applications
-(e.g. they are in different repositories), use same ID for all of them.</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="l3">
- <property name="text">
- <string comment="@label:textbox">ID:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="kcfg_MailingList"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="l4">
- <property name="text">
- <string comment="@label:textbox">Mailing list:</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="5" column="1">
- <widget class="LangCodeSaver" name="kcfg_LangCode"/>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KUrlRequester</class>
- <extends>QFrame</extends>
- <header>kurlrequester.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- <customwidget>
- <class>RelPathSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- <customwidget>
- <class>LangCodeSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>kcfg_ProjectID</tabstop>
- <tabstop>LangCode</tabstop>
- <tabstop>kcfg_MailingList</tabstop>
- <tabstop>poBaseDir</tabstop>
- <tabstop>glossaryTbx</tabstop>
- </tabstops>
- <resources/>
- <connections>
- <connection>
- <sender>LangCode</sender>
- <signal>currentIndexChanged(QString)</signal>
- <receiver>kcfg_LangCode</receiver>
- <slot>setText(QString)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>361</x>
- <y>48</y>
- </hint>
- <hint type="destinationlabel">
- <x>359</x>
- <y>190</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
+++ /dev/null
-<ui version="4.0" >
- <class>prefs_tm</class>
- <widget class="QWidget" name="prefs_tm" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>612</width>
- <height>375</height>
- </rect>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>11</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="7" column="0" colspan="2" >
- <spacer>
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="0" column="0" >
- <widget class="QCheckBox" name="kcfg_PrefetchTM" >
- <property name="toolTip" >
- <string>If checked, get translation memory suggestions </string>
- </property>
- <property name="whatsThis" >
- <string>If this is checked, the program will fetch translation memories as soon as you open a file.</string>
- </property>
- <property name="text" >
- <string>Prefetch translation memory suggestions on file open</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Maximum number of suggestions:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QSpinBox" name="kcfg_SuggCount" >
- <property name="toolTip" >
- <string>Set the maximum number of suggestions</string>
- </property>
- <property name="whatsThis" >
- <string>You can change the maximum number of suggestions, default is 7.</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QCheckBox" name="kcfg_AutoaddTM" >
- <property name="text" >
- <string>Update/Add edited entries to translation memory</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0" >
- <widget class="QCheckBox" name="kcfg_ScanToTMOnOpen" >
- <property name="text" >
- <string>Add opened files to translation memory automatically</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "project.h"
-#include "projectmodel.h"
-#include "projectlocal.h"
-
-#include "prefs.h"
-#include "jobs.h"
-#include "glossary.h"
-
-#include "tmmanager.h"
-#include "glossarywindow.h"
-#include "editortab.h"
-#include "dbfilesmodel.h"
-#include "qamodel.h"
-
-#include <QTimer>
-#include <QtCore/qdatetime.h>
-
-#include <kurl.h>
-#include <kdirlister.h>
-#include <kdebug.h>
-#include <klocale.h>
-#include <kstandarddirs.h>
-#include <kpassivepopup.h>
-#include <kmessagebox.h>
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QDBusArgument>
-
-Project* Project::_instance=0;
-void Project::cleanupProject()
-{
- delete Project::_instance; Project::_instance = 0;
-}
-
-Project* Project::instance()
-{
- if (_instance==0 )
- {
- _instance=new Project();
- qAddPostRoutine(Project::cleanupProject);
- }
- return _instance;
-}
-
-Project::Project()
- : ProjectBase()
- , m_localConfig(new ProjectLocal())
- , m_model(0)
- , m_glossary(new GlossaryNS::Glossary(this))
- , m_glossaryWindow(0)
- , m_tmManagerWindow(0)
-{
- ThreadWeaver::Weaver::instance()->setMaximumNumberOfThreads(1);
-
- setDefaults();
-/*
- qRegisterMetaType<DocPosition>("DocPosition");
- qDBusRegisterMetaType<DocPosition>();
-*/
- //QTimer::singleShot(66,this,SLOT(initLater()));
-}
-/*
-void Project::initLater()
-{
- if (isLoaded())
- return;
-
- KConfig cfg;
- KConfigGroup gr(&cfg,"State");
- QString file=gr.readEntry("Project");
- if (!file.isEmpty())
- load(file);
-
-}
-*/
-
-Project::~Project()
-{
- delete m_localConfig;
- //Project::save()
-}
-
-void Project::load(const QString &newProjectPath)
-{
- QTime a;a.start();
-
- ThreadWeaver::Weaver::instance()->dequeue();
- kDebug()<<"loading"<<newProjectPath<<"Finishing jobs...";
-
- if (!m_path.isEmpty())
- {
- TM::CloseDBJob* closeDBJob=new TM::CloseDBJob(projectID(),this);
- connect(closeDBJob,SIGNAL(done(ThreadWeaver::Job*)),closeDBJob,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(closeDBJob);
- }
- ThreadWeaver::Weaver::instance()->finish();//more safety
-
- kDebug()<<"5...";
-
- setSharedConfig(KSharedConfig::openConfig(newProjectPath, KConfig::NoGlobals));
- kDebug()<<"4...";
- readConfig();
- m_path=newProjectPath;
- m_desirablePath.clear();
-
- //cache:
- m_projectDir=KUrl(m_path).directory();
-
- kDebug()<<"3...";
- m_localConfig->setSharedConfig(KSharedConfig::openConfig(projectID()+".local", KConfig::NoGlobals,"appdata"));
- m_localConfig->readConfig();
-
- if (langCode().isEmpty())
- setLangCode(KGlobal::locale()->language());
- kDebug()<<"2...";
-
- //KConfig config;
- //delete m_localConfig; m_localConfig=new KConfigGroup(&config,"Project-"+path());
-
- populateDirModel();
-
- kDebug()<<"1...";
-
- //put 'em into thread?
- //QTimer::singleShot(0,this,SLOT(populateGlossary()));
- populateGlossary();//we cant postpone it because project load can be called from define new term function
-
- if (newProjectPath.isEmpty())
- return;
-
- //NOTE do we need to explicitly call it when project id changes?
- TM::DBFilesModel::instance()->openDB(projectID());
-
- if (QaModel::isInstantiated())
- {
- QaModel::instance()->saveRules();
- QaModel::instance()->loadRules(qaPath());
- }
-
- kDebug()<<"until emitting signal"<<a.elapsed();
-
- emit loaded();
- kDebug()<<"loaded!"<<a.elapsed();
-}
-
-QString Project::absolutePath(const QString& possiblyRelPath) const
-{
- if (KUrl::isRelativeUrl(possiblyRelPath))
- {
- KUrl url(m_path);
- url.setFileName(QString());
- url.cd(possiblyRelPath);
- return url.toLocalFile(KUrl::RemoveTrailingSlash);
- }
- return possiblyRelPath;
-}
-
-void Project::populateDirModel()
-{
- if (Q_UNLIKELY( m_path.isEmpty() || !QFile::exists(poDir()) ))
- return;
-
- KUrl potUrl;
- if (QFile::exists(potDir()))
- potUrl=KUrl::fromLocalFile(potDir());
- model()->setUrl(KUrl(poDir()), potUrl);
-}
-
-void Project::populateGlossary()
-{
- m_glossary->load(glossaryPath());
-}
-
-GlossaryNS::GlossaryWindow* Project::showGlossary()
-{
- return defineNewTerm();
-}
-
-GlossaryNS::GlossaryWindow* Project::defineNewTerm(QString en, QString target)
-{
- if (!SettingsController::instance()->ensureProjectIsLoaded())
- return 0;
-
- if (!m_glossaryWindow)
- m_glossaryWindow=new GlossaryNS::GlossaryWindow(SettingsController::instance()->mainWindowPtr());
- m_glossaryWindow->show();
- m_glossaryWindow->activateWindow();
- if (!en.isEmpty()||!target.isEmpty())
- m_glossaryWindow->newTermEntry(en,target);
-
- return m_glossaryWindow;
-}
-
-bool Project::queryCloseForAuxiliaryWindows()
-{
- if (m_glossaryWindow && m_glossaryWindow->isVisible())
- return m_glossaryWindow->queryClose();
-
- return true;
-}
-
-bool Project::isTmSupported() const
-{
- QStringList drivers=QSqlDatabase::drivers();
- return drivers.contains("QSQLITE");
-}
-
-void Project::showTMManager()
-{
- if (!m_tmManagerWindow)
- {
- if (!isTmSupported())
- {
- KMessageBox::information(0, i18n("TM facility requires SQLite Qt module."), i18n("No SQLite module available"));
- return;
- }
-
- m_tmManagerWindow=new TM::TMManagerWin(SettingsController::instance()->mainWindowPtr());
- }
- m_tmManagerWindow->show();
- m_tmManagerWindow->activateWindow();
-}
-
-void Project::save()
-{
- m_localConfig->setFirstRun(false);
-
- ProjectBase::setTargetLangCode(langCode());
- writeConfig();
- m_localConfig->writeConfig();
-}
-
-ProjectModel* Project::model()
-{
- if (Q_UNLIKELY(!m_model))
- m_model=new ProjectModel(this);
-
- return m_model;
-}
-
-void Project::setDefaults()
-{
- ProjectBase::setDefaults();
- setLangCode(KGlobal::locale()->language());
-}
-
-void Project::init(const QString& path, const QString& kind, const QString& id,
- const QString& sourceLang, const QString& targetLang)
-{
- setDefaults();
- bool stop=false;
- while(true)
- {
- setKind(kind);setSourceLangCode(sourceLang);setLangCode(targetLang);setProjectID(id);
- if (stop) break;
- else {load(path);stop=true;}
- }
- save();
-}
-
-
-#include "moc_project.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef PROJECT_H
-#define PROJECT_H
-
-#include <QVector>
-#include <QList>
-#include "projectbase.h"
-
-class ProjectModel;
-class ProjectLocal;
-namespace GlossaryNS{class Glossary;}
-namespace GlossaryNS{class GlossaryWindow;}
-namespace TM{class TMManagerWin;}
-
-/**
- * Singleton object that represents project.
- * It is shared between EditorWindow 'mainwindows' that use the same project file.
- * Keeps project's KDirModel and Glossary
- *
- * GUI for config handling is implemented in prefs.cpp
- *
- * @short Singleton object that represents project
- */
-
-class Project: public ProjectBase
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.Project")
- //qdbuscpp2xml -m -s project.h -o org.kde.lokalize.Project.xml
-public:
- explicit Project();
- virtual ~Project();
-
- void load(const QString &file);
- void save();
- bool isLoaded()const{return !m_path.isEmpty();}
- ProjectModel* model();
-
- //void setPath(const QString& p){m_path=p;}
- QString path()const{return m_path;}
- QString projectDir()const{return m_projectDir;}
- QString poDir()const{return absolutePath(poBaseDir());}
- QString potDir()const{return absolutePath(potBaseDir());}
- QString branchDir()const{return absolutePath(ProjectBase::branchDir());}
- QString glossaryPath()const{return absolutePath(glossaryTbx());}
- QString qaPath()const{return absolutePath(mainQA());}
- GlossaryNS::Glossary* glossary()const{return m_glossary;}
- QString altTransDir()const{return absolutePath(altDir());}
-
- bool queryCloseForAuxiliaryWindows();
-
- void setDefaults();
-// private slots:
-// void initLater();
-
-public slots:
- Q_SCRIPTABLE QString translationsRoot()const{return poDir();}
- Q_SCRIPTABLE QString templatesRoot()const{return potDir();}
-
-
- Q_SCRIPTABLE QString targetLangCode()const{return ProjectBase::langCode();}
- Q_SCRIPTABLE QString sourceLangCode()const{return ProjectBase::sourceLangCode();}
- Q_SCRIPTABLE void init(const QString& path, const QString& kind, const QString& id,
- const QString& sourceLang, const QString& targetLang);
- Q_SCRIPTABLE QString kind()const{return ProjectBase::kind();}
-
- Q_SCRIPTABLE QString absolutePath(const QString&) const;
-
- Q_SCRIPTABLE void setDesirablePath(const QString& path){m_desirablePath=path;}
- Q_SCRIPTABLE QString desirablePath() const{return m_desirablePath;}
-
- Q_SCRIPTABLE bool isTmSupported() const;
-
-signals:
- Q_SCRIPTABLE void loaded();
-
-public slots:
- void populateDirModel();
- void populateGlossary();
-
- void showTMManager();
- GlossaryNS::GlossaryWindow* showGlossary();
- GlossaryNS::GlossaryWindow* defineNewTerm(QString en=QString(),QString target=QString());
-
-private:
- static Project* _instance;
- static void cleanupProject();
-public:
- static Project* instance();
- static ProjectLocal* local(){return instance()->m_localConfig;}
-
-private:
- QString m_path;
- QString m_desirablePath;
- ProjectLocal* m_localConfig;
- ProjectModel* m_model;
- GlossaryNS::Glossary* m_glossary;
- GlossaryNS::GlossaryWindow* m_glossaryWindow;
- TM::TMManagerWin* m_tmManagerWindow;
-
- //cache
- QString m_projectDir;
- };
-
-
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2008 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef LISTS_H
-#define LISTS_H
-
-#include <QString>
-#include <klocale.h>
-#include <kglobal.h>
-
-static inline QString getMailingList()
-{
- QString lang(KGlobal::locale()->language());
- if(lang.startsWith("ca"))
- return "kde-i18n-ca@kde.org";
- if(lang.startsWith("de"))
- return "kde-i18n-de@kde.org";
- if(lang.startsWith("hu"))
- return "kde-l10n-hu@kde.org";
- if(lang.startsWith("tr"))
- return "kde-l10n-tr@kde.org";
- if(lang.startsWith("it"))
- return "kde-i18n-it@kde.org";
- if(lang.startsWith("lt"))
- return "kde-i18n-lt@kde.org";
- if(lang.startsWith("nb"))
- return "i18n-nb@lister.ping.uio.no";
- if(lang.startsWith("nn"))
- return "i18n-nn@lister.ping.uio.no";
- if(lang.startsWith("pt_BR"))
- return "kde-i18n-pt_BR@kde.org";
- if(lang.startsWith("ru"))
- return "kde-russian@lists.kde.ru";
- if(lang.startsWith("se"))
- return "i18n-sme@lister.ping.uio.no";
- if(lang.startsWith("sl"))
- return "lugos-slo@lugos.si";
-
- return "kde-i18n-doc@kde.org";
-}
-
-#endif
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.Project">
- <signal name="loaded">
- </signal>
- <method name="translationsRoot">
- <arg type="s" direction="out"/>
- </method>
- <method name="templatesRoot">
- <arg type="s" direction="out"/>
- </method>
- <method name="targetLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="sourceLangCode">
- <arg type="s" direction="out"/>
- </method>
- <method name="init">
- <arg name="path" type="s" direction="in"/>
- <arg name="kind" type="s" direction="in"/>
- <arg name="id" type="s" direction="in"/>
- <arg name="sourceLang" type="s" direction="in"/>
- <arg name="targetLang" type="s" direction="in"/>
- </method>
- <method name="kind">
- <arg type="s" direction="out"/>
- </method>
- <method name="absolutePath">
- <arg type="s" direction="out"/>
- <arg type="s" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.ProjectOverview">
- <method name="setCurrentItem">
- <arg name="url" type="s" direction="in"/>
- </method>
- <method name="currentItem">
- <arg type="s" direction="out"/>
- </method>
- <method name="selectedItems">
- <arg type="as" direction="out"/>
- </method>
- <method name="currentItemIsTranslationFile">
- <arg type="b" direction="out"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-<ui version="4.0" >
- <class>project_advanced</class>
- <widget class="QWidget" name="project_advanced" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>419</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <widget class="QGroupBox" name="groupBox" >
- <property name="title" >
- <string>Syntax</string>
- </property>
- <layout class="QFormLayout" name="formLayout" >
- <item row="0" column="0" >
- <widget class="QLabel" name="l0" >
- <property name="text" >
- <string comment="@label:textbox" >Accelerator:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="kcfg_Accel" >
- <property name="toolTip" >
- <string>Usually '&', but may also be '_' for GTK apps.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="l1" >
- <property name="text" >
- <string comment="@label:textbox" >Markup:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QLineEdit" name="kcfg_Markup" >
- <property name="toolTip" >
- <string>Regular expression of markup. It is used for translation memory matching and for 'Insert tag' feature.
-
-A default value (suitable for XML-based texts) is:
-(<[^>]+>)+|(&[A-Za-z_:][A-Za-z0-9_\.:-]*;)+
-
-It is only used for gettext PO files, as XLIFF format has its own way of specifying where markup is.</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox_2" >
- <property name="title" >
- <string>Paths</string>
- </property>
- <layout class="QFormLayout" name="formLayout_2" >
- <property name="fieldGrowthPolicy" >
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="l2" >
- <property name="text" >
- <string comment="@label:textbox" >Template files folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="KUrlRequester" name="potBaseDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string>Usually your translation project will be a subproject of a project
-for translating same texts into multiple languages.
-
-Set this to path of a folder containing empty translation files
-(i.e. files without translation into any language)
-shared among all subprojects.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="l3" >
- <property name="text" >
- <string comment="@label:textbox" >Branch folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="KUrlRequester" name="branchDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string comment="this message contains text from documentation, so use its translation when you're translating docs" >This setting is for Sync Mode.
-
-Sync Mode may be used to make changes to translation
-for two branches simultaneously.
-
-Set this to path that corresponds to root folder of the branch project,
-and Secondary Sync view will automatically open files from branch.
-Then, each time you make changes in files of your main branch,
-they will automatically be replicated to the branch
-(of course, if it contains the same English string).
-
-See documentation for more details.</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="l4" >
- <property name="text" >
- <string comment="@label:textbox" >Alternate translations folder:</string>
- </property>
- <property name="wordWrap" >
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <widget class="KUrlRequester" name="altDir" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip" >
- <string comment="this message contains text from documentation, so use its translation when you're translating docs" >Set this to path of a folder with structure similar to Root Folder.
-
-On each translation file open, a corresponding file in Alternate translations directory will be looked up and,
-if it is found, it will be used for Alternate Translations view.
-
-You will likely want to use translations of another target language (i.e. another subproject), which is close to yours.
-Also, you can use other subproject's translations either immediately, or have them pretranslated to your language by machine.
-
-See documentation for more details.</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_PotBaseDir" />
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_BranchDir" />
- </item>
- <item>
- <widget class="RelPathSaver" name="kcfg_AltDir" />
- </item>
- <item>
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KUrlRequester</class>
- <extends>QFrame</extends>
- <header>kurlrequester.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>RelPathSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<ui version="4.0" >
- <class>prefs_project_local</class>
- <widget class="QWidget" name="prefs_project_local" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>439</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" >
- <item>
- <layout class="QFormLayout" name="formLayout" >
- <property name="fieldGrowthPolicy" >
- <enum>QFormLayout::ExpandingFieldsGrow</enum>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="l0" >
- <property name="text" >
- <string>Role:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QComboBox" name="kcfg_Role" >
- <item>
- <property name="text" >
- <string>Translator</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Reviewer</string>
- </property>
- </item>
- <item>
- <property name="text" >
- <string>Approver</string>
- </property>
- </item>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>prefs_projectmain</class>
- <widget class="QWidget" name="prefs_projectmain">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>611</width>
- <height>340</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="6" column="1">
- <widget class="RelPathSaver" name="kcfg_PoBaseDir"/>
- </item>
- <item row="7" column="1">
- <widget class="RelPathSaver" name="kcfg_GlossaryTbx"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="l0">
- <property name="text">
- <string comment="@label:textbox">Target language:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="KComboBox" name="LangCode">
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>0</height>
- </size>
- </property>
- <property name="toolTip">
- <string>Target language of the project.</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="KUrlRequester" name="poBaseDir">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>16</height>
- </size>
- </property>
- <property name="toolTip">
- <string>This is main setting. Set this to path of a folder with translation files
-for your project (or a subproject for your target language).</string>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="KUrlRequester" name="glossaryTbx">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>400</width>
- <height>16</height>
- </size>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="l1">
- <property name="text">
- <string comment="@label:textbox">Root folder:</string>
- </property>
- <property name="wordWrap">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="l2">
- <property name="text">
- <string comment="@label:textbox">Glossary:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="kcfg_ProjectID">
- <property name="toolTip">
- <string>Project ID is used to differentiate translation memories of absolutely different projects and languages.
-
-For example, if you have several projects for translating KDE applications
-(e.g. they are in different repositories), use same ID for all of them.</string>
- </property>
- </widget>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="l3">
- <property name="text">
- <string comment="@label:textbox">ID:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="kcfg_MailingList"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="l4">
- <property name="text">
- <string comment="@label:textbox">Mailing list:</string>
- </property>
- </widget>
- </item>
- <item row="8" column="0">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- <item row="5" column="1">
- <widget class="LangCodeSaver" name="kcfg_LangCode"/>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KUrlRequester</class>
- <extends>QFrame</extends>
- <header>kurlrequester.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- <customwidget>
- <class>RelPathSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- <customwidget>
- <class>LangCodeSaver</class>
- <extends>QLineEdit</extends>
- <header>prefs.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>kcfg_ProjectID</tabstop>
- <tabstop>LangCode</tabstop>
- <tabstop>kcfg_MailingList</tabstop>
- <tabstop>poBaseDir</tabstop>
- <tabstop>glossaryTbx</tabstop>
- </tabstops>
- <resources/>
- <connections>
- <connection>
- <sender>LangCode</sender>
- <signal>currentIndexChanged(QString)</signal>
- <receiver>kcfg_LangCode</receiver>
- <slot>setText(QString)</slot>
- <hints>
- <hint type="sourcelabel">
- <x>361</x>
- <y>48</y>
- </hint>
- <hint type="destinationlabel">
- <x>359</x>
- <y>190</y>
- </hint>
- </hints>
- </connection>
- </connections>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "project.h"
-#include "projectmodel.h"
-#include "projectlocal.h"
-
-#include "prefs.h"
-#include "jobs.h"
-#include "glossary.h"
-
-#include "tmmanager.h"
-#include "glossarywindow.h"
-#include "editortab.h"
-#include "dbfilesmodel.h"
-#include "qamodel.h"
-
-#include <QTimer>
-#include <QtCore/qdatetime.h>
-
-#include <kurl.h>
-#include <kdirlister.h>
-#include <kdebug.h>
-#include <klocale.h>
-#include <kstandarddirs.h>
-#include <kpassivepopup.h>
-#include <kmessagebox.h>
-#include <threadweaver/ThreadWeaver.h>
-
-#include <QDBusArgument>
-
-Project* Project::_instance=0;
-void Project::cleanupProject()
-{
- delete Project::_instance; Project::_instance = 0;
-}
-
-Project* Project::instance()
-{
- if (_instance==0 )
- {
- _instance=new Project();
- qAddPostRoutine(Project::cleanupProject);
- }
- return _instance;
-}
-
-Project::Project()
- : ProjectBase()
- , m_localConfig(new ProjectLocal())
- , m_model(0)
- , m_glossary(new GlossaryNS::Glossary(this))
- , m_glossaryWindow(0)
- , m_tmManagerWindow(0)
-{
- ThreadWeaver::Weaver::instance()->setMaximumNumberOfThreads(1);
-
- setDefaults();
-/*
- qRegisterMetaType<DocPosition>("DocPosition");
- qDBusRegisterMetaType<DocPosition>();
-*/
- //QTimer::singleShot(66,this,SLOT(initLater()));
-}
-/*
-void Project::initLater()
-{
- if (isLoaded())
- return;
-
- KConfig cfg;
- KConfigGroup gr(&cfg,"State");
- QString file=gr.readEntry("Project");
- if (!file.isEmpty())
- load(file);
-
-}
-*/
-
-Project::~Project()
-{
- delete m_localConfig;
- //Project::save()
-}
-
-void Project::load(const QString &newProjectPath)
-{
- QTime a;a.start();
-
- ThreadWeaver::Weaver::instance()->dequeue();
- kDebug()<<"loading"<<newProjectPath<<"Finishing jobs...";
-
- if (!m_path.isEmpty())
- {
- TM::CloseDBJob* closeDBJob=new TM::CloseDBJob(projectID(),this);
- connect(closeDBJob,SIGNAL(done(ThreadWeaver::Job*)),closeDBJob,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(closeDBJob);
- }
- ThreadWeaver::Weaver::instance()->finish();//more safety
-
- kDebug()<<"5...";
-
- setSharedConfig(KSharedConfig::openConfig(newProjectPath, KConfig::NoGlobals));
- kDebug()<<"4...";
- readConfig();
- m_path=newProjectPath;
- m_desirablePath.clear();
-
- //cache:
- m_projectDir=KUrl(m_path).directory();
-
- kDebug()<<"3...";
- m_localConfig->setSharedConfig(KSharedConfig::openConfig(projectID()+".local", KConfig::NoGlobals,"appdata"));
- m_localConfig->readConfig();
-
- if (langCode().isEmpty())
- setLangCode(KGlobal::locale()->language());
- kDebug()<<"2...";
-
- //KConfig config;
- //delete m_localConfig; m_localConfig=new KConfigGroup(&config,"Project-"+path());
-
- populateDirModel();
-
- kDebug()<<"1...";
-
- //put 'em into thread?
- //QTimer::singleShot(0,this,SLOT(populateGlossary()));
- populateGlossary();//we cant postpone it because project load can be called from define new term function
-
- if (newProjectPath.isEmpty())
- return;
-
- //NOTE do we need to explicitly call it when project id changes?
- TM::DBFilesModel::instance()->openDB(projectID());
-
- if (QaModel::isInstantiated())
- {
- QaModel::instance()->saveRules();
- QaModel::instance()->loadRules(qaPath());
- }
-
- kDebug()<<"until emitting signal"<<a.elapsed();
-
- emit loaded();
- kDebug()<<"loaded!"<<a.elapsed();
-}
-
-QString Project::absolutePath(const QString& possiblyRelPath) const
-{
- if (KUrl::isRelativeUrl(possiblyRelPath))
- {
- KUrl url(m_path);
- url.setFileName(QString());
- url.cd(possiblyRelPath);
- return url.toLocalFile(KUrl::RemoveTrailingSlash);
- }
- return possiblyRelPath;
-}
-
-void Project::populateDirModel()
-{
- if (Q_UNLIKELY( m_path.isEmpty() || !QFile::exists(poDir()) ))
- return;
-
- KUrl potUrl;
- if (QFile::exists(potDir()))
- potUrl=KUrl::fromLocalFile(potDir());
- model()->setUrl(KUrl(poDir()), potUrl);
-}
-
-void Project::populateGlossary()
-{
- m_glossary->load(glossaryPath());
-}
-
-GlossaryNS::GlossaryWindow* Project::showGlossary()
-{
- return defineNewTerm();
-}
-
-GlossaryNS::GlossaryWindow* Project::defineNewTerm(QString en, QString target)
-{
- if (!SettingsController::instance()->ensureProjectIsLoaded())
- return 0;
-
- if (!m_glossaryWindow)
- m_glossaryWindow=new GlossaryNS::GlossaryWindow(SettingsController::instance()->mainWindowPtr());
- m_glossaryWindow->show();
- m_glossaryWindow->activateWindow();
- if (!en.isEmpty()||!target.isEmpty())
- m_glossaryWindow->newTermEntry(en,target);
-
- return m_glossaryWindow;
-}
-
-bool Project::queryCloseForAuxiliaryWindows()
-{
- if (m_glossaryWindow && m_glossaryWindow->isVisible())
- return m_glossaryWindow->queryClose();
-
- return true;
-}
-
-bool Project::isTmSupported() const
-{
- QStringList drivers=QSqlDatabase::drivers();
- return drivers.contains("QSQLITE");
-}
-
-void Project::showTMManager()
-{
- if (!m_tmManagerWindow)
- {
- if (!isTmSupported())
- {
- KMessageBox::information(0, i18n("TM facility requires SQLite Qt module."), i18n("No SQLite module available"));
- return;
- }
-
- m_tmManagerWindow=new TM::TMManagerWin(SettingsController::instance()->mainWindowPtr());
- }
- m_tmManagerWindow->show();
- m_tmManagerWindow->activateWindow();
-}
-
-void Project::save()
-{
- m_localConfig->setFirstRun(false);
-
- ProjectBase::setTargetLangCode(langCode());
- writeConfig();
- m_localConfig->writeConfig();
-}
-
-ProjectModel* Project::model()
-{
- if (Q_UNLIKELY(!m_model))
- m_model=new ProjectModel(this);
-
- return m_model;
-}
-
-void Project::setDefaults()
-{
- ProjectBase::setDefaults();
- setLangCode(KGlobal::locale()->language());
-}
-
-void Project::init(const QString& path, const QString& kind, const QString& id,
- const QString& sourceLang, const QString& targetLang)
-{
- setDefaults();
- bool stop=false;
- while(true)
- {
- setKind(kind);setSourceLangCode(sourceLang);setLangCode(targetLang);setProjectID(id);
- if (stop) break;
- else {load(path);stop=true;}
- }
- save();
-}
-
-
-#include "moc_project.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef PROJECT_H
-#define PROJECT_H
-
-#include <QVector>
-#include <QList>
-#include "projectbase.h"
-
-class ProjectModel;
-class ProjectLocal;
-namespace GlossaryNS{class Glossary;}
-namespace GlossaryNS{class GlossaryWindow;}
-namespace TM{class TMManagerWin;}
-
-/**
- * Singleton object that represents project.
- * It is shared between EditorWindow 'mainwindows' that use the same project file.
- * Keeps project's KDirModel and Glossary
- *
- * GUI for config handling is implemented in prefs.cpp
- *
- * @short Singleton object that represents project
- */
-
-///////// * Also provides list of web-query scripts
-class Project: public ProjectBase
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.Project")
- //qdbuscpp2xml -m -s project.h -o org.kde.lokalize.Project.xml
-public:
- explicit Project();
- virtual ~Project();
-
- void load(const QString &file);
- void save();
- bool isLoaded()const{return !m_path.isEmpty();}
- ProjectModel* model();
-
- //void setPath(const QString& p){m_path=p;}
- QString path()const{return m_path;}
- QString projectDir()const{return m_projectDir;}
- QString poDir()const{return absolutePath(poBaseDir());}
- QString potDir()const{return absolutePath(potBaseDir());}
- QString branchDir()const{return absolutePath(ProjectBase::branchDir());}
- QString glossaryPath()const{return absolutePath(glossaryTbx());}
- QString qaPath()const{return absolutePath(mainQA());}
- GlossaryNS::Glossary* glossary()const{return m_glossary;}
- QString altTransDir()const{return absolutePath(altDir());}
-
- bool queryCloseForAuxiliaryWindows();
-
- void setDefaults();
-// private slots:
-// void initLater();
-
-public slots:
- Q_SCRIPTABLE QString translationsRoot()const{return poDir();}
- Q_SCRIPTABLE QString templatesRoot()const{return potDir();}
-
-
- Q_SCRIPTABLE QString targetLangCode()const{return ProjectBase::langCode();}
- Q_SCRIPTABLE QString sourceLangCode()const{return ProjectBase::sourceLangCode();}
- Q_SCRIPTABLE void init(const QString& path, const QString& kind, const QString& id,
- const QString& sourceLang, const QString& targetLang);
- Q_SCRIPTABLE QString kind()const{return ProjectBase::kind();}
-
- Q_SCRIPTABLE QString absolutePath(const QString&) const;
-
- Q_SCRIPTABLE void setDesirablePath(const QString& path){m_desirablePath=path;}
- Q_SCRIPTABLE QString desirablePath() const{return m_desirablePath;}
-
- Q_SCRIPTABLE bool isTmSupported() const;
-
-signals:
- Q_SCRIPTABLE void loaded();
-
-public slots:
- void populateDirModel();
- void populateGlossary();
-
- void showTMManager();
- GlossaryNS::GlossaryWindow* showGlossary();
- GlossaryNS::GlossaryWindow* defineNewTerm(QString en=QString(),QString target=QString());
-
-private:
- static Project* _instance;
- static void cleanupProject();
-public:
- static Project* instance();
- static ProjectLocal* local(){return instance()->m_localConfig;}
-
-private:
- QString m_path;
- QString m_desirablePath;
- ProjectLocal* m_localConfig;
- ProjectModel* m_model;
- GlossaryNS::Glossary* m_glossary;
- GlossaryNS::GlossaryWindow* m_glossaryWindow;
- TM::TMManagerWin* m_tmManagerWindow;
-
- //cache
- QString m_projectDir;
- };
-
-
-
-
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
- <kcfgfile arg="true"/>
- <include>klocale.h</include>
- <include>kde-i18n-lists.h</include>
- <group name="General">
- <entry name="ProjectID" type="String">
- <default>default</default>
- </entry>
- <entry name="Kind" type="String">
- <default>kde</default>
- </entry>
- <entry name="LangCode" type="String">
-<!--
- <label>Language</label>
-
- <default code="true">KGlobal::locale()->language()</default>
--->
- </entry>
- <entry name="TargetLangCode" type="String">
- </entry>
- <entry name="SourceLangCode" type="String">
- <default>en_US</default>
- </entry>
- <entry name="MailingList" type="String">
- <default code="true">getMailingList()</default>
- </entry>
- <entry name="PoBaseDir" type="String">
-<!--
- <label>The base directory for PO files (translations)</label>
--->
- <default>./</default>
- </entry>
- <entry name="PotBaseDir" type="String">
-<!--
- <label>The base directory for POT files (templates to be translated)</label>
--->
- <default>../templates</default>
- </entry>
- <entry name="BranchDir" type="String"></entry>
- <entry name="AltDir" type="String"></entry>
- <entry name="GlossaryTbx" type="String">
-<!--
- <label>Project's glossary</label>
--->
- <default>./terms.tbx</default>
- </entry>
- <entry name="MainQA" type="String">
- <default>./main.lqa</default>
- </entry>
- </group>
- <group name="RegExps">
- <entry name="Accel" type="String">
- <default>&</default>
-<!--
- <default>(&)[^(\w+;)]</default>
--->
- </entry>
- <entry name="Markup" type="String">
- <default>(<[^>]+>)+|(&[A-Za-z_:][A-Za-z0-9_\.:-]*;)+</default>
- </entry>
- <entry name="WordWrap" type="Int">
- <default>80</default>
- </entry>
- </group>
-</kcfg>
+++ /dev/null
-File=projectbase.kcfg
-ClassName=ProjectBase
-Singleton=false
-Mutators=true
-GlobalEnums=true
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
- <kcfgfile arg="true"/>
- <group name="Personal">
- <entry name="Role" type="Enum">
- <choices name="PersonRole">
- <choice name="Translator" />
- <choice name="Reviewer" />
- <choice name="Approver" />
- <choice name="Undefined" />
- </choices>
- <default>Approver</default>
- </entry>
- <entry name="FirstRun" type="Bool">
- <default>true</default>
- </entry>
- </group>
-</kcfg>
+++ /dev/null
-File=projectlocal.kcfg
-ClassName=ProjectLocal
-Singleton=false
-Mutators=true
-GlobalEnums=true
-UseEnumTypes=true
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="ProjectOverview" version="3">
-<MenuBar>
- <Menu name="go"><text>&Go</text>
- <Action name="go_prev_fuzzyUntr"/>
- <Action name="go_next_fuzzyUntr"/>
- <Action name="go_prev_fuzzy"/>
- <Action name="go_next_fuzzy"/>
- <Action name="go_prev_untrans"/>
- <Action name="go_next_untrans"/>
- <Separator/>
- <Action name="go_prev_templateOnly"/>
- <Action name="go_next_templateOnly"/>
- <Action name="go_prev_transOnly"/>
- <Action name="go_next_transOnly"/>
- </Menu>
-</MenuBar>
-<ToolBar name="mainToolBar"><text>Main Toolbar</text>
- <Action name="project_open"/>
- <Separator/>
- <Action name="go_prev_fuzzyUntr"/>
- <Action name="go_next_fuzzyUntr"/>
-</ToolBar>
-</kpartgui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2009 by Viesturs Zarins <viesturs.zarins@mii.lu.lv>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projectmodel.h"
-#include "project.h"
-
-#include <threadweaver/ThreadWeaver.h>
-#include <threadweaver/Thread.h>
-
-#include <kio/netaccess.h>
-#include <klocale.h>
-#include <kapplication.h>
-#include <kstandarddirs.h>
-
-#include <QtCore/qdatetime.h>
-#include <QFile>
-#include <QtCore/qalgorithms.h>
-#include <QTimer>
-#include <QSqlDatabase>
-#include <QSqlQuery>
-#include <QSqlError>
-
-#undef KDE_NO_DEBUG_OUTPUT
-static int nodeCounter=0;
-
-//TODO: figure out how to handle file and folder renames...
-//TODO: fix behavior on folder removing, adding.
-
-
-ProjectModel::ProjectModel(QObject *parent)
- : QAbstractItemModel(parent)
- , m_poModel(this)
- , m_potModel(this)
- , m_rootNode(ProjectNode(NULL, -1, -1, -1))
- , m_dirIcon(KIcon(QLatin1String("inode-directory")))
- , m_poIcon(KIcon(QLatin1String("flag-blue")))
- , m_poComplIcon(KIcon(QLatin1String("flag-green")))
- , m_potIcon(KIcon(QLatin1String("flag-black")))
- , m_activeJob(NULL)
- , m_activeNode(NULL)
- , m_weaver(new ThreadWeaver::Weaver())
- , m_completeScan(true)
-{
- m_weaver->setMaximumNumberOfThreads(1);
-
- m_poModel.dirLister()->setAutoErrorHandlingEnabled(false, NULL);
- m_poModel.dirLister()->setNameFilter("*.po *.pot *.xlf");
-
- m_potModel.dirLister()->setAutoErrorHandlingEnabled(false, NULL);
- m_potModel.dirLister()->setNameFilter("*.pot");
-
- connect(&m_poModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(po_dataChanged(QModelIndex,QModelIndex)));
-
- connect(&m_poModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(po_rowsInserted(QModelIndex,int,int)));
-
- connect(&m_poModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(po_rowsRemoved(QModelIndex,int,int)));
-
- connect(&m_potModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(pot_dataChanged(QModelIndex,QModelIndex)));
-
- connect(&m_potModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(pot_rowsInserted(QModelIndex,int,int)));
-
- connect(&m_potModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(pot_rowsRemoved(QModelIndex,int,int)));
-
- m_doneTimer = new QTimer();
- m_doneTimer->setSingleShot(true);
- connect(m_doneTimer, SIGNAL(timeout()), this, SLOT(updateTotalsChanged()));
-
- setUrl(KUrl(), KUrl());
-}
-
-
-ProjectModel::~ProjectModel()
-{
- m_dirsWaitingForMetadata.clear();
-
- if (m_activeJob != NULL)
- m_activeJob->setStatus(-2);
-
- m_activeJob = NULL;
-
- for (int pos = 0; pos < m_rootNode.rows.count(); pos ++)
- deleteSubtree(m_rootNode.rows.at(pos));
-}
-
-void ProjectModel::setUrl(const KUrl &poUrl, const KUrl &potUrl)
-{
- //kDebug() << "ProjectModel::openUrl("<< poUrl.pathOrUrl() << +", " << potUrl.pathOrUrl() << ")";
-
- //cleanup old data
-
- m_dirsWaitingForMetadata.clear();
-
- if (m_activeJob != NULL)
- m_activeJob->setStatus(-1);
- m_activeJob = NULL;
-
- if (m_rootNode.rows.count())
- {
- beginRemoveRows(QModelIndex(), 0, m_rootNode.rows.count());
-
- for (int pos = 0; pos < m_rootNode.rows.count(); pos ++)
- deleteSubtree(m_rootNode.rows.at(pos));
- m_rootNode.rows.clear();
- m_rootNode.poCount = 0;
- m_rootNode.translated = -1;
- m_rootNode.translated_reviewer = -1;
- m_rootNode.translated_approver = -1;
- m_rootNode.untranslated = -1;
- m_rootNode.fuzzy = -1;
- m_rootNode.fuzzy_reviewer = -1;
- m_rootNode.fuzzy_approver = -1;
-
- endRemoveRows();
- }
-
- //add trailing slashes to base URLs, needed for potToPo and poToPot
- m_poUrl = poUrl;
- m_potUrl = potUrl;
- m_poUrl.adjustPath(KUrl::AddTrailingSlash);
- m_potUrl.adjustPath(KUrl::AddTrailingSlash);
-
- emit loading();
-
- if (!poUrl.isEmpty())
- m_poModel.dirLister()->openUrl(m_poUrl, KDirLister::Reload);
- if (!potUrl.isEmpty())
- m_potModel.dirLister()->openUrl(m_potUrl, KDirLister::Reload);
-}
-
-
-KUrl ProjectModel::beginEditing(const QModelIndex& index)
-{
- Q_ASSERT(index.isValid());
-
- QModelIndex poIndex = poIndexForOuter(index);
- QModelIndex potIndex = potIndexForOuter(index);
-
- if (poIndex.isValid())
- {
- KFileItem item = m_poModel.itemForIndex(poIndex);
- return item.url();
- }
- else if (potIndex.isValid())
- {
- //copy over the file
- KUrl potFile = m_potModel.itemForIndex(potIndex).url();
- KUrl poFile = potToPo(potFile);
-
- //EditorTab::fileOpen takes care of this
- //be careful, copy only if file does not exist already.
- // if (!KIO::NetAccess::exists(poFile, KIO::NetAccess::DestinationSide, NULL))
- // KIO::NetAccess::file_copy(potFile, poFile);
-
- return poFile;
- }
- else
- {
- Q_ASSERT(false);
- return KUrl();
- }
-}
-
-//Theese methds update the combined model from POT and PO model changes.
-//Quite complex stuff here, better do not change anything.
-
-void ProjectModel::po_dataChanged(const QModelIndex& po_topLeft, const QModelIndex& po_bottomRight)
-{
- //nothing special here
- //map from source and propagate
- QModelIndex topLeft = indexForPoIndex(po_topLeft);
- QModelIndex bottomRight = indexForPoIndex(po_bottomRight);
-
- emit dataChanged(topLeft, bottomRight);
-
- enqueueNodeForMetadataUpdate(nodeForIndex(topLeft.parent()));
-}
-
-void ProjectModel::pot_dataChanged(const QModelIndex& pot_topLeft, const QModelIndex& pot_bottomRight)
-{
- //tricky here - some of the pot items may be represented by po items
- //let's propagate that all subitems changed
-
-
- QModelIndex pot_parent = pot_topLeft.parent();
- QModelIndex parent = indexForPotIndex(pot_parent);
-
- ProjectNode* node = nodeForIndex(parent);
- int count = node->rows.count();
-
- QModelIndex topLeft = index(0, pot_topLeft.column(), parent);
- QModelIndex bottomRight = index(count-1, pot_bottomRight.column(), parent);
-
- emit dataChanged(topLeft, bottomRight);
-
- enqueueNodeForMetadataUpdate(nodeForIndex(topLeft.parent()));
-}
-
-
-void ProjectModel::po_rowsInserted(const QModelIndex& po_parent, int first, int last)
-{
- QModelIndex parent = indexForPoIndex(po_parent);
- QModelIndex pot_parent = potIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
-
- //insert po rows
- beginInsertRows(parent, first, last);
-
- for (int pos = first; pos <= last; pos ++)
- {
- ProjectNode * childNode = new ProjectNode(node, pos, pos, -1);
- node->rows.insert(pos, childNode);
- }
-
- node->poCount += last - first + 1;
-
- //update rowNumber
- for (int pos = last + 1; pos < node->rows.count(); pos++)
- node->rows[pos]->rowNumber = pos;
-
- endInsertRows();
-
- //remove unneeded pot rows, update PO rows
- if (pot_parent.isValid() || !parent.isValid())
- {
- QVector<int> pot2PoMapping;
- generatePOTMapping(pot2PoMapping, po_parent, pot_parent);
-
- for (int pos = node->poCount; pos < node->rows.count(); pos ++)
- {
- ProjectNode* potNode = node->rows.at(pos);
- int potIndex = potNode->potRowNumber;
- int poIndex = pot2PoMapping[potIndex];
-
- if (poIndex != -1)
- {
- //found pot node, that now has a PO index.
- //remove the pot node and change the corresponding PO node
- beginRemoveRows(parent, pos, pos);
- node->rows.remove(pos);
- deleteSubtree(potNode);
- endRemoveRows();
-
- node->rows[poIndex]->potRowNumber = potIndex;
- //This change does not need notification
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
-
- pos--;
- }
- }
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-void ProjectModel::pot_rowsInserted(const QModelIndex& pot_parent, int start, int end)
-{
- QModelIndex parent = indexForPotIndex(pot_parent);
- QModelIndex po_parent = poIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
-
- int insertedCount = end + 1 - start;
- QVector<int> newPotNodes;
-
- if (po_parent.isValid() || !parent.isValid())
- {
- //this node containts mixed items - add and merge the stuff
-
- QVector<int> pot2PoMapping;
- generatePOTMapping(pot2PoMapping, po_parent, pot_parent);
-
- //reassign affected PO row POT indices
- for (int pos = 0; pos < node->poCount;pos ++)
- {
- ProjectNode* n=node->rows[pos];
- if (n->potRowNumber >= start)
- n->potRowNumber += insertedCount;
- }
-
- //assign new POT indices
- for (int potIndex = start; potIndex <= end; potIndex ++)
- {
- int poIndex = pot2PoMapping[potIndex];
- if (poIndex != -1)
- {
- //found pot node, that has a PO index.
- //change the corresponding PO node
- node->rows[poIndex]->potRowNumber = potIndex;
- //This change does not need notification
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
- }
- else
- newPotNodes.append(potIndex);
- }
- }
- else
- {
- for (int pos = start; pos < end; pos ++)
- newPotNodes.append(pos);
- }
-
- //insert standalone POT rows, preserving POT order
-
- int newNodesCount = newPotNodes.count();
- if (newNodesCount)
- {
- int insertionPoint = node->poCount;
- while ((insertionPoint < node->rows.count()) && (node->rows[insertionPoint]->potRowNumber < start))
- insertionPoint++;
-
- beginInsertRows(parent, insertionPoint, insertionPoint + newNodesCount - 1);
-
- for (int pos = 0; pos < newNodesCount; pos ++)
- {
- int potIndex = newPotNodes.at(pos);
- ProjectNode * childNode = new ProjectNode(node, insertionPoint, -1, potIndex);
- node->rows.insert(insertionPoint, childNode);
- insertionPoint++;
- }
-
- //renumber remaining POT rows
- for (int pos = insertionPoint; pos < node->rows.count(); pos ++)
- {
- node->rows[pos]->rowNumber = pos;
- node->rows[pos]->potRowNumber += insertedCount;
- }
-
- endInsertRows();
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-void ProjectModel::po_rowsRemoved(const QModelIndex& po_parent, int start, int end)
-{
- QModelIndex parent = indexForPoIndex(po_parent);
- QModelIndex pot_parent = potIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
- int removedCount = end + 1 - start;
-
- if ((!parent.isValid()) && (node->rows.count() == 0))
- {
- //events after removing entire contents
- return;
- }
-
- //remove PO rows
- QList<int> potRowsToInsert;
-
- beginRemoveRows(parent, start, end);
-
- //renumber all rows after removed.
- for (int pos = end + 1; pos < node->rows.count(); pos ++)
- {
- ProjectNode* childNode = node->rows.at(pos);
- childNode->rowNumber -= removedCount;
-
- if (childNode->poRowNumber > end)
- node->rows[pos]->poRowNumber -= removedCount;
- }
-
- //remove
- for (int pos = end; pos >= start; pos --)
- {
- int potIndex = node->rows.at(pos)->potRowNumber;
- deleteSubtree(node->rows.at(pos));
- node->rows.remove(pos);
-
- if (potIndex != -1)
- potRowsToInsert.append(potIndex);
- }
-
-
- node->poCount -= removedCount;
-
- endRemoveRows(); //< fires removed event - the list has to be consistent now
-
- //add back rows that have POT files and fix row order
- qSort(potRowsToInsert.begin(), potRowsToInsert.end());
-
- int insertionPoint = node->poCount;
-
- for (int pos = 0; pos < potRowsToInsert.count(); pos ++)
- {
- int potIndex = potRowsToInsert.at(pos);
- while (insertionPoint < node->rows.count() && node->rows[insertionPoint]->potRowNumber < potIndex)
- {
- node->rows[insertionPoint]->rowNumber = insertionPoint;
- insertionPoint ++;
- }
-
- beginInsertRows(parent, insertionPoint, insertionPoint);
-
- ProjectNode * childNode = new ProjectNode(node, insertionPoint, -1, potIndex);
- node->rows.insert(insertionPoint, childNode);
- insertionPoint++;
- endInsertRows();
- }
-
- //renumber remaining rows
- while (insertionPoint < node->rows.count())
- {
- node->rows[insertionPoint]->rowNumber = insertionPoint;
- insertionPoint++;
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-void ProjectModel::pot_rowsRemoved(const QModelIndex& pot_parent, int start, int end)
-{
- QModelIndex parent = indexForPotIndex(pot_parent);
- QModelIndex po_parent = poIndexForOuter(parent);
- ProjectNode * node = nodeForIndex(parent);
- int removedCount = end + 1 - start;
-
- if ((!parent.isValid()) && (node->rows.count() == 0))
- {
- //events after removing entire contents
- return;
- }
-
- //First remove POT nodes
-
- int firstPOTToRemove = node->poCount;
- int lastPOTToRemove = node->rows.count() - 1;
-
- while (firstPOTToRemove <= lastPOTToRemove && node->rows[firstPOTToRemove]->potRowNumber < start)
- firstPOTToRemove ++;
- while (lastPOTToRemove >= firstPOTToRemove && node->rows[lastPOTToRemove]->potRowNumber > end)
- lastPOTToRemove --;
-
- if (firstPOTToRemove <= lastPOTToRemove)
- {
- beginRemoveRows(parent, firstPOTToRemove, lastPOTToRemove);
-
- for (int pos = lastPOTToRemove; pos >= firstPOTToRemove; pos --)
- {
- ProjectNode* childNode = node->rows.at(pos);
- Q_ASSERT(childNode->potRowNumber >= start);
- Q_ASSERT(childNode->potRowNumber <= end);
- deleteSubtree(childNode);
- node->rows.remove(pos);
- }
-
- //renumber remaining rows
- for (int pos = firstPOTToRemove; pos < node->rows.count(); pos ++)
- {
- node->rows[pos]->rowNumber = pos;
- node->rows[pos]->potRowNumber -= removedCount;
- }
-
- endRemoveRows();
- }
-
- //now remove POT indices form PO rows
-
- if (po_parent.isValid() || !parent.isValid())
- {
- for (int poIndex = 0; poIndex < node->poCount; poIndex ++)
- {
- ProjectNode * childNode = node->rows[poIndex];
- int potIndex = childNode->potRowNumber;
-
- if (potIndex >= start && potIndex <= end)
- {
- //found PO node, that has a POT index in range.
- //change the corresponding PO node
- node->rows[poIndex]->potRowNumber = -1;
- //this change does not affect the model
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
- }
- else if (childNode->potRowNumber > end)
- {
- //reassign POT indices
- childNode->potRowNumber -= removedCount;
- }
- }
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-int ProjectModel::columnCount(const QModelIndex& /*parent*/)const
-{
- return ProjectModelColumnCount;
-}
-
-
-QVariant ProjectModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- case FileName: return i18nc("@title:column File name","Name");
- case Graph: return i18nc("@title:column Graphical representation of Translated/Fuzzy/Untranslated counts","Graph");
- case TotalCount: return i18nc("@title:column Number of entries","Total");
- case TranslatedCount: return i18nc("@title:column Number of entries","Translated");
- case FuzzyCount: return i18nc("@title:column Number of entries","Not ready");
- case UntranslatedCount: return i18nc("@title:column Number of entries","Untranslated");
- case TranslationDate: return i18nc("@title:column","Last Translation");
- case SourceDate: return i18nc("@title:column","Template Revision");
- case LastTranslator: return i18nc("@title:column","Last Translator");
- default: return QVariant();
- }
-}
-
-
-Qt::ItemFlags ProjectModel::flags( const QModelIndex & index ) const
-{
- if (index.column() == FileName)
- return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
- else
- return Qt::ItemIsSelectable;
-}
-
-
-int ProjectModel::rowCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const
-{
- return nodeForIndex(parent)->rows.size();
-}
-
-
-bool ProjectModel::hasChildren ( const QModelIndex & parent /*= QModelIndex()*/ ) const
-{
- if (!parent.isValid())
- return true;
-
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- return ((poIndex.isValid() && m_poModel.hasChildren(poIndex)) ||
- (potIndex.isValid() && m_potModel.hasChildren(potIndex)));
-}
-
-bool ProjectModel::canFetchMore ( const QModelIndex & parent ) const
-{
- if (!parent.isValid())
- return m_poModel.canFetchMore(QModelIndex()) || m_potModel.canFetchMore(QModelIndex());
-
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- return ((poIndex.isValid() && m_poModel.canFetchMore(poIndex)) ||
- (potIndex.isValid() && m_potModel.canFetchMore(potIndex)));
-}
-
-void ProjectModel::fetchMore ( const QModelIndex & parent )
-{
- if (!parent.isValid())
- {
- if (m_poModel.canFetchMore(QModelIndex()))
- m_poModel.fetchMore(QModelIndex());
-
- if (m_potModel.canFetchMore(QModelIndex()))
- m_potModel.fetchMore(QModelIndex());
- }
- else
- {
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- if (poIndex.isValid() && (m_poModel.canFetchMore(poIndex)))
- m_poModel.fetchMore(poIndex);
-
- if (potIndex.isValid() && (m_potModel.canFetchMore(potIndex)))
- m_potModel.fetchMore(potIndex);
- }
-}
-
-
-
-/**
- * we use QRect to pass data through QVariant tunnel
- *
- * order is tran, untr, fuzzy
- * left() top() width()
- *
- */
-QVariant ProjectModel::data(const QModelIndex& index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- const ProjectModelColumns& column=(ProjectModelColumns)index.column();
- ProjectNode* node = nodeForIndex(index);
- QModelIndex internalIndex = poOrPotIndexForOuter(index);
-
- if (!internalIndex.isValid())
- return QVariant();
-
- KFileItem item=itemForIndex(index);
- bool isDir = item.isDir();
-
- int translated = node->translatedAsPerRole();
- int fuzzy = node->fuzzyAsPerRole();
- int untranslated = node->untranslated;
- bool hasStats = translated != -1;
-
- switch(role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case FileName: return item.text();
- case Graph: return hasStats?QRect(translated, untranslated, fuzzy, 0):QVariant();
- case TotalCount: return hasStats?(translated + untranslated + fuzzy):QVariant();
- case TranslatedCount:return hasStats?translated:QVariant();
- case FuzzyCount: return hasStats?fuzzy:QVariant();
- case UntranslatedCount:return hasStats?untranslated:QVariant();
- case SourceDate: return node->sourceDate;
- case TranslationDate:return node->translationDate;
- case LastTranslator:return node->lastTranslator;
- default: return QVariant();
- }
- case Qt::ToolTipRole:
- switch (column)
- {
- case FileName: return item.text();
- default: return QVariant();
- }
- case KDirModel::FileItemRole:
- return QVariant::fromValue(item);
- case Qt::DecorationRole:
- switch (column)
- {
- case FileName:
- if (isDir)
- return m_dirIcon;
- if (hasStats && fuzzy == 0 && untranslated == 0)
- return m_poComplIcon;
- else if (node->poRowNumber != -1)
- return m_poIcon;
- else if (node->potRowNumber != -1)
- return m_potIcon;
- default:
- return QVariant();
- }
- case FuzzyUntrCountRole:
- return item.isFile()?(fuzzy + untranslated):0;
- case FuzzyCountRole:
- return item.isFile()?fuzzy:0;
- case UntransCountRole:
- return item.isFile()?untranslated:0;
- case TemplateOnlyRole:
- return item.isFile()?(node->poRowNumber == -1):0;
- case TransOnlyRole:
- return item.isFile()?(node->potRowNumber == -1):0;
- case TotalRole:
- return hasStats?(fuzzy + untranslated + translated):0;
- default:
- return QVariant();
- }
-}
-
-
-QModelIndex ProjectModel::index(int row, int column, const QModelIndex& parent) const
-{
- ProjectNode* parentNode = nodeForIndex(parent);
- //kWarning()<<(sizeof(ProjectNode))<<nodeCounter;
- if (row>=parentNode->rows.size())
- {
- kWarning()<<"SHIT HAPPENED WITH INDEXES"<<row<<parentNode->rows.size()<<itemForIndex(parent).url();
- return QModelIndex();
- }
- return createIndex(row, column, parentNode->rows.at(row));
-}
-
-
-KFileItem ProjectModel::itemForIndex(const QModelIndex& index) const
-{
- if (!index.isValid())
- {
- //file item for root node.
- return m_poModel.itemForIndex(index);
- }
- QModelIndex poIndex = poIndexForOuter(index);
-
- if (poIndex.isValid())
- return m_poModel.itemForIndex(poIndex);
- else
- {
- QModelIndex potIndex = potIndexForOuter(index);
-
- if (potIndex.isValid())
- return m_potModel.itemForIndex(potIndex);
- }
-
- kWarning()<<"returning empty KFileItem()"<<index.row()<<index.column();
- kWarning()<<"returning empty KFileItem()"<<index.parent().isValid();
- kWarning()<<"returning empty KFileItem()"<<index.parent().internalPointer();
- kWarning()<<"returning empty KFileItem()"<<index.parent().data().toString();
- kWarning()<<"returning empty KFileItem()"<<index.internalPointer();
- kWarning()<<"returning empty KFileItem()"<<static_cast<ProjectNode*>(index.internalPointer())->untranslated<<static_cast<ProjectNode*>(index.internalPointer())->sourceDate;
- return KFileItem();
-}
-
-
-ProjectModel::ProjectNode* ProjectModel::nodeForIndex(const QModelIndex& index) const
-{
- if (index.isValid())
- {
- ProjectNode * node = static_cast<ProjectNode *>(index.internalPointer());
- Q_ASSERT(node != NULL);
- return node;
- }
- else
- {
- ProjectNode * node = const_cast<ProjectNode *>(&m_rootNode);
- Q_ASSERT(node != NULL);
- return node;
- }
-}
-
-
-QModelIndex ProjectModel::indexForNode(const ProjectNode* node)
-{
- if (node == &m_rootNode)
- return QModelIndex();
-
- int row = node->rowNumber;
- QModelIndex index = createIndex(row, 0, (void*)node);
- return index;
-}
-
-QModelIndex ProjectModel::indexForUrl(const KUrl& url)
-{
- if (m_poUrl.isParentOf(url))
- {
- QModelIndex poIndex = m_poModel.indexForUrl(url);
- return indexForPoIndex(poIndex);
- }
- else if (m_potUrl.isParentOf(url))
- {
- QModelIndex potIndex = m_potModel.indexForUrl(url);
- return indexForPotIndex(potIndex);
- }
-
- return QModelIndex();
-}
-
-QModelIndex ProjectModel::parent(const QModelIndex& childIndex) const
-{
- if (!childIndex.isValid())
- return QModelIndex();
-
- ProjectNode* childNode = nodeForIndex(childIndex);
- ProjectNode* parentNode = childNode->parent;
-
- if (!parentNode || (childNode == &m_rootNode) || (parentNode == &m_rootNode))
- return QModelIndex();
-
- return createIndex(parentNode->rowNumber, 0, parentNode);
-}
-
-
-/**
- * Theese methods map from project model indices to PO and POT model indices.
- * In each folder files form PO model comes first, and files from POT that do not exist in PO model come after.
- */
-QModelIndex ProjectModel::indexForOuter(const QModelIndex& outerIndex, IndexType type) const
-{
- if (!outerIndex.isValid())
- return QModelIndex();
-
- QModelIndex parent = outerIndex.parent();
-
- QModelIndex internalParent;
- if (parent.isValid())
- {
- internalParent = indexForOuter(parent, type);
- if (!internalParent.isValid())
- return QModelIndex();
- }
-
- ProjectNode* node = nodeForIndex(outerIndex);
-
- short rowNumber=(type==PoIndex?node->poRowNumber:node->potRowNumber);
- if (rowNumber == -1)
- return QModelIndex();
- return (type==PoIndex?m_poModel:m_potModel).index(rowNumber, outerIndex.column(), internalParent);
-}
-
-QModelIndex ProjectModel::poIndexForOuter(const QModelIndex& outerIndex) const
-{
- return indexForOuter(outerIndex, PoIndex);
-}
-
-
-QModelIndex ProjectModel::potIndexForOuter(const QModelIndex& outerIndex) const
-{
- return indexForOuter(outerIndex, PotIndex);
-}
-
-
-QModelIndex ProjectModel::poOrPotIndexForOuter(const QModelIndex& outerIndex) const
-{
- if (!outerIndex.isValid())
- return QModelIndex();
-
- QModelIndex poIndex = poIndexForOuter(outerIndex);
-
- if (poIndex.isValid())
- return poIndex;
-
- QModelIndex potIndex = potIndexForOuter(outerIndex);
-
- if (!potIndex.isValid())
- kWarning()<<"error mapping index to PO or POT";
-
- return potIndex;
-}
-
-QModelIndex ProjectModel::indexForPoIndex(const QModelIndex& poIndex) const
-{
- if (!poIndex.isValid())
- return QModelIndex();
-
- QModelIndex outerParent = indexForPoIndex(poIndex.parent());
- int row = poIndex.row(); //keep the same row, no changes
-
- return index(row, poIndex.column(), outerParent);
-}
-
-QModelIndex ProjectModel::indexForPotIndex(const QModelIndex& potIndex) const
-{
- if (!potIndex.isValid())
- return QModelIndex();
-
- QModelIndex outerParent = indexForPotIndex(potIndex.parent());
- ProjectNode* node = nodeForIndex(outerParent);
-
- int potRow = potIndex.row();
- int row = 0;
-
- while(row<node->rows.count() && node->rows.at(row)->potRowNumber!=potRow)
- row++;
-
- if (row != node->rows.count())
- return index(row, potIndex.column(), outerParent);
-
- kWarning()<<"error mapping index from POT to outer, searched for potRow:"<<potRow;
- return QModelIndex();
-}
-
-
-/**
- * Makes a list of indices where pot items map to poItems.
- * result[potRow] = poRow or -1 if the pot entry is not found in po.
- * Does not use internal pot and po row number cache.
- */
-void ProjectModel::generatePOTMapping(QVector<int> & result, const QModelIndex& poParent, const QModelIndex& potParent) const
-{
- result.clear();
-
- int poRows = m_poModel.rowCount(poParent);
- int potRows = m_potModel.rowCount(potParent);
-
- if (potRows == 0)
- return;
-
- QList<KUrl> poOccupiedUrls;
-
- for (int poPos = 0; poPos < poRows; poPos ++)
- {
- KFileItem file = m_poModel.itemForIndex(m_poModel.index(poPos, 0, poParent));
- KUrl potUrl = poToPot(file.url());
- poOccupiedUrls.append(potUrl);
- }
-
- for (int potPos = 0; potPos < potRows; potPos ++)
- {
-
- KUrl potUrl = m_potModel.itemForIndex(m_potModel.index(potPos, 0, potParent)).url();
- int occupiedPos = -1;
-
- //TODO: this is slow
- for (int poPos = 0; occupiedPos == -1 && poPos < poOccupiedUrls.count(); poPos ++)
- {
- KUrl& occupiedUrl = poOccupiedUrls[poPos];
- if (potUrl.equals(occupiedUrl))
- occupiedPos = poPos;
- }
-
- result.append(occupiedPos);
- }
-}
-
-
-KUrl ProjectModel::poToPot(const KUrl& poPath) const
-{
- if (!m_poUrl.isParentOf(poPath))
- {
- kWarning()<<"PO path not in project: " << poPath.url();
- return KUrl();
- }
-
- QString pathToAdd = KUrl::relativeUrl(m_poUrl, poPath);
-
- //change ".po" into ".pot"
- if (pathToAdd.endsWith(".po")) //TODO: what about folders ??
- pathToAdd+='t';
-
- KUrl potPath = m_potUrl;
- potPath.addPath(pathToAdd);
-
- //kDebug() << "ProjectModel::poToPot("<< poPath.pathOrUrl() << +") = " << potPath.pathOrUrl();
- return potPath;
-}
-
-KUrl ProjectModel::potToPo(const KUrl& potPath) const
-{
- if (!m_potUrl.isParentOf(potPath))
- {
- kWarning()<<"POT path not in project: " << potPath.url();
- return KUrl();
- }
-
- QString pathToAdd = KUrl::relativeUrl(m_potUrl, potPath);
-
- //change ".pot" into ".po"
- if (pathToAdd.endsWith(".pot")) //TODO: what about folders ??
- pathToAdd = pathToAdd.left(pathToAdd.length() - 1);
-
- KUrl poPath = m_poUrl;
- poPath.addPath(pathToAdd);
-
- //kDebug() << "ProjectModel::potToPo("<< potPath.pathOrUrl() << +") = " << poPath.pathOrUrl();
- return poPath;
-}
-
-
-//Metadata stuff
-//For updating translation stats
-
-void ProjectModel::enqueueNodeForMetadataUpdate(ProjectNode* node)
-{
- m_doneTimer->stop();
-
- if (m_dirsWaitingForMetadata.contains(node))
- {
- if ((m_activeJob != NULL) && (m_activeNode == node))
- m_activeJob->setStatus(-1);
-
- return;
- }
-
- m_dirsWaitingForMetadata.insert(node);
-
- if (m_activeJob == NULL)
- startNewMetadataJob();
-}
-
-
-void ProjectModel::deleteSubtree(ProjectNode* node)
-{
- for (int row = 0; row < node->rows.count(); row ++)
- deleteSubtree(node->rows.at(row));
-
- m_dirsWaitingForMetadata.remove(node);
-
- if ((m_activeJob != NULL) && (m_activeNode == node))
- m_activeJob->setStatus(-1);
-
- delete node;
-}
-
-
-void ProjectModel::startNewMetadataJob()
-{
- if (!m_completeScan) //hack for debugging
- return;
-
- m_activeJob = NULL;
- m_activeNode = NULL;
-
- if (m_dirsWaitingForMetadata.isEmpty())
- return;
-
- ProjectNode* node = *m_dirsWaitingForMetadata.begin();
-
- //prepare new work
- m_activeNode = node;
-
- QList<KFileItem> files;
-
- QModelIndex item = indexForNode(node);
-
- for (int row=0; row < node->rows.count(); row ++)
- files.append(itemForIndex(index(row, 0, item)));
-
- m_activeJob = new UpdateStatsJob(files, this);
- connect(
- m_activeJob,SIGNAL(done(ThreadWeaver::Job*)),
- this,SLOT(finishMetadataUpdate(ThreadWeaver::Job*)));
-
- m_weaver->enqueue(m_activeJob);
-}
-
-void ProjectModel::finishMetadataUpdate(ThreadWeaver::Job * _job)
-{
- UpdateStatsJob* job = static_cast<UpdateStatsJob *>(_job);
-
- if (job->m_status == -2)
- {
- delete job;
- return;
- }
-
- if ((m_dirsWaitingForMetadata.contains(m_activeNode)) && (job->m_status == 0))
- {
- m_dirsWaitingForMetadata.remove(m_activeNode);
- //store the results
-
- setMetadataForDir(m_activeNode, m_activeJob->m_info);
-
- QModelIndex item = indexForNode(m_activeNode);
-
- //scan dubdirs - initiate data loading into the model.
- for (int row=0; row < m_activeNode->rows.count(); row++)
- {
- QModelIndex child = index(row, 0, item);
-
- if (canFetchMore(child))
- fetchMore(child);
- //QCoreApplication::processEvents();
- }
- }
-
- delete m_activeJob;
-
- startNewMetadataJob();
-}
-
-
-void ProjectModel::slotFileSaved(const KUrl& url)
-{
- QModelIndex index = indexForUrl(url);
-
- if (!index.isValid())
- return;
-
- QList<KFileItem> files;
- files.append(itemForIndex(index));
-
- UpdateStatsJob* j = new UpdateStatsJob(files);
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),
- this,SLOT(finishSingleMetadataUpdate(ThreadWeaver::Job*)));
-
- m_weaver->enqueue(j);
-}
-
-void ProjectModel::finishSingleMetadataUpdate(ThreadWeaver::Job* _job)
-{
- UpdateStatsJob* job = static_cast<UpdateStatsJob*>(_job);
-
- if (job->m_status != 0)
- {
- delete job;
- return;
- }
-
- const KFileMetaInfo& info=job->m_info.first();
- QModelIndex index = indexForUrl(info.url());
- if (!index.isValid())
- return;
-
- ProjectNode* node = nodeForIndex(index);
- node->setFileStats(job->m_info.first());
- updateDirStats(nodeForIndex(index.parent()));
-
- QModelIndex topLeft = index.sibling(index.row(), Graph);
- QModelIndex bottomRight = index.sibling(index.row(), ProjectModelColumnCount - 1);
- emit dataChanged(topLeft, bottomRight);
-
- delete job;
-}
-
-void ProjectModel::setMetadataForDir(ProjectNode* node, const QList<KFileMetaInfo>& data)
-{
- int dataCount = data.count();
- int rowsCount = node->rows.count();
- Q_ASSERT(dataCount == rowsCount);
-
- for (int row = 0; row < rowsCount; row ++)
- node->rows[row]->setFileStats(data.at(row));
-
- if (!dataCount)
- return;
-
- updateDirStats(node);
-
- QModelIndex item = indexForNode(node);
- QModelIndex topLeft = index(0, Graph, item);
- QModelIndex bottomRight = index(rowsCount - 1, ProjectModelColumnCount - 1, item);
- emit dataChanged(topLeft, bottomRight);
-}
-
-void ProjectModel::updateDirStats(ProjectNode* node)
-{
- node->calculateDirStats();
- if (node == &m_rootNode)
- {
- updateTotalsChanged();
- return;
- }
-
- updateDirStats(node->parent);
-
- if (node->parent->rows.count()==0 || node->parent->rows.count()>=node->rowNumber)
- return;
- QModelIndex index = indexForNode(node);
- kWarning()<<index.row()<<node->parent->rows.count();
- if (index.row()>=node->parent->rows.count())
- return;
- QModelIndex topLeft = index.sibling(index.row(), Graph);
- QModelIndex bottomRight = index.sibling(index.row(), ProjectModelColumnCount - 1);
- emit dataChanged(topLeft, bottomRight);
-}
-
-bool ProjectModel::updateDone(const QModelIndex& index, const KDirModel& model)
-{
- if (model.canFetchMore(index))
- return false;
-
- int row=model.rowCount(index);
- while (--row>=0)
- {
- if (!updateDone(model.index(row, 0, index), model))
- return false;
- }
- return true;
-}
-
-void ProjectModel::updateTotalsChanged()
-{
- bool done = m_dirsWaitingForMetadata.isEmpty();
- if (done)
- {
- done = updateDone(m_poModel.indexForUrl(m_poUrl), m_poModel) &&
- updateDone(m_potModel.indexForUrl(m_potUrl), m_potModel);
- if (m_rootNode.fuzzyAsPerRole() + m_rootNode.translatedAsPerRole() + m_rootNode.untranslated > 0 && !done)
- m_doneTimer->start(2000);
- }
- emit totalsChanged(m_rootNode.fuzzyAsPerRole(), m_rootNode.translatedAsPerRole(), m_rootNode.untranslated, done);
-}
-
-
-//ProjectNode class
-
-ProjectModel::ProjectNode::ProjectNode(ProjectNode* _parent, int _rowNum, int _poIndex, int _potIndex)
- : parent(_parent)
- , rowNumber(_rowNum)
- , poRowNumber(_poIndex)
- , potRowNumber(_potIndex)
- , poCount(0)
- , translated(-1)
- , translated_reviewer(-1)
- , translated_approver(-1)
- , untranslated(-10)
- , fuzzy(-1)
- , fuzzy_reviewer(-10)
- , fuzzy_approver(-10)
-{
- ++nodeCounter;
-}
-
-ProjectModel::ProjectNode::~ProjectNode()
-{
- --nodeCounter;
-}
-
-void ProjectModel::ProjectNode::calculateDirStats()
-{
- fuzzy = 0;
- fuzzy_reviewer = 0;
- fuzzy_approver = 0;
- translated = 0;
- translated_reviewer = 0;
- translated_approver = 0;
- untranslated = 0;
-
- for (int pos = 0; pos < rows.count(); pos++)
- {
- ProjectNode* child = rows.at(pos);
- if (child->translated != -1)
- {
- fuzzy += child->fuzzy;
- fuzzy_reviewer += child->fuzzy_reviewer;
- fuzzy_approver += child->fuzzy_approver;
- translated += child->translated;
- translated_reviewer += child->translated_reviewer;
- translated_approver += child->translated_approver;
- untranslated += child->untranslated;
- }
- }
-}
-
-
-void ProjectModel::ProjectNode::setFileStats(const KFileMetaInfo& info)
-{
- if (info.keys().count() == 0)
- return;
-
- translated = info.item("translation.translated").value().toInt();
- const QVariant translated_reviewer_variant = info.item("translation.translated_reviewer").value();
- translated_reviewer = translated_reviewer_variant.isValid() ? translated_reviewer_variant.toInt() : translated;
- const QVariant translated_approver_variant = info.item("translation.translated_approver").value();
- translated_approver = translated_approver_variant.isValid() ? translated_approver_variant.toInt() : translated;
- untranslated = info.item("translation.untranslated").value().toInt();
- fuzzy = info.item("translation.fuzzy").value().toInt();
- const QVariant fuzzy_reviewer_variant = info.item("translation.fuzzy_reviewer").value();
- fuzzy_reviewer = fuzzy_reviewer_variant.isValid() ? fuzzy_reviewer_variant.toInt() : fuzzy;
- const QVariant fuzzy_approver_variant = info.item("translation.fuzzy_approver").value();
- fuzzy_approver = fuzzy_approver_variant.isValid() ? fuzzy_approver_variant.toInt() : fuzzy;
- lastTranslator = info.item("translation.last_translator").value().toString();
- sourceDate = info.item("translation.source_date").value().toString();
- translationDate = info.item("translation.translation_date").value().toString();
- lastTranslator.squeeze();
- sourceDate.squeeze();
- translationDate.squeeze();
-}
-
-
-//BEGIN UpdateStatsJob
-//these are run in separate thread
-UpdateStatsJob::UpdateStatsJob(QList<KFileItem> files, QObject* owner)
- : ThreadWeaver::Job(owner)
- , m_files(files)
- , m_status(0)
-{
-}
-
-UpdateStatsJob::~UpdateStatsJob()
-{
-}
-
-static void initDataBase(QSqlDatabase& db)
-{
- QSqlQuery queryMain(db);
- queryMain.exec("PRAGMA encoding = \"UTF-8\"");
- queryMain.exec("CREATE TABLE IF NOT EXISTS metainfo ("
- "filepath INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- //"filepath TEXT UNIQUE ON CONFLICT REPLACE, "
- "metainfo BLOB, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "changedate INTEGER"
- ")");
-
- //queryMain.exec("CREATE INDEX IF NOT EXISTS filepath_index ON metainfo ("filepath)");
-}
-
-
-static KFileMetaInfo cachedMetaInfo(const KFileItem& file)
-{
- QString dbName="metainfocache";
- if (!QSqlDatabase::contains(dbName))
- {
- QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE",dbName);
- db.setDatabaseName(KStandardDirs::locateLocal("appdata", dbName+".sqlite"));
- if (Q_UNLIKELY( !db.open() ))
- return KFileMetaInfo(file.url());
- initDataBase(db);
- }
- QSqlDatabase db=QSqlDatabase::database(dbName);
- if (!db.isOpen())
- return KFileMetaInfo(file.url());
-
- static const QString fields[]={
- "translation.translated",
- "translation.untranslated",
- "translation.fuzzy",
- "translation.last_translator",
- "translation.source_date",
- "translation.translation_date",
- "translation.translated_reviewer",
- "translation.translated_approver",
- "translation.fuzzy_reviewer",
- "translation.fuzzy_approver"
- };
- static const int nFields = sizeof(fields) / sizeof(fields[0]);
-
- QByteArray result;
-
- QSqlQuery queryCache(db);
- queryCache.prepare("SELECT * from metainfo where filepath=?");
- queryCache.bindValue(0, qHash(file.localPath()));
- queryCache.exec();
- if (queryCache.next() && file.time(KFileItem::ModificationTime).dateTime()==queryCache.value(2).toDateTime())
- {
- result=queryCache.value(1).toByteArray();
- QDataStream stream(&result,QIODevice::ReadOnly);
-
- //unfortunately direct KFileMetaInfo << operator doesn't work
- KFileMetaInfo info;
- QVector<QVariant> keys;
- stream>>keys;
- for(int i=0;i<keys.count();i++)
- info.item(fields[i]).setValue(keys.at(i));
- return info;
- }
-
- KFileMetaInfo info(file.url());
-
- QDataStream stream(&result,QIODevice::WriteOnly);
- //this is synced with ProjectModel::ProjectNode::setFileStats
- QVector<QVariant> keys(nFields);
- for(int i=0;i<nFields;i++)
- keys[i] = info.item(fields[i]).value();
- stream<<keys;
-
- QSqlQuery query(db);
-
- query.prepare("INSERT INTO metainfo (filepath, metainfo, changedate) "
- "VALUES (?, ?, ?)");
- query.bindValue(0, qHash(file.localPath()));
- query.bindValue(1, result);
- query.bindValue(2, file.time(KFileItem::ModificationTime).dateTime());
- if (Q_UNLIKELY(!query.exec()))
- qWarning() <<"metainfo cache acquiring error: " <<query.lastError().text();
-
- return info;
-}
-
-void UpdateStatsJob::run()
-{
- static QString dbName="metainfocache";
- bool ok=QSqlDatabase::contains(dbName);
- if (ok)
- {
- QSqlDatabase db=QSqlDatabase::database(dbName);
- QSqlQuery queryBegin("BEGIN",db);
- }
- for (int pos=0; pos<m_files.count(); pos++)
- {
- if (m_status!=0)
- return;
-
- const KFileItem& file=m_files.at(pos);
- KFileMetaInfo info;
-
- if ((!file.isNull()) && (!file.isDir()))
- {
- //force population of metainfo, do not use the KFileItem default behavior
- if (file.metaInfo(false).keys().isEmpty())
- info=cachedMetaInfo(file);
- //info=KFileMetaInfo(file.url());
- else
- info=file.metaInfo(false);
- }
-
- m_info.append(info);
- }
- if (ok)
- {
- QSqlDatabase db=QSqlDatabase::database(dbName);
- {
- //braces are needed to avoid resource leak on close
- QSqlQuery queryEnd("END",db);
- }
- db.close();
- db.open();
- }
-}
-
-void UpdateStatsJob::setStatus(int status)
-{
- m_status=status;
-}
-//END UpdateStatsJob
-
-#include "moc_projectmodel.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2009 by Viesturs Zarins <viesturs.zarins@mii.lu.lv>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTMODEL_H
-#define PROJECTMODEL_H
-
-#include <threadweaver/Job.h>
-
-#include <kdirmodel.h>
-#include <kdirlister.h>
-#include <kicon.h>
-#include <QHash>
-#include <QList>
-#include <kdebug.h>
-
-#include "project.h"
-#include "projectlocal.h"
-
-#include <QTimer>
-class UpdateStatsJob;
-namespace ThreadWeaver {class Weaver;}
-
-/**
-* Some notes:
-* Uses two KDirModels for template and translations dir.
-* Listens to their signals and constructs a combined model.
-* Stats calculation:
-* Uses threadweawer for stats calculation.
-* Each job analyzes files in one dir and adds subdirs to queue.
-* A change in one file forces whole dir to be rescanned
-* The job priority needs some tweaking.
- */
-class ProjectModel: public QAbstractItemModel
-{
- Q_OBJECT
-
- class ProjectNode
- {
- public:
- ProjectNode(ProjectNode* parent, int rowNum, int poIndex, int potIndex);
- ~ProjectNode();
- void calculateDirStats();
- void setFileStats(const KFileMetaInfo& info);
-
- int translatedAsPerRole() const
- {
- switch (Project::local()->role())
- {
- case ProjectLocal::Translator:
- case ProjectLocal::Undefined:
- return translated;
- case ProjectLocal::Reviewer:
- return translated_reviewer;
- case ProjectLocal::Approver:
- return translated_approver;
- }
- return -1;
- }
-
- int fuzzyAsPerRole() const
- {
- switch (Project::local()->role())
- {
- case ProjectLocal::Translator:
- case ProjectLocal::Undefined:
- return fuzzy;
- case ProjectLocal::Reviewer:
- return fuzzy_reviewer;
- case ProjectLocal::Approver:
- return fuzzy_approver;
- }
- return -1;
- }
-
- ProjectNode* parent;
- short rowNumber; //in parent's list
-
- short poRowNumber; //row number in po model, -1 if this has no po item.
- short potRowNumber; //row number in pot model, -1 if this has no pot item.
-
- short poCount; //number of items from PO in rows. The others will be form POT exclusively.
- QVector<ProjectNode*> rows; //rows from po and pot, pot rows start from poCount;
-
- int translated;
- int translated_reviewer;
- int translated_approver;
- int untranslated;
- int fuzzy;
- int fuzzy_reviewer;
- int fuzzy_approver;
- QString sourceDate;
- QString lastTranslator;
- QString translationDate;
- };
-
-
-public:
-
- enum ProjectModelColumns
- {
- FileName,
- Graph,
- TotalCount,
- TranslatedCount,
- FuzzyCount,
- UntranslatedCount,
- SourceDate,
- TranslationDate,
- LastTranslator,
- ProjectModelColumnCount
- };
-
- enum AdditionalRoles {
- FuzzyUntrCountRole = Qt::UserRole,
- FuzzyCountRole,
- UntransCountRole,
- TemplateOnlyRole,
- TransOnlyRole,
- TotalRole
- };
-
- ProjectModel(QObject *parent);
- ~ProjectModel();
-
- void setUrl(const KUrl &poUrl, const KUrl &potUrl);
- QModelIndex indexForUrl(const KUrl& url);
- KFileItem itemForIndex(const QModelIndex& index) const;
- KUrl beginEditing(const QModelIndex& index); //copies POT file to PO file and returns url of the PO file
-
- // QAbstractItemModel methods
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- Qt::ItemFlags flags(const QModelIndex& index) const;
-
- QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const ;
-
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex& parent = QModelIndex()) const;
-
- bool canFetchMore(const QModelIndex& parent) const;
- void fetchMore(const QModelIndex& parent);
-
-
- ThreadWeaver::Weaver* weaver(){return m_weaver;}
- void setCompleteScan(bool enable){m_completeScan=enable;}
-
-signals:
- void totalsChanged(int fuzzy, int translated, int untranslated, bool done);
- void loading();
-
-private slots:
- void po_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
- void po_rowsInserted(const QModelIndex& parent, int start, int end);
- void po_rowsRemoved(const QModelIndex& parent, int start, int end);
-
- void pot_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
- void pot_rowsInserted(const QModelIndex& parent, int start, int end);
- void pot_rowsRemoved(const QModelIndex& parent, int start, int end);
-
- void finishMetadataUpdate(ThreadWeaver::Job*);
- void finishSingleMetadataUpdate(ThreadWeaver::Job*);
-
- void updateTotalsChanged();
-
-public slots:
- void slotFileSaved(const KUrl&);
-
-private:
- ProjectNode* nodeForIndex(const QModelIndex& index) const;
- QModelIndex indexForNode(const ProjectNode* node);
-
- enum IndexType {PoIndex, PotIndex};
- QModelIndex indexForOuter(const QModelIndex& outerIndex, IndexType type) const;
- QModelIndex poIndexForOuter(const QModelIndex& outerIndex) const;
- QModelIndex potIndexForOuter(const QModelIndex& outerIndex) const;
- QModelIndex poOrPotIndexForOuter(const QModelIndex& outerIndex) const;
-
- QModelIndex indexForPoIndex(const QModelIndex& poIndex) const;
- QModelIndex indexForPotIndex(const QModelIndex& potIndex) const;
- void generatePOTMapping(QVector<int> & result, const QModelIndex& poParent, const QModelIndex& potParent) const;
-
- KUrl poToPot(const KUrl& path) const;
- KUrl potToPo(const KUrl& path) const;
-
- void enqueueNodeForMetadataUpdate(ProjectNode* node);
- void deleteSubtree(ProjectNode* node);
-
- void startNewMetadataJob();
- void setMetadataForDir(ProjectNode* node, const QList<KFileMetaInfo>& data);
- void updateDirStats(ProjectNode* node);
- bool updateDone(const QModelIndex& index, const KDirModel& model);
-
- KUrl m_poUrl;
- KUrl m_potUrl;
- KDirModel m_poModel;
- KDirModel m_potModel;
-
- ProjectNode m_rootNode;
-
- QVariant m_dirIcon;
- QVariant m_poIcon;
- QVariant m_poComplIcon;
- QVariant m_potIcon;
-
- //for updating stats
- QSet<ProjectNode *> m_dirsWaitingForMetadata;
- UpdateStatsJob* m_activeJob;
- ProjectNode* m_activeNode;
- QTimer* m_doneTimer;
-
- ThreadWeaver::Weaver* m_weaver;
-
- bool m_completeScan;
-};
-
-
-
-class UpdateStatsJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit UpdateStatsJob(QList<KFileItem> files, QObject* owner=0);
- ~UpdateStatsJob();
- int priority()const{return 35;} //SEE jobs.h
-
- void setStatus(int status);
-
- QList<KFileItem> m_files;
- QList<KFileMetaInfo> m_info;
- volatile int m_status; // 0 = running; -1 = cancel; -2 = abort
-
-protected:
- void run();
-
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projecttab.h"
-#include "project.h"
-#include "projectwidget.h"
-#include "tmscanapi.h"
-#include "prefs.h"
-
-#include <klocale.h>
-#include <kaction.h>
-#include <kactioncategory.h>
-#include <kactioncollection.h>
-#include <kstandardaction.h>
-#include <kxmlguifactory.h>
-#include <klineedit.h>
-#include <kstatusbar.h>
-#include <khbox.h>
-
-#include <QtGui/qevent.h>
-#include <QMenu>
-#include <QVBoxLayout>
-#include <QShortcut>
-#include <QSortFilterProxyModel>
-#include <QProgressBar>
-#include <QStackedLayout>
-#include <QLabel>
-#include <QPushButton>
-
-ProjectTab::ProjectTab(QWidget *parent)
- : LokalizeSubwindowBase2(parent)
- , m_browser(new ProjectWidget(this))
- , m_filterEdit(new KLineEdit(this))
- , m_legacyUnitsCount(-1)
- , m_currentUnitsCount(0)
-
-{
- setWindowTitle(i18nc("@title:window","Project Overview"));//setCaption(i18nc("@title:window","Project"),false);
-//BEGIN setup welcome widget
- QWidget* welcomeWidget=new QWidget(this);
- QVBoxLayout* wl=new QVBoxLayout(welcomeWidget);
- QLabel* about = new QLabel(i18n("<html>" //copied from kaboutkdedialog_p.cpp
- "You do not have to be a software developer to be a member of the "
- "KDE team. You can join the national teams that translate "
- "program interfaces. You can provide graphics, themes, sounds, and "
- "improved documentation. You decide!"
- "<br /><br />"
- "Visit "
- "<a href=\"%1\">%1</a> "
- "for information on some projects in which you can participate."
- "<br /><br />"
- "If you need more information or documentation, then a visit to "
- "<a href=\"%2\">%2</a> "
- "will provide you with what you need.</html>",
- QLatin1String("http://community.kde.org/Getinvolved"),
- QLatin1String("http://techbase.kde.org/")), welcomeWidget);
- about->setAlignment(Qt::AlignCenter);
- about->setWordWrap(true);
- about->setOpenExternalLinks(true);
- about->setTextInteractionFlags(Qt::TextBrowserInteraction);
- about->setTextFormat(Qt::RichText);
-
- QPushButton* conf = new QPushButton(i18n("&Configure Lokalize..."), welcomeWidget);
- QPushButton* createProject = new QPushButton(i18nc("@action:inmenu","Create new project"), welcomeWidget);
- QPushButton* openProject = new QPushButton(i18nc("@action:inmenu","Open project"), welcomeWidget);
- connect(conf, SIGNAL(clicked(bool)), SettingsController::instance(),SLOT(showSettingsDialog()));
- connect(openProject, SIGNAL(clicked(bool)), this, SIGNAL(projectOpenRequested()));
- connect(createProject, SIGNAL(clicked(bool)), SettingsController::instance(), SLOT(projectCreate()));
- QHBoxLayout* wbtnl=new QHBoxLayout();
- wbtnl->addStretch(1);
- wbtnl->addWidget(conf);
- wbtnl->addWidget(createProject);
- wbtnl->addWidget(openProject);
- wbtnl->addStretch(1);
-
- wl->addStretch(1);
- wl->addWidget(about);
- wl->addStretch(1);
- wl->addLayout(wbtnl);
- wl->addStretch(1);
-
-
-//END setup welcome widget
- QWidget* baseWidget=new QWidget(this);
- m_stackedLayout = new QStackedLayout(baseWidget);
- QWidget* w=new QWidget(this);
- m_stackedLayout->addWidget(welcomeWidget);
- m_stackedLayout->addWidget(w);
- connect(Project::instance(), SIGNAL(loaded()), this, SLOT(showRealProjectOverview()));
- if (Project::instance()->isLoaded()) //for --project cmd option
- showRealProjectOverview();
-
- QVBoxLayout* l=new QVBoxLayout(w);
-
-
- m_filterEdit->setClearButtonShown(true);
- m_filterEdit->setClickMessage(i18n("Quick search..."));
- m_filterEdit->setToolTip(i18nc("@info:tooltip","Activated by Ctrl+L.")+" "+i18nc("@info:tooltip","Accepts regular expressions"));
- connect (m_filterEdit,SIGNAL(textChanged(QString)),this,SLOT(setFilterRegExp()),Qt::QueuedConnection);
- new QShortcut(Qt::CTRL+Qt::Key_L,this,SLOT(setFocus()),0,Qt::WidgetWithChildrenShortcut);
-
- l->addWidget(m_filterEdit);
- l->addWidget(m_browser);
- connect(m_browser,SIGNAL(fileOpenRequested(KUrl)),this,SIGNAL(fileOpenRequested(KUrl)));
- connect(Project::instance()->model(), SIGNAL(totalsChanged(int,int,int,bool)),
- this, SLOT(updateStatusBar(int,int,int,bool)));
- connect(Project::instance()->model(),SIGNAL(loading()),this,SLOT(initStatusBarProgress()));
-
- setCentralWidget(baseWidget);
-
- KHBox *progressBox = new KHBox();
- KStatusBar* statusBar = static_cast<LokalizeSubwindowBase2*>(parent)->statusBar();
-
- m_progressBar = new QProgressBar(progressBox);
- m_progressBar->setVisible(false);
- progressBox->setMinimumWidth(200);
- progressBox->setMaximumWidth(200);
- progressBox->setMaximumHeight(statusBar->sizeHint().height() - 4);
- statusBar->insertWidget(ID_STATUS_PROGRESS, progressBox, 1);
-
- setXMLFile("projectmanagerui.rc",true);
- //QAction* action = KStandardAction::find(Project::instance(),SLOT(showTM()),actionCollection());
-
-#define ADD_ACTION_SHORTCUT_ICON(_name,_text,_shortcut,_icon)\
- action = nav->addAction(_name);\
- action->setText(_text);\
- action->setShortcut(QKeySequence( _shortcut ));\
- action->setIcon(KIcon(_icon));
-
- KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* nav=new KActionCategory(i18nc("@title actions category","Navigation"), ac);
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous not ready"),Qt::CTRL+Qt::SHIFT+Qt::Key_PageUp,"prevfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzyUntr()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next not ready"),Qt::CTRL+Qt::SHIFT+Qt::Key_PageDown,"nextfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzyUntr()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous non-empty but not ready"),Qt::CTRL+Qt::Key_PageUp,"prevfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzy()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next non-empty but not ready"),Qt::CTRL+Qt::Key_PageDown,"nextfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzy()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_untrans",i18nc("@action:inmenu","Previous untranslated"),Qt::ALT+Qt::Key_PageUp,"prevuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevUntranslated()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_untrans",i18nc("@action:inmenu","Next untranslated"),Qt::ALT+Qt::Key_PageDown,"nextuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextUntranslated()));
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_templateOnly",i18nc("@action:inmenu","Previous template only"),Qt::CTRL+Qt::Key_Up,"prevtemplate")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevTemplateOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_templateOnly",i18nc("@action:inmenu","Next template only"),Qt::CTRL+Qt::Key_Down,"nexttemplate")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextTemplateOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_transOnly",i18nc("@action:inmenu","Previous translation only"),Qt::ALT+Qt::Key_Up,"prevpo")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevTransOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_transOnly",i18nc("@action:inmenu","Next translation only"),Qt::ALT+Qt::Key_Down,"nextpo")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextTransOnly()));
-
-
- KActionCategory* proj=new KActionCategory(i18nc("@title actions category","Project"), ac);
-
- action = proj->addAction("project_open",this,SIGNAL(projectOpenRequested()));
- action->setText(i18nc("@action:inmenu","Open project"));
- action->setIcon(KIcon("project-open"));
-
- int i=6;
- while (--i>ID_STATUS_PROGRESS)
- statusBarItems.insert(i,QString());
-
-}
-
-ProjectTab::~ProjectTab()
-{
- //kWarning()<<"destroyed";
-}
-
-void ProjectTab::showRealProjectOverview()
-{
- m_stackedLayout->setCurrentIndex(1);
-}
-
-KUrl ProjectTab::currentUrl()
-{
- return KUrl::fromLocalFile(Project::instance()->projectDir());
-}
-
-void ProjectTab::setFocus()
-{
- m_filterEdit->setFocus();
- m_filterEdit->selectAll();
-}
-
-void ProjectTab::setFilterRegExp()
-{
- QString newPattern=m_filterEdit->text();
- if (m_browser->proxyModel()->filterRegExp().pattern()==newPattern)
- return;
-
- m_browser->proxyModel()->setFilterRegExp(newPattern);
- if (newPattern.size()>2)
- m_browser->expandItems();
-}
-
-void ProjectTab::contextMenuEvent(QContextMenuEvent *event)
-{
- QMenu* menu=new QMenu(this);
- connect(menu,SIGNAL(aboutToHide()),menu,SLOT(deleteLater()));
-
- if (m_browser->currentIsTranslationFile())
- {
- menu->addAction(i18nc("@action:inmenu","Open"),this,SLOT(openFile()));
- menu->addSeparator();
- }
- /*menu.addAction(i18nc("@action:inmenu","Find in files"),this,SLOT(findInFiles()));
- menu.addAction(i18nc("@action:inmenu","Replace in files"),this,SLOT(replaceInFiles()));
- menu.addAction(i18nc("@action:inmenu","Spellcheck files"),this,SLOT(spellcheckFiles()));
- menu.addSeparator();
- menu->addAction(i18nc("@action:inmenu","Get statistics for subfolders"),m_browser,SLOT(expandItems()));
- */
- menu->addAction(i18nc("@action:inmenu","Add to translation memory"),this,SLOT(scanFilesToTM()));
-
- menu->addAction(i18nc("@action:inmenu","Search in files"),this,SLOT(searchInFiles()));
- if (QFileInfo(Project::instance()->templatesRoot()).exists())
- menu->addAction(i18nc("@action:inmenu","Search in files (including templates)"),this,SLOT(searchInFilesInclTempl()));
-
-// else if (Project::instance()->model()->hasChildren(/*m_proxyModel->mapToSource(*/(m_browser->currentIndex()))
-// )
-// {
-// menu.addSeparator();
-// menu.addAction(i18n("Force Scanning"),this,SLOT(slotForceStats()));
-//
-// }
-
- menu->popup(event->globalPos());
-}
-
-
-void ProjectTab::scanFilesToTM()
-{
- QList<QUrl> urls;
- foreach(const KUrl& url, m_browser->selectedItems())
- urls.append(url);
- TM::scanRecursive(urls,Project::instance()->projectID());
-}
-
-void ProjectTab::searchInFiles(bool templ)
-{
- QStringList files;
- foreach(const KUrl& url, m_browser->selectedItems())
- files.append(url.toLocalFile());
-
- if (!templ)
- {
- QString templatesRoot=Project::instance()->templatesRoot();
- int i=files.size();
- while(--i>=0)
- {
- if (files.at(i).startsWith(templatesRoot))
- files.removeAt(i);
- }
- }
-
- emit searchRequested(files);
-}
-
-void ProjectTab::searchInFilesInclTempl()
-{
- searchInFiles(true);
-}
-
-void ProjectTab::openFile() {emit fileOpenRequested(m_browser->currentItem());}
-void ProjectTab::findInFiles() {emit searchRequested(m_browser->selectedItems());}
-void ProjectTab::replaceInFiles() {emit replaceRequested(m_browser->selectedItems());}
-void ProjectTab::spellcheckFiles(){emit spellcheckRequested(m_browser->selectedItems());}
-
-void ProjectTab::gotoPrevFuzzyUntr() {m_browser->gotoPrevFuzzyUntr();}
-void ProjectTab::gotoNextFuzzyUntr() {m_browser->gotoNextFuzzyUntr();}
-void ProjectTab::gotoPrevFuzzy() {m_browser->gotoPrevFuzzy();}
-void ProjectTab::gotoNextFuzzy() {m_browser->gotoNextFuzzy();}
-void ProjectTab::gotoPrevUntranslated() {m_browser->gotoPrevUntranslated();}
-void ProjectTab::gotoNextUntranslated() {m_browser->gotoNextUntranslated();}
-void ProjectTab::gotoPrevTemplateOnly() {m_browser->gotoPrevTemplateOnly();}
-void ProjectTab::gotoNextTemplateOnly() {m_browser->gotoNextTemplateOnly();}
-void ProjectTab::gotoPrevTransOnly() {m_browser->gotoPrevTransOnly();}
-void ProjectTab::gotoNextTransOnly() {m_browser->gotoNextTransOnly();}
-
-bool ProjectTab::currentItemIsTranslationFile() const {return m_browser->currentIsTranslationFile();}
-void ProjectTab::setCurrentItem(const QString& url){m_browser->setCurrentItem(KUrl::fromLocalFile(url));}
-QString ProjectTab::currentItem() const {return m_browser->currentItem().toLocalFile();}
-QStringList ProjectTab::selectedItems() const
-{
- QStringList result;
- foreach (const KUrl& url, m_browser->selectedItems())
- result.append(url.toLocalFile());
- return result;
-}
-
-void ProjectTab::updateStatusBar(int fuzzy, int translated, int untranslated, bool done)
-{
- int total = fuzzy + translated + untranslated;
- m_currentUnitsCount = total;
-
- if (m_progressBar->value() != total && m_legacyUnitsCount > 0)
- m_progressBar->setValue(total);
- if (m_progressBar->maximum() < qMax(total,m_legacyUnitsCount))
- m_progressBar->setMaximum(qMax(total,m_legacyUnitsCount));
- m_progressBar->setVisible(!done);
- if (done)
- m_legacyUnitsCount = total;
-
- statusBarItems.insert(ID_STATUS_TOTAL, i18nc("@info:status message entries","Total: %1", total));
- reflectNonApprovedCount(fuzzy, total);
- reflectUntranslatedCount(untranslated, total);
-}
-
-void ProjectTab::initStatusBarProgress()
-{
- if (m_legacyUnitsCount > 0)
- {
- if (m_progressBar->value() != 0)
- m_progressBar->setValue(0);
- if (m_progressBar->maximum() != m_legacyUnitsCount)
- m_progressBar->setMaximum(m_legacyUnitsCount);
- updateStatusBar();
- }
-}
-
-void ProjectTab::setLegacyUnitsCount(int to)
-{
- m_legacyUnitsCount = to;
- m_currentUnitsCount = to;
- initStatusBarProgress();
-}
-
-//bool ProjectTab::isShown() const {return isVisible();}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTTAB_H
-#define PROJECTTAB_H
-
-#include "lokalizesubwindowbase.h"
-
-#include <KMainWindow>
-#include <KUrl>
-
-#include <KXMLGUIClient>
-
-#include <QStackedLayout>
-class ProjectWidget;
-class KLineEdit;
-#include <QContextMenuEvent>
-#include <QProgressBar>
-
-/**
- * Project Overview Tab
- */
-class ProjectTab: public LokalizeSubwindowBase2
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.ProjectOverview")
- //qdbuscpp2xml -m -s projecttab.h -o org.kde.lokalize.ProjectOverview.xml
-
-public:
- ProjectTab(QWidget *parent);
- ~ProjectTab();
-
- void contextMenuEvent(QContextMenuEvent *event);
-
- void hideDocks(){};
- void showDocks(){};
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
- KUrl currentUrl();
-
- int unitsCount(){return m_currentUnitsCount;}
- void setLegacyUnitsCount(int to);
-
-signals:
- void projectOpenRequested(QString path=QString());
-
- void fileOpenRequested(const KUrl&);
-
- void searchRequested(const QStringList&);
- void searchRequested(const KUrl::List&);
- void replaceRequested(const KUrl::List&);
- void spellcheckRequested(const KUrl::List&);
-
-public slots:
- Q_SCRIPTABLE void setCurrentItem(const QString& url);
- Q_SCRIPTABLE QString currentItem() const;
- ///@returns list of selected files recursively
- Q_SCRIPTABLE QStringList selectedItems() const;
- Q_SCRIPTABLE bool currentItemIsTranslationFile() const;
- void showRealProjectOverview();
-
- //Q_SCRIPTABLE bool isShown() const;
-
-private slots:
- void setFilterRegExp();
- void setFocus();
- void scanFilesToTM();
- void searchInFiles(bool templ=false);
- void searchInFilesInclTempl();
- void openFile();
- void findInFiles();
- void replaceInFiles();
- void spellcheckFiles();
-
- void gotoPrevFuzzyUntr();
- void gotoNextFuzzyUntr();
- void gotoPrevFuzzy();
- void gotoNextFuzzy();
- void gotoPrevUntranslated();
- void gotoNextUntranslated();
- void gotoPrevTemplateOnly();
- void gotoNextTemplateOnly();
- void gotoPrevTransOnly();
- void gotoNextTransOnly();
-
- void updateStatusBar(int fuzzy = 0, int translated = 0, int untranslated = 0, bool done = false);
- void initStatusBarProgress();
-
-private:
- ProjectWidget* m_browser;
- KLineEdit* m_filterEdit;
- QProgressBar* m_progressBar;
-
- QStackedLayout *m_stackedLayout;
-
- int m_legacyUnitsCount, m_currentUnitsCount;
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projectwidget.h"
-
-#include "project.h"
-#include "catalog.h"
-
-#include <kdebug.h>
-#include <klocale.h>
-#include <kdirlister.h>
-#include <kstringhandler.h>
-#include <kdirsortfilterproxymodel.h>
-#include <kcolorscheme.h>
-
-#include <QTreeView>
-#include <QTimer>
-
-#include <QtGui/qevent.h>
-#include <QPainter>
-#include <QtGui/qbrush.h>
-#include <QHeaderView>
-#include <QItemDelegate>
-#include <QStyledItemDelegate>
-
-#undef KDE_NO_DEBUG_OUTPUT
-
-
-class PoItemDelegate: public QStyledItemDelegate
-{
-public:
- PoItemDelegate(QObject *parent=0);
- ~PoItemDelegate(){}
- void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-private:
- KColorScheme m_colorScheme;
-};
-
-PoItemDelegate::PoItemDelegate(QObject *parent)
- : QStyledItemDelegate(parent)
- , m_colorScheme(QPalette::Normal)
-{}
-
-QSize PoItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
-{
- QString text=index.data().toString();
- int lineCount=1;
- int nPos=text.indexOf('\n');
- if (nPos==-1)
- nPos=text.size();
- else
- lineCount+=text.count('\n');
- static QFontMetrics metrics(option.font);
- return QSize(metrics.averageCharWidth()*nPos, metrics.height()*lineCount);
-}
-
-void PoItemDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
- if (index.column() != ProjectModel::Graph)
- return QStyledItemDelegate::paint(painter,option,index);
-
- QVariant graphData = index.data(Qt::DisplayRole);
- if (Q_UNLIKELY( !graphData.isValid()))
- {
- painter->fillRect(option.rect,Qt::transparent);
- return;
- }
-
- QRect rect = graphData.toRect();
- int translated = rect.left();
- int untranslated = rect.top();
- int fuzzy = rect.width();
- int total = translated + untranslated + fuzzy;
-
- if (total > 0)
- {
- QBrush brush;
- painter->setPen(Qt::white);
- QRect myRect(option.rect);
-
- if (translated)
- {
- brush=m_colorScheme.foreground(KColorScheme::PositiveText);
- myRect.setWidth(option.rect.width() * translated / total);
- painter->fillRect(myRect, brush);
- }
-
- if (fuzzy)
- {
- brush=m_colorScheme.foreground(KColorScheme::NeutralText);
- myRect.setLeft(myRect.left() + myRect.width());
- myRect.setWidth(option.rect.width() * fuzzy / total);
- painter->fillRect(myRect, brush);
- // painter->drawText(myRect,Qt::AlignRight,QString("%1").arg(data.width()));
- }
-
- if (untranslated)
- brush=m_colorScheme.foreground(KColorScheme::NegativeText);
- myRect.setLeft(myRect.left() + myRect.width());
- myRect.setWidth(option.rect.width() - myRect.left() + option.rect.left());
- painter->fillRect(myRect, brush);
- // painter->drawText(myRect,Qt::AlignRight,QString("%1").arg(data.top()));
- }
- else if (total == -1)
- painter->fillRect(option.rect,Qt::transparent);
- else if (total == 0)
- painter->fillRect(option.rect,QBrush(Qt::gray));
-}
-
-
-
-
-
-class SortFilterProxyModel : public KDirSortFilterProxyModel
-{
-public:
- SortFilterProxyModel(QObject* parent=0)
- : KDirSortFilterProxyModel(parent)
- {
- connect(Project::instance()->model(),SIGNAL(totalsChanged(int,int,int,bool)),this,SLOT(invalidate()));
- }
- ~SortFilterProxyModel(){}
-protected:
- bool lessThan(const QModelIndex& left,
- const QModelIndex& right) const;
- bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-
-};
-
-
-bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-{
-#ifdef _MSC_VER
- return true;
-#endif
-
- bool result=false;
- const QAbstractItemModel* model=sourceModel();
- QModelIndex item=model->index(source_row,0,source_parent);
-/*
- if (model->hasChildren(item))
- model->fetchMore(item);
-*/
- if (item.data(ProjectModel::TotalRole) == 0)
- return false; // Hide rows with no translations
-
- int i=model->rowCount(item);
- while(--i>=0 && !result)
- result=filterAcceptsRow(i,item);
-
- return result || QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
-}
-
-bool SortFilterProxyModel::lessThan(const QModelIndex& left,
- const QModelIndex& right) const
-{
-// kWarning()<<right.column()<<"--"<<left.row()<<right.row()<<left.internalPointer()<<right.internalPointer()<<left.parent().isValid()<<right.parent().isValid();
- //<<left.data().toString()<<right.data().toString()
- ProjectModel* projectModel = static_cast<ProjectModel*>(sourceModel());
- const KFileItem leftFileItem = projectModel->itemForIndex(left);
- const KFileItem rightFileItem = projectModel->itemForIndex(right);
-
- //Code taken from KDirSortFilterProxyModel, as it is not compatible with our model.
- //TODO: make KDirSortFilterProxyModel::subSortLessThan not cast model to KDirModel, but use data() with FileItemRole instead.
-
- // Directories and hidden files should always be on the top, independent
- // from the sort order.
- const bool isLessThan = (sortOrder() == Qt::AscendingOrder);
-
-
-
- if (leftFileItem.isNull() || rightFileItem.isNull())
- {
- kWarning()<<".isNull()";
- return false;
- }
-
- // On our priority, folders go above regular files.
- if (leftFileItem.isDir() && !rightFileItem.isDir()) {
- return isLessThan;
- } else if (!leftFileItem.isDir() && rightFileItem.isDir()) {
- return !isLessThan;
- }
-
- // Hidden elements go before visible ones, if they both are
- // folders or files.
- if (leftFileItem.isHidden() && !rightFileItem.isHidden()) {
- return isLessThan;
- } else if (!leftFileItem.isHidden() && rightFileItem.isHidden()) {
- return !isLessThan;
- }
-
-
- // Hidden elements go before visible ones, if they both are
- // folders or files.
- if (leftFileItem.isHidden() && !rightFileItem.isHidden()) {
- return true;
- } else if (!leftFileItem.isHidden() && rightFileItem.isHidden()) {
- return false;
- }
-
- switch(left.column()) {
- case ProjectModel::FileName:
- return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
- case ProjectModel::Graph:{
- QRect leftRect(left.data(Qt::DisplayRole).toRect());
- QRect rightRect(right.data(Qt::DisplayRole).toRect());
-
- int leftAll=leftRect.left()+leftRect.top()+leftRect.width();
- int rightAll=rightRect.left()+rightRect.top()+rightRect.width();
-
- if (!leftAll || !rightAll)
- return false;
-
- float leftVal=(float)leftRect.left()/leftAll;
- float rightVal=(float)rightRect.left()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- if (leftVal>rightVal)
- return false;
-
- leftVal=(float)leftRect.top()/leftAll;
- rightVal=(float)rightRect.top()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- if (leftVal>rightVal)
- return false;
-
- leftVal=(float)leftRect.width()/leftAll;
- rightVal=(float)rightRect.width()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- return false;
- }
- case ProjectModel::LastTranslator:
- case ProjectModel::SourceDate:
- case ProjectModel::TranslationDate:
- return KStringHandler::naturalCompare(projectModel->data(left).toString(), projectModel->data(right).toString(), sortCaseSensitivity()) < 0;
- case ProjectModel::TotalCount:
- case ProjectModel::TranslatedCount:
- case ProjectModel::UntranslatedCount:
- case ProjectModel::FuzzyCount:
- return projectModel->data(left).toInt() < projectModel->data(right).toInt();
- default:
- return false;
- }
-}
-
-ProjectWidget::ProjectWidget(/*Catalog* catalog, */QWidget* parent)
- : QTreeView(parent)
- , m_proxyModel(new SortFilterProxyModel(this))
-// , m_catalog(catalog)
-{
- PoItemDelegate* delegate=new PoItemDelegate(this);
- setItemDelegate(delegate);
-
- connect(this,SIGNAL(activated(QModelIndex)),this,SLOT(slotItemActivated(QModelIndex)));
-
- m_proxyModel->setSourceModel(Project::instance()->model());
- //m_proxyModel->setDynamicSortFilter(true);
- setModel(m_proxyModel);
- //setModel(Project::instance()->model());
-
- setUniformRowHeights(true);
- setAllColumnsShowFocus(true);
- int widthDefaults[]={6,1,1,1,1,1,4,4};
- int i=sizeof(widthDefaults)/sizeof(int);
- int baseWidth=columnWidth(0);
- while(--i>=0)
- setColumnWidth(i, baseWidth*widthDefaults[i]/2);
-
- setSortingEnabled(true);
- sortByColumn(0, Qt::AscendingOrder);
-
- setSelectionMode(QAbstractItemView::ExtendedSelection);
- setSelectionBehavior(QAbstractItemView::SelectRows);
-// QTimer::singleShot(0,this,SLOT(initLater()));
-
- KConfig config;
- KConfigGroup stateGroup(&config,"ProjectWindow");
- header()->restoreState(QByteArray::fromBase64( stateGroup.readEntry("ListHeaderState", QByteArray()) ));
-}
-
-ProjectWidget::~ProjectWidget()
-{
- KConfig config;
- KConfigGroup stateGroup(&config,"ProjectWindow");
- stateGroup.writeEntry("ListHeaderState",header()->saveState().toBase64());
-
-}
-
-void ProjectWidget::setCurrentItem(const KUrl& u)
-{
- if (u.isEmpty())
- return;
- setCurrentIndex(m_proxyModel->mapFromSource(
- Project::instance()->model()->indexForUrl(u))
- /*,true*/);
-}
-
-KUrl ProjectWidget::currentItem() const
-{
- if (!currentIndex().isValid())
- return KUrl();
- return Project::instance()->model()->itemForIndex(
- m_proxyModel->mapToSource(currentIndex())
- ).url();
-}
-
-bool ProjectWidget::currentIsTranslationFile() const
-{
- //remember 'bout empty state
- return Catalog::extIsSupported(currentItem().path());
-}
-
-
-
-void ProjectWidget::slotItemActivated(const QModelIndex& index)
-{
- if (currentIsTranslationFile())
- {
- ProjectModel * srcModel = static_cast<ProjectModel *>(static_cast<QSortFilterProxyModel*>(m_proxyModel)->sourceModel());
- QModelIndex srcIndex = static_cast<QSortFilterProxyModel*>(m_proxyModel)->mapToSource(index);
- KUrl fileUrl = srcModel->beginEditing(srcIndex);
-
- emit fileOpenRequested(fileUrl);
- }
-}
-
-static void recursiveAdd(KUrl::List& list, const QModelIndex& idx)
-{
- ProjectModel& model=*(Project::instance()->model());
- const KFileItem& item(model.itemForIndex(idx));
- if (item.isDir())
- {
- int j=model.rowCount(idx);
- while (--j>=0)
- {
- const KFileItem& childItem(model.itemForIndex(idx.child(j,0)));
-
- if (childItem.isDir())
- recursiveAdd(list,idx.child(j,0));
- else
- list.prepend(childItem.url());
- }
- }
- else //if (!list.contains(u))
- list.prepend(item.url());
-}
-
-KUrl::List ProjectWidget::selectedItems() const
-{
- KUrl::List list;
- foreach(const QModelIndex& item, selectedIndexes())
- {
- if (item.column()==0)
- recursiveAdd(list,m_proxyModel->mapToSource(item));
- }
-
- return list;
-}
-
-void ProjectWidget::expandItems(const QModelIndex& parent)
-{
- const QAbstractItemModel* m=model();
- expand(parent);
-
- int i=m->rowCount(parent);
- while(--i>=0)
- expandItems(m->index(i,0,parent));
-}
-
-
-bool ProjectWidget::gotoIndexCheck(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role)
-{
- // Check if role is found for this index
- if (currentIndex.isValid()) {
- ProjectModel *srcModel = static_cast<ProjectModel *>(static_cast<QSortFilterProxyModel*>(m_proxyModel)->sourceModel());
- QModelIndex srcIndex = static_cast<QSortFilterProxyModel*>(m_proxyModel)->mapToSource(currentIndex);
- QVariant result = srcModel->data(srcIndex, role);
- return result.isValid() && result.toInt() > 0;
- }
- return false;
-}
-
-QModelIndex ProjectWidget::gotoIndexPrevNext(const QModelIndex& currentIndex, int direction) const
-{
- QModelIndex index = currentIndex;
- QModelIndex sibling;
-
- // Unless first or last sibling reached, continue with previous or next
- // sibling, otherwise continue with previous or next parent
- while (index.isValid())
- {
- sibling = index.sibling(index.row() + direction, index.column());
- if (sibling.isValid())
- return sibling;
- index = index.parent();
- }
- return index;
-}
-
-ProjectWidget::gotoIndexResult ProjectWidget::gotoIndexFind(
- const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction)
-{
- QModelIndex index = currentIndex;
-
- while (index.isValid())
- {
- // Set current index and show it if role is found for this index
- if (gotoIndexCheck(index, role))
- {
- clearSelection();
- setCurrentIndex(index);
- scrollTo(index);
- return gotoIndex_found;
- }
-
- // Handle child recursively if index is not a leaf
- QModelIndex child = index.child((direction == 1) ? 0 : (m_proxyModel->rowCount(index) - 1), index.column());
- if (child.isValid())
- {
- ProjectWidget::gotoIndexResult result = gotoIndexFind(child, role, direction);
- if (result != gotoIndex_notfound)
- return result;
- }
-
- // Go to previous or next item
- index = gotoIndexPrevNext(index, direction);
- }
- if (index.parent().isValid())
- return gotoIndex_notfound;
- else
- return gotoIndex_end;
-}
-
-ProjectWidget::gotoIndexResult ProjectWidget::gotoIndex(
- const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction)
-{
- QModelIndex index = currentIndex;
-
- // Check if current index already found, and if so go to previous or next item
- if (gotoIndexCheck(index, role))
- index = gotoIndexPrevNext(index, direction);
-
- return gotoIndexFind(index, role, direction);
-}
-
-void ProjectWidget::gotoPrevFuzzyUntr() {gotoIndex(currentIndex(), ProjectModel::FuzzyUntrCountRole, -1);}
-void ProjectWidget::gotoNextFuzzyUntr() {gotoIndex(currentIndex(), ProjectModel::FuzzyUntrCountRole, +1);}
-void ProjectWidget::gotoPrevFuzzy() {gotoIndex(currentIndex(), ProjectModel::FuzzyCountRole, -1);}
-void ProjectWidget::gotoNextFuzzy() {gotoIndex(currentIndex(), ProjectModel::FuzzyCountRole, +1);}
-void ProjectWidget::gotoPrevUntranslated() {gotoIndex(currentIndex(), ProjectModel::UntransCountRole, -1);}
-void ProjectWidget::gotoNextUntranslated() {gotoIndex(currentIndex(), ProjectModel::UntransCountRole, +1);}
-void ProjectWidget::gotoPrevTemplateOnly() {gotoIndex(currentIndex(), ProjectModel::TemplateOnlyRole, -1);}
-void ProjectWidget::gotoNextTemplateOnly() {gotoIndex(currentIndex(), ProjectModel::TemplateOnlyRole, +1);}
-void ProjectWidget::gotoPrevTransOnly() {gotoIndex(currentIndex(), ProjectModel::TransOnlyRole, -1);}
-void ProjectWidget::gotoNextTransOnly() {gotoIndex(currentIndex(), ProjectModel::TransOnlyRole, +1);}
-
-QSortFilterProxyModel* ProjectWidget::proxyModel(){return m_proxyModel;}
-
-#include "moc_projectwidget.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTWIDGET_H
-#define PROJECTWIDGET_H
-
-#include <kurl.h>
-
-#include <QTreeView>
-
-#include "projectmodel.h"
-
-class SortFilterProxyModel;
-#include <QSortFilterProxyModel>
-
-/**
- * This class is considered a 'view',
- * and ProjectWindow + ProjectView are its controllers
- * the data is project-wide KDirModel based ProjectModel
- */
-class ProjectWidget: public QTreeView
-{
- Q_OBJECT
-public:
- ProjectWidget(QWidget* parent);
- ~ProjectWidget();
-
- void setCurrentItem(const KUrl&);
- KUrl currentItem() const;
- KUrl::List selectedItems() const;
- bool currentIsTranslationFile() const;
-
- QSortFilterProxyModel* proxyModel();
- void expandItems(const QModelIndex& parent=QModelIndex());
-
- void gotoPrevFuzzyUntr();
- void gotoNextFuzzyUntr();
- void gotoPrevFuzzy();
- void gotoNextFuzzy();
- void gotoPrevUntranslated();
- void gotoNextUntranslated();
- void gotoPrevTemplateOnly();
- void gotoNextTemplateOnly();
- void gotoPrevTransOnly();
- void gotoNextTransOnly();
-
-signals:
- void fileOpenRequested(const KUrl&);
- void newWindowOpenRequested(const KUrl&);
-
-private slots:
- void slotItemActivated(const QModelIndex&);
-
-private:
- enum gotoIndexResult {gotoIndex_end = -1, gotoIndex_notfound = 0, gotoIndex_found = 1};
-
- bool gotoIndexCheck(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role);
- QModelIndex gotoIndexPrevNext(const QModelIndex& currentIndex, int direction) const;
- gotoIndexResult gotoIndexFind(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction);
- gotoIndexResult gotoIndex(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction);
-
- QWidget* m_parent;
- SortFilterProxyModel* m_proxyModel;
-};
-
-
-
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
- <kcfgfile arg="true"/>
- <include>klocale.h</include>
- <include>kde-i18n-lists.h</include>
- <group name="General">
- <entry name="ProjectID" type="String">
- <default>default</default>
- </entry>
- <entry name="Kind" type="String">
- <default>kde</default>
- </entry>
- <entry name="LangCode" type="String">
-<!--
- <label>Language</label>
-
- <default code="true">KGlobal::locale()->language()</default>
--->
- </entry>
- <entry name="TargetLangCode" type="String">
- </entry>
- <entry name="SourceLangCode" type="String">
- <default>en_US</default>
- </entry>
- <entry name="MailingList" type="String">
- <default code="true">getMailingList()</default>
- </entry>
- <entry name="PoBaseDir" type="String">
-<!--
- <label>The base directory for PO files (translations)</label>
--->
- <default>./</default>
- </entry>
- <entry name="PotBaseDir" type="String">
-<!--
- <label>The base directory for POT files (templates to be translated)</label>
--->
- <default>../templates</default>
- </entry>
- <entry name="BranchDir" type="String"></entry>
- <entry name="AltDir" type="String"></entry>
- <entry name="GlossaryTbx" type="String">
-<!--
- <label>Project's glossary</label>
--->
- <default>./terms.tbx</default>
- </entry>
- <entry name="MainQA" type="String">
- <default>./main.lqa</default>
- </entry>
- </group>
- <group name="RegExps">
- <entry name="Accel" type="String">
- <default>&</default>
-<!--
- <default>(&)[^(\w+;)]</default>
--->
- </entry>
- <entry name="Markup" type="String">
- <default>(<[^>]+>)+|(&[A-Za-z_:][A-Za-z0-9_\.:-]*;)+</default>
- </entry>
- <entry name="WordWrap" type="Int">
- <default>80</default>
- </entry>
- </group>
-</kcfg>
+++ /dev/null
-File=projectbase.kcfg
-ClassName=ProjectBase
-Singleton=false
-Mutators=true
-GlobalEnums=true
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
- http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
- <kcfgfile arg="true"/>
- <group name="Personal">
- <entry name="Role" type="Enum">
- <choices name="PersonRole">
- <choice name="Translator" />
- <choice name="Reviewer" />
- <choice name="Approver" />
- <choice name="Undefined" />
- </choices>
- <default>Approver</default>
- </entry>
- <entry name="FirstRun" type="Bool">
- <default>true</default>
- </entry>
- </group>
-</kcfg>
+++ /dev/null
-File=projectlocal.kcfg
-ClassName=ProjectLocal
-Singleton=false
-Mutators=true
-GlobalEnums=true
-UseEnumTypes=true
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="ProjectOverview" version="3">
-<MenuBar>
- <Menu name="go"><text>&Go</text>
- <Action name="go_prev_fuzzyUntr"/>
- <Action name="go_next_fuzzyUntr"/>
- <Action name="go_prev_fuzzy"/>
- <Action name="go_next_fuzzy"/>
- <Action name="go_prev_untrans"/>
- <Action name="go_next_untrans"/>
- <Separator/>
- <Action name="go_prev_templateOnly"/>
- <Action name="go_next_templateOnly"/>
- <Action name="go_prev_transOnly"/>
- <Action name="go_next_transOnly"/>
- </Menu>
-</MenuBar>
-<ToolBar name="mainToolBar"><text>Main Toolbar</text>
- <Action name="project_open"/>
- <Separator/>
- <Action name="go_prev_fuzzyUntr"/>
- <Action name="go_next_fuzzyUntr"/>
-</ToolBar>
-</kpartgui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2009 by Viesturs Zarins <viesturs.zarins@mii.lu.lv>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projectmodel.h"
-#include "project.h"
-
-#include <threadweaver/ThreadWeaver.h>
-#include <threadweaver/Thread.h>
-
-#include <kio/netaccess.h>
-#include <klocale.h>
-#include <kapplication.h>
-#include <kstandarddirs.h>
-
-#include <QtCore/qdatetime.h>
-#include <QFile>
-#include <QtCore/qalgorithms.h>
-#include <QTimer>
-#include <QSqlDatabase>
-#include <QSqlQuery>
-#include <QSqlError>
-
-#undef KDE_NO_DEBUG_OUTPUT
-static int nodeCounter=0;
-
-//TODO: figure out how to handle file and folder renames...
-//TODO: fix behavior on folder removing, adding.
-
-
-ProjectModel::ProjectModel(QObject *parent)
- : QAbstractItemModel(parent)
- , m_poModel(this)
- , m_potModel(this)
- , m_rootNode(ProjectNode(NULL, -1, -1, -1))
- , m_dirIcon(KIcon(QLatin1String("inode-directory")))
- , m_poIcon(KIcon(QLatin1String("flag-blue")))
- , m_poComplIcon(KIcon(QLatin1String("flag-green")))
- , m_potIcon(KIcon(QLatin1String("flag-black")))
- , m_activeJob(NULL)
- , m_activeNode(NULL)
- , m_weaver(new ThreadWeaver::Weaver())
- , m_completeScan(true)
-{
- m_weaver->setMaximumNumberOfThreads(1);
-
- m_poModel.dirLister()->setAutoErrorHandlingEnabled(false, NULL);
- m_poModel.dirLister()->setNameFilter("*.po *.pot *.xlf");
-
- m_potModel.dirLister()->setAutoErrorHandlingEnabled(false, NULL);
- m_potModel.dirLister()->setNameFilter("*.pot");
-
- connect(&m_poModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(po_dataChanged(QModelIndex,QModelIndex)));
-
- connect(&m_poModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(po_rowsInserted(QModelIndex,int,int)));
-
- connect(&m_poModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(po_rowsRemoved(QModelIndex,int,int)));
-
- connect(&m_potModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this, SLOT(pot_dataChanged(QModelIndex,QModelIndex)));
-
- connect(&m_potModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
- this, SLOT(pot_rowsInserted(QModelIndex,int,int)));
-
- connect(&m_potModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
- this, SLOT(pot_rowsRemoved(QModelIndex,int,int)));
-
- m_doneTimer = new QTimer();
- m_doneTimer->setSingleShot(true);
- connect(m_doneTimer, SIGNAL(timeout()), this, SLOT(updateTotalsChanged()));
-
- setUrl(KUrl(), KUrl());
-}
-
-
-ProjectModel::~ProjectModel()
-{
- m_dirsWaitingForMetadata.clear();
-
- if (m_activeJob != NULL)
- m_activeJob->setStatus(-2);
-
- m_activeJob = NULL;
-
- for (int pos = 0; pos < m_rootNode.rows.count(); pos ++)
- deleteSubtree(m_rootNode.rows.at(pos));
-}
-
-void ProjectModel::setUrl(const KUrl &poUrl, const KUrl &potUrl)
-{
- //kDebug() << "ProjectModel::openUrl("<< poUrl.pathOrUrl() << +", " << potUrl.pathOrUrl() << ")";
-
- //cleanup old data
-
- m_dirsWaitingForMetadata.clear();
-
- if (m_activeJob != NULL)
- m_activeJob->setStatus(-1);
- m_activeJob = NULL;
-
- if (m_rootNode.rows.count())
- {
- beginRemoveRows(QModelIndex(), 0, m_rootNode.rows.count());
-
- for (int pos = 0; pos < m_rootNode.rows.count(); pos ++)
- deleteSubtree(m_rootNode.rows.at(pos));
- m_rootNode.rows.clear();
- m_rootNode.poCount = 0;
- m_rootNode.translated = -1;
- m_rootNode.translated_reviewer = -1;
- m_rootNode.translated_approver = -1;
- m_rootNode.untranslated = -1;
- m_rootNode.fuzzy = -1;
- m_rootNode.fuzzy_reviewer = -1;
- m_rootNode.fuzzy_approver = -1;
-
- endRemoveRows();
- }
-
- //add trailing slashes to base URLs, needed for potToPo and poToPot
- m_poUrl = poUrl;
- m_potUrl = potUrl;
- m_poUrl.adjustPath(KUrl::AddTrailingSlash);
- m_potUrl.adjustPath(KUrl::AddTrailingSlash);
-
- emit loading();
-
- if (!poUrl.isEmpty())
- m_poModel.dirLister()->openUrl(m_poUrl, KDirLister::Reload);
- if (!potUrl.isEmpty())
- m_potModel.dirLister()->openUrl(m_potUrl, KDirLister::Reload);
-}
-
-
-KUrl ProjectModel::beginEditing(const QModelIndex& index)
-{
- Q_ASSERT(index.isValid());
-
- QModelIndex poIndex = poIndexForOuter(index);
- QModelIndex potIndex = potIndexForOuter(index);
-
- if (poIndex.isValid())
- {
- KFileItem item = m_poModel.itemForIndex(poIndex);
- return item.url();
- }
- else if (potIndex.isValid())
- {
- //copy over the file
- KUrl potFile = m_potModel.itemForIndex(potIndex).url();
- KUrl poFile = potToPo(potFile);
-
- //EditorTab::fileOpen takes care of this
- //be careful, copy only if file does not exist already.
- // if (!KIO::NetAccess::exists(poFile, KIO::NetAccess::DestinationSide, NULL))
- // KIO::NetAccess::file_copy(potFile, poFile);
-
- return poFile;
- }
- else
- {
- Q_ASSERT(false);
- return KUrl();
- }
-}
-
-//Theese methds update the combined model from POT and PO model changes.
-//Quite complex stuff here, better do not change anything.
-
-void ProjectModel::po_dataChanged(const QModelIndex& po_topLeft, const QModelIndex& po_bottomRight)
-{
- //nothing special here
- //map from source and propagate
- QModelIndex topLeft = indexForPoIndex(po_topLeft);
- QModelIndex bottomRight = indexForPoIndex(po_bottomRight);
-
- emit dataChanged(topLeft, bottomRight);
-
- enqueueNodeForMetadataUpdate(nodeForIndex(topLeft.parent()));
-}
-
-void ProjectModel::pot_dataChanged(const QModelIndex& pot_topLeft, const QModelIndex& pot_bottomRight)
-{
- //tricky here - some of the pot items may be represented by po items
- //let's propagate that all subitems changed
-
-
- QModelIndex pot_parent = pot_topLeft.parent();
- QModelIndex parent = indexForPotIndex(pot_parent);
-
- ProjectNode* node = nodeForIndex(parent);
- int count = node->rows.count();
-
- QModelIndex topLeft = index(0, pot_topLeft.column(), parent);
- QModelIndex bottomRight = index(count-1, pot_bottomRight.column(), parent);
-
- emit dataChanged(topLeft, bottomRight);
-
- enqueueNodeForMetadataUpdate(nodeForIndex(topLeft.parent()));
-}
-
-
-void ProjectModel::po_rowsInserted(const QModelIndex& po_parent, int first, int last)
-{
- QModelIndex parent = indexForPoIndex(po_parent);
- QModelIndex pot_parent = potIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
-
- //insert po rows
- beginInsertRows(parent, first, last);
-
- for (int pos = first; pos <= last; pos ++)
- {
- ProjectNode * childNode = new ProjectNode(node, pos, pos, -1);
- node->rows.insert(pos, childNode);
- }
-
- node->poCount += last - first + 1;
-
- //update rowNumber
- for (int pos = last + 1; pos < node->rows.count(); pos++)
- node->rows[pos]->rowNumber = pos;
-
- endInsertRows();
-
- //remove unneeded pot rows, update PO rows
- if (pot_parent.isValid() || !parent.isValid())
- {
- QVector<int> pot2PoMapping;
- generatePOTMapping(pot2PoMapping, po_parent, pot_parent);
-
- for (int pos = node->poCount; pos < node->rows.count(); pos ++)
- {
- ProjectNode* potNode = node->rows.at(pos);
- int potIndex = potNode->potRowNumber;
- int poIndex = pot2PoMapping[potIndex];
-
- if (poIndex != -1)
- {
- //found pot node, that now has a PO index.
- //remove the pot node and change the corresponding PO node
- beginRemoveRows(parent, pos, pos);
- node->rows.remove(pos);
- deleteSubtree(potNode);
- endRemoveRows();
-
- node->rows[poIndex]->potRowNumber = potIndex;
- //This change does not need notification
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
-
- pos--;
- }
- }
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-void ProjectModel::pot_rowsInserted(const QModelIndex& pot_parent, int start, int end)
-{
- QModelIndex parent = indexForPotIndex(pot_parent);
- QModelIndex po_parent = poIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
-
- int insertedCount = end + 1 - start;
- QVector<int> newPotNodes;
-
- if (po_parent.isValid() || !parent.isValid())
- {
- //this node containts mixed items - add and merge the stuff
-
- QVector<int> pot2PoMapping;
- generatePOTMapping(pot2PoMapping, po_parent, pot_parent);
-
- //reassign affected PO row POT indices
- for (int pos = 0; pos < node->poCount;pos ++)
- {
- ProjectNode* n=node->rows[pos];
- if (n->potRowNumber >= start)
- n->potRowNumber += insertedCount;
- }
-
- //assign new POT indices
- for (int potIndex = start; potIndex <= end; potIndex ++)
- {
- int poIndex = pot2PoMapping[potIndex];
- if (poIndex != -1)
- {
- //found pot node, that has a PO index.
- //change the corresponding PO node
- node->rows[poIndex]->potRowNumber = potIndex;
- //This change does not need notification
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
- }
- else
- newPotNodes.append(potIndex);
- }
- }
- else
- {
- for (int pos = start; pos < end; pos ++)
- newPotNodes.append(pos);
- }
-
- //insert standalone POT rows, preserving POT order
-
- int newNodesCount = newPotNodes.count();
- if (newNodesCount)
- {
- int insertionPoint = node->poCount;
- while ((insertionPoint < node->rows.count()) && (node->rows[insertionPoint]->potRowNumber < start))
- insertionPoint++;
-
- beginInsertRows(parent, insertionPoint, insertionPoint + newNodesCount - 1);
-
- for (int pos = 0; pos < newNodesCount; pos ++)
- {
- int potIndex = newPotNodes.at(pos);
- ProjectNode * childNode = new ProjectNode(node, insertionPoint, -1, potIndex);
- node->rows.insert(insertionPoint, childNode);
- insertionPoint++;
- }
-
- //renumber remaining POT rows
- for (int pos = insertionPoint; pos < node->rows.count(); pos ++)
- {
- node->rows[pos]->rowNumber = pos;
- node->rows[pos]->potRowNumber += insertedCount;
- }
-
- endInsertRows();
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-void ProjectModel::po_rowsRemoved(const QModelIndex& po_parent, int start, int end)
-{
- QModelIndex parent = indexForPoIndex(po_parent);
- QModelIndex pot_parent = potIndexForOuter(parent);
- ProjectNode* node = nodeForIndex(parent);
- int removedCount = end + 1 - start;
-
- if ((!parent.isValid()) && (node->rows.count() == 0))
- {
- //events after removing entire contents
- return;
- }
-
- //remove PO rows
- QList<int> potRowsToInsert;
-
- beginRemoveRows(parent, start, end);
-
- //renumber all rows after removed.
- for (int pos = end + 1; pos < node->rows.count(); pos ++)
- {
- ProjectNode* childNode = node->rows.at(pos);
- childNode->rowNumber -= removedCount;
-
- if (childNode->poRowNumber > end)
- node->rows[pos]->poRowNumber -= removedCount;
- }
-
- //remove
- for (int pos = end; pos >= start; pos --)
- {
- int potIndex = node->rows.at(pos)->potRowNumber;
- deleteSubtree(node->rows.at(pos));
- node->rows.remove(pos);
-
- if (potIndex != -1)
- potRowsToInsert.append(potIndex);
- }
-
-
- node->poCount -= removedCount;
-
- endRemoveRows(); //< fires removed event - the list has to be consistent now
-
- //add back rows that have POT files and fix row order
- qSort(potRowsToInsert.begin(), potRowsToInsert.end());
-
- int insertionPoint = node->poCount;
-
- for (int pos = 0; pos < potRowsToInsert.count(); pos ++)
- {
- int potIndex = potRowsToInsert.at(pos);
- while (insertionPoint < node->rows.count() && node->rows[insertionPoint]->potRowNumber < potIndex)
- {
- node->rows[insertionPoint]->rowNumber = insertionPoint;
- insertionPoint ++;
- }
-
- beginInsertRows(parent, insertionPoint, insertionPoint);
-
- ProjectNode * childNode = new ProjectNode(node, insertionPoint, -1, potIndex);
- node->rows.insert(insertionPoint, childNode);
- insertionPoint++;
- endInsertRows();
- }
-
- //renumber remaining rows
- while (insertionPoint < node->rows.count())
- {
- node->rows[insertionPoint]->rowNumber = insertionPoint;
- insertionPoint++;
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-void ProjectModel::pot_rowsRemoved(const QModelIndex& pot_parent, int start, int end)
-{
- QModelIndex parent = indexForPotIndex(pot_parent);
- QModelIndex po_parent = poIndexForOuter(parent);
- ProjectNode * node = nodeForIndex(parent);
- int removedCount = end + 1 - start;
-
- if ((!parent.isValid()) && (node->rows.count() == 0))
- {
- //events after removing entire contents
- return;
- }
-
- //First remove POT nodes
-
- int firstPOTToRemove = node->poCount;
- int lastPOTToRemove = node->rows.count() - 1;
-
- while (firstPOTToRemove <= lastPOTToRemove && node->rows[firstPOTToRemove]->potRowNumber < start)
- firstPOTToRemove ++;
- while (lastPOTToRemove >= firstPOTToRemove && node->rows[lastPOTToRemove]->potRowNumber > end)
- lastPOTToRemove --;
-
- if (firstPOTToRemove <= lastPOTToRemove)
- {
- beginRemoveRows(parent, firstPOTToRemove, lastPOTToRemove);
-
- for (int pos = lastPOTToRemove; pos >= firstPOTToRemove; pos --)
- {
- ProjectNode* childNode = node->rows.at(pos);
- Q_ASSERT(childNode->potRowNumber >= start);
- Q_ASSERT(childNode->potRowNumber <= end);
- deleteSubtree(childNode);
- node->rows.remove(pos);
- }
-
- //renumber remaining rows
- for (int pos = firstPOTToRemove; pos < node->rows.count(); pos ++)
- {
- node->rows[pos]->rowNumber = pos;
- node->rows[pos]->potRowNumber -= removedCount;
- }
-
- endRemoveRows();
- }
-
- //now remove POT indices form PO rows
-
- if (po_parent.isValid() || !parent.isValid())
- {
- for (int poIndex = 0; poIndex < node->poCount; poIndex ++)
- {
- ProjectNode * childNode = node->rows[poIndex];
- int potIndex = childNode->potRowNumber;
-
- if (potIndex >= start && potIndex <= end)
- {
- //found PO node, that has a POT index in range.
- //change the corresponding PO node
- node->rows[poIndex]->potRowNumber = -1;
- //this change does not affect the model
- //dataChanged(index(poIndex, 0, parent), index(poIndex, ProjectModelColumnCount, parent));
- }
- else if (childNode->potRowNumber > end)
- {
- //reassign POT indices
- childNode->potRowNumber -= removedCount;
- }
- }
- }
-
- enqueueNodeForMetadataUpdate(node);
-}
-
-
-int ProjectModel::columnCount(const QModelIndex& /*parent*/)const
-{
- return ProjectModelColumnCount;
-}
-
-
-QVariant ProjectModel::headerData(int section, Qt::Orientation, int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- case FileName: return i18nc("@title:column File name","Name");
- case Graph: return i18nc("@title:column Graphical representation of Translated/Fuzzy/Untranslated counts","Graph");
- case TotalCount: return i18nc("@title:column Number of entries","Total");
- case TranslatedCount: return i18nc("@title:column Number of entries","Translated");
- case FuzzyCount: return i18nc("@title:column Number of entries","Not ready");
- case UntranslatedCount: return i18nc("@title:column Number of entries","Untranslated");
- case TranslationDate: return i18nc("@title:column","Last Translation");
- case SourceDate: return i18nc("@title:column","Template Revision");
- case LastTranslator: return i18nc("@title:column","Last Translator");
- default: return QVariant();
- }
-}
-
-
-Qt::ItemFlags ProjectModel::flags( const QModelIndex & index ) const
-{
- if (index.column() == FileName)
- return Qt::ItemIsSelectable|Qt::ItemIsEnabled;
- else
- return Qt::ItemIsSelectable;
-}
-
-
-int ProjectModel::rowCount ( const QModelIndex & parent /*= QModelIndex()*/ ) const
-{
- return nodeForIndex(parent)->rows.size();
-}
-
-
-bool ProjectModel::hasChildren ( const QModelIndex & parent /*= QModelIndex()*/ ) const
-{
- if (!parent.isValid())
- return true;
-
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- return ((poIndex.isValid() && m_poModel.hasChildren(poIndex)) ||
- (potIndex.isValid() && m_potModel.hasChildren(potIndex)));
-}
-
-bool ProjectModel::canFetchMore ( const QModelIndex & parent ) const
-{
- if (!parent.isValid())
- return m_poModel.canFetchMore(QModelIndex()) || m_potModel.canFetchMore(QModelIndex());
-
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- return ((poIndex.isValid() && m_poModel.canFetchMore(poIndex)) ||
- (potIndex.isValid() && m_potModel.canFetchMore(potIndex)));
-}
-
-void ProjectModel::fetchMore ( const QModelIndex & parent )
-{
- if (!parent.isValid())
- {
- if (m_poModel.canFetchMore(QModelIndex()))
- m_poModel.fetchMore(QModelIndex());
-
- if (m_potModel.canFetchMore(QModelIndex()))
- m_potModel.fetchMore(QModelIndex());
- }
- else
- {
- QModelIndex poIndex = poIndexForOuter(parent);
- QModelIndex potIndex = potIndexForOuter(parent);
-
- if (poIndex.isValid() && (m_poModel.canFetchMore(poIndex)))
- m_poModel.fetchMore(poIndex);
-
- if (potIndex.isValid() && (m_potModel.canFetchMore(potIndex)))
- m_potModel.fetchMore(potIndex);
- }
-}
-
-
-
-/**
- * we use QRect to pass data through QVariant tunnel
- *
- * order is tran, untr, fuzzy
- * left() top() width()
- *
- */
-QVariant ProjectModel::data(const QModelIndex& index, int role) const
-{
- if (!index.isValid())
- return QVariant();
-
- const ProjectModelColumns& column=(ProjectModelColumns)index.column();
- ProjectNode* node = nodeForIndex(index);
- QModelIndex internalIndex = poOrPotIndexForOuter(index);
-
- if (!internalIndex.isValid())
- return QVariant();
-
- KFileItem item=itemForIndex(index);
- bool isDir = item.isDir();
-
- int translated = node->translatedAsPerRole();
- int fuzzy = node->fuzzyAsPerRole();
- int untranslated = node->untranslated;
- bool hasStats = translated != -1;
-
- switch(role)
- {
- case Qt::DisplayRole:
- switch (column)
- {
- case FileName: return item.text();
- case Graph: return hasStats?QRect(translated, untranslated, fuzzy, 0):QVariant();
- case TotalCount: return hasStats?(translated + untranslated + fuzzy):QVariant();
- case TranslatedCount:return hasStats?translated:QVariant();
- case FuzzyCount: return hasStats?fuzzy:QVariant();
- case UntranslatedCount:return hasStats?untranslated:QVariant();
- case SourceDate: return node->sourceDate;
- case TranslationDate:return node->translationDate;
- case LastTranslator:return node->lastTranslator;
- default: return QVariant();
- }
- case Qt::ToolTipRole:
- switch (column)
- {
- case FileName: return item.text();
- default: return QVariant();
- }
- case KDirModel::FileItemRole:
- return QVariant::fromValue(item);
- case Qt::DecorationRole:
- switch (column)
- {
- case FileName:
- if (isDir)
- return m_dirIcon;
- if (hasStats && fuzzy == 0 && untranslated == 0)
- return m_poComplIcon;
- else if (node->poRowNumber != -1)
- return m_poIcon;
- else if (node->potRowNumber != -1)
- return m_potIcon;
- default:
- return QVariant();
- }
- case FuzzyUntrCountRole:
- return item.isFile()?(fuzzy + untranslated):0;
- case FuzzyCountRole:
- return item.isFile()?fuzzy:0;
- case UntransCountRole:
- return item.isFile()?untranslated:0;
- case TemplateOnlyRole:
- return item.isFile()?(node->poRowNumber == -1):0;
- case TransOnlyRole:
- return item.isFile()?(node->potRowNumber == -1):0;
- case TotalRole:
- return hasStats?(fuzzy + untranslated + translated):0;
- default:
- return QVariant();
- }
-}
-
-
-QModelIndex ProjectModel::index(int row, int column, const QModelIndex& parent) const
-{
- ProjectNode* parentNode = nodeForIndex(parent);
- //kWarning()<<(sizeof(ProjectNode))<<nodeCounter;
- if (row>=parentNode->rows.size())
- {
- kWarning()<<"SHIT HAPPENED WITH INDEXES"<<row<<parentNode->rows.size()<<itemForIndex(parent).url();
- return QModelIndex();
- }
- return createIndex(row, column, parentNode->rows.at(row));
-}
-
-
-KFileItem ProjectModel::itemForIndex(const QModelIndex& index) const
-{
- if (!index.isValid())
- {
- //file item for root node.
- return m_poModel.itemForIndex(index);
- }
- QModelIndex poIndex = poIndexForOuter(index);
-
- if (poIndex.isValid())
- return m_poModel.itemForIndex(poIndex);
- else
- {
- QModelIndex potIndex = potIndexForOuter(index);
-
- if (potIndex.isValid())
- return m_potModel.itemForIndex(potIndex);
- }
-
- kWarning()<<"returning empty KFileItem()"<<index.row()<<index.column();
- kWarning()<<"returning empty KFileItem()"<<index.parent().isValid();
- kWarning()<<"returning empty KFileItem()"<<index.parent().internalPointer();
- kWarning()<<"returning empty KFileItem()"<<index.parent().data().toString();
- kWarning()<<"returning empty KFileItem()"<<index.internalPointer();
- kWarning()<<"returning empty KFileItem()"<<static_cast<ProjectNode*>(index.internalPointer())->untranslated<<static_cast<ProjectNode*>(index.internalPointer())->sourceDate;
- return KFileItem();
-}
-
-
-ProjectModel::ProjectNode* ProjectModel::nodeForIndex(const QModelIndex& index) const
-{
- if (index.isValid())
- {
- ProjectNode * node = static_cast<ProjectNode *>(index.internalPointer());
- Q_ASSERT(node != NULL);
- return node;
- }
- else
- {
- ProjectNode * node = const_cast<ProjectNode *>(&m_rootNode);
- Q_ASSERT(node != NULL);
- return node;
- }
-}
-
-
-QModelIndex ProjectModel::indexForNode(const ProjectNode* node)
-{
- if (node == &m_rootNode)
- return QModelIndex();
-
- int row = node->rowNumber;
- QModelIndex index = createIndex(row, 0, (void*)node);
- return index;
-}
-
-QModelIndex ProjectModel::indexForUrl(const KUrl& url)
-{
- if (m_poUrl.isParentOf(url))
- {
- QModelIndex poIndex = m_poModel.indexForUrl(url);
- return indexForPoIndex(poIndex);
- }
- else if (m_potUrl.isParentOf(url))
- {
- QModelIndex potIndex = m_potModel.indexForUrl(url);
- return indexForPotIndex(potIndex);
- }
-
- return QModelIndex();
-}
-
-QModelIndex ProjectModel::parent(const QModelIndex& childIndex) const
-{
- if (!childIndex.isValid())
- return QModelIndex();
-
- ProjectNode* childNode = nodeForIndex(childIndex);
- ProjectNode* parentNode = childNode->parent;
-
- if (!parentNode || (childNode == &m_rootNode) || (parentNode == &m_rootNode))
- return QModelIndex();
-
- return createIndex(parentNode->rowNumber, 0, parentNode);
-}
-
-
-/**
- * Theese methods map from project model indices to PO and POT model indices.
- * In each folder files form PO model comes first, and files from POT that do not exist in PO model come after.
- */
-QModelIndex ProjectModel::indexForOuter(const QModelIndex& outerIndex, IndexType type) const
-{
- if (!outerIndex.isValid())
- return QModelIndex();
-
- QModelIndex parent = outerIndex.parent();
-
- QModelIndex internalParent;
- if (parent.isValid())
- {
- internalParent = indexForOuter(parent, type);
- if (!internalParent.isValid())
- return QModelIndex();
- }
-
- ProjectNode* node = nodeForIndex(outerIndex);
-
- short rowNumber=(type==PoIndex?node->poRowNumber:node->potRowNumber);
- if (rowNumber == -1)
- return QModelIndex();
- return (type==PoIndex?m_poModel:m_potModel).index(rowNumber, outerIndex.column(), internalParent);
-}
-
-QModelIndex ProjectModel::poIndexForOuter(const QModelIndex& outerIndex) const
-{
- return indexForOuter(outerIndex, PoIndex);
-}
-
-
-QModelIndex ProjectModel::potIndexForOuter(const QModelIndex& outerIndex) const
-{
- return indexForOuter(outerIndex, PotIndex);
-}
-
-
-QModelIndex ProjectModel::poOrPotIndexForOuter(const QModelIndex& outerIndex) const
-{
- if (!outerIndex.isValid())
- return QModelIndex();
-
- QModelIndex poIndex = poIndexForOuter(outerIndex);
-
- if (poIndex.isValid())
- return poIndex;
-
- QModelIndex potIndex = potIndexForOuter(outerIndex);
-
- if (!potIndex.isValid())
- kWarning()<<"error mapping index to PO or POT";
-
- return potIndex;
-}
-
-QModelIndex ProjectModel::indexForPoIndex(const QModelIndex& poIndex) const
-{
- if (!poIndex.isValid())
- return QModelIndex();
-
- QModelIndex outerParent = indexForPoIndex(poIndex.parent());
- int row = poIndex.row(); //keep the same row, no changes
-
- return index(row, poIndex.column(), outerParent);
-}
-
-QModelIndex ProjectModel::indexForPotIndex(const QModelIndex& potIndex) const
-{
- if (!potIndex.isValid())
- return QModelIndex();
-
- QModelIndex outerParent = indexForPotIndex(potIndex.parent());
- ProjectNode* node = nodeForIndex(outerParent);
-
- int potRow = potIndex.row();
- int row = 0;
-
- while(row<node->rows.count() && node->rows.at(row)->potRowNumber!=potRow)
- row++;
-
- if (row != node->rows.count())
- return index(row, potIndex.column(), outerParent);
-
- kWarning()<<"error mapping index from POT to outer, searched for potRow:"<<potRow;
- return QModelIndex();
-}
-
-
-/**
- * Makes a list of indices where pot items map to poItems.
- * result[potRow] = poRow or -1 if the pot entry is not found in po.
- * Does not use internal pot and po row number cache.
- */
-void ProjectModel::generatePOTMapping(QVector<int> & result, const QModelIndex& poParent, const QModelIndex& potParent) const
-{
- result.clear();
-
- int poRows = m_poModel.rowCount(poParent);
- int potRows = m_potModel.rowCount(potParent);
-
- if (potRows == 0)
- return;
-
- QList<KUrl> poOccupiedUrls;
-
- for (int poPos = 0; poPos < poRows; poPos ++)
- {
- KFileItem file = m_poModel.itemForIndex(m_poModel.index(poPos, 0, poParent));
- KUrl potUrl = poToPot(file.url());
- poOccupiedUrls.append(potUrl);
- }
-
- for (int potPos = 0; potPos < potRows; potPos ++)
- {
-
- KUrl potUrl = m_potModel.itemForIndex(m_potModel.index(potPos, 0, potParent)).url();
- int occupiedPos = -1;
-
- //TODO: this is slow
- for (int poPos = 0; occupiedPos == -1 && poPos < poOccupiedUrls.count(); poPos ++)
- {
- KUrl& occupiedUrl = poOccupiedUrls[poPos];
- if (potUrl.equals(occupiedUrl))
- occupiedPos = poPos;
- }
-
- result.append(occupiedPos);
- }
-}
-
-
-KUrl ProjectModel::poToPot(const KUrl& poPath) const
-{
- if (!m_poUrl.isParentOf(poPath))
- {
- kWarning()<<"PO path not in project: " << poPath.url();
- return KUrl();
- }
-
- QString pathToAdd = KUrl::relativeUrl(m_poUrl, poPath);
-
- //change ".po" into ".pot"
- if (pathToAdd.endsWith(".po")) //TODO: what about folders ??
- pathToAdd+='t';
-
- KUrl potPath = m_potUrl;
- potPath.addPath(pathToAdd);
-
- //kDebug() << "ProjectModel::poToPot("<< poPath.pathOrUrl() << +") = " << potPath.pathOrUrl();
- return potPath;
-}
-
-KUrl ProjectModel::potToPo(const KUrl& potPath) const
-{
- if (!m_potUrl.isParentOf(potPath))
- {
- kWarning()<<"POT path not in project: " << potPath.url();
- return KUrl();
- }
-
- QString pathToAdd = KUrl::relativeUrl(m_potUrl, potPath);
-
- //change ".pot" into ".po"
- if (pathToAdd.endsWith(".pot")) //TODO: what about folders ??
- pathToAdd = pathToAdd.left(pathToAdd.length() - 1);
-
- KUrl poPath = m_poUrl;
- poPath.addPath(pathToAdd);
-
- //kDebug() << "ProjectModel::potToPo("<< potPath.pathOrUrl() << +") = " << poPath.pathOrUrl();
- return poPath;
-}
-
-
-//Metadata stuff
-//For updating translation stats
-
-void ProjectModel::enqueueNodeForMetadataUpdate(ProjectNode* node)
-{
- m_doneTimer->stop();
-
- if (m_dirsWaitingForMetadata.contains(node))
- {
- if ((m_activeJob != NULL) && (m_activeNode == node))
- m_activeJob->setStatus(-1);
-
- return;
- }
-
- m_dirsWaitingForMetadata.insert(node);
-
- if (m_activeJob == NULL)
- startNewMetadataJob();
-}
-
-
-void ProjectModel::deleteSubtree(ProjectNode* node)
-{
- for (int row = 0; row < node->rows.count(); row ++)
- deleteSubtree(node->rows.at(row));
-
- m_dirsWaitingForMetadata.remove(node);
-
- if ((m_activeJob != NULL) && (m_activeNode == node))
- m_activeJob->setStatus(-1);
-
- delete node;
-}
-
-
-void ProjectModel::startNewMetadataJob()
-{
- if (!m_completeScan) //hack for debugging
- return;
-
- m_activeJob = NULL;
- m_activeNode = NULL;
-
- if (m_dirsWaitingForMetadata.isEmpty())
- return;
-
- ProjectNode* node = *m_dirsWaitingForMetadata.begin();
-
- //prepare new work
- m_activeNode = node;
-
- QList<KFileItem> files;
-
- QModelIndex item = indexForNode(node);
-
- for (int row=0; row < node->rows.count(); row ++)
- files.append(itemForIndex(index(row, 0, item)));
-
- m_activeJob = new UpdateStatsJob(files, this);
- connect(
- m_activeJob,SIGNAL(done(ThreadWeaver::Job*)),
- this,SLOT(finishMetadataUpdate(ThreadWeaver::Job*)));
-
- m_weaver->enqueue(m_activeJob);
-}
-
-void ProjectModel::finishMetadataUpdate(ThreadWeaver::Job * _job)
-{
- UpdateStatsJob* job = static_cast<UpdateStatsJob *>(_job);
-
- if (job->m_status == -2)
- {
- delete job;
- return;
- }
-
- if ((m_dirsWaitingForMetadata.contains(m_activeNode)) && (job->m_status == 0))
- {
- m_dirsWaitingForMetadata.remove(m_activeNode);
- //store the results
-
- setMetadataForDir(m_activeNode, m_activeJob->m_info);
-
- QModelIndex item = indexForNode(m_activeNode);
-
- //scan dubdirs - initiate data loading into the model.
- for (int row=0; row < m_activeNode->rows.count(); row++)
- {
- QModelIndex child = index(row, 0, item);
-
- if (canFetchMore(child))
- fetchMore(child);
- //QCoreApplication::processEvents();
- }
- }
-
- delete m_activeJob;
-
- startNewMetadataJob();
-}
-
-
-void ProjectModel::slotFileSaved(const KUrl& url)
-{
- QModelIndex index = indexForUrl(url);
-
- if (!index.isValid())
- return;
-
- QList<KFileItem> files;
- files.append(itemForIndex(index));
-
- UpdateStatsJob* j = new UpdateStatsJob(files);
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),
- this,SLOT(finishSingleMetadataUpdate(ThreadWeaver::Job*)));
-
- m_weaver->enqueue(j);
-}
-
-void ProjectModel::finishSingleMetadataUpdate(ThreadWeaver::Job* _job)
-{
- UpdateStatsJob* job = static_cast<UpdateStatsJob*>(_job);
-
- if (job->m_status != 0)
- {
- delete job;
- return;
- }
-
- const KFileMetaInfo& info=job->m_info.first();
- QModelIndex index = indexForUrl(info.url());
- if (!index.isValid())
- return;
-
- ProjectNode* node = nodeForIndex(index);
- node->setFileStats(job->m_info.first());
- updateDirStats(nodeForIndex(index.parent()));
-
- QModelIndex topLeft = index.sibling(index.row(), Graph);
- QModelIndex bottomRight = index.sibling(index.row(), ProjectModelColumnCount - 1);
- emit dataChanged(topLeft, bottomRight);
-
- delete job;
-}
-
-void ProjectModel::setMetadataForDir(ProjectNode* node, const QList<KFileMetaInfo>& data)
-{
- int dataCount = data.count();
- int rowsCount = node->rows.count();
- Q_ASSERT(dataCount == rowsCount);
-
- for (int row = 0; row < rowsCount; row ++)
- node->rows[row]->setFileStats(data.at(row));
-
- if (!dataCount)
- return;
-
- updateDirStats(node);
-
- QModelIndex item = indexForNode(node);
- QModelIndex topLeft = index(0, Graph, item);
- QModelIndex bottomRight = index(rowsCount - 1, ProjectModelColumnCount - 1, item);
- emit dataChanged(topLeft, bottomRight);
-}
-
-void ProjectModel::updateDirStats(ProjectNode* node)
-{
- node->calculateDirStats();
- if (node == &m_rootNode)
- {
- updateTotalsChanged();
- return;
- }
-
- updateDirStats(node->parent);
-
- if (node->parent->rows.count()==0 || node->parent->rows.count()>=node->rowNumber)
- return;
- QModelIndex index = indexForNode(node);
- kWarning()<<index.row()<<node->parent->rows.count();
- if (index.row()>=node->parent->rows.count())
- return;
- QModelIndex topLeft = index.sibling(index.row(), Graph);
- QModelIndex bottomRight = index.sibling(index.row(), ProjectModelColumnCount - 1);
- emit dataChanged(topLeft, bottomRight);
-}
-
-bool ProjectModel::updateDone(const QModelIndex& index, const KDirModel& model)
-{
- if (model.canFetchMore(index))
- return false;
-
- int row=model.rowCount(index);
- while (--row>=0)
- {
- if (!updateDone(model.index(row, 0, index), model))
- return false;
- }
- return true;
-}
-
-void ProjectModel::updateTotalsChanged()
-{
- bool done = m_dirsWaitingForMetadata.isEmpty();
- if (done)
- {
- done = updateDone(m_poModel.indexForUrl(m_poUrl), m_poModel) &&
- updateDone(m_potModel.indexForUrl(m_potUrl), m_potModel);
- if (m_rootNode.fuzzyAsPerRole() + m_rootNode.translatedAsPerRole() + m_rootNode.untranslated > 0 && !done)
- m_doneTimer->start(2000);
- }
- emit totalsChanged(m_rootNode.fuzzyAsPerRole(), m_rootNode.translatedAsPerRole(), m_rootNode.untranslated, done);
-}
-
-
-//ProjectNode class
-
-ProjectModel::ProjectNode::ProjectNode(ProjectNode* _parent, int _rowNum, int _poIndex, int _potIndex)
- : parent(_parent)
- , rowNumber(_rowNum)
- , poRowNumber(_poIndex)
- , potRowNumber(_potIndex)
- , poCount(0)
- , translated(-1)
- , translated_reviewer(-1)
- , translated_approver(-1)
- , untranslated(-10)
- , fuzzy(-1)
- , fuzzy_reviewer(-10)
- , fuzzy_approver(-10)
-{
- ++nodeCounter;
-}
-
-ProjectModel::ProjectNode::~ProjectNode()
-{
- --nodeCounter;
-}
-
-void ProjectModel::ProjectNode::calculateDirStats()
-{
- fuzzy = 0;
- fuzzy_reviewer = 0;
- fuzzy_approver = 0;
- translated = 0;
- translated_reviewer = 0;
- translated_approver = 0;
- untranslated = 0;
-
- for (int pos = 0; pos < rows.count(); pos++)
- {
- ProjectNode* child = rows.at(pos);
- if (child->translated != -1)
- {
- fuzzy += child->fuzzy;
- fuzzy_reviewer += child->fuzzy_reviewer;
- fuzzy_approver += child->fuzzy_approver;
- translated += child->translated;
- translated_reviewer += child->translated_reviewer;
- translated_approver += child->translated_approver;
- untranslated += child->untranslated;
- }
- }
-}
-
-
-void ProjectModel::ProjectNode::setFileStats(const KFileMetaInfo& info)
-{
- if (info.keys().count() == 0)
- return;
-
- translated = info.item("translation.translated").value().toInt();
- const QVariant translated_reviewer_variant = info.item("translation.translated_reviewer").value();
- translated_reviewer = translated_reviewer_variant.isValid() ? translated_reviewer_variant.toInt() : translated;
- const QVariant translated_approver_variant = info.item("translation.translated_approver").value();
- translated_approver = translated_approver_variant.isValid() ? translated_approver_variant.toInt() : translated;
- untranslated = info.item("translation.untranslated").value().toInt();
- fuzzy = info.item("translation.fuzzy").value().toInt();
- const QVariant fuzzy_reviewer_variant = info.item("translation.fuzzy_reviewer").value();
- fuzzy_reviewer = fuzzy_reviewer_variant.isValid() ? fuzzy_reviewer_variant.toInt() : fuzzy;
- const QVariant fuzzy_approver_variant = info.item("translation.fuzzy_approver").value();
- fuzzy_approver = fuzzy_approver_variant.isValid() ? fuzzy_approver_variant.toInt() : fuzzy;
- lastTranslator = info.item("translation.last_translator").value().toString();
- sourceDate = info.item("translation.source_date").value().toString();
- translationDate = info.item("translation.translation_date").value().toString();
- lastTranslator.squeeze();
- sourceDate.squeeze();
- translationDate.squeeze();
-}
-
-
-//BEGIN UpdateStatsJob
-//these are run in separate thread
-UpdateStatsJob::UpdateStatsJob(QList<KFileItem> files, QObject* owner)
- : ThreadWeaver::Job(owner)
- , m_files(files)
- , m_status(0)
-{
-}
-
-UpdateStatsJob::~UpdateStatsJob()
-{
-}
-
-static void initDataBase(QSqlDatabase& db)
-{
- QSqlQuery queryMain(db);
- queryMain.exec("PRAGMA encoding = \"UTF-8\"");
- queryMain.exec("CREATE TABLE IF NOT EXISTS metainfo ("
- "filepath INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- //"filepath TEXT UNIQUE ON CONFLICT REPLACE, "
- "metainfo BLOB, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "changedate INTEGER"
- ")");
-
- //queryMain.exec("CREATE INDEX IF NOT EXISTS filepath_index ON metainfo ("filepath)");
-}
-
-
-static KFileMetaInfo cachedMetaInfo(const KFileItem& file)
-{
- QString dbName="metainfocache";
- if (!QSqlDatabase::contains(dbName))
- {
- QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE",dbName);
- db.setDatabaseName(KStandardDirs::locateLocal("appdata", dbName+".sqlite"));
- if (Q_UNLIKELY( !db.open() ))
- return KFileMetaInfo(file.url());
- initDataBase(db);
- }
- QSqlDatabase db=QSqlDatabase::database(dbName);
- if (!db.isOpen())
- return KFileMetaInfo(file.url());
-
- static const QString fields[]={
- "translation.translated",
- "translation.untranslated",
- "translation.fuzzy",
- "translation.last_translator",
- "translation.source_date",
- "translation.translation_date",
- "translation.translated_reviewer",
- "translation.translated_approver",
- "translation.fuzzy_reviewer",
- "translation.fuzzy_approver"
- };
- static const int nFields = sizeof(fields) / sizeof(fields[0]);
-
- QByteArray result;
-
- QSqlQuery queryCache(db);
- queryCache.prepare("SELECT * from metainfo where filepath=?");
- queryCache.bindValue(0, qHash(file.localPath()));
- queryCache.exec();
- if (queryCache.next() && file.time(KFileItem::ModificationTime).dateTime()==queryCache.value(2).toDateTime())
- {
- result=queryCache.value(1).toByteArray();
- QDataStream stream(&result,QIODevice::ReadOnly);
-
- //unfortunately direct KFileMetaInfo << operator doesn't work
- KFileMetaInfo info;
- QVector<QVariant> keys;
- stream>>keys;
- for(int i=0;i<keys.count();i++)
- info.item(fields[i]).setValue(keys.at(i));
- return info;
- }
-
- KFileMetaInfo info(file.url());
-
- QDataStream stream(&result,QIODevice::WriteOnly);
- //this is synced with ProjectModel::ProjectNode::setFileStats
- QVector<QVariant> keys(nFields);
- for(int i=0;i<nFields;i++)
- keys[i] = info.item(fields[i]).value();
- stream<<keys;
-
- QSqlQuery query(db);
-
- query.prepare("INSERT INTO metainfo (filepath, metainfo, changedate) "
- "VALUES (?, ?, ?)");
- query.bindValue(0, qHash(file.localPath()));
- query.bindValue(1, result);
- query.bindValue(2, file.time(KFileItem::ModificationTime).dateTime());
- if (Q_UNLIKELY(!query.exec()))
- qWarning() <<"metainfo cache acquiring error: " <<query.lastError().text();
-
- return info;
-}
-
-void UpdateStatsJob::run()
-{
- static QString dbName="metainfocache";
- bool ok=QSqlDatabase::contains(dbName);
- if (ok)
- {
- QSqlDatabase db=QSqlDatabase::database(dbName);
- QSqlQuery queryBegin("BEGIN",db);
- }
- for (int pos=0; pos<m_files.count(); pos++)
- {
- if (m_status!=0)
- return;
-
- const KFileItem& file=m_files.at(pos);
- KFileMetaInfo info;
-
- if ((!file.isNull()) && (!file.isDir()))
- {
- //force population of metainfo, do not use the KFileItem default behavior
- if (file.metaInfo(false).keys().isEmpty())
- info=cachedMetaInfo(file);
- //info=KFileMetaInfo(file.url());
- else
- info=file.metaInfo(false);
- }
-
- m_info.append(info);
- }
- if (ok)
- {
- QSqlDatabase db=QSqlDatabase::database(dbName);
- {
- //braces are needed to avoid resource leak on close
- QSqlQuery queryEnd("END",db);
- }
- db.close();
- db.open();
- }
-}
-
-void UpdateStatsJob::setStatus(int status)
-{
- m_status=status;
-}
-//END UpdateStatsJob
-
-#include "moc_projectmodel.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2013 by Nick Shaforostoff <shafff@ukr.net>
- Copyright (C) 2009 by Viesturs Zarins <viesturs.zarins@mii.lu.lv>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTMODEL_H
-#define PROJECTMODEL_H
-
-#include <threadweaver/Job.h>
-
-#include <kdirmodel.h>
-#include <kdirlister.h>
-#include <kicon.h>
-#include <QHash>
-#include <QList>
-#include <kdebug.h>
-
-#include "project.h"
-#include "projectlocal.h"
-
-#include <QTimer>
-class UpdateStatsJob;
-namespace ThreadWeaver {class Weaver;}
-
-/**
-* Some notes:
-* Uses two KDirModels for template and translations dir.
-* Listens to their signals and constructs a combined model.
-* Stats calculation:
-* Uses threadweawer for stats calculation.
-* Each job analyzes files in one dir and adds subdirs to queue.
-* A change in one file forces whole dir to be rescanned
-* The job priority needs some tweaking.
- */
-class ProjectModel: public QAbstractItemModel
-{
- Q_OBJECT
-
- class ProjectNode
- {
- public:
- ProjectNode(ProjectNode* parent, int rowNum, int poIndex, int potIndex);
- ~ProjectNode();
- void calculateDirStats();
- void setFileStats(const KFileMetaInfo& info);
-
- int translatedAsPerRole() const
- {
- switch (Project::local()->role())
- {
- case ProjectLocal::Translator:
- case ProjectLocal::Undefined:
- return translated;
- case ProjectLocal::Reviewer:
- return translated_reviewer;
- case ProjectLocal::Approver:
- return translated_approver;
- }
- return -1;
- }
-
- int fuzzyAsPerRole() const
- {
- switch (Project::local()->role())
- {
- case ProjectLocal::Translator:
- case ProjectLocal::Undefined:
- return fuzzy;
- case ProjectLocal::Reviewer:
- return fuzzy_reviewer;
- case ProjectLocal::Approver:
- return fuzzy_approver;
- }
- return -1;
- }
-
- ProjectNode* parent;
- short rowNumber; //in parent's list
-
- short poRowNumber; //row number in po model, -1 if this has no po item.
- short potRowNumber; //row number in pot model, -1 if this has no pot item.
-
- short poCount; //number of items from PO in rows. The others will be form POT exclusively.
- QVector<ProjectNode*> rows; //rows from po and pot, pot rows start from poCount;
-
- int translated;
- int translated_reviewer;
- int translated_approver;
- int untranslated;
- int fuzzy;
- int fuzzy_reviewer;
- int fuzzy_approver;
- QString sourceDate;
- QString lastTranslator;
- QString translationDate;
- };
-
-
-public:
-
- enum ProjectModelColumns
- {
- FileName,
- Graph,
- TotalCount,
- TranslatedCount,
- FuzzyCount,
- UntranslatedCount,
- SourceDate,
- TranslationDate,
- LastTranslator,
- ProjectModelColumnCount
- };
-
- enum AdditionalRoles {
- FuzzyUntrCountRole = Qt::UserRole,
- FuzzyCountRole,
- UntransCountRole,
- TemplateOnlyRole,
- TransOnlyRole,
- TotalRole
- };
-
- ProjectModel(QObject *parent);
- ~ProjectModel();
-
- void setUrl(const KUrl &poUrl, const KUrl &potUrl);
- QModelIndex indexForUrl(const KUrl& url);
- KFileItem itemForIndex(const QModelIndex& index) const;
- KUrl beginEditing(const QModelIndex& index); //copies POT file to PO file and returns url of the PO file
-
- // QAbstractItemModel methods
- int columnCount(const QModelIndex& parent = QModelIndex()) const;
- QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
- Qt::ItemFlags flags(const QModelIndex& index) const;
-
- QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const;
- QModelIndex parent(const QModelIndex& index) const ;
-
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
- int rowCount(const QModelIndex& parent = QModelIndex()) const;
- bool hasChildren(const QModelIndex& parent = QModelIndex()) const;
-
- bool canFetchMore(const QModelIndex& parent) const;
- void fetchMore(const QModelIndex& parent);
-
-
- ThreadWeaver::Weaver* weaver(){return m_weaver;}
- void setCompleteScan(bool enable){m_completeScan=enable;}
-
-signals:
- void totalsChanged(int fuzzy, int translated, int untranslated, bool done);
- void loading();
-
-private slots:
- void po_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
- void po_rowsInserted(const QModelIndex& parent, int start, int end);
- void po_rowsRemoved(const QModelIndex& parent, int start, int end);
-
- void pot_dataChanged(const QModelIndex& topLeft, const QModelIndex& bottomRight);
- void pot_rowsInserted(const QModelIndex& parent, int start, int end);
- void pot_rowsRemoved(const QModelIndex& parent, int start, int end);
-
- void finishMetadataUpdate(ThreadWeaver::Job*);
- void finishSingleMetadataUpdate(ThreadWeaver::Job*);
-
- void updateTotalsChanged();
-
-public slots:
- void slotFileSaved(const KUrl&);
-
-private:
- ProjectNode* nodeForIndex(const QModelIndex& index) const;
- QModelIndex indexForNode(const ProjectNode* node);
-
- enum IndexType {PoIndex, PotIndex};
- QModelIndex indexForOuter(const QModelIndex& outerIndex, IndexType type) const;
- QModelIndex poIndexForOuter(const QModelIndex& outerIndex) const;
- QModelIndex potIndexForOuter(const QModelIndex& outerIndex) const;
- QModelIndex poOrPotIndexForOuter(const QModelIndex& outerIndex) const;
-
- QModelIndex indexForPoIndex(const QModelIndex& poIndex) const;
- QModelIndex indexForPotIndex(const QModelIndex& potIndex) const;
- void generatePOTMapping(QVector<int> & result, const QModelIndex& poParent, const QModelIndex& potParent) const;
-
- KUrl poToPot(const KUrl& path) const;
- KUrl potToPo(const KUrl& path) const;
-
- void enqueueNodeForMetadataUpdate(ProjectNode* node);
- void deleteSubtree(ProjectNode* node);
-
- void startNewMetadataJob();
- void setMetadataForDir(ProjectNode* node, const QList<KFileMetaInfo>& data);
- void updateDirStats(ProjectNode* node);
- bool updateDone(const QModelIndex& index, const KDirModel& model);
-
- KUrl m_poUrl;
- KUrl m_potUrl;
- KDirModel m_poModel;
- KDirModel m_potModel;
-
- ProjectNode m_rootNode;
-
- QVariant m_dirIcon;
- QVariant m_poIcon;
- QVariant m_poComplIcon;
- QVariant m_potIcon;
-
- //for updating stats
- QSet<ProjectNode *> m_dirsWaitingForMetadata;
- UpdateStatsJob* m_activeJob;
- ProjectNode* m_activeNode;
- QTimer* m_doneTimer;
-
- ThreadWeaver::Weaver* m_weaver;
-
- bool m_completeScan;
-};
-
-
-
-class UpdateStatsJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit UpdateStatsJob(QList<KFileItem> files, QObject* owner=0);
- ~UpdateStatsJob();
- int priority()const{return 35;} //SEE jobs.h
-
- void setStatus(int status);
-
- QList<KFileItem> m_files;
- QList<KFileMetaInfo> m_info;
- volatile int m_status; // 0 = running; -1 = cancel; -2 = abort
-
-protected:
- void run();
-
-};
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projecttab.h"
-#include "project.h"
-#include "projectwidget.h"
-#include "tmscanapi.h"
-#include "prefs.h"
-
-#include <klocale.h>
-#include <kaction.h>
-#include <kactioncategory.h>
-#include <kactioncollection.h>
-#include <kstandardaction.h>
-#include <kxmlguifactory.h>
-#include <klineedit.h>
-#include <kstatusbar.h>
-#include <khbox.h>
-
-#include <QtGui/qevent.h>
-#include <QMenu>
-#include <QVBoxLayout>
-#include <QShortcut>
-#include <QSortFilterProxyModel>
-#include <QProgressBar>
-#include <QStackedLayout>
-#include <QLabel>
-#include <QPushButton>
-
-ProjectTab::ProjectTab(QWidget *parent)
- : LokalizeSubwindowBase2(parent)
- , m_browser(new ProjectWidget(this))
- , m_filterEdit(new KLineEdit(this))
- , m_legacyUnitsCount(-1)
- , m_currentUnitsCount(0)
-
-{
- setWindowTitle(i18nc("@title:window","Project Overview"));//setCaption(i18nc("@title:window","Project"),false);
-//BEGIN setup welcome widget
- QWidget* welcomeWidget=new QWidget(this);
- QVBoxLayout* wl=new QVBoxLayout(welcomeWidget);
- QLabel* about = new QLabel(i18n("<html>" //copied from kaboutkdedialog_p.cpp
- "You do not have to be a software developer to be a member of the "
- "KDE team. You can join the national teams that translate "
- "program interfaces. You can provide graphics, themes, sounds, and "
- "improved documentation. You decide!"
- "<br /><br />"
- "Visit "
- "<a href=\"%1\">%1</a> "
- "for information on some projects in which you can participate."
- "<br /><br />"
- "If you need more information or documentation, then a visit to "
- "<a href=\"%2\">%2</a> "
- "will provide you with what you need.</html>",
- QLatin1String("http://community.kde.org/Getinvolved"),
- QLatin1String("http://techbase.kde.org/")), welcomeWidget);
- about->setAlignment(Qt::AlignCenter);
- about->setWordWrap(true);
- about->setOpenExternalLinks(true);
- about->setTextInteractionFlags(Qt::TextBrowserInteraction);
- about->setTextFormat(Qt::RichText);
-
- QPushButton* conf = new QPushButton(i18n("&Configure Lokalize..."), welcomeWidget);
- QPushButton* createProject = new QPushButton(i18nc("@action:inmenu","Create new project"), welcomeWidget);
- QPushButton* openProject = new QPushButton(i18nc("@action:inmenu","Open project"), welcomeWidget);
- connect(conf, SIGNAL(clicked(bool)), SettingsController::instance(),SLOT(showSettingsDialog()));
- connect(openProject, SIGNAL(clicked(bool)), this, SIGNAL(projectOpenRequested()));
- connect(createProject, SIGNAL(clicked(bool)), SettingsController::instance(), SLOT(projectCreate()));
- QHBoxLayout* wbtnl=new QHBoxLayout();
- wbtnl->addStretch(1);
- wbtnl->addWidget(conf);
- wbtnl->addWidget(createProject);
- wbtnl->addWidget(openProject);
- wbtnl->addStretch(1);
-
- wl->addStretch(1);
- wl->addWidget(about);
- wl->addStretch(1);
- wl->addLayout(wbtnl);
- wl->addStretch(1);
-
-
-//END setup welcome widget
- QWidget* baseWidget=new QWidget(this);
- m_stackedLayout = new QStackedLayout(baseWidget);
- QWidget* w=new QWidget(this);
- m_stackedLayout->addWidget(welcomeWidget);
- m_stackedLayout->addWidget(w);
- connect(Project::instance(), SIGNAL(loaded()), this, SLOT(showRealProjectOverview()));
- if (Project::instance()->isLoaded()) //for --project cmd option
- showRealProjectOverview();
-
- QVBoxLayout* l=new QVBoxLayout(w);
-
-
- m_filterEdit->setClearButtonShown(true);
- m_filterEdit->setClickMessage(i18n("Quick search..."));
- m_filterEdit->setToolTip(i18nc("@info:tooltip","Activated by Ctrl+L.")+" "+i18nc("@info:tooltip","Accepts regular expressions"));
- connect (m_filterEdit,SIGNAL(textChanged(QString)),this,SLOT(setFilterRegExp()),Qt::QueuedConnection);
- new QShortcut(Qt::CTRL+Qt::Key_L,this,SLOT(setFocus()),0,Qt::WidgetWithChildrenShortcut);
-
- l->addWidget(m_filterEdit);
- l->addWidget(m_browser);
- connect(m_browser,SIGNAL(fileOpenRequested(KUrl)),this,SIGNAL(fileOpenRequested(KUrl)));
- connect(Project::instance()->model(), SIGNAL(totalsChanged(int,int,int,bool)),
- this, SLOT(updateStatusBar(int,int,int,bool)));
- connect(Project::instance()->model(),SIGNAL(loading()),this,SLOT(initStatusBarProgress()));
-
- setCentralWidget(baseWidget);
-
- KHBox *progressBox = new KHBox();
- KStatusBar* statusBar = static_cast<LokalizeSubwindowBase2*>(parent)->statusBar();
-
- m_progressBar = new QProgressBar(progressBox);
- m_progressBar->setVisible(false);
- progressBox->setMinimumWidth(200);
- progressBox->setMaximumWidth(200);
- progressBox->setMaximumHeight(statusBar->sizeHint().height() - 4);
- statusBar->insertWidget(ID_STATUS_PROGRESS, progressBox, 1);
-
- setXMLFile("projectmanagerui.rc",true);
- //QAction* action = KStandardAction::find(Project::instance(),SLOT(showTM()),actionCollection());
-
-#define ADD_ACTION_SHORTCUT_ICON(_name,_text,_shortcut,_icon)\
- action = nav->addAction(_name);\
- action->setText(_text);\
- action->setShortcut(QKeySequence( _shortcut ));\
- action->setIcon(KIcon(_icon));
-
- KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* nav=new KActionCategory(i18nc("@title actions category","Navigation"), ac);
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous not ready"),Qt::CTRL+Qt::SHIFT+Qt::Key_PageUp,"prevfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzyUntr()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzyUntr",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next not ready"),Qt::CTRL+Qt::SHIFT+Qt::Key_PageDown,"nextfuzzyuntrans")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzyUntr()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Previous non-empty but not ready"),Qt::CTRL+Qt::Key_PageUp,"prevfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevFuzzy()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_next_fuzzy",i18nc("@action:inmenu\n'not ready' means 'fuzzy' in gettext terminology","Next non-empty but not ready"),Qt::CTRL+Qt::Key_PageDown,"nextfuzzy")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextFuzzy()) );
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_untrans",i18nc("@action:inmenu","Previous untranslated"),Qt::ALT+Qt::Key_PageUp,"prevuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevUntranslated()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_untrans",i18nc("@action:inmenu","Next untranslated"),Qt::ALT+Qt::Key_PageDown,"nextuntranslated")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextUntranslated()));
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_templateOnly",i18nc("@action:inmenu","Previous template only"),Qt::CTRL+Qt::Key_Up,"prevtemplate")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevTemplateOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_templateOnly",i18nc("@action:inmenu","Next template only"),Qt::CTRL+Qt::Key_Down,"nexttemplate")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextTemplateOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_prev_transOnly",i18nc("@action:inmenu","Previous translation only"),Qt::ALT+Qt::Key_Up,"prevpo")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoPrevTransOnly()));
-
- ADD_ACTION_SHORTCUT_ICON("go_next_transOnly",i18nc("@action:inmenu","Next translation only"),Qt::ALT+Qt::Key_Down,"nextpo")
- connect( action, SIGNAL(triggered(bool)), this, SLOT(gotoNextTransOnly()));
-
-
- KActionCategory* proj=new KActionCategory(i18nc("@title actions category","Project"), ac);
-
- action = proj->addAction("project_open",this,SIGNAL(projectOpenRequested()));
- action->setText(i18nc("@action:inmenu","Open project"));
- action->setIcon(KIcon("project-open"));
-
- int i=6;
- while (--i>ID_STATUS_PROGRESS)
- statusBarItems.insert(i,QString());
-
-}
-
-ProjectTab::~ProjectTab()
-{
- //kWarning()<<"destroyed";
-}
-
-void ProjectTab::showRealProjectOverview()
-{
- m_stackedLayout->setCurrentIndex(1);
-}
-
-KUrl ProjectTab::currentUrl()
-{
- return KUrl::fromLocalFile(Project::instance()->projectDir());
-}
-
-void ProjectTab::setFocus()
-{
- m_filterEdit->setFocus();
- m_filterEdit->selectAll();
-}
-
-void ProjectTab::setFilterRegExp()
-{
- QString newPattern=m_filterEdit->text();
- if (m_browser->proxyModel()->filterRegExp().pattern()==newPattern)
- return;
-
- m_browser->proxyModel()->setFilterRegExp(newPattern);
- if (newPattern.size()>2)
- m_browser->expandItems();
-}
-
-void ProjectTab::contextMenuEvent(QContextMenuEvent *event)
-{
- QMenu* menu=new QMenu(this);
- connect(menu,SIGNAL(aboutToHide()),menu,SLOT(deleteLater()));
-
- if (m_browser->currentIsTranslationFile())
- {
- menu->addAction(i18nc("@action:inmenu","Open"),this,SLOT(openFile()));
- menu->addSeparator();
- }
- /*menu.addAction(i18nc("@action:inmenu","Find in files"),this,SLOT(findInFiles()));
- menu.addAction(i18nc("@action:inmenu","Replace in files"),this,SLOT(replaceInFiles()));
- menu.addAction(i18nc("@action:inmenu","Spellcheck files"),this,SLOT(spellcheckFiles()));
- menu.addSeparator();
- menu->addAction(i18nc("@action:inmenu","Get statistics for subfolders"),m_browser,SLOT(expandItems()));
- */
- menu->addAction(i18nc("@action:inmenu","Add to translation memory"),this,SLOT(scanFilesToTM()));
-
- menu->addAction(i18nc("@action:inmenu","Search in files"),this,SLOT(searchInFiles()));
- if (QFileInfo(Project::instance()->templatesRoot()).exists())
- menu->addAction(i18nc("@action:inmenu","Search in files (including templates)"),this,SLOT(searchInFilesInclTempl()));
-
-// else if (Project::instance()->model()->hasChildren(/*m_proxyModel->mapToSource(*/(m_browser->currentIndex()))
-// )
-// {
-// menu.addSeparator();
-// menu.addAction(i18n("Force Scanning"),this,SLOT(slotForceStats()));
-//
-// }
-
- menu->popup(event->globalPos());
-}
-
-
-void ProjectTab::scanFilesToTM()
-{
- QList<QUrl> urls;
- foreach(const KUrl& url, m_browser->selectedItems())
- urls.append(url);
- TM::scanRecursive(urls,Project::instance()->projectID());
-}
-
-void ProjectTab::searchInFiles(bool templ)
-{
- QStringList files;
- foreach(const KUrl& url, m_browser->selectedItems())
- files.append(url.toLocalFile());
-
- if (!templ)
- {
- QString templatesRoot=Project::instance()->templatesRoot();
- int i=files.size();
- while(--i>=0)
- {
- if (files.at(i).startsWith(templatesRoot))
- files.removeAt(i);
- }
- }
-
- emit searchRequested(files);
-}
-
-void ProjectTab::searchInFilesInclTempl()
-{
- searchInFiles(true);
-}
-
-void ProjectTab::openFile() {emit fileOpenRequested(m_browser->currentItem());}
-void ProjectTab::findInFiles() {emit searchRequested(m_browser->selectedItems());}
-void ProjectTab::replaceInFiles() {emit replaceRequested(m_browser->selectedItems());}
-void ProjectTab::spellcheckFiles(){emit spellcheckRequested(m_browser->selectedItems());}
-
-void ProjectTab::gotoPrevFuzzyUntr() {m_browser->gotoPrevFuzzyUntr();}
-void ProjectTab::gotoNextFuzzyUntr() {m_browser->gotoNextFuzzyUntr();}
-void ProjectTab::gotoPrevFuzzy() {m_browser->gotoPrevFuzzy();}
-void ProjectTab::gotoNextFuzzy() {m_browser->gotoNextFuzzy();}
-void ProjectTab::gotoPrevUntranslated() {m_browser->gotoPrevUntranslated();}
-void ProjectTab::gotoNextUntranslated() {m_browser->gotoNextUntranslated();}
-void ProjectTab::gotoPrevTemplateOnly() {m_browser->gotoPrevTemplateOnly();}
-void ProjectTab::gotoNextTemplateOnly() {m_browser->gotoNextTemplateOnly();}
-void ProjectTab::gotoPrevTransOnly() {m_browser->gotoPrevTransOnly();}
-void ProjectTab::gotoNextTransOnly() {m_browser->gotoNextTransOnly();}
-
-bool ProjectTab::currentItemIsTranslationFile() const {return m_browser->currentIsTranslationFile();}
-void ProjectTab::setCurrentItem(const QString& url){m_browser->setCurrentItem(KUrl::fromLocalFile(url));}
-QString ProjectTab::currentItem() const {return m_browser->currentItem().toLocalFile();}
-QStringList ProjectTab::selectedItems() const
-{
- QStringList result;
- foreach (const KUrl& url, m_browser->selectedItems())
- result.append(url.toLocalFile());
- return result;
-}
-
-void ProjectTab::updateStatusBar(int fuzzy, int translated, int untranslated, bool done)
-{
- int total = fuzzy + translated + untranslated;
- m_currentUnitsCount = total;
-
- if (m_progressBar->value() != total && m_legacyUnitsCount > 0)
- m_progressBar->setValue(total);
- if (m_progressBar->maximum() < qMax(total,m_legacyUnitsCount))
- m_progressBar->setMaximum(qMax(total,m_legacyUnitsCount));
- m_progressBar->setVisible(!done);
- if (done)
- m_legacyUnitsCount = total;
-
- statusBarItems.insert(ID_STATUS_TOTAL, i18nc("@info:status message entries","Total: %1", total));
- reflectNonApprovedCount(fuzzy, total);
- reflectUntranslatedCount(untranslated, total);
-}
-
-void ProjectTab::initStatusBarProgress()
-{
- if (m_legacyUnitsCount > 0)
- {
- if (m_progressBar->value() != 0)
- m_progressBar->setValue(0);
- if (m_progressBar->maximum() != m_legacyUnitsCount)
- m_progressBar->setMaximum(m_legacyUnitsCount);
- updateStatusBar();
- }
-}
-
-void ProjectTab::setLegacyUnitsCount(int to)
-{
- m_legacyUnitsCount = to;
- m_currentUnitsCount = to;
- initStatusBarProgress();
-}
-
-//bool ProjectTab::isShown() const {return isVisible();}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTTAB_H
-#define PROJECTTAB_H
-
-#include "lokalizesubwindowbase.h"
-
-#include <KMainWindow>
-#include <KUrl>
-
-#include <KXMLGUIClient>
-
-#include <QStackedLayout>
-class ProjectWidget;
-class KLineEdit;
-#include <QContextMenuEvent>
-#include <QProgressBar>
-
-/**
- * Project Overview Tab
- */
-class ProjectTab: public LokalizeSubwindowBase2
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.ProjectOverview")
- //qdbuscpp2xml -m -s projecttab.h -o org.kde.lokalize.ProjectOverview.xml
-
-public:
- ProjectTab(QWidget *parent);
- ~ProjectTab();
-
- void contextMenuEvent(QContextMenuEvent *event);
-
- void hideDocks(){};
- void showDocks(){};
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
- KUrl currentUrl();
-
- int unitsCount(){return m_currentUnitsCount;}
- void setLegacyUnitsCount(int to);
-
-signals:
- void projectOpenRequested(QString path=QString());
-
- void fileOpenRequested(const KUrl&);
-
- void searchRequested(const QStringList&);
- void searchRequested(const KUrl::List&);
- void replaceRequested(const KUrl::List&);
- void spellcheckRequested(const KUrl::List&);
-
-public slots:
- Q_SCRIPTABLE void setCurrentItem(const QString& url);
- Q_SCRIPTABLE QString currentItem() const;
- ///@returns list of selected files recursively
- Q_SCRIPTABLE QStringList selectedItems() const;
- Q_SCRIPTABLE bool currentItemIsTranslationFile() const;
- void showRealProjectOverview();
-
- //Q_SCRIPTABLE bool isShown() const;
-
-private slots:
- void setFilterRegExp();
- void setFocus();
- void scanFilesToTM();
- void searchInFiles(bool templ=false);
- void searchInFilesInclTempl();
- void openFile();
- void findInFiles();
- void replaceInFiles();
- void spellcheckFiles();
-
- void gotoPrevFuzzyUntr();
- void gotoNextFuzzyUntr();
- void gotoPrevFuzzy();
- void gotoNextFuzzy();
- void gotoPrevUntranslated();
- void gotoNextUntranslated();
- void gotoPrevTemplateOnly();
- void gotoNextTemplateOnly();
- void gotoPrevTransOnly();
- void gotoNextTransOnly();
-
- void updateStatusBar(int fuzzy = 0, int translated = 0, int untranslated = 0, bool done = false);
- void initStatusBarProgress();
-
-private:
- ProjectWidget* m_browser;
- KLineEdit* m_filterEdit;
- QProgressBar* m_progressBar;
-
- QStackedLayout *m_stackedLayout;
-
- int m_legacyUnitsCount, m_currentUnitsCount;
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "projectwidget.h"
-
-#include "project.h"
-#include "catalog.h"
-
-#include <kdebug.h>
-#include <klocale.h>
-#include <kdirlister.h>
-#include <kstringhandler.h>
-#include <kdirsortfilterproxymodel.h>
-#include <kcolorscheme.h>
-
-#include <QTreeView>
-#include <QTimer>
-
-#include <QtGui/qevent.h>
-#include <QPainter>
-#include <QtGui/qbrush.h>
-#include <QHeaderView>
-#include <QItemDelegate>
-#include <QStyledItemDelegate>
-
-#undef KDE_NO_DEBUG_OUTPUT
-
-
-class PoItemDelegate: public QStyledItemDelegate
-{
-public:
- PoItemDelegate(QObject *parent=0);
- ~PoItemDelegate(){}
- void paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
- QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
-private:
- KColorScheme m_colorScheme;
-};
-
-PoItemDelegate::PoItemDelegate(QObject *parent)
- : QStyledItemDelegate(parent)
- , m_colorScheme(QPalette::Normal)
-{}
-
-QSize PoItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
-{
- QString text=index.data().toString();
- int lineCount=1;
- int nPos=text.indexOf('\n');
- if (nPos==-1)
- nPos=text.size();
- else
- lineCount+=text.count('\n');
- static QFontMetrics metrics(option.font);
- return QSize(metrics.averageCharWidth()*nPos, metrics.height()*lineCount);
-}
-
-void PoItemDelegate::paint (QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
-{
- if (index.column() != ProjectModel::Graph)
- return QStyledItemDelegate::paint(painter,option,index);
-
- QVariant graphData = index.data(Qt::DisplayRole);
- if (Q_UNLIKELY( !graphData.isValid()))
- {
- painter->fillRect(option.rect,Qt::transparent);
- return;
- }
-
- QRect rect = graphData.toRect();
- int translated = rect.left();
- int untranslated = rect.top();
- int fuzzy = rect.width();
- int total = translated + untranslated + fuzzy;
-
- if (total > 0)
- {
- QBrush brush;
- painter->setPen(Qt::white);
- QRect myRect(option.rect);
-
- if (translated)
- {
- brush=m_colorScheme.foreground(KColorScheme::PositiveText);
- myRect.setWidth(option.rect.width() * translated / total);
- painter->fillRect(myRect, brush);
- }
-
- if (fuzzy)
- {
- brush=m_colorScheme.foreground(KColorScheme::NeutralText);
- myRect.setLeft(myRect.left() + myRect.width());
- myRect.setWidth(option.rect.width() * fuzzy / total);
- painter->fillRect(myRect, brush);
- // painter->drawText(myRect,Qt::AlignRight,QString("%1").arg(data.width()));
- }
-
- if (untranslated)
- brush=m_colorScheme.foreground(KColorScheme::NegativeText);
- myRect.setLeft(myRect.left() + myRect.width());
- myRect.setWidth(option.rect.width() - myRect.left() + option.rect.left());
- painter->fillRect(myRect, brush);
- // painter->drawText(myRect,Qt::AlignRight,QString("%1").arg(data.top()));
- }
- else if (total == -1)
- painter->fillRect(option.rect,Qt::transparent);
- else if (total == 0)
- painter->fillRect(option.rect,QBrush(Qt::gray));
-}
-
-
-
-
-
-class SortFilterProxyModel : public KDirSortFilterProxyModel
-{
-public:
- SortFilterProxyModel(QObject* parent=0)
- : KDirSortFilterProxyModel(parent)
- {
- connect(Project::instance()->model(),SIGNAL(totalsChanged(int,int,int,bool)),this,SLOT(invalidate()));
- }
- ~SortFilterProxyModel(){}
-protected:
- bool lessThan(const QModelIndex& left,
- const QModelIndex& right) const;
- bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-
-};
-
-
-bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-{
-#ifdef _MSC_VER
- return true;
-#endif
-
- bool result=false;
- const QAbstractItemModel* model=sourceModel();
- QModelIndex item=model->index(source_row,0,source_parent);
-/*
- if (model->hasChildren(item))
- model->fetchMore(item);
-*/
- if (item.data(ProjectModel::TotalRole) == 0)
- return false; // Hide rows with no translations
-
- int i=model->rowCount(item);
- while(--i>=0 && !result)
- result=filterAcceptsRow(i,item);
-
- return result || QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
-}
-
-bool SortFilterProxyModel::lessThan(const QModelIndex& left,
- const QModelIndex& right) const
-{
-// kWarning()<<right.column()<<"--"<<left.row()<<right.row()<<left.internalPointer()<<right.internalPointer()<<left.parent().isValid()<<right.parent().isValid();
- //<<left.data().toString()<<right.data().toString()
- ProjectModel* projectModel = static_cast<ProjectModel*>(sourceModel());
- const KFileItem leftFileItem = projectModel->itemForIndex(left);
- const KFileItem rightFileItem = projectModel->itemForIndex(right);
-
- //Code taken from KDirSortFilterProxyModel, as it is not compatible with our model.
- //TODO: make KDirSortFilterProxyModel::subSortLessThan not cast model to KDirModel, but use data() with FileItemRole instead.
-
- // Directories and hidden files should always be on the top, independent
- // from the sort order.
- const bool isLessThan = (sortOrder() == Qt::AscendingOrder);
-
-
-
- if (leftFileItem.isNull() || rightFileItem.isNull())
- {
- kWarning()<<".isNull()";
- return false;
- }
-
- // On our priority, folders go above regular files.
- if (leftFileItem.isDir() && !rightFileItem.isDir()) {
- return isLessThan;
- } else if (!leftFileItem.isDir() && rightFileItem.isDir()) {
- return !isLessThan;
- }
-
- // Hidden elements go before visible ones, if they both are
- // folders or files.
- if (leftFileItem.isHidden() && !rightFileItem.isHidden()) {
- return isLessThan;
- } else if (!leftFileItem.isHidden() && rightFileItem.isHidden()) {
- return !isLessThan;
- }
-
-
- // Hidden elements go before visible ones, if they both are
- // folders or files.
- if (leftFileItem.isHidden() && !rightFileItem.isHidden()) {
- return true;
- } else if (!leftFileItem.isHidden() && rightFileItem.isHidden()) {
- return false;
- }
-
- switch(left.column()) {
- case ProjectModel::FileName:
- return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
- case ProjectModel::Graph:{
- QRect leftRect(left.data(Qt::DisplayRole).toRect());
- QRect rightRect(right.data(Qt::DisplayRole).toRect());
-
- int leftAll=leftRect.left()+leftRect.top()+leftRect.width();
- int rightAll=rightRect.left()+rightRect.top()+rightRect.width();
-
- if (!leftAll || !rightAll)
- return false;
-
- float leftVal=(float)leftRect.left()/leftAll;
- float rightVal=(float)rightRect.left()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- if (leftVal>rightVal)
- return false;
-
- leftVal=(float)leftRect.top()/leftAll;
- rightVal=(float)rightRect.top()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- if (leftVal>rightVal)
- return false;
-
- leftVal=(float)leftRect.width()/leftAll;
- rightVal=(float)rightRect.width()/rightAll;
-
- if (leftVal<rightVal)
- return true;
- return false;
- }
- case ProjectModel::LastTranslator:
- case ProjectModel::SourceDate:
- case ProjectModel::TranslationDate:
- return KStringHandler::naturalCompare(projectModel->data(left).toString(), projectModel->data(right).toString(), sortCaseSensitivity()) < 0;
- case ProjectModel::TotalCount:
- case ProjectModel::TranslatedCount:
- case ProjectModel::UntranslatedCount:
- case ProjectModel::FuzzyCount:
- return projectModel->data(left).toInt() < projectModel->data(right).toInt();
- default:
- return false;
- }
-}
-
-ProjectWidget::ProjectWidget(/*Catalog* catalog, */QWidget* parent)
- : QTreeView(parent)
- , m_proxyModel(new SortFilterProxyModel(this))
-// , m_catalog(catalog)
-{
- PoItemDelegate* delegate=new PoItemDelegate(this);
- setItemDelegate(delegate);
-
- connect(this,SIGNAL(activated(QModelIndex)),this,SLOT(slotItemActivated(QModelIndex)));
-
- m_proxyModel->setSourceModel(Project::instance()->model());
- //m_proxyModel->setDynamicSortFilter(true);
- setModel(m_proxyModel);
- //setModel(Project::instance()->model());
-
- setUniformRowHeights(true);
- setAllColumnsShowFocus(true);
- int widthDefaults[]={6,1,1,1,1,1,4,4};
- int i=sizeof(widthDefaults)/sizeof(int);
- int baseWidth=columnWidth(0);
- while(--i>=0)
- setColumnWidth(i, baseWidth*widthDefaults[i]/2);
-
- setSortingEnabled(true);
- sortByColumn(0, Qt::AscendingOrder);
-
- setSelectionMode(QAbstractItemView::ExtendedSelection);
- setSelectionBehavior(QAbstractItemView::SelectRows);
-// QTimer::singleShot(0,this,SLOT(initLater()));
-
- KConfig config;
- KConfigGroup stateGroup(&config,"ProjectWindow");
- header()->restoreState(QByteArray::fromBase64( stateGroup.readEntry("ListHeaderState", QByteArray()) ));
-}
-
-ProjectWidget::~ProjectWidget()
-{
- KConfig config;
- KConfigGroup stateGroup(&config,"ProjectWindow");
- stateGroup.writeEntry("ListHeaderState",header()->saveState().toBase64());
-
-}
-
-void ProjectWidget::setCurrentItem(const KUrl& u)
-{
- if (u.isEmpty())
- return;
- setCurrentIndex(m_proxyModel->mapFromSource(
- Project::instance()->model()->indexForUrl(u))
- /*,true*/);
-}
-
-KUrl ProjectWidget::currentItem() const
-{
- if (!currentIndex().isValid())
- return KUrl();
- return Project::instance()->model()->itemForIndex(
- m_proxyModel->mapToSource(currentIndex())
- ).url();
-}
-
-bool ProjectWidget::currentIsTranslationFile() const
-{
- //remember 'bout empty state
- return Catalog::extIsSupported(currentItem().path());
-}
-
-
-
-void ProjectWidget::slotItemActivated(const QModelIndex& index)
-{
- if (currentIsTranslationFile())
- {
- ProjectModel * srcModel = static_cast<ProjectModel *>(static_cast<QSortFilterProxyModel*>(m_proxyModel)->sourceModel());
- QModelIndex srcIndex = static_cast<QSortFilterProxyModel*>(m_proxyModel)->mapToSource(index);
- KUrl fileUrl = srcModel->beginEditing(srcIndex);
-
- emit fileOpenRequested(fileUrl);
- }
-}
-
-static void recursiveAdd(KUrl::List& list, const QModelIndex& idx)
-{
- ProjectModel& model=*(Project::instance()->model());
- const KFileItem& item(model.itemForIndex(idx));
- if (item.isDir())
- {
- int j=model.rowCount(idx);
- while (--j>=0)
- {
- const KFileItem& childItem(model.itemForIndex(idx.child(j,0)));
-
- if (childItem.isDir())
- recursiveAdd(list,idx.child(j,0));
- else
- list.prepend(childItem.url());
- }
- }
- else //if (!list.contains(u))
- list.prepend(item.url());
-}
-
-KUrl::List ProjectWidget::selectedItems() const
-{
- KUrl::List list;
- foreach(const QModelIndex& item, selectedIndexes())
- {
- if (item.column()==0)
- recursiveAdd(list,m_proxyModel->mapToSource(item));
- }
-
- return list;
-}
-
-void ProjectWidget::expandItems(const QModelIndex& parent)
-{
- const QAbstractItemModel* m=model();
- expand(parent);
-
- int i=m->rowCount(parent);
- while(--i>=0)
- expandItems(m->index(i,0,parent));
-}
-
-
-bool ProjectWidget::gotoIndexCheck(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role)
-{
- // Check if role is found for this index
- if (currentIndex.isValid()) {
- ProjectModel *srcModel = static_cast<ProjectModel *>(static_cast<QSortFilterProxyModel*>(m_proxyModel)->sourceModel());
- QModelIndex srcIndex = static_cast<QSortFilterProxyModel*>(m_proxyModel)->mapToSource(currentIndex);
- QVariant result = srcModel->data(srcIndex, role);
- return result.isValid() && result.toInt() > 0;
- }
- return false;
-}
-
-QModelIndex ProjectWidget::gotoIndexPrevNext(const QModelIndex& currentIndex, int direction) const
-{
- QModelIndex index = currentIndex;
- QModelIndex sibling;
-
- // Unless first or last sibling reached, continue with previous or next
- // sibling, otherwise continue with previous or next parent
- while (index.isValid())
- {
- sibling = index.sibling(index.row() + direction, index.column());
- if (sibling.isValid())
- return sibling;
- index = index.parent();
- }
- return index;
-}
-
-ProjectWidget::gotoIndexResult ProjectWidget::gotoIndexFind(
- const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction)
-{
- QModelIndex index = currentIndex;
-
- while (index.isValid())
- {
- // Set current index and show it if role is found for this index
- if (gotoIndexCheck(index, role))
- {
- clearSelection();
- setCurrentIndex(index);
- scrollTo(index);
- return gotoIndex_found;
- }
-
- // Handle child recursively if index is not a leaf
- QModelIndex child = index.child((direction == 1) ? 0 : (m_proxyModel->rowCount(index) - 1), index.column());
- if (child.isValid())
- {
- ProjectWidget::gotoIndexResult result = gotoIndexFind(child, role, direction);
- if (result != gotoIndex_notfound)
- return result;
- }
-
- // Go to previous or next item
- index = gotoIndexPrevNext(index, direction);
- }
- if (index.parent().isValid())
- return gotoIndex_notfound;
- else
- return gotoIndex_end;
-}
-
-ProjectWidget::gotoIndexResult ProjectWidget::gotoIndex(
- const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction)
-{
- QModelIndex index = currentIndex;
-
- // Check if current index already found, and if so go to previous or next item
- if (gotoIndexCheck(index, role))
- index = gotoIndexPrevNext(index, direction);
-
- return gotoIndexFind(index, role, direction);
-}
-
-void ProjectWidget::gotoPrevFuzzyUntr() {gotoIndex(currentIndex(), ProjectModel::FuzzyUntrCountRole, -1);}
-void ProjectWidget::gotoNextFuzzyUntr() {gotoIndex(currentIndex(), ProjectModel::FuzzyUntrCountRole, +1);}
-void ProjectWidget::gotoPrevFuzzy() {gotoIndex(currentIndex(), ProjectModel::FuzzyCountRole, -1);}
-void ProjectWidget::gotoNextFuzzy() {gotoIndex(currentIndex(), ProjectModel::FuzzyCountRole, +1);}
-void ProjectWidget::gotoPrevUntranslated() {gotoIndex(currentIndex(), ProjectModel::UntransCountRole, -1);}
-void ProjectWidget::gotoNextUntranslated() {gotoIndex(currentIndex(), ProjectModel::UntransCountRole, +1);}
-void ProjectWidget::gotoPrevTemplateOnly() {gotoIndex(currentIndex(), ProjectModel::TemplateOnlyRole, -1);}
-void ProjectWidget::gotoNextTemplateOnly() {gotoIndex(currentIndex(), ProjectModel::TemplateOnlyRole, +1);}
-void ProjectWidget::gotoPrevTransOnly() {gotoIndex(currentIndex(), ProjectModel::TransOnlyRole, -1);}
-void ProjectWidget::gotoNextTransOnly() {gotoIndex(currentIndex(), ProjectModel::TransOnlyRole, +1);}
-
-QSortFilterProxyModel* ProjectWidget::proxyModel(){return m_proxyModel;}
-
-#include "moc_projectwidget.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef PROJECTWIDGET_H
-#define PROJECTWIDGET_H
-
-#include <kurl.h>
-
-#include <QTreeView>
-
-#include "projectmodel.h"
-
-class SortFilterProxyModel;
-#include <QSortFilterProxyModel>
-
-/**
- * This class is considered a 'view',
- * and ProjectWindow + ProjectView are its controllers
- * the data is project-wide KDirModel based ProjectModel
- */
-class ProjectWidget: public QTreeView
-{
- Q_OBJECT
-public:
- ProjectWidget(QWidget* parent);
- ~ProjectWidget();
-
- void setCurrentItem(const KUrl&);
- KUrl currentItem() const;
- KUrl::List selectedItems() const;
- bool currentIsTranslationFile() const;
-
- QSortFilterProxyModel* proxyModel();
- void expandItems(const QModelIndex& parent=QModelIndex());
-
- void gotoPrevFuzzyUntr();
- void gotoNextFuzzyUntr();
- void gotoPrevFuzzy();
- void gotoNextFuzzy();
- void gotoPrevUntranslated();
- void gotoNextUntranslated();
- void gotoPrevTemplateOnly();
- void gotoNextTemplateOnly();
- void gotoPrevTransOnly();
- void gotoNextTransOnly();
-
-signals:
- void fileOpenRequested(const KUrl&);
- void newWindowOpenRequested(const KUrl&);
-
-private slots:
- void slotItemActivated(const QModelIndex&);
-
-private:
- enum gotoIndexResult {gotoIndex_end = -1, gotoIndex_notfound = 0, gotoIndex_found = 1};
-
- bool gotoIndexCheck(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role);
- QModelIndex gotoIndexPrevNext(const QModelIndex& currentIndex, int direction) const;
- gotoIndexResult gotoIndexFind(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction);
- gotoIndexResult gotoIndex(const QModelIndex& currentIndex, ProjectModel::AdditionalRoles role, int direction);
-
- QWidget* m_parent;
- SortFilterProxyModel* m_proxyModel;
-};
-
-
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "syntaxhighlighter.h"
-
-#include "project.h"
-#include "prefs_lokalize.h"
-#include "prefs.h"
-
-#include <KDebug>
-#include <KColorScheme>
-
-#include <QTextEdit>
-#include <QApplication>
-
-#define STATE_NORMAL 0
-#define STATE_TAG 1
-
-
-
-#define NUM_OF_RULES 5
-
-SyntaxHighlighter::SyntaxHighlighter(QTextEdit *parent)
- : Sonnet::Highlighter(parent)
- , tagBrush(KColorScheme::View,KColorScheme::VisitedText)
- , m_approved(true)
-// , fuzzyState(false)
-// , fromDocbook(docbook)
-{
- setAutomatic(false);
-
- highlightingRules.reserve(NUM_OF_RULES);
- HighlightingRule rule;
- //rule.format.setFontItalic(true);
-// tagFormat.setForeground(tagBrush.brush(QApplication::palette()));
- tagFormat.setForeground(tagBrush.brush(QApplication::palette()));
- //QTextCharFormat format;
- //tagFormat.setForeground(Qt::darkBlue);
-// if (!docbook) //support multiline tags
-// {
-// rule.format = tagFormat;
-// rule.pattern = QRegExp("<.+>");
-// rule.pattern.setMinimal(true);
-// highlightingRules.append(rule);
-// }
-
- //entity
- rule.format.setForeground(Qt::darkMagenta);
- rule.pattern = QRegExp("(&[A-Za-z_:][A-Za-z0-9_\\.:-]*;)");
- highlightingRules.append(rule);
-
- QString accel=Project::instance()->accel();
- if (!accel.isEmpty())
- {
- rule.format.setForeground(Qt::darkMagenta);
- rule.pattern = QRegExp(accel);
- highlightingRules.append(rule);
- }
-
- //\n \t \"
- rule.format.setForeground(Qt::darkGreen);
- rule.pattern = QRegExp("(\\\\[abfnrtv'\?\\\\])|(\\\\\\d+)|(\\\\x[\\dabcdef]+)");
- highlightingRules.append(rule);
-
-
-
-
-
- //spaces
- settingsChanged();
- connect(SettingsController::instance(),SIGNAL(generalSettingsChanged()),this, SLOT(settingsChanged()));
-
-}
-
-void SyntaxHighlighter::settingsChanged()
-{
- QRegExp re(QString(" +$|^ +|.?")+QChar(0x0000AD)+".?"); //soft hyphen
- if (Settings::highlightSpaces() && highlightingRules.last().pattern!=re)
- {
- KColorScheme colorScheme(QPalette::Normal);
- HighlightingRule rule;
- rule.format.clearForeground();
-
- //nbsp
- rule.format.setBackground(colorScheme.background(KColorScheme::AlternateBackground));
- rule.pattern = QRegExp(QChar(0x00a0U));
- highlightingRules.append(rule);
-
- //usual spaces at the end
- rule.format.setBackground(colorScheme.background(KColorScheme::ActiveBackground));
- rule.pattern = re;
- highlightingRules.append(rule);
- rehighlight();
- }
- else if (!Settings::highlightSpaces() && highlightingRules.last().pattern==re)
- {
- highlightingRules.resize(highlightingRules.size()-2);
- rehighlight();
- }
-}
-
-/*
-void SyntaxHighlighter::setFuzzyState(bool fuzzy)
-{
- return;
- int i=NUM_OF_RULES;
- while(--i>=0)
- highlightingRules[i].format.setFontItalic(fuzzy);
-
- tagFormat.setFontItalic(fuzzy);
-}*/
-
-void SyntaxHighlighter::highlightBlock(const QString &text)
-{
- int currentBlockState = STATE_NORMAL;
- QTextCharFormat f;
- f.setFontItalic(!m_approved);
- setFormat(0, text.length(), f);
-
- tagFormat.setFontItalic(!m_approved);
- //if (fromDocbook)
- {
- int startIndex = STATE_NORMAL;
- if (previousBlockState() != STATE_TAG)
- startIndex = text.indexOf('<');
-
- while (startIndex >= 0)
- {
- int endIndex = text.indexOf('>', startIndex);
- int commentLength;
- if (endIndex == -1)
- {
- currentBlockState = STATE_TAG;
- commentLength = text.length() - startIndex;
- }
- else
- {
- commentLength = endIndex - startIndex
- +1/*+ commentEndExpression.matchedLength()*/;
- }
- setFormat(startIndex, commentLength, tagFormat);
- startIndex = text.indexOf('<', startIndex + commentLength);
- }
- }
-
- foreach (const HighlightingRule &rule, highlightingRules)
- {
- QRegExp expression(rule.pattern);
- int index = expression.indexIn(text);
- while (index >= 0)
- {
- int length = expression.matchedLength();
- QTextCharFormat f=rule.format;
- f.setFontItalic(!m_approved);
- setFormat(index, length, f);
- index = expression.indexIn(text, index + length);
- }
- }
-
- if (spellCheckerFound())
- Sonnet::Highlighter::highlightBlock(text); // Resets current block state
-
- setCurrentBlockState(currentBlockState);
-}
-
-#if 0
-void SyntaxHighlighter::setFormatRetainingUnderlines(int start, int count, QTextCharFormat f)
-{
- QVector<bool> underLines(count);
- for (int i=0;i<count;++i)
- underLines[i]=format(start+i).fontUnderline();
-
- setFormat(start, count, f);
-
- f.setFontUnderline(true);
- int prevStart=-1;
- bool isPrevUnderLined=false;
- for (int i=0;i<count;++i)
- {
- if (!underLines.at(i) && prevStart!=-1)
- setFormat(start+isPrevUnderLined, i-prevStart, f);
- else if (underLines.at(i)&&!isPrevUnderLined)
- prevStart=i;
-
- isPrevUnderLined=underLines.at(i);
- }
-}
-#endif
-
-void SyntaxHighlighter::setMisspelled(int start, int count)
-{
- QString text=currentBlock().text();
- QString word=text.mid(start,count);
- if (m_sourceString.contains(word))
- return;
-
- QString accel=Project::instance()->accel();
-
- if (!isWordMisspelled(word.remove(accel)))
- return;
- count=word.length();//safety
-
- bool smthPreceeding=(start>0) &&
- (accel.endsWith(text.at(start-1))
- || text.at(start-1)==QChar(0x0000AD) //soft hyphen
- );
-
- //HACK. Needs Sonnet API redesign (KDE 5)
- if (smthPreceeding)
- {
- kWarning()<<"ampersand is in the way. word len:"<<count;
- int realStart=text.lastIndexOf(QRegExp("\\b"),start-2);
- if (realStart==-1)
- realStart=0;
- QString t=text.mid(realStart, count+start-realStart);
- t.remove(accel);
- t.remove(QChar(0x0000AD));
- if (!isWordMisspelled(t))
- return;
- }
-
- bool smthAfter=(start+count+1<text.size()) &&
- (accel.startsWith(text.at(start+count))
- || text.at(start+count)==QChar(0x0000AD) //soft hyphen
- );
- if (smthAfter)
- {
- kWarning()<<"smthAfter. ampersand is in the way. word len:"<<count;
- int realEnd=text.indexOf(QRegExp("\\b"),start+count+2);
- if (realEnd==-1)
- realEnd=text.size();
- QString t=text.mid(start, realEnd-start);
- t.remove(accel);
- t.remove(QChar(0x0000AD));
- if (!isWordMisspelled(t))
- return;
- }
-
- if (count && format(start)==tagFormat)
- return;
-
- for (int i=0;i<count;++i)
- {
- QTextCharFormat f(format(start+i));
- f.setFontUnderline(true);
- f.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
- f.setUnderlineColor(Qt::red);
- setFormat(start+i, 1, f);
- }
-}
-
-void SyntaxHighlighter::unsetMisspelled(int start, int count)
-{
- for (int i=0;i<count;++i)
- {
- QTextCharFormat f(format(start+i));
- f.setFontUnderline(false);
- setFormat(start+i, 1, f);
- }
-}
-
-
-
-#include "moc_syntaxhighlighter.cpp"
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef HIGHLIGHTER_H
-#define HIGHLIGHTER_H
-
-#include <QSyntaxHighlighter>
-#include <sonnet/highlighter.h>
-#include <kcolorscheme.h>
-
-#include <QHash>
-#include <QtGui/qtextformat.h>
-
-
-#include <QTextDocument>
-
-class SyntaxHighlighter : public Sonnet::Highlighter
-{
- Q_OBJECT
-
-public:
- explicit SyntaxHighlighter(QTextEdit *parent);
- ~SyntaxHighlighter(){};
-
- void setApprovementState(bool a){m_approved=a;};
- void setSourceString(const QString& s){m_sourceString=s;}
-
-protected:
- void highlightBlock(const QString &text);
-
- void setMisspelled(int start, int count);
- void unsetMisspelled(int start, int count);
-
-private slots:
- void settingsChanged();
-
-// void setFormatRetainingUnderlines(int start, int count, QTextCharFormat format);
-private:
- struct HighlightingRule
- {
- QRegExp pattern;
- QTextCharFormat format;
- };
- QVector<HighlightingRule> highlightingRules;
-
-// bool fromDocbook;
- QTextCharFormat tagFormat;
- KStatefulBrush tagBrush;
- bool m_approved;
- QString m_sourceString;
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "dbfilesmodel.h"
-#include "jobs.h"
-#include "project.h"
-
-#include <QCoreApplication>
-#include <QFileSystemModel>
-
-#include <threadweaver/ThreadWeaver.h>
-#include <kstandarddirs.h>
-using namespace TM;
-
-static QString tmFileExtension(TM_DATABASE_EXTENSION);
-static QString remoteTmExtension(REMOTETM_DATABASE_EXTENSION);
-
-
-DBFilesModel* DBFilesModel::_instance=0;
-void DBFilesModel::cleanupDBFilesModel()
-{
- delete DBFilesModel::_instance; DBFilesModel::_instance = 0;
-}
-
-DBFilesModel* DBFilesModel::instance()
-{
- if (Q_UNLIKELY( _instance==0 )) {
- _instance=new DBFilesModel;
- qAddPostRoutine(DBFilesModel::cleanupDBFilesModel);
- }
-
- return _instance;
-}
-
-
-DBFilesModel::DBFilesModel()
- : QSortFilterProxyModel()
- , projectDB(0)
- , m_fileSystemModel(new QFileSystemModel(this))
- , m_tmRootPath(KStandardDirs::locateLocal("appdata", ""))
-{
- m_fileSystemModel->setNameFilters(QStringList(QString("*.") + TM_DATABASE_EXTENSION));
- m_fileSystemModel->setFilter(QDir::Files);
- m_fileSystemModel->setRootPath(KStandardDirs::locateLocal("appdata", ""));
-
- setSourceModel(m_fileSystemModel);
- connect (this,SIGNAL(rowsInserted(QModelIndex,int,int)),
- this,SLOT(calcStats(QModelIndex,int,int))/*,Qt::QueuedConnection*/);
-
- connect (this,SIGNAL(dataChanged(QModelIndex,QModelIndex)),
- this,SLOT(updateStats(QModelIndex,QModelIndex)),Qt::QueuedConnection);
- m_timeSinceLastUpdate.start();
-
- int count=rowCount(rootIndex());
- if (count) calcStats(rootIndex(),0,count-1);
- openDB("default"); //behave when no project is loaded
-}
-
-DBFilesModel::~DBFilesModel()
-{
- delete projectDB;
-}
-
-
-bool DBFilesModel::filterAcceptsRow ( int source_row, const QModelIndex& source_parent ) const
-{
- if (source_parent!=m_fileSystemModel->index(m_tmRootPath))
- return true;
-
- const QString& fileName=m_fileSystemModel->index(source_row, 0, source_parent).data().toString();
- return (fileName.endsWith(tmFileExtension) && !fileName.endsWith("-journal.db")) || fileName.endsWith(remoteTmExtension);
-}
-
-QModelIndex DBFilesModel::rootIndex() const
-{
- return mapFromSource(m_fileSystemModel->index(m_tmRootPath));
-}
-
-QVariant DBFilesModel::headerData(int section, Qt::Orientation orientation, int role) const
-{
- Q_UNUSED(orientation);
- if (role!=Qt::DisplayRole) return QVariant();
-
- const char* const columns[]={
- I18N_NOOP2("@title:column","Name"),
- I18N_NOOP2("@title:column","Source language"),
- I18N_NOOP2("@title:column","Target language"),
- I18N_NOOP2("@title:column","Pairs"),
- I18N_NOOP2("@title:column","Unique original entries"),
- I18N_NOOP2("@title:column","Unique translations")
- };
-
- return i18nc("@title:column",columns[section]);
-}
-
-void DBFilesModel::openDB(const QString& name)
-{
- if (QFileInfo(KStandardDirs::locateLocal("appdata", name + REMOTETM_DATABASE_EXTENSION)).exists())
- openDB(name, TM::Remote);
- else
- openDB(name, TM::Local);
-}
-
-void DBFilesModel::openDB(const QString& name, DbType type)
-{
- openDB(new OpenDBJob(name, type));
-}
-
-void DBFilesModel::openDB(OpenDBJob* openDBJob)
-{
- connect(openDBJob,SIGNAL(done(ThreadWeaver::Job*)),openDBJob,SLOT(deleteLater()));
- connect(openDBJob,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(openJobDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(openDBJob);
-}
-
-void DBFilesModel::updateStats(const QModelIndex& topLeft, const QModelIndex& bottomRight)
-{
- if (m_timeSinceLastUpdate.elapsed()<60000
- || !topLeft.isValid() || !bottomRight.isValid())
- return;
-
- qDebug()<<"DBFilesModel::updateStats() called";
- calcStats(topLeft.parent(), topLeft.row(), bottomRight.row());
- m_timeSinceLastUpdate.start();
-}
-
-void DBFilesModel::calcStats(const QModelIndex& parent, int start, int end)
-{
- if (parent!=rootIndex())
- return;
-
- const QString& projectID=Project::instance()->projectID();
- while (start<=end)
- {
- QModelIndex index=QSortFilterProxyModel::index(start++, 0, parent);
- QString res=index.data().toString();
- if (Q_UNLIKELY(res==projectID && (!projectDB || data(*projectDB).toString()!=projectID)))
- projectDB=new QPersistentModelIndex(index);//TODO if user switches the project
-// if (Q_LIKELY( QSqlDatabase::contains(res) ))
-// continue;
- openDB(res, DbType(index.data(NameRole).toString().endsWith(remoteTmExtension)));
- }
-}
-
-void DBFilesModel::openJobDone(ThreadWeaver::Job* job)
-{
- OpenDBJob* j=static_cast<OpenDBJob*>(job);
- m_stats[j->m_dbName]=j->m_stat;
- m_configurations[j->m_dbName]=j->m_tmConfig;
- kDebug()<<j->m_dbName<<j->m_tmConfig.targetLangCode;
-}
-
-void DBFilesModel::removeTM ( QModelIndex index )
-{
- index=index.sibling(index.row(),0);
- CloseDBJob* closeDBJob=new CloseDBJob(index.data().toString());
- connect(closeDBJob,SIGNAL(done(ThreadWeaver::Job*)),closeDBJob,SLOT(deleteLater()));
- connect(closeDBJob,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(closeJobDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(closeDBJob);
-}
-
-void DBFilesModel::closeJobDone(ThreadWeaver::Job* job)
-{
- CloseDBJob* j=static_cast<CloseDBJob*>(job);
- QFile::remove(m_fileSystemModel->rootPath() + '/' + j->dbName() + tmFileExtension);
-}
-
-void DBFilesModel::updateProjectTmIndex()
-{
- if (projectDB && data(*projectDB).toString()!=Project::instance()->projectID())
- {
- delete projectDB; projectDB=0;
- }
-}
-
-int DBFilesModel::columnCount (const QModelIndex&) const
-{
- return 4; //FIXME the lat two columns are not displayed even if 6 is returned
-}
-
-
-QVariant DBFilesModel::data (const QModelIndex& index, int role) const
-{
- if (role==Qt::DecorationRole) return QVariant();
- if (role!=Qt::DisplayRole && role!=NameRole && index.column()<4) return QSortFilterProxyModel::data(index, role);
- //if (role!=Qt::DisplayRole && role!=NameRole) return QVariant();
-
- QString res=QSortFilterProxyModel::data(index.sibling(index.row(), 0), QFileSystemModel::FileNameRole).toString();
-
- if (role==NameRole) return res;
- if (res.endsWith(remoteTmExtension))
- res.chop(remoteTmExtension.size());
- else
- res.chop(tmFileExtension.size());
- //qDebug()<<m_stats[res].uniqueSourcesCount<<(index.column()==OriginalsCount);
-
- switch (index.column())
- {
- case Name: return res;
- case SourceLang: return m_configurations[res].sourceLangCode;
- case TargetLang: return m_configurations[res].targetLangCode;
- case Pairs: return m_stats[res].pairsCount;
- case OriginalsCount: return m_stats[res].uniqueSourcesCount;
- case TranslationsCount: return m_stats[res].uniqueTranslationsCount;
- }
-
- return res;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef DBFILESMODEL_H
-#define DBFILESMODEL_H
-
-#include "jobs.h"
-
-#include <QSortFilterProxyModel>
-#include <QtCore/qdatetime.h>
-#include <QFileSystemModel>
-#include <QPersistentModelIndex>
-
-namespace ThreadWeaver{class Job;}
-
-namespace TM{
-class OpenDBJob;
-
-class DBFilesModel: public QSortFilterProxyModel
-{
-Q_OBJECT
-public:
-
- enum Columns
- {
- Name=0,
- SourceLang,
- TargetLang,
- Pairs,
- OriginalsCount,
- TranslationsCount,
- ColumnCount
- };
-
- enum Rolse
- {
- NameRole=Qt::UserRole+50
- };
-
- DBFilesModel();
- ~DBFilesModel();
-
- QVariant data(const QModelIndex& index, int role=Qt::DisplayRole) const;
- int columnCount ( const QModelIndex& parent = QModelIndex() ) const;
- Qt::ItemFlags flags(const QModelIndex&) const {return Qt::ItemIsSelectable|Qt::ItemIsEnabled;}
- QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const;
-
- QModelIndex rootIndex() const;
- void removeTM(QModelIndex);
-
-
- //can be zero!!!
- QPersistentModelIndex* projectDBIndex()const{return projectDB;}
-
- void openDB(const QString& name);
- void openDB(const QString& name, DbType type);
- void openDB(OpenDBJob*);
-
- static DBFilesModel* instance();
-private:
- static DBFilesModel* _instance;
- static void cleanupDBFilesModel();
-
-protected:
- bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-
-public slots:
- void updateStats(const QModelIndex& topLeft, const QModelIndex& bottomRight);
- void calcStats(const QModelIndex& parent, int start, int end);
- void openJobDone(ThreadWeaver::Job*);
- void closeJobDone(ThreadWeaver::Job*);
- void updateProjectTmIndex();
-
-private:
- mutable QPersistentModelIndex* projectDB;
- QFileSystemModel* m_fileSystemModel;
- QString m_tmRootPath;
- QTime m_timeSinceLastUpdate;
-
- QMap< QString,OpenDBJob::DBStat> m_stats;
-public:
- QMap< QString,TMConfig> m_configurations;
-};
-
-}
-#endif
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>DBParams</class>
- <widget class="QWidget" name="DBParams">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>770</width>
- <height>773</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="0" column="1">
- <widget class="QLineEdit" name="name"/>
- </item>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="text">
- <string>Name:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="dbType">
- <item>
- <property name="text">
- <string>Local</string>
- </property>
- </item>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_6">
- <property name="text">
- <string>Database type:</string>
- </property>
- </widget>
- </item>
- <item row="6" column="0" colspan="2">
- <widget class="QGroupBox" name="connectionBox">
- <property name="title">
- <string>Connection</string>
- </property>
- <layout class="QFormLayout" name="formLayout_2">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Database name:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLineEdit" name="dbName"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_7">
- <property name="text">
- <string>Host:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QComboBox" name="dbHost">
- <property name="editable">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_8">
- <property name="text">
- <string>User:</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="dbUser"/>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_9">
- <property name="text">
- <string>Password:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="dbPasswd">
- <property name="echoMode">
- <enum>QLineEdit::Password</enum>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="7" column="0" colspan="2">
- <widget class="QGroupBox" name="contentBox">
- <property name="title">
- <string>Content</string>
- </property>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label_4">
- <property name="text">
- <string>Source language:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="KComboBox" name="sourceLang"/>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_5">
- <property name="text">
- <string>Target language:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="KComboBox" name="targetLang"/>
- </item>
- <item row="2" column="1">
- <widget class="QLineEdit" name="markup"/>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_2">
- <property name="text">
- <string>Markup regex:</string>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLineEdit" name="accel"/>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Accelerator:</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item row="8" column="0" colspan="2">
- <spacer name="verticalSpacer">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>name</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#undef KDE_NO_DEBUG_OUTPUT
-
-#include "jobs.h"
-#include "catalog.h"
-#include "project.h"
-#include "diff.h"
-#include "prefs_lokalize.h"
-#include "version.h"
-
-#include "stemming.h"
-
-#include <kdebug.h>
-#include <kstandarddirs.h>
-#include <threadweaver/ThreadWeaver.h>
-#include <threadweaver/Thread.h>
-#include <QSqlDatabase>
-#include <QSqlQuery>
-#include <QSqlError>
-#include <QRegExp>
-#include <QMap>
-
-#include <iostream>
-
-#include <math.h>
-using namespace TM;
-
-#define TM_DELIMITER '\v'
-#define TM_SEPARATOR '\b'
-#define TM_NOTAPPROVED 0x04
-
-
-static bool stop=false;
-void TM::cancelAllJobs(){stop=true;}
-
-/**
- * splits string into words, removing any markup
- *
- * TODO segmentation by sentences...
-**/
-static void doSplit(QString& cleanEn,
- QStringList& words,
- QRegExp& rxClean1,
- const QString& accel
- )
-{
- static QRegExp rxSplit("\\W+|\\d+");
-
- if (!rxClean1.pattern().isEmpty())
- cleanEn.replace(rxClean1," ");
- cleanEn.remove(accel);
-
- words=cleanEn.toLower().split(rxSplit,QString::SkipEmptyParts);
- if (words.size()>4)
- {
- int i=0;
- for(;i<words.size();++i)
- {
- if (words.at(i).size()<4)
- words.removeAt(i--);
- else if (words.at(i).startsWith('t')&&words.at(i).size()==4)
- {
- if (words.at(i)=="then"
- || words.at(i)=="than"
- || words.at(i)=="that"
- || words.at(i)=="this"
- )
- words.removeAt(i--);
- }
- }
- }
-
-}
-
-
-
-static qlonglong getFileId(const QString& path,
- QSqlDatabase& db)
-{
- QSqlQuery query1(db);
- QString escapedPath=path;
- escapedPath.replace('\'',"''");
-
- QString pathExpr="path='"+escapedPath+'\'';
- if (path.isEmpty())
- pathExpr="path ISNULL";
- if (Q_UNLIKELY(!query1.exec("SELECT id FROM files WHERE "
- "path='"+escapedPath+'\'')))
- kWarning(TM_AREA) <<"select db error: " <<query1.lastError().text();
-
- if (Q_LIKELY(query1.next()))
- {
- //this is translation of en string that is already present in db
-
- qlonglong id=query1.value(0).toLongLong();
- query1.clear();
- return id;
- }
- query1.clear();
-
- //nope, this is new file
- bool qpsql=(db.driverName()=="QPSQL");
- QString sql="INSERT INTO files (path) VALUES (?)";
- if (qpsql)
- sql+=" RETURNING id";
- query1.prepare(sql);
-
- query1.bindValue(0, path);
- if (Q_LIKELY(query1.exec()))
- return qpsql ? (query1.next(), query1.value(0).toLongLong()) : query1.lastInsertId().toLongLong();
- else
- kWarning(TM_AREA) <<"insert db error: " <<query1.lastError().text();
-
- return -1;
-}
-
-
-
-
-static void addToIndex(qlonglong sourceId, QString sourceString,
- QRegExp& rxClean1, const QString& accel, QSqlDatabase& db)
-{
- //kDebug(TM_AREA)<<sourceString;
-
- QStringList words;
- doSplit(sourceString,words,rxClean1,accel);
-
- if (Q_UNLIKELY( words.isEmpty() ))
- return;
-
- QSqlQuery query1(db);
-
- QByteArray sourceIdStr=QByteArray::number(sourceId,36);
-
- bool isShort=words.size()<20;
- int j=words.size();
- while (--j>=0)
- {
- // insert word (if we do not have it)
- if (Q_UNLIKELY(!query1.exec("SELECT word, ids_short, ids_long FROM words WHERE "
- "word='"+words.at(j)+'\'')))
- kWarning(TM_AREA) <<"select error 3: " <<query1.lastError().text();
-
- //we _have_ it
- bool weHaveIt=query1.next();
-
- if (weHaveIt)
- {
- //just add new id
- QByteArray arr;
- QString field;
- if (isShort)
- {
- arr=query1.value(1).toByteArray();
- field="ids_short";
- }
- else
- {
- arr=query1.value(2).toByteArray();
- field="ids_long";
- }
- query1.clear();
-
- if (arr.contains(' '+sourceIdStr+' ')
- || arr.startsWith(sourceIdStr+' ')
- || arr.endsWith(' '+sourceIdStr)
- || arr==sourceIdStr)
- return;//this string is already indexed
-
- query1.prepare("UPDATE words "
- "SET "+field+"=? "
- "WHERE word='"+words.at(j)+'\'');
-
- if (!arr.isEmpty())
- arr+=' ';
- arr+=sourceIdStr;
- query1.bindValue(0, arr);
-
- if (Q_UNLIKELY(!query1.exec()))
- kWarning(TM_AREA) <<"update error 4: " <<query1.lastError().text();
-
- }
- else
- {
- query1.clear();
- query1.prepare("INSERT INTO words (word, ids_short, ids_long) "
- "VALUES (?, ?, ?)");
- QByteArray idsShort;
- QByteArray idsLong;
- if (isShort)
- idsShort=sourceIdStr;
- else
- idsLong=sourceIdStr;
- query1.bindValue(0, words.at(j));
- query1.bindValue(1, idsShort);
- query1.bindValue(2, idsLong);
- if (Q_UNLIKELY(!query1.exec()))
- kWarning(TM_AREA) <<"insert error 2: " <<query1.lastError().text() ;
-
- }
- }
-}
-
-/**
- * remove source string from index if there are no other
- * 'good' entries using it but the entry specified with mainId
- */
-static void removeFromIndex(qlonglong mainId, qlonglong sourceId, QString sourceString,
- QRegExp& rxClean1, const QString& accel, QSqlDatabase& db)
-{
- kDebug(TM_AREA)<<"here for" <<sourceString;
- QStringList words;
- doSplit(sourceString,words,rxClean1,accel);
-
- if (Q_UNLIKELY( words.isEmpty() ))
- return;
-
- QSqlQuery query1(db);
- QByteArray sourceIdStr=QByteArray::number(sourceId,36);
-
-//BEGIN check
- //TM_NOTAPPROVED=4
- if (Q_UNLIKELY(!query1.exec("SELECT count(*) FROM main, target_strings WHERE "
- "main.source="+QString::number(sourceId)+" AND "
- "main.target=target_strings.id AND "
- "target_strings.target NOTNULL AND "
- "main.id!="+QString::number(mainId)+" AND "
- "(main.bits&4)!=4")))
- {
- kWarning(TM_AREA) <<"select error 500: " <<query1.lastError().text();
- return;
- }
-
- bool exit=query1.next() && (query1.value(0).toLongLong()>0);
- query1.clear();
- if (exit)
- return;
-//END check
-
- bool isShort=words.size()<20;
- int j=words.size();
- while (--j>=0)
- {
- // remove from record for the word (if we do not have it)
- if (Q_UNLIKELY(!query1.exec("SELECT word, ids_short, ids_long FROM words WHERE "
- "word='"+words.at(j)+'\'')))
- {
- kWarning(TM_AREA) <<"select error 3: " <<query1.lastError().text();
- return;
- }
- if (!query1.next())
- {
- kWarning(TM_AREA)<<"exit here 1";
- //we don't have record for the word, so nothing to remove
- query1.clear();
- return;
- }
-
- QByteArray arr;
- QString field;
- if (isShort)
- {
- arr=query1.value(1).toByteArray();
- field="ids_short";
- }
- else
- {
- arr=query1.value(2).toByteArray();
- field="ids_long";
- }
- query1.clear();
-
- if (arr.contains(' '+sourceIdStr+' '))
- arr.replace(' '+sourceIdStr+' '," ");
- else if (arr.startsWith(sourceIdStr+' '))
- arr.remove(0,sourceIdStr.size()+1);
- else if (arr.endsWith(' '+sourceIdStr))
- arr.chop(sourceIdStr.size()+1);
- else if (arr==sourceIdStr)
- arr.clear();
-
-
- query1.prepare("UPDATE words "
- "SET "+field+"=? "
- "WHERE word='"+words.at(j)+'\'');
-
- query1.bindValue(0, arr);
-
- if (Q_UNLIKELY(!query1.exec()))
- kWarning(TM_AREA) <<"update error 504: " <<query1.lastError().text();
-
- }
-}
-
-static bool doRemoveEntry(qlonglong mainId, QRegExp& rxClean1, const QString& accel, QSqlDatabase& db)
-{
- QSqlQuery query1(db);
-
- if (Q_UNLIKELY(!query1.exec(QString("SELECT source_strings.id, source_strings.source FROM source_strings, main WHERE "
- "source_strings.id=main.source AND main.id=%1").arg(mainId))))
- return false;
-
- if (!query1.next())
- return false;
-
- qlonglong sourceId=query1.value(0).toLongLong();
- QString source_string=query1.value(1).toString();
- query1.clear();
-
- if(!query1.exec(QString("SELECT count(*) FROM main WHERE source=%1").arg(sourceId))
- || !query1.next())
- return false;
-
- bool theOnly=query1.value(0).toInt()==1;
- query1.clear();
- if (theOnly)
- {
- removeFromIndex(mainId, sourceId, source_string, rxClean1, accel, db);
- kWarning(TM_AREA)<<"ok delete?"<<query1.exec(QString("DELETE FROM source_strings WHERE id=%1").arg(sourceId));
- }
-
- if (Q_UNLIKELY(!query1.exec(QString("SELECT target FROM main WHERE "
- "main.id=%1").arg(mainId))
- || !query1.next()))
- return false;
-
- qlonglong targetId=query1.value(0).toLongLong();
- query1.clear();
-
- if (!query1.exec(QString("SELECT count(*) FROM main WHERE target=%1").arg(targetId))
- ||! query1.next())
- return false;
- theOnly=query1.value(0).toInt()==1;
- query1.clear();
- if (theOnly)
- query1.exec(QString("DELETE FROM target_strings WHERE id=%1").arg(targetId));
-
- return query1.exec(QString("DELETE FROM main WHERE id=%1").arg(mainId));
-}
-
-static QString escape(QString str)
-{
- return str.replace('\'',"''");
-}
-
-static bool doInsertEntry(CatalogString source,
- CatalogString target,
- const QString& ctxt, //TODO QStringList -- after XLIFF
- bool approved,
- qlonglong fileId,
- QSqlDatabase& db,
- QRegExp& rxClean1,//cleaning regexps for word index update
- const QString& accel,
- qlonglong priorId,
- qlonglong& mainId
- )
-{
- QTime a;a.start();
-
- mainId=-1;
-
- if (Q_UNLIKELY( source.isEmpty() ))
- {
- kWarning(TM_AREA)<<"source empty";
- return false;
- }
-
- bool qpsql=(db.driverName()=="QPSQL");
-
- //we store non-entranslaed entries to make search over all source parts possible
- bool untranslated=target.isEmpty();
- bool shouldBeInIndex=!untranslated&&approved;
-
- //remove first occurrence of accel character so that search returns words containing accel mark
- int sourceAccelPos=source.string.indexOf(accel);
- if (sourceAccelPos!=-1)
- source.string.remove(sourceAccelPos,accel.size());
- int targetAccelPos=target.string.indexOf(accel);
- if (targetAccelPos!=-1)
- target.string.remove(targetAccelPos,accel.size());
-
- //check if we already have record with the same en string
- QSqlQuery query1(db);
- QString escapedCtxt =escape(ctxt);
-
- QByteArray sourceTags=source.tagsAsByteArray();
- QByteArray targetTags=target.tagsAsByteArray();
-
-//BEGIN get sourceId
- query1.prepare(QString("SELECT id FROM source_strings WHERE "
- "source=? AND (source_accel%1) AND source_markup%2").arg
- (sourceAccelPos!=-1?"=?":"=-1 OR source_accel ISNULL").arg
- (sourceTags.isEmpty()?" ISNULL":"=?"));
- int paranum=0;
- query1.bindValue(paranum++,source.string);
- if (sourceAccelPos!=-1)
- query1.bindValue(paranum++,sourceAccelPos);
- if (!sourceTags.isEmpty())
- query1.bindValue(paranum++,sourceTags);
- if (Q_UNLIKELY(!query1.exec()))
- {
- kWarning(TM_AREA) <<"select db source_strings error: " <<query1.lastError().text();
- return false;
- }
- qlonglong sourceId;
- if (!query1.next())
- {
-//BEGIN insert source anew
- kDebug(TM_AREA) <<"insert source anew";;
-
- QString sql="INSERT INTO source_strings (source, source_markup, source_accel) VALUES (?, ?, ?)";
- if (qpsql)
- sql+=" RETURNING id";
-
- query1.clear();
- query1.prepare(sql);
-
- query1.bindValue(0, source.string);
- query1.bindValue(1, sourceTags);
- query1.bindValue(2, sourceAccelPos!=-1?QVariant(sourceAccelPos):QVariant());
- if (Q_UNLIKELY(!query1.exec()))
- {
- kWarning(TM_AREA) <<"select db source_strings error: " <<query1.lastError().text();
- return false;
- }
- sourceId=qpsql ? (query1.next(), query1.value(0).toLongLong()) : query1.lastInsertId().toLongLong();
- query1.clear();
-
- //update index
- if (shouldBeInIndex)
- addToIndex(sourceId,source.string,rxClean1,accel,db);
-//END insert source anew
- }
- else
- {
- sourceId=query1.value(0).toLongLong();
- //kDebug(TM_AREA)<<"SOURCE ALREADY PRESENT"<<source.string<<sourceId;
- }
- query1.clear();
-//END get sourceId
-
-
- if (Q_UNLIKELY(!query1.exec(QString("SELECT id, target, bits FROM main WHERE "
- "source=%1 AND file=%2 AND ctxt%3").arg(sourceId).arg(fileId).arg
- (escapedCtxt.isEmpty()?" ISNULL":QString("='"+escapedCtxt+'\'')))))
- {
- kWarning(TM_AREA) <<"select db main error: " <<query1.lastError().text();
- return false;
- }
-
-//case:
-// aaa-bbb
-// aaa-""
-// aaa-ccc
-//bbb shouldn't be present in db
-
-
- //update instead of adding record to main?
- qlonglong bits=0;
-//BEGIN target update
- if (query1.next())
- {
- //kDebug(TM_AREA)<<target.string<<": update instead of adding record to main";
- mainId=query1.value(0).toLongLong();
- bits=query1.value(2).toLongLong();
- bits=bits&(0xff-1);//clear obsolete bit
- qlonglong targetId=query1.value(1).toLongLong();
- query1.clear();
-
- //kWarning(TM_AREA)<<"8... "<<a.elapsed();
-
- bool dbApproved=!(bits&TM_NOTAPPROVED);
- bool approvalChanged=dbApproved!=approved;
- if (approvalChanged)
- {
- query1.prepare("UPDATE main "
- "SET bits=?, change_date=CURRENT_DATE "
- "WHERE id="+QString::number(mainId));
-
- query1.bindValue(0, bits^TM_NOTAPPROVED);
- if (Q_UNLIKELY(!query1.exec()))
- {
- kWarning(TM_AREA)<<"fail #9"<<query1.lastError().text();
- return false;
- }
- }
- query1.clear();
-
- //check if target in TM matches
- if (Q_UNLIKELY(!query1.exec("SELECT target, target_markup, target_accel FROM target_strings WHERE "
- "id="+QString::number(targetId))))
- {
- kWarning(TM_AREA)<<"select db target_strings error: " <<query1.lastError().text();
- return false;
- }
-
- if (Q_UNLIKELY(!query1.next()))
- {
- kWarning(TM_AREA)<<"linking to non-existing target should never happen";
- return false;
- }
- QString dbTarget=query1.value(0).toString();
- int accelPos=query1.value(2).isNull()?-1:query1.value(2).toInt();
- bool matches=dbTarget==target.string && accelPos==targetAccelPos;
- query1.clear();
-
- bool untransStatusChanged=((target.isEmpty() || dbTarget.isEmpty())&&!matches);
- if (approvalChanged || untransStatusChanged) //only modify index if there were changes (this is not rescan)
- {
- if (shouldBeInIndex)
- //this adds source to index if it's not already there
- addToIndex(sourceId,source.string,rxClean1,accel,db);
- else
- //entry changed from indexable to non-indexable:
- //remove source string from index if there are no other
- //'good' entries using it
- removeFromIndex(mainId,sourceId,source.string,rxClean1,accel,db);
- }
-
- if (matches) //TODO XLIFF target_markup
- {
- if (!target.string.isEmpty())
- kWarning(TM_AREA)<<"oops, it just matches!"<<source.string<<target.string;
- return false;
- }
- // no, translation has changed: just update old target if it isn't used elsewhere
- if (Q_UNLIKELY(!query1.exec("SELECT count(*) FROM main WHERE "
- "target="+QString::number(targetId))))
- kWarning(TM_AREA) <<"select db target_strings error: " <<query1.lastError().text();
-
- if (query1.next() && query1.value(0).toLongLong()==1)
- {
- //TODO tnis may create duplicates, while no strings should be lost
- query1.clear();
-
- query1.prepare("UPDATE target_strings "
- "SET target=?, target_accel=?, target_markup=? "
- "WHERE id="+QString::number(targetId));
-
- query1.bindValue(0, target.string.isEmpty()?QVariant():target.string);
- query1.bindValue(1, targetAccelPos!=-1?QVariant(targetAccelPos):QVariant());
- query1.bindValue(2, target.tagsAsByteArray());
- bool ok=query1.exec();//note the RETURN!!!!
- if (!ok)
- kWarning(TM_AREA)<<"target update failed"<<query1.lastError().text();
- else
- ok=query1.exec("UPDATE main SET change_date=CURRENT_DATE WHERE target="+QString::number(targetId));
- return ok;
- }
- //else -> there will be new record insertion and main table update below
- }
- //kDebug(TM_AREA)<<target.string<<": update instead of adding record to main NOT"<<query1.executedQuery();
- query1.clear();
-//END target update
-
-//BEGIN get targetId
- query1.prepare(QString("SELECT id FROM target_strings WHERE "
- "target=? AND (target_accel%1) AND target_markup%2").arg
- (targetAccelPos!=-1?"=?":"=-1 OR target_accel ISNULL").arg
- (targetTags.isEmpty()?" ISNULL":"=?"));
- paranum=0;
- query1.bindValue(paranum++,target.string);
- if (targetAccelPos!=-1)
- query1.bindValue(paranum++,targetAccelPos);
- if (!targetTags.isEmpty())
- query1.bindValue(paranum++,targetTags);
- if (Q_UNLIKELY(!query1.exec()))
- {
- kWarning(TM_AREA) <<"select db target_strings error: " <<query1.lastError().text();
- return false;
- }
- qlonglong targetId;
- if (!query1.next())
- {
- QString sql="INSERT INTO target_strings (target, target_markup, target_accel) VALUES (?, ?, ?)";
- if (qpsql)
- sql+=" RETURNING id";
-
- query1.clear();
- query1.prepare(sql);
-
- query1.bindValue(0, target.string);
- query1.bindValue(1, target.tagsAsByteArray());
- query1.bindValue(2, targetAccelPos!=-1?QVariant(targetAccelPos):QVariant());
- if (Q_UNLIKELY(!query1.exec()))
- {
- kWarning(TM_AREA)<<"error inserting";
- return false;
- }
- targetId=qpsql ? (query1.next(), query1.value(0).toLongLong()) : query1.lastInsertId().toLongLong();
- }
- else
- {
- //very unlikely, except for empty string case
- targetId=query1.value(0).toLongLong();
- }
- query1.clear();
-//END get targetId
-
- bool dbApproved=!(bits&TM_NOTAPPROVED);
- if (dbApproved!=approved)
- bits^=TM_NOTAPPROVED;
-
- if (mainId!=-1)
- {
- //just update main with new targetId
- //(this is the case when target changed, but there were other users of the old one)
-
- //kWarning(TM_AREA) <<"YES! UPDATING!";
- query1.prepare("UPDATE main "
- "SET target=?, bits=?, change_date=CURRENT_DATE "
- "WHERE id="+QString::number(mainId));
-
- query1.bindValue(0, targetId);
- query1.bindValue(1, bits);
- bool ok=query1.exec();
- //kDebug(TM_AREA)<<"ok?"<<ok;
- return ok;
- }
-
- //for case when previous source additions were
- //for entries that didn't deserve indexing
- if (shouldBeInIndex)
- //this adds source to index if it's not already there
- addToIndex(sourceId,source.string,rxClean1,accel,db);
-
- QString sql="INSERT INTO main (source, target, file, ctxt, bits, prior) "
- "VALUES (?, ?, ?, ?, ?, ?)";
- if (qpsql)
- sql+=" RETURNING id";
-
- query1.prepare(sql);
-
-// query1.prepare(QString("INSERT INTO main (source, target, file, ctxt, bits%1) "
-// "VALUES (?, ?, ?, ?, ?%2)").arg((priorId!=-1)?", prior":"").arg((priorId!=-1)?", ?":""));
-
- query1.bindValue(0, sourceId);
- query1.bindValue(1, targetId);
- query1.bindValue(2, fileId);
- query1.bindValue(3, ctxt.isEmpty()?QVariant():ctxt);
- query1.bindValue(4, bits);
- query1.bindValue(5, priorId!=-1?QVariant(priorId):QVariant());
- bool ok=query1.exec();
- mainId=qpsql ? (query1.next(), query1.value(0).toLongLong()) : query1.lastInsertId().toLongLong();
- //kDebug(TM_AREA)<<"ok?"<<ok;
- return ok;
-}
-
-//TODO smth with its usage in places except opendbjob
-static bool initSqliteDb(QSqlDatabase& db)
-{
- QSqlQuery queryMain(db);
- //NOTE do this only if no japanese, chinese etc?
- queryMain.exec("PRAGMA encoding = \"UTF-8\"");
- queryMain.exec("CREATE TABLE IF NOT EXISTS source_strings ("
- "id INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- "source TEXT, "
- "source_markup BLOB, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "source_accel INTEGER "
- ")");
-
- queryMain.exec("CREATE TABLE IF NOT EXISTS target_strings ("
- "id INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- "target TEXT, "
- "target_markup BLOB, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "target_accel INTEGER "
- ")");
-
- queryMain.exec("CREATE TABLE IF NOT EXISTS main ("
- "id INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- "source INTEGER, "
- "target INTEGER, "
- "file INTEGER, "// AUTOINCREMENT,"
- "ctxt TEXT, "//context, after \v may be a plural form
- "date DEFAULT CURRENT_DATE, "//creation date
- "change_date DEFAULT CURRENT_DATE, "//last update date
- //change_author
- "bits NUMERIC DEFAULT 0, "
- //bits&0x01 means entry obsolete (not present in file)
- //bits&0x02 means entry is NOT equiv-trans (see XLIFF spec)
- //bits&0x04 TM_NOTAPPROVED entry is NOT approved?
-
- //ALTER TABLE main ADD COLUMN prior INTEGER;
- "prior INTEGER"// helps restoring full context!
- //"reusability NUMERIC DEFAULT 0" //e.g. whether the translation is context-free, see XLIFF spec (equiv-trans)
- //"hits NUMERIC DEFAULT 0"
- ")");
-
- queryMain.exec("ALTER TABLE main ADD COLUMN prior INTEGER");
- queryMain.exec("ALTER TABLE main ADD COLUMN change_date"); //DEFAULT CURRENT_DATE is not possible here
-
-
- queryMain.exec("CREATE INDEX IF NOT EXISTS source_index ON source_strings ("
- "source"
- ")");
-
- queryMain.exec("CREATE INDEX IF NOT EXISTS target_index ON target_strings ("
- "target"
- ")");
-
- queryMain.exec("CREATE INDEX IF NOT EXISTS main_index ON main ("
- "source, target, file"
- ")");
-
- queryMain.exec("CREATE TABLE IF NOT EXISTS files ("
- "id INTEGER PRIMARY KEY ON CONFLICT REPLACE, "
- "path TEXT UNIQUE ON CONFLICT REPLACE, "
- "date DEFAULT CURRENT_DATE " //last edit date when last scanned
- ")");
-
-/* NOTE //"don't implement it till i'm sure it is actually useful"
- //this is used to prevent readding translations that were removed by user
- queryMain.exec("CREATE TABLE IF NOT EXISTS tm_removed ("
- "id INTEGER PRIMARY KEY ON CONFLICT REPLACE, "
- "english BLOB, "//qChecksum
- "target BLOB, "
- "ctxt TEXT, "//context; delimiter is \b
- "date DEFAULT CURRENT_DATE, "
- "hits NUMERIC DEFAULT 0"
- ")");*/
-
-
- //we create indexes manually, in a customized way
-//OR: SELECT (tm_links.id) FROM tm_links,words WHERE tm_links.wordid==words.wordid AND (words.word) IN ("africa","abidjan");
- queryMain.exec("CREATE TABLE IF NOT EXISTS words ("
- "word TEXT UNIQUE ON CONFLICT REPLACE, "
- "ids_short BLOB, " // actually, it's text,
- "ids_long BLOB " // but it will never contain non-latin chars
- ")");
-
- queryMain.exec("CREATE TABLE IF NOT EXISTS tm_config ("
- "key INTEGER PRIMARY KEY ON CONFLICT REPLACE, "// AUTOINCREMENT,"
- "value TEXT "
- ")");
-
-
- bool ok=queryMain.exec("select * from main limit 1");
- return ok || !queryMain.lastError().text().contains("database disk image is malformed");
-
- //queryMain.exec("CREATE TEMP TRIGGER set_user_id_trigger AFTER UPDATE ON main FOR EACH ROW BEGIN UPDATE main SET change_author = 0 WHERE main.id=NEW.id; END;");
- //CREATE TEMP TRIGGER set_user_id_trigger INSTEAD OF UPDATE ON main FOR EACH ROW BEGIN UPDATE main SET ctxt = 'test', source=NEW.source, target=NEW.target, WHERE main.id=NEW.id; END;
-//config:
- //accel
- //markup
-//(see a little below)
-}
-
-//special SQL for PostgreSQL
-static void initPgDb(QSqlDatabase& db)
-{
- QSqlQuery queryMain(db);
- queryMain.exec("CREATE SEQUENCE source_id_serial");
- queryMain.exec("CREATE TABLE source_strings ("
- "id INTEGER PRIMARY KEY DEFAULT nextval('source_id_serial'), "
- "source TEXT, "
- "source_markup TEXT, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "source_accel INTEGER "
- ")");
-
- queryMain.exec("CREATE SEQUENCE target_id_serial");
- queryMain.exec("CREATE TABLE target_strings ("
- "id INTEGER PRIMARY KEY DEFAULT nextval('target_id_serial'), "
- "target TEXT, "
- "target_markup TEXT, "//XLIFF markup info, see catalog/catalogstring.h catalog/xliff/*
- "target_accel INTEGER "
- ")");
-
- queryMain.exec("CREATE SEQUENCE main_id_serial");
- queryMain.exec("CREATE TABLE main ("
- "id INTEGER PRIMARY KEY DEFAULT nextval('main_id_serial'), "
- "source INTEGER, "
- "target INTEGER, "
- "file INTEGER, "// AUTOINCREMENT,"
- "ctxt TEXT, "//context, after \v may be a plural form
- "date DATE DEFAULT CURRENT_DATE, "//last update date
- "change_date DATE DEFAULT CURRENT_DATE, "//last update date
- "change_author OID, "//last update date
- "bits INTEGER DEFAULT 0, "
- "prior INTEGER"// helps restoring full context!
- ")");
-
- queryMain.exec("CREATE INDEX source_index ON source_strings ("
- "source"
- ")");
-
- queryMain.exec("CREATE INDEX target_index ON target_strings ("
- "target"
- ")");
-
- queryMain.exec("CREATE INDEX main_index ON main ("
- "source, target, file"
- ")");
-
- queryMain.exec("CREATE SEQUENCE file_id_serial");
- queryMain.exec("CREATE TABLE files ("
- "id INTEGER PRIMARY KEY DEFAULT nextval('file_id_serial'), "
- "path TEXT UNIQUE, "
- "date DATE DEFAULT CURRENT_DATE " //last edit date when last scanned
- ")");
-
- //we create indexes manually, in a customized way
-//OR: SELECT (tm_links.id) FROM tm_links,words WHERE tm_links.wordid==words.wordid AND (words.word) IN ("africa","abidjan");
- queryMain.exec("CREATE TABLE words ("
- "word TEXT UNIQUE, "
- "ids_short BYTEA, " // actually, it's text,
- "ids_long BYTEA " //` but it will never contain non-latin chars
- ")");
-
- queryMain.exec("CREATE TABLE tm_config ("
- "key INTEGER PRIMARY KEY, "// AUTOINCREMENT,"
- "value TEXT "
- ")");
-//config:
- //accel
- //markup
-//(see a little below)
-
- queryMain.exec("CREATE OR REPLACE FUNCTION set_user_id() RETURNS trigger AS $$"
- "BEGIN"
- " NEW.change_author = (SELECT usesysid FROM pg_user WHERE usename = CURRENT_USER);"
- " RETURN NEW;"
- "END"
- "$$ LANGUAGE plpgsql;");
-
- //DROP TRIGGER set_user_id_trigger ON main;
- queryMain.exec("CREATE TRIGGER set_user_id_trigger BEFORE INSERT OR UPDATE ON main FOR EACH ROW EXECUTE PROCEDURE set_user_id();");
-}
-
-QMap<QString,TMConfig> tmConfigCache;
-
-static void setConfig(QSqlDatabase& db, const TMConfig& c)
-{
- qDebug()<<"setConfig"<<db.databaseName();
- QSqlQuery query(db);
- query.prepare("INSERT INTO tm_config (key, value) "
- "VALUES (?, ?)");
-
- query.addBindValue(0);
- query.addBindValue(c.markup);
- //kDebug(TM_AREA)<<"setting tm db config:"<<query.exec();
- qDebug()<<"setting tm db config 1:"<<query.exec();
-
- query.addBindValue(1);
- query.addBindValue(c.accel);
- qDebug()<<"setting tm db config 2:"<<query.exec();
-
- query.addBindValue(2);
- query.addBindValue(c.sourceLangCode);
- qDebug()<<"setting tm db config 3:"<<query.exec();
-
- query.addBindValue(3);
- query.addBindValue(c.targetLangCode);
- query.exec();
-
- tmConfigCache[db.databaseName()]=c;
-}
-
-static TMConfig getConfig(QSqlDatabase& db, bool useCache=true) //int& emptyTargetId
-{
- if (useCache && tmConfigCache.contains(db.databaseName()))
- {
- //kDebug()<<"using config cache for"<<db.databaseName();
- return tmConfigCache.value(db.databaseName());
- }
-
- QSqlQuery query(db);
- bool ok=query.exec("SELECT key, value FROM tm_config ORDER BY key ASC");
- qDebug()<<"accessing tm db config"<<ok<<"use cache:"<<useCache;
- Project& p=*(Project::instance());
- bool f=query.next();
- TMConfig c;
- c.markup= f?query.value(1).toString():p.markup();
- c.accel= query.next()?query.value(1).toString():p.accel();
- c.sourceLangCode=query.next()?query.value(1).toString():p.sourceLangCode();
- c.targetLangCode=query.next()?query.value(1).toString():p.targetLangCode();
- query.clear();
-
- if (Q_UNLIKELY( !f )) //tmConfigCache[db.databaseName()]=c;
- setConfig(db,c);
-
- tmConfigCache.insert(db.databaseName(), c);
- return c;
-}
-
-
-static void getStats(const QSqlDatabase& db,
- int& pairsCount,
- int& uniqueSourcesCount,
- int& uniqueTranslationsCount
- )
-
-{
- QSqlQuery query(db);
- if (!query.exec("SELECT count(id) FROM main")
- || !query.next())
- return;
- pairsCount=query.value(0).toInt();
- query.clear();
-
- if(!query.exec("SELECT count(*) FROM source_strings")
- || !query.next())
- return;
- uniqueSourcesCount=query.value(0).toInt();
- query.clear();
-
- if(!query.exec("SELECT count(*) FROM target_strings")
- || !query.next())
- return;
- uniqueTranslationsCount=query.value(0).toInt();
-
- kDebug(TM_AREA)<<"getStats ok";
- query.clear();
-}
-
-OpenDBJob::OpenDBJob(const QString& name, DbType type, bool reconnect, const ConnectionParams& connParams, QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_dbName(name)
- , m_type(type)
- , m_setParams(false)
- , m_connectionSuccessful(false)
- , m_reconnect(reconnect)
- , m_connParams(connParams)
-{
- kDebug(TM_AREA)<<m_dbName;
-}
-
-OpenDBJob::~OpenDBJob()
-{
- kDebug(TM_AREA)<<m_dbName;
-}
-
-void OpenDBJob::run()
-{
- QTime a;a.start();
- if (!QSqlDatabase::contains(m_dbName) || m_reconnect)
- {
- thread()->setPriority(QThread::IdlePriority);
-
- if (m_type==TM::Local)
- {
- QSqlDatabase db=QSqlDatabase::addDatabase("QSQLITE",m_dbName);
- db.setDatabaseName(KStandardDirs::locateLocal("appdata", m_dbName + TM_DATABASE_EXTENSION));
- m_connectionSuccessful=db.open();
- if (Q_UNLIKELY( !m_connectionSuccessful ))
- {
- QSqlDatabase::removeDatabase(m_dbName);
- return;
- }
- if (!initSqliteDb(db)) //need to recreate db ;(
- {
- QString filename=db.databaseName();
- db.close();
- QSqlDatabase::removeDatabase(m_dbName);
- QFile::remove(filename);
-
- db=QSqlDatabase::addDatabase("QSQLITE",m_dbName);
- db.setDatabaseName(filename);
- m_connectionSuccessful=db.open() && initSqliteDb(db);
- if (!m_connectionSuccessful)
- {
- QSqlDatabase::removeDatabase(m_dbName);
- return;
- }
- }
- }
- else
- {
- if (QSqlDatabase::contains(m_dbName))//reconnect is true
- {
- QSqlDatabase::database(m_dbName).close();
- QSqlDatabase::removeDatabase(m_dbName);
- }
-
- if (!m_connParams.isFilled())
- {
- QFile rdb(KStandardDirs::locateLocal("appdata", m_dbName + REMOTETM_DATABASE_EXTENSION));
- if (!rdb.open(QIODevice::ReadOnly | QIODevice::Text))
- return;
-
- QTextStream rdbParams(&rdb);
-
- m_connParams.driver=rdbParams.readLine();
- m_connParams.host=rdbParams.readLine();
- m_connParams.db=rdbParams.readLine();
- m_connParams.user=rdbParams.readLine();
- m_connParams.passwd=rdbParams.readLine();
- }
-
- QSqlDatabase db=QSqlDatabase::addDatabase(m_connParams.driver,m_dbName);
- db.setHostName(m_connParams.host);
- db.setDatabaseName(m_connParams.db);
- db.setUserName(m_connParams.user);
- db.setPassword(m_connParams.passwd);
- m_connectionSuccessful=db.open();
- if (Q_UNLIKELY( !m_connectionSuccessful ))
- {
- QSqlDatabase::removeDatabase(m_dbName);
- return;
- }
- m_connParams.user=db.userName();
- initPgDb(db);
- }
-
- }
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
- //if (!m_markup.isEmpty()||!m_accel.isEmpty())
- if (m_setParams)
- setConfig(db,m_tmConfig);
- else
- m_tmConfig=getConfig(db);
- kWarning(TM_AREA) <<"db"<<m_dbName<<" opened "<<a.elapsed()<<m_tmConfig.targetLangCode;
-
- getStats(db,m_stat.pairsCount,m_stat.uniqueSourcesCount,m_stat.uniqueTranslationsCount);
-
- if (m_type==TM::Local)
- {
- db.close();
- db.open();
- }
-}
-
-
-CloseDBJob::CloseDBJob(const QString& name, QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_dbName(name)
-{
- kWarning(TM_AREA)<<"here";
-}
-
-CloseDBJob::~CloseDBJob()
-{
- kWarning(TM_AREA)<<m_dbName;
-}
-
-void CloseDBJob::run ()
-{
- //kWarning(TM_AREA) <<"started";
-// thread()->setPriority(QThread::IdlePriority);
- QTime a;
- a.start();
-
-// QString dbFile=KStandardDirs::locateLocal("appdata", m_name+".db");
-
- QSqlDatabase::removeDatabase(m_dbName);
- kWarning(TM_AREA) <<"db closed "<<a.elapsed();
-}
-
-
-static QString makeAcceledString(QString source, const QString& accel, const QVariant& accelPos)
-{
- if (accelPos.isNull())
- return source;
- int accelPosInt=accelPos.toInt();
- if (accelPosInt!=-1)
- source.insert(accelPosInt, accel);
- return source;
-}
-
-
-SelectJob* TM::initSelectJob(Catalog* catalog, DocPosition pos, QString db, int opt)
-{
- SelectJob* job=new SelectJob(catalog->sourceWithTags(pos),
- catalog->context(pos.entry).first(),
- catalog->url().pathOrUrl(),
- pos,
- db.isEmpty()?Project::instance()->projectID():db);
- if (opt&Enqueue)
- {
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- }
- return job;
-}
-
-SelectJob::SelectJob(const CatalogString& source,
- const QString& ctxt,
- const QString& file,
- const DocPosition& pos,
- const QString& dbName,
- QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_source(source)
- , m_ctxt(ctxt)
- , m_file(file)
- , m_dequeued(false)
- , m_pos(pos)
- , m_dbName(dbName)
-{
- kDebug(TM_AREA)<<dbName<<m_source.string;
-}
-
-SelectJob::~SelectJob()
-{
- //kDebug(TM_AREA)<<m_source.string;
-}
-
-void SelectJob::aboutToBeDequeued(ThreadWeaver::WeaverInterface*)
-{
- m_dequeued=true;
-}
-
-
-inline QMap<uint,qlonglong> invertMap(const QMap<qlonglong,uint>& source)
-{
- //uses the fact that map has its keys always sorted
- QMap<uint,qlonglong> sortingMap;
- for(QMap<qlonglong,uint>::const_iterator i=source.constBegin(); i!=source.constEnd(); ++i)
- {
- sortingMap.insertMulti(i.value(), i.key());
- }
- return sortingMap;
-}
-
-//returns true if seen translation with >85%
-bool SelectJob::doSelect(QSqlDatabase& db,
- QStringList& words,
- //QList<TMEntry>& entries,
- bool isShort)
-{
- bool qpsql=(db.driverName()=="QPSQL");
- QMap<qlonglong,uint> occurencies;
- QVector<qlonglong> idsForWord;
-
- QSqlQuery queryWords(db);
- //TODO ??? not sure. make another loop before to create QList< QList<qlonglong> > then reorder it by size
- static const QString queryC[]={QString("SELECT ids_long FROM words WHERE word='%1'"),
- QString("SELECT ids_short FROM words WHERE word='%1'")};
- QString queryString=queryC[isShort];
-
- //for each word...
- int o=words.size();
- while (--o>=0)
- {
- //if this is not the first word occurrence, just readd ids for it
- if (!( !idsForWord.isEmpty() && words.at(o)==words.at(o+1) ))
- {
- idsForWord.clear();
- queryWords.exec(queryString.arg(words.at(o)));
- if (Q_UNLIKELY(!queryWords.exec(queryString.arg(words.at(o)))))
- kWarning(TM_AREA) <<"select error: " <<queryWords.lastError().text() << endl;
-
- if (queryWords.next())
- {
- QByteArray arr(queryWords.value(0).toByteArray());
- queryWords.clear();
-
- QList<QByteArray> ids(arr.split(' '));
- int p=ids.size();
- idsForWord.reserve(p);
- while (--p>=0)
- idsForWord.append(ids.at(p).toLongLong(/*bool ok*/0,36));
- }
- else
- {
- queryWords.clear();
- continue;
- }
- }
-
- //kWarning(TM_AREA) <<"SelectJob: idsForWord.size() "<<idsForWord.size()<<endl;
-
- //iterate over ids: this computes hit count for each id
- for(QVector<qlonglong>::const_iterator i=idsForWord.constBegin(); i!=idsForWord.constEnd(); i++)
- occurencies[*i]++; //0 is default value
- }
-
- //accels are removed
- TMConfig c=getConfig(db);
- QString tmp=c.markup;
- if (!c.markup.isEmpty())
- tmp+='|';
- QRegExp rxSplit('('+tmp+"\\W+|\\d+)+");
-
- QString sourceClean(m_source.string);
- sourceClean.remove(c.accel);
- //split m_english for use in wordDiff later--all words are needed so we cant use list we already have
- QStringList englishList(sourceClean.toLower().split(rxSplit,QString::SkipEmptyParts));
- static QRegExp delPart("<KBABELDEL>*</KBABELDEL>", Qt::CaseSensitive, QRegExp::Wildcard);
- static QRegExp addPart("<KBABELADD>*</KBABELADD>", Qt::CaseSensitive, QRegExp::Wildcard);
- delPart.setMinimal(true);
- addPart.setMinimal(true);
-
- //QList<uint> concordanceLevels=sortedUniqueValues(occurencies); //we start from entries with higher word-concordance level
- QMap<uint,qlonglong> concordanceLevelToIds=invertMap(occurencies);
- if (concordanceLevelToIds.isEmpty())
- return false;
- bool seen85=false;
- int limit=200;
- QMap<uint,qlonglong>::const_iterator clit=concordanceLevelToIds.constEnd();
- if (concordanceLevelToIds.size()) --clit;
- if (concordanceLevelToIds.size()) while (--limit>=0)
- {
- if (Q_UNLIKELY( m_dequeued ))
- break;
-
- //for every concordance level
- qlonglong level=clit.key();
- QString joined;
- while(level==clit.key())
- {
- joined+=QString::number(clit.value())+',';
- if (clit==concordanceLevelToIds.constBegin() || --limit<0)
- break;
- --clit;
- }
- joined.chop(1);
-
- //get records containing current word
- QSqlQuery queryFetch("SELECT id, source, source_accel, source_markup FROM source_strings WHERE "
- "source_strings.id IN ("+joined+')',db);
- TMEntry e;
- while (queryFetch.next())
- {
- e.id=queryFetch.value(0).toLongLong();
- if (queryFetch.value(3).toByteArray().size())
- qDebug()<<"BA"<<queryFetch.value(3).toByteArray();
- e.source=CatalogString( makeAcceledString(queryFetch.value(1).toString(), c.accel, queryFetch.value(2)),
- queryFetch.value(3).toByteArray() );
- if (e.source.string.contains(TAGRANGE_IMAGE_SYMBOL))
- {
- if (!e.source.tags.size())
- kWarning(TM_AREA)<<queryFetch.value(3).toByteArray().size()<<queryFetch.value(3).toByteArray();
- }
- //e.target=queryFetch.value(2).toString();
- //QStringList e_ctxt=queryFetch.value(3).toString().split('\b',QString::SkipEmptyParts);
- //e.date=queryFetch.value(4).toString();
- e.markupExpr=c.markup;
- e.accelExpr=c.accel;
- e.dbName=db.connectionName();
-
-
-//BEGIN calc score
- QString str=e.source.string;
- str.remove(c.accel);
-
- QStringList englishSuggList(str.toLower().split(rxSplit,QString::SkipEmptyParts));
- if (englishSuggList.size()>10*englishList.size())
- continue;
- //sugg is 'old' --translator has to adapt its translation to 'new'--current
- QString result=wordDiff(englishSuggList,englishList);
- //kWarning(TM_AREA) <<"SelectJob: doin "<<j<<" "<<result;
-
- int pos=0;
- int delSubStrCount=0;
- int delLen=0;
- while ((pos=delPart.indexIn(result,pos))!=-1)
- {
- //kWarning(TM_AREA) <<"SelectJob: match del "<<delPart.cap(0);
- delLen+=delPart.matchedLength()-23;
- ++delSubStrCount;
- pos+=delPart.matchedLength();
- }
- pos=0;
- int addSubStrCount=0;
- int addLen=0;
- while ((pos=addPart.indexIn(result,pos))!=-1)
- {
- addLen+=addPart.matchedLength()-23;
- ++addSubStrCount;
- pos+=addPart.matchedLength();
- }
-
- //allLen - length of suggestion
- int allLen=result.size()-23*addSubStrCount-23*delSubStrCount;
- int commonLen=allLen-delLen-addLen;
- //now, allLen is the length of the string being translated
- allLen=m_source.string.size();
- bool possibleExactMatch=!(delLen+addLen);
- if (!possibleExactMatch)
- {
- //del is better than add
- if (addLen)
- {
- //kWarning(TM_AREA) <<"SelectJob: addLen:"<<addLen<<" "<<9500*(pow(float(commonLen)/float(allLen),0.20))<<" / "
- //<<pow(float(addLen*addSubStrCount),0.2)<<" "
- //<<endl;
-
- float score=9500*(pow(float(commonLen)/float(allLen),0.12f))//this was < 1 so we have increased it
- //this was > 1 so we have decreased it, and increased result:
- / exp(0.014*float(addLen)*log10(3.0f+addSubStrCount));
-
- if (delLen)
- {
- //kWarning(TM_AREA) <<"SelectJob: delLen:"<<delLen<<" / "
- //<<pow(float(delLen*delSubStrCount),0.1)<<" "
- //<<endl;
-
- float a=exp(0.008*float(delLen)*log10(3.0f+delSubStrCount));
-
- if (a!=0.0)
- score/=a;
- }
- e.score=(int)score;
-
- }
- else//==to adapt, only deletion is needed
- {
- //kWarning(TM_AREA) <<"SelectJob: b "<<int(pow(float(delLen*delSubStrCount),0.10));
- float score=9900*(pow(float(commonLen)/float(allLen),0.15f))
- / exp(0.008*float(delLen)*log10(3.0f+delSubStrCount));
- e.score=(int)score;
- }
- }
- else
- e.score=10000;
-
-//END calc score
- if (e.score<3500)
- continue;
- seen85=seen85 || e.score>8500;
- if (seen85 && e.score<6000)
- continue;
-
-//BEGIN fetch rest of the data
- QString change_author_str;
- QString authors_table_str;
- if (qpsql)
- {
- //change_author_str=", main.change_author ";
- change_author_str=", pg_user.usename ";
- authors_table_str=" JOIN pg_user ON (pg_user.usesysid=main.change_author) ";
- }
-
- QSqlQuery queryRest("SELECT main.id, main.date, main.ctxt, main.bits, "
- "target_strings.target, target_strings.target_accel, target_strings.target_markup, "
- "files.path, main.change_date " + change_author_str +
- "FROM main JOIN target_strings ON (target_strings.id=main.target) JOIN files ON (files.id=main.file) " + authors_table_str + "WHERE "
- "main.source="+QString::number(e.id)+" AND "
- "(main.bits&4)!=4 AND "
- "target_strings.target NOTNULL"
- ,db); //ORDER BY tm_main.id ?
- queryRest.exec();
- //qDebug()<<"main select error"<<queryRest.lastError().text();
- QMap<TMEntry,bool> sortedEntryList;//to eliminate same targets from different files
- while (queryRest.next())
- {
- e.id=queryRest.value(0).toLongLong();
- e.date=queryRest.value(1).toDate();
- e.ctxt=queryRest.value(2).toString();
- e.target=CatalogString( makeAcceledString(queryRest.value(4).toString(), c.accel, queryRest.value(5)),
- queryRest.value(6).toByteArray() );
-
- QStringList matchData=queryRest.value(2).toString().split(TM_DELIMITER,QString::KeepEmptyParts);//context|plural
- e.file=queryRest.value(7).toString();
- if (e.target.isEmpty())
- continue;
-
- e.obsolete=queryRest.value(3).toInt()&1;
-
- e.changeDate=queryRest.value(8).toDate();
- if (qpsql)
- e.changeAuthor=queryRest.value(9).toString();
-
-//BEGIN exact match score++
- if (possibleExactMatch) //"exact" match (case insensitive+w/o non-word characters!)
- {
- if (m_source.string==e.source.string)
- e.score=10000;
- else
- e.score=9900;
- }
- if (!m_ctxt.isEmpty()&&matchData.size()>0)//check not needed?
- {
- if (matchData.at(0)==m_ctxt)
- e.score+=33;
- }
- //kWarning(TM_AREA)<<"m_pos"<<QString::number(m_pos.form);
-// bool pluralMatches=false;
- if (matchData.size()>1)
- {
- int form=matchData.at(1).toInt();
-
- //pluralMatches=(form&&form==m_pos.form);
- if (form&&form==(int)m_pos.form)
- {
- //kWarning(TM_AREA)<<"this"<<matchData.at(1);
- e.score+=33;
- }
- }
- if (e.file==m_file)
- e.score+=33;
-//END exact match score++
- //kWarning(TM_AREA)<<"appending"<<e.target;
- sortedEntryList.insertMulti(e, false);
- }
- queryRest.clear();
- //eliminate same targets from different files
- QHash<QString,int> hash;
- int oldCount=m_entries.size();
- QMap<TMEntry,bool>::const_iterator it=sortedEntryList.constEnd();
- if (sortedEntryList.size()) while(true)
- {
- --it;
- const TMEntry& e=it.key();
- int& hits=hash[e.target.string];
- if (!hits) //0 was default value
- m_entries.append(e);
- hits++;
- if (it==sortedEntryList.constBegin())
- break;
- }
- for (int i=oldCount;i<m_entries.size();++i)
- m_entries[i].hits=hash.value(m_entries.at(i).target.string);
-//END fetch rest of the data
- }
- queryFetch.clear();
- if (clit==concordanceLevelToIds.constBegin())
- break;
- if (seen85) limit=qMin(limit, 100); //be more restrictive for the next concordance levels
- }
- return seen85;
-}
-
-void SelectJob::run ()
-{
- kDebug(TM_AREA)<<"started"<<m_dbName<<m_source.string;
- if (m_source.isEmpty() || stop) //sanity check
- return;
- //thread()->setPriority(QThread::IdlePriority);
- QTime a;a.start();
-
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
-
- TMConfig c=getConfig(db);
- QRegExp rxClean1(c.markup);rxClean1.setMinimal(true);
-
- QString cleanSource=m_source.string;
- QStringList words;
- doSplit(cleanSource,words,rxClean1,c.accel);
- if (Q_UNLIKELY( words.isEmpty() ))
- return;
- qSort(words);//to speed up if some words occur multiple times
-
- bool isShort=words.size()<20;
-
- if (!doSelect(db,words,isShort))
- doSelect(db,words,!isShort);
-
- //kWarning(TM_AREA) <<"SelectJob: done "<<a.elapsed()<<m_entries.size();
- qSort(m_entries.begin(), m_entries.end(), qGreater<TMEntry>());
- int limit=qMin(Settings::suggCount(),m_entries.size());
- int i=m_entries.size();
- while(--i>=limit)
- m_entries.removeLast();
-
- if (Q_UNLIKELY( m_dequeued ))
- return;
-
- ++i;
- while(--i>=0)
- {
- m_entries[i].accelExpr=c.accel;
- m_entries[i].markupExpr=c.markup;
- m_entries[i].diff=userVisibleWordDiff(m_entries.at(i).source.string,
- m_source.string,
- m_entries.at(i).accelExpr,
- m_entries.at(i).markupExpr);
- }
-}
-
-
-
-
-
-
-ScanJob::ScanJob(const KUrl& url,
- const QString& dbName,
- QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_url(url)
- , m_time(0)
- , m_size(0)
- , m_dbName(dbName)
-{
- kDebug(TM_AREA)<<m_dbName<<m_url.pathOrUrl();
-}
-
-ScanJob::~ScanJob()
-{
- kWarning(TM_AREA) <<m_url;
-}
-
-void ScanJob::run()
-{
- if (stop)
- return;
- kWarning(TM_AREA) <<"started"<<m_url.pathOrUrl()<<m_dbName;
- thread()->setPriority(QThread::IdlePriority);
- QTime a;a.start();
-
- m_added=0; //stats
- m_newVersions=0;//stats
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
- //initSqliteDb(db);
- TMConfig c=getConfig(db,true);
- QRegExp rxClean1(c.markup);rxClean1.setMinimal(true);
-
- Catalog catalog(thread());
- if (Q_LIKELY(catalog.loadFromUrl(m_url, KUrl(), &m_size, true)==0))
- {
- if (c.targetLangCode!=catalog.targetLangCode())
- {
- kWarning()<<"not indexing file because target languages don't match:"<<c.targetLangCode<<"in TM vs"<<catalog.targetLangCode()<<"in file";
- return;
- }
- qlonglong priorId=-1;
-
- QSqlQuery queryBegin("BEGIN",db);
- //kWarning(TM_AREA) <<"queryBegin error: " <<queryBegin.lastError().text();
-
- qlonglong fileId=getFileId(m_url.pathOrUrl(),db);
- //mark everything as obsolete
- queryBegin.exec(QString("UPDATE main SET bits=(bits|1) WHERE file=%1").arg(fileId));
- //kWarning(TM_AREA) <<"UPDATE error: " <<queryBegin.lastError().text();
-
- int numberOfEntries=catalog.numberOfEntries();
- DocPosition pos(0);
- for (;pos.entry<numberOfEntries;pos.entry++)
- {
- bool ok=true;
- if (catalog.isPlural(pos.entry))
- {
- DocPosition ppos=pos;
- for (ppos.form=0;ppos.form<catalog.numberOfPluralForms();++ppos.form)
- {
-/*
- QString target;
- if ( catalog.isApproved(i) && !catalog.isUntranslated(pos))
- target=catalog.target(pos);
-*/
- ok=ok&&doInsertEntry(catalog.sourceWithTags(ppos),
- catalog.targetWithTags(ppos),
- catalog.context(ppos).first()+TM_DELIMITER+QString::number(ppos.form),
- catalog.isApproved(ppos),
- fileId,db,rxClean1,c.accel,priorId,priorId);
- }
- }
- else
- {
-/*
- QString target;
- if ( catalog.isApproved(i) && !catalog.isUntranslated(i))
- target=catalog.target(i);
-*/
- ok=doInsertEntry(catalog.sourceWithTags(pos),
- catalog.targetWithTags(pos),
- catalog.context(pos).first(),
- catalog.isApproved(pos),
- fileId,db,rxClean1,c.accel,priorId,priorId);
- }
- if (Q_LIKELY( ok ))
- ++m_added;
- }
- QSqlQuery queryEnd("END",db);
- kWarning(TM_AREA) <<"ScanJob: done "<<a.elapsed();
- }
- //kWarning(TM_AREA) <<"Done scanning "<<m_url.prettyUrl();
- m_time=a.elapsed();
-}
-
-
-RemoveJob::RemoveJob(const TMEntry& entry, QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_entry(entry)
-{
- kWarning(TM_AREA)<<m_entry.file<<m_entry.source.string;
-}
-
-RemoveJob::~RemoveJob()
-{
- kWarning(TM_AREA)<<m_entry.file<<m_entry.source.string;
-}
-
-
-void RemoveJob::run ()
-{
- kDebug(TM_AREA)<<m_entry.dbName;
- QSqlDatabase db=QSqlDatabase::database(m_entry.dbName);
-
- //cleaning regexps for word index update
- TMConfig c=getConfig(db);
- QRegExp rxClean1(c.markup);rxClean1.setMinimal(true);
-
- kWarning(TM_AREA)<<doRemoveEntry(m_entry.id,rxClean1,c.accel,db);
-}
-
-
-UpdateJob::UpdateJob(const QString& filePath,
- const QString& ctxt,
- const CatalogString& english,
- const CatalogString& newTarget,
- //const DocPosition&,//for back tracking
- int form,
- bool approved,
- const QString& dbName,
- QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_filePath(filePath)
- , m_ctxt(ctxt)
- , m_english(english)
- , m_newTarget(newTarget)
- , m_form(form)
- , m_approved(approved)
- , m_dbName(dbName)
-{
- kDebug(TM_AREA)<<m_english.string<<m_newTarget.string;
-}
-
-void UpdateJob::run ()
-{
- kDebug(TM_AREA)<<"run"<<m_english.string<<m_newTarget.string;
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
-
- //cleaning regexps for word index update
- TMConfig c=getConfig(db);
- QRegExp rxClean1(c.markup);rxClean1.setMinimal(true);
-
-
- qlonglong fileId=getFileId(m_filePath,db);
-
- if (m_form!=-1)
- m_ctxt+=TM_DELIMITER+QString::number(m_form);
-
- QSqlQuery queryBegin("BEGIN",db);
- qlonglong priorId=-1;
- if (!doInsertEntry(m_english,m_newTarget,
- m_ctxt, //TODO QStringList -- after XLIFF
- m_approved, fileId,db,rxClean1,c.accel,priorId,priorId))
- kWarning(TM_AREA)<<"error updating db";
- QSqlQuery queryEnd("END",db);
-}
-
-
-
-//BEGIN TMX
-
-
-#include <QtXml/qxml.h>
-
-/**
- @author Nick Shaforostoff <shafff@ukr.net>
-*/
-class TmxParser : public QXmlDefaultHandler
-{
- enum State //localstate for getting chars into right place
- {
- null=0,
- seg,
- propContext,
- propFile,
- propPluralForm,
- propApproved
- };
-
- enum Lang
- {
- Source,
- Target,
- Null
- };
-
-public:
- TmxParser(const QString& dbName);
- ~TmxParser();
-
-private:
- bool startDocument();
- bool startElement(const QString&,const QString&,const QString&,const QXmlAttributes&);
- bool endElement(const QString&,const QString&,const QString&);
- bool characters(const QString&);
-
-private:
- QSqlDatabase db;
- QRegExp rxClean1;
- QString accel;
-
- int m_hits;
- CatalogString m_segment[3]; //Lang enum
- QList<InlineTag> m_inlineTags;
- QString m_context;
- QString m_pluralForm;
- QString m_filePath;
- QString m_approvedString;
-
- State m_state:8;
- Lang m_lang:8;
-
- ushort m_added;
-
-
- QMap<QString,qlonglong> m_fileIds;
- QString m_dbLangCode;
-};
-
-
-TmxParser::TmxParser(const QString& dbName)
- : m_dbLangCode(Project::instance()->langCode().toLower())
-{
- m_added=0; //stats
- db=QSqlDatabase::database(dbName);
-
- TMConfig c=getConfig(db);
- rxClean1.setPattern(c.markup);rxClean1.setMinimal(true);
- accel=c.accel;
-}
-
-bool TmxParser::startDocument()
-{
- //initSqliteDb(db);
- m_fileIds.clear();
-
- QSqlQuery queryBegin("BEGIN",db);
-
- m_state=null;
- m_lang=Null;
- return true;
-}
-
-
-TmxParser::~TmxParser()
-{
- QSqlQuery queryEnd("END",db);
-}
-
-
-bool TmxParser::startElement( const QString&, const QString&,
- const QString& qName,
- const QXmlAttributes& attr)
-{
- if (qName=="tu")
- {
- bool ok;
- m_hits=attr.value("usagecount").toInt(&ok);
- if (!ok)
- m_hits=-1;
-
- m_segment[Source].clear();
- m_segment[Target].clear();
- m_context.clear();
- m_pluralForm.clear();
- m_filePath.clear();
- m_approvedString.clear();
-
- }
- else if (qName=="tuv")
- {
- if (attr.value("xml:lang").toLower()=="en")
- m_lang=Source;
- else if (attr.value("xml:lang").toLower()==m_dbLangCode)
- m_lang=Target;
- else
- {
- kWarning(TM_AREA)<<"skipping lang"<<attr.value("xml:lang");
- m_lang=Null;
- }
- }
- else if (qName=="prop")
- {
- if (attr.value("type").toLower()=="x-context")
- m_state=propContext;
- else if (attr.value("type").toLower()=="x-file")
- m_state=propFile;
- else if (attr.value("type").toLower()=="x-pluralform")
- m_state=propPluralForm;
- else if (attr.value("type").toLower()=="x-approved")
- m_state=propApproved;
- else
- m_state=null;
- }
- else if (qName=="seg")
- {
- m_state=seg;
- }
- else if (m_state==seg && m_lang!=Null)
- {
- InlineTag::InlineElement t=InlineTag::getElementType(qName.toLatin1());
- if (t!=InlineTag::_unknown)
- {
- m_segment[m_lang].string+=QChar(TAGRANGE_IMAGE_SYMBOL);
- int pos=m_segment[m_lang].string.size();
- m_inlineTags.append(InlineTag(pos, pos, t, attr.value("id")));
- }
- }
- return true;
-}
-
-bool TmxParser::endElement(const QString&,const QString&,const QString& qName)
-{
- static const char* tmxFilename="tmx-import";
- static const char* no="no";
- if (qName=="tu")
- {
- if (m_filePath.isEmpty())
- m_filePath=tmxFilename;
- if (!m_fileIds.contains(m_filePath))
- m_fileIds.insert(m_filePath,getFileId(m_filePath,db));
- qlonglong fileId=m_fileIds.value(m_filePath);
-
- if (!m_pluralForm.isEmpty())
- m_context+=TM_DELIMITER+m_pluralForm;
-
- qlonglong priorId=-1;
- bool ok=doInsertEntry(m_segment[Source],
- m_segment[Target],
- m_context,
- m_approvedString!=no,
- fileId,db,rxClean1,accel,priorId,priorId);
- if (Q_LIKELY( ok ))
- ++m_added;
- }
- else if (m_state==seg && m_lang!=Null)
- {
- InlineTag::InlineElement t=InlineTag::getElementType(qName.toLatin1());
- if (t!=InlineTag::_unknown)
- {
- InlineTag tag=m_inlineTags.takeLast();
- kWarning(TM_AREA)<<qName<<tag.getElementName();
-
- if (tag.isPaired())
- {
- tag.end=m_segment[m_lang].string.size();
- m_segment[m_lang].string+=QChar(TAGRANGE_IMAGE_SYMBOL);
- }
- m_segment[m_lang].tags.append(tag);
- }
- }
- m_state=null;
- return true;
-}
-
-
-
-bool TmxParser::characters ( const QString& ch )
-{
- if(m_state==seg && m_lang!=Null)
- m_segment[m_lang].string+=ch;
- else if(m_state==propFile)
- m_filePath+=ch;
- else if(m_state==propContext)
- m_context+=ch;
- else if(m_state==propPluralForm)
- m_pluralForm+=ch;
- else if(m_state==propApproved)
- m_approvedString+=ch;
-
- return true;
-}
-
-
-
-
-
-ImportTmxJob::ImportTmxJob(const QString& filename,//const KUrl& url,
- const QString& dbName,
- QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_filename(filename)
- , m_dbName(dbName)
-{
-}
-
-ImportTmxJob::~ImportTmxJob()
-{
- kWarning(TM_AREA) <<"ImportTmxJob dtor ";
-}
-
-void ImportTmxJob::run()
-{
- thread()->setPriority(QThread::IdlePriority);
- QTime a;a.start();
-
- QFile file(m_filename);
- if (!file.open(QFile::ReadOnly | QFile::Text))
- return;
-
- TmxParser parser(m_dbName);
- QXmlSimpleReader reader;
- reader.setContentHandler(&parser);
-
- QXmlInputSource xmlInputSource(&file);
- if (!reader.parse(xmlInputSource))
- kWarning(TM_AREA) << "failed to load "<< m_filename;
-
- //kWarning(TM_AREA) <<"Done scanning "<<m_url.prettyUrl();
- m_time=a.elapsed();
-}
-
-
-
-
-#include <qxmlstream.h>
-
-ExportTmxJob::ExportTmxJob(const QString& filename,//const KUrl& url,
- const QString& dbName,
- QObject* parent)
- : ThreadWeaver::Job(parent)
- , m_filename(filename)
- , m_dbName(dbName)
-{
-}
-
-ExportTmxJob::~ExportTmxJob()
-{
- kWarning(TM_AREA) <<"ExportTmxJob dtor ";
-}
-
-void ExportTmxJob::run()
-{
- thread()->setPriority(QThread::IdlePriority);
- QTime a;a.start();
-
- QFile out(m_filename);
- if (!out.open(QFile::WriteOnly|QFile::Text))
- return;
-
- QXmlStreamWriter xmlOut(&out);
- xmlOut.setAutoFormatting(true);
- xmlOut.writeStartDocument("1.0");
-
-
-
- xmlOut.writeStartElement("tmx");
- xmlOut.writeAttribute("version","2.0");
-
- xmlOut.writeStartElement("header");
- xmlOut.writeAttribute("creationtool","lokalize");
- xmlOut.writeAttribute("creationtoolversion",LOKALIZE_VERSION);
- xmlOut.writeAttribute("segtype","paragraph");
- xmlOut.writeAttribute("o-encoding","UTF-8");
- xmlOut.writeEndElement();
-
- xmlOut.writeStartElement("body");
-
-
-
- QString dbLangCode=Project::instance()->langCode();
-
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
- QSqlQuery query1(db);
-
- if (Q_UNLIKELY(!query1.exec("SELECT main.id, main.ctxt, main.date, main.bits, "
- "source_strings.source, source_strings.source_accel, "
- "target_strings.target, target_strings.target_accel, "
- "files.path, main.change_date "
- "FROM main, source_strings, target_strings, files "
- "WHERE source_strings.id=main.source AND "
- "target_strings.id=main.target AND "
- "files.id=main.file")))
- kWarning(TM_AREA) <<"select error: " <<query1.lastError().text();
-
- TMConfig c=getConfig(db);
-
- while (query1.next())
- {
- QString source=makeAcceledString(query1.value(4).toString(),c.accel,query1.value(5));
- QString target=makeAcceledString(query1.value(6).toString(),c.accel,query1.value(7));
-
- xmlOut.writeStartElement("tu");
- xmlOut.writeAttribute("tuid",QString::number(query1.value(0).toLongLong()));
-
- xmlOut.writeStartElement("tuv");
- xmlOut.writeAttribute("xml:lang","en");
- xmlOut.writeStartElement("seg");
- xmlOut.writeCharacters(source);
- xmlOut.writeEndElement();
- xmlOut.writeEndElement();
-
- xmlOut.writeStartElement("tuv");
- xmlOut.writeAttribute("xml:lang",dbLangCode);
- xmlOut.writeAttribute("creationdate",QDate::fromString( query1.value(2).toString(), Qt::ISODate ).toString("yyyyMMdd"));
- xmlOut.writeAttribute("changedate",QDate::fromString( query1.value(9).toString(), Qt::ISODate ).toString("yyyyMMdd"));
- QString ctxt=query1.value(1).toString();
- if (!ctxt.isEmpty())
- {
- int pos=ctxt.indexOf(TM_DELIMITER);
- if (pos!=-1)
- {
- QString plural=ctxt;
- plural.remove(0,pos+1);
- ctxt.remove(pos, plural.size());
- xmlOut.writeStartElement("prop");
- xmlOut.writeAttribute("type","x-pluralform");
- xmlOut.writeCharacters(plural);
- xmlOut.writeEndElement();
- }
- if (!ctxt.isEmpty())
- {
- xmlOut.writeStartElement("prop");
- xmlOut.writeAttribute("type","x-context");
- xmlOut.writeCharacters(ctxt);
- xmlOut.writeEndElement();
- }
- }
- QString filePath=query1.value(8).toString();
- if (!filePath.isEmpty())
- {
- xmlOut.writeStartElement("prop");
- xmlOut.writeAttribute("type","x-file");
- xmlOut.writeCharacters(filePath);
- xmlOut.writeEndElement();
- }
- qlonglong bits=query1.value(8).toLongLong();
- if (bits&TM_NOTAPPROVED)
- if (!filePath.isEmpty())
- {
- xmlOut.writeStartElement("prop");
- xmlOut.writeAttribute("type","x-approved");
- xmlOut.writeCharacters("no");
- xmlOut.writeEndElement();
- }
- xmlOut.writeStartElement("seg");
- xmlOut.writeCharacters(target);
- xmlOut.writeEndElement();
- xmlOut.writeEndElement();
- xmlOut.writeEndElement();
-
-
-
- }
- query1.clear();
-
-
- xmlOut.writeEndDocument();
- out.close();
-
- kWarning(TM_AREA) <<"Done exporting "<<a.elapsed();
- m_time=a.elapsed();
-}
-
-
-//END TMX
-
-
-ExecQueryJob::ExecQueryJob(const QString& queryString, const QString& dbName, QObject* parent)
- : ThreadWeaver::Job(parent)
- , query(0)
- , m_dbName(dbName)
- , m_query(queryString)
-{
- kDebug(TM_AREA)<<dbName<<queryString;
-}
-
-ExecQueryJob::~ExecQueryJob()
-{
- delete query;
- kDebug(TM_AREA)<<"destroy";
-}
-
-void ExecQueryJob::run()
-{
- QSqlDatabase db=QSqlDatabase::database(m_dbName);
- kDebug(TM_AREA)<<"running"<<m_dbName<<"db.isOpen() ="<<db.isOpen();
- //temporarily:
- if (!db.isOpen())
- kWarning(TM_AREA)<<"db.open()="<<db.open();
- query=new QSqlQuery(m_query,db);
- query->exec();
- kDebug(TM_AREA)<<"done"<<query->lastError().text();
-}
-
-
-
-#include "moc_jobs.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef JOBS_H
-#define JOBS_H
-
-#include "pos.h"
-#include "tmentry.h"
-
-#include <threadweaver/Job.h>
-#include <kurl.h>
-#include <QString>
-#include <QSqlDatabase>
-#include <QSqlQuery>
-
-/**
- * Translation Memory classes. see initDb() function for the database scheme
- */
-namespace TM {
-
-#define TM_DATABASE_EXTENSION ".db"
-#define REMOTETM_DATABASE_EXTENSION ".remotedb"
-enum DbType {Local, Remote}; //is needed only on opening
-
-#define TM_AREA 8111
-
-
-
-#define CLOSEDB 10001
-#define OPENDB 10000
-#define TMTABSELECT 100
-#define UPDATE 80
-#define REMOVE 70
-#define INSERT 60
-#define SELECT 50
-#define BATCHSELECTFINISHED 49
-#define IMPORT 30
-#define EXPORT 25
-#define SCAN 10
-#define SCANFINISHED 9
-
-
-struct TMConfig
-{
- QString markup;
- QString accel;
- QString sourceLangCode;
- QString targetLangCode;
-};
-
-void cancelAllJobs(); //HACK because threadweaver's dequeue is not workin'
-
-//called on startup
-class OpenDBJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- struct ConnectionParams
- {
- QString driver, host, db, user, passwd;
- bool isFilled(){return !host.isEmpty() && !db.isEmpty() && !user.isEmpty();}
- };
-
- explicit OpenDBJob(const QString& dbName, DbType type=TM::Local, bool reconnect=false, const ConnectionParams& connParams=ConnectionParams(), QObject* parent=0);
- ~OpenDBJob();
-
- int priority()const{return OPENDB;}
-
- struct DBStat{int pairsCount,uniqueSourcesCount,uniqueTranslationsCount;};
-
-protected:
- void run ();
-
-public:
- QString m_dbName;
- DbType m_type;
- //statistics
- DBStat m_stat;
-
- //for the new DB creation
- TMConfig m_tmConfig;
- bool m_setParams;
-
- bool m_connectionSuccessful;
- bool m_reconnect;
- ConnectionParams m_connParams;
-};
-
-//called on startup
-class CloseDBJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit CloseDBJob(const QString& dbName, QObject* parent=0);
- ~CloseDBJob();
-
- int priority()const{return CLOSEDB;}
- QString dbName(){return m_dbName;}
-
-protected:
- void run ();
-
- QString m_dbName;
- //statistics?
-};
-
-
-
-
-class SelectJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- SelectJob(const CatalogString& source,
- const QString& ctxt,
- const QString& file,
- const DocPosition&,//for back tracking
- const QString& dbName,
- QObject* parent=0);
- ~SelectJob();
-
- int priority()const{return SELECT;}
-
-protected:
- void run ();
- void aboutToBeDequeued(ThreadWeaver::WeaverInterface*);
-
-private:
- //returns true if seen translation with >85%
- bool doSelect(QSqlDatabase&,
- QStringList& words,
- bool isShort);
-
-public:
- CatalogString m_source;
-private:
- QString m_ctxt;
- QString m_file;
- bool m_dequeued;
-
-public:
- DocPosition m_pos;
- QList<TMEntry> m_entries;
-
- QString m_dbName;
-};
-
-enum {Enqueue=1};
-SelectJob* initSelectJob(Catalog*, DocPosition pos, QString db=QString(), int opt=Enqueue);
-
-
-
-class RemoveJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit RemoveJob(const TMEntry& entry, QObject* parent=0);
- ~RemoveJob();
- int priority()const{return REMOVE;}
-
-protected:
- void run();
-
- TMEntry m_entry;
-};
-
-
-/**
- * used to eliminate a lot of duplicate entries
- *
- * it is supposed to run on entry switch/file close in Editor
-**/
-//TODO a mechanism to get rid of dead dups (use strigi?).
-//also, display usage of different translations and suggest user
-//to use only one of them (listview, checkboxes)
-class UpdateJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit UpdateJob(const QString& filePath,
- const QString& ctxt,
- const CatalogString& en,
- const CatalogString& newTarget,
- int form,
- bool approved,
- //const DocPosition&,//for back tracking
- const QString& dbName,
- QObject* parent=0);
-
- ~UpdateJob(){}
-
- int priority()const{return UPDATE;}
-
-protected:
- void run ();
-// public:
-
-private:
- QString m_filePath;
- QString m_ctxt;
- CatalogString m_english;
- CatalogString m_newTarget;
- int m_form;
- bool m_approved;
- QString m_dbName;
-};
-
-//scan one file
-class ScanJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit ScanJob(const KUrl& url,
- const QString& dbName,
- QObject* parent=0);
- ~ScanJob();
-
- int priority()const{return SCAN;}
-
-protected:
- void run ();
-public:
- KUrl m_url;
-
- //statistics
- ushort m_time;
- ushort m_added;
- ushort m_newVersions;//e1.english==e2.english, e1.target!=e2.target
-
- int m_size;
-
- QString m_dbName;
-};
-
-
-//helper
-class BatchSelectFinishedJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit BatchSelectFinishedJob(QWidget* view,QObject* parent=0)
- : ThreadWeaver::Job(parent)
- , m_view(view)
- {}
- ~BatchSelectFinishedJob(){};
-
- int priority()const{return BATCHSELECTFINISHED;}
-
-protected:
- void run (){};
-public:
- QWidget* m_view;
-};
-#if 0
-we use index stored in db now...
-
-
-
-//create index --called on startup
-class IndexWordsJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- IndexWordsJob(QObject* parent=0);
- ~IndexWordsJob();
-
- int priority()const{return 100;}
-
-protected:
- void run ();
-public:
- TMWordHash m_tmWordHash;
-
- //statistics?
-};
-#endif
-
-
-
-
-
-
-class ImportTmxJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit ImportTmxJob(const QString& url,
- const QString& dbName,
- QObject* parent=0);
- ~ImportTmxJob();
-
- int priority()const{return IMPORT;}
-
-protected:
- void run ();
-public:
- QString m_filename;
-
- //statistics
- ushort m_time;
- ushort m_added;
- ushort m_newVersions;//e1.english==e2.english, e1.target!=e2.target
-
- QString m_dbName;
-};
-
-// #if 0
-
-class ExportTmxJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit ExportTmxJob(const QString& url,
- const QString& dbName,
- QObject* parent=0);
- ~ExportTmxJob();
-
- int priority()const{return IMPORT;}
-
-protected:
- void run ();
-public:
- QString m_filename;
-
- //statistics
- ushort m_time;
- ushort m_added;
- ushort m_newVersions;//e1.english==e2.english, e1.target!=e2.target
-
- QString m_dbName;
-};
-
-// #endif
-}
-
-class ExecQueryJob: public ThreadWeaver::Job
-{
- Q_OBJECT
-public:
- explicit ExecQueryJob(const QString& queryString, const QString& dbName, QObject* parent=0);
- ~ExecQueryJob();
-
- int priority()const{return TMTABSELECT;}
-
-
- QSqlQuery* query;
-protected:
- void run ();
-
- QString m_dbName;
- QString m_query;
- //statistics?
-};
-
-
-#endif
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>TMManager</class>
- <widget class="QWidget" name="TMManager">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>557</width>
- <height>401</height>
- </rect>
- </property>
- <layout class="QGridLayout">
- <item row="3" column="0">
- <layout class="QHBoxLayout">
- <item>
- <widget class="QPushButton" name="create">
- <property name="text">
- <string>Create</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="addData">
- <property name="text">
- <string>Add Data</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="importTMX">
- <property name="text">
- <string>Add Data from TMX</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="exportTMX">
- <property name="text">
- <string>Export to TMX</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="remove">
- <property name="text">
- <string>Remove</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="0">
- <widget class="QTreeView" name="list">
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="uniformRowHeights">
- <bool>true</bool>
- </property>
- <property name="itemsExpandable">
- <bool>false</bool>
- </property>
- <property name="allColumnsShowFocus">
- <bool>true</bool>
- </property>
- <property name="expandsOnDoubleClick">
- <bool>false</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node>
- <interface name="org.kde.Lokalize.TranslationMemory">
- <method name="findGuiText">
- <arg type="b" direction="out"/>
- <arg name="text" type="s" direction="in"/>
- </method>
- <method name="findGuiTextPackage">
- <arg type="b" direction="out"/>
- <arg name="text" type="s" direction="in"/>
- <arg name="package" type="s" direction="in"/>
- </method>
- </interface>
-</node>
+++ /dev/null
-/*
- This file is part of Lokalize
- Copyright (C) 2011-2012 Nick Shaforostoff <shafff@ukr.net>
-
- 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 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-
-#include "qamodel.h"
-#include "domroutines.h"
-#include <QStringList>
-#include <klocalizedstring.h>
-#include <QFile>
-#include <QTextStream>
-#include <QCoreApplication>
-
-static QString ruleTagNames[]={QString("source"), QString("falseFriend"), QString("target")};
-
-static QStringList domListToStringList(const QDomNodeList& nodes)
-{
- QStringList result;
- result.reserve(nodes.size());
- for (int i=0;i<nodes.size();i++)
- result.append(nodes.at(i).toElement().text());
-
- return result;
-}
-
-static QRegExp domNodeToRegExp(const QDomNode& node)
-{
- QRegExp re(node.toElement().text());
- re.setMinimal(true);
- return re;
-}
-
-static QVector<QRegExp> domListToRegExpVector(const QDomNodeList& nodes)
-{
- QVector<QRegExp> result;
- result.reserve(nodes.size());
- for (int i=0;i<nodes.size();i++)
- result.append(domNodeToRegExp(nodes.at(i)));
-
- return result;
-}
-
-
-QaModel* QaModel::_instance=0;
-void QaModel::cleanupQaModel()
-{
- delete QaModel::_instance; QaModel::_instance = 0;
-}
-
-bool QaModel::isInstantiated()
-{
- return _instance!=0;
-}
-
-QaModel* QaModel::instance()
-{
- if (Q_UNLIKELY( _instance==0 )) {
- _instance=new QaModel;
- qAddPostRoutine(QaModel::cleanupQaModel);
- }
-
- return _instance;
-}
-
-
-QaModel::QaModel(QObject* parent): QAbstractListModel(parent)
-{
-}
-
-QaModel::~QaModel()
-{
- saveRules();
-}
-
-int QaModel::rowCount(const QModelIndex& parent) const
-{
- if (parent.isValid())
- return 0;
- return m_entries.count();
-}
-
-QVariant QaModel::headerData(int section, Qt::Orientation , int role) const
-{
- if (role!=Qt::DisplayRole)
- return QVariant();
-
- switch (section)
- {
- //case ID: return i18nc("@title:column","ID");
- case Source: return i18nc("@title:column Original text","Source");;
- case FalseFriend: return i18nc("@title:column Translator's false friend","False Friend");
- }
- return QVariant();
-}
-
-
-QVariant QaModel::data(const QModelIndex& item, int role) const
-{
- if (role==Qt::ToolTipRole)
- return m_filename;
-
- if (role!=Qt::DisplayRole && role!=Qt::EditRole)
- return QVariant();
-
- static const QString nl("\n");
- const QDomElement& entry=m_entries.at(item.row()).toElement();
- return domListToStringList(entry.elementsByTagName(ruleTagNames[item.column()])).join(nl);
- return QVariant();
-}
-
-QVector<Rule> QaModel::toVector() const
-{
- QVector<Rule> rules;
- QDomNodeList m_categories=m_doc.elementsByTagName("category");
- for (int i=0;i<m_categories.size();i++)
- {
- static const QString ruleTagName("rule");
- QDomNodeList m_rules=m_categories.at(i).toElement().elementsByTagName(ruleTagName);
- for (int j=0;j<m_rules.size();j++)
- {
- Rule rule;
- rule.sources=domListToRegExpVector(m_rules.at(j).toElement().elementsByTagName(ruleTagNames[Source]));
- rule.falseFriends=domListToRegExpVector(m_rules.at(j).toElement().elementsByTagName(ruleTagNames[FalseFriend]));
- rule.targets=domListToRegExpVector(m_rules.at(j).toElement().elementsByTagName("target"));
- rules.append(rule);
- }
- }
- return rules;
-}
-
-bool QaModel::loadRules(const QString& filename)
-{
- QFile file(filename);
- if (file.open(QIODevice::ReadOnly))
- {
- bool ok=m_doc.setContent(&file);
- file.close();
- if (!ok)
- return false;
- }
- else
- {
- m_doc.setContent(QByteArray(
-"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
-"<qa version=\"1.0\">\n"
-" <category name=\"default\">\n"
-" </category>\n"
-"</qa>\n"));
- }
-
- m_entries=m_doc.elementsByTagName("rule");
- m_filename=filename;
- return true;
-}
-
-bool QaModel::saveRules(QString filename)
-{
- if (filename.isEmpty())
- filename=m_filename;
-
- if (filename.isEmpty())
- return false;
-
- QFile device(filename);
- if (!device.open(QFile::WriteOnly | QFile::Truncate))
- return false;
- QTextStream stream(&device);
- m_doc.save(stream,2);
-
- //setClean(true);
- return true;
-}
-
-
-QModelIndex QaModel::appendRow()
-{
- beginInsertRows(QModelIndex(),rowCount(),rowCount());
-
- QDomElement category=m_doc.elementsByTagName("qa").at(0).toElement().elementsByTagName("category").at(0).toElement();
- QDomElement rule=category.appendChild(m_doc.createElement("rule")).toElement();
- rule.appendChild(m_doc.createElement(ruleTagNames[Source]));
- rule.appendChild(m_doc.createElement(ruleTagNames[FalseFriend]));
-
- endInsertRows();
-
- return index(m_entries.count()-1);
-}
-
-void QaModel::removeRow(const QModelIndex& rowIndex)
-{
- //TODO optimize for contiguous selections
- beginRemoveRows(QModelIndex(),rowIndex.row(),rowIndex.row());
-
- QDomElement category=m_doc.elementsByTagName("qa").at(0).toElement().elementsByTagName("category").at(0).toElement();
- category.removeChild(m_entries.at(rowIndex.row()));
-
- endRemoveRows();
-}
-
-
-Qt::ItemFlags QaModel::flags(const QModelIndex& ) const
-{
- return Qt::ItemIsSelectable|Qt::ItemIsEnabled|Qt::ItemIsEditable;
-}
-
-bool QaModel::setData(const QModelIndex& item, const QVariant& value, int role)
-{
- if (role!=Qt::DisplayRole && role!=Qt::EditRole)
- return false;
-
- QDomElement entry=m_entries.at(item.row()).toElement();
- QDomNodeList sources=entry.elementsByTagName(ruleTagNames[item.column()]);
-
- QStringList newSources=value.toString().split('\n');
- while(sources.size()<newSources.size())
- entry.insertAfter(m_doc.createElement(ruleTagNames[item.column()]), sources.at(sources.size()-1));
-
- while(sources.size()>newSources.size())
- entry.removeChild(sources.at(sources.size()-1));
-
- for (int i=0;i<sources.size();i++)
- setText(sources.at(i).toElement(), newSources.at(i));
-
- emit dataChanged(item, item);
- return true;
-}
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef QAMODEL_H
-#define QAMODEL_H
-
-#include "rule.h"
-#include <QtCore/qabstractitemmodel.h>
-#include <QtXml/qdom.h>
-
-class QaModel: public QAbstractListModel
-{
- //Q_OBJECT
-public:
-
- enum Columns
- {
- //ID = 0,
- Source = 0,
- FalseFriend,
- ColumnCount
- };
-
- QaModel(QObject* parent=0/*, Glossary* glossary*/);
- ~QaModel();
-
- bool loadRules(const QString& filename);
- bool saveRules(QString filename=QString());
-
- int rowCount(const QModelIndex& parent=QModelIndex()) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const {return ColumnCount;}
- QVariant headerData(int section,Qt::Orientation, int role = Qt::DisplayRole ) const;
- Qt::ItemFlags flags(const QModelIndex&) const;
- bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole);
- QVariant data(const QModelIndex&, int role=Qt::DisplayRole) const;
-
- QVector<Rule> toVector() const;
-
- QModelIndex appendRow();
- void removeRow(const QModelIndex&);
-
-
- static QaModel* instance();
- static bool isInstantiated();
-private:
- static QaModel* _instance;
- static void cleanupQaModel();
-
-
-private:
- QDomDocument m_doc;
- QDomNodeList m_entries;
- QString m_filename;
-};
-
-
-#endif // QAMODEL_H
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#include "qaview.h"
-#include "qamodel.h"
-#include "project.h"
-
-#include <KLocale>
-#include <QtXml/qdom.h>
-#include <QFile>
-#include <QAction>
-
-
-QaView::QaView(QWidget* parent)
- : QDockWidget ( i18nc("@title:window","Quality Assurance"), parent)
- , m_browser(new QTreeView(this))
-{
- if (!QaModel::isInstantiated())
- QaModel::instance()->loadRules(Project::instance()->qaPath());
- m_qaModel=QaModel::instance();
-
- setWidget(m_browser);
- m_browser->setModel(m_qaModel);
- m_browser->setRootIsDecorated(false);
- m_browser->setContextMenuPolicy(Qt::ActionsContextMenu);
-
- QAction* action=new QAction(i18nc("@action:inmenu", "Add"), m_browser);
- connect(action, SIGNAL(triggered()), this, SLOT(addRule()));
- m_browser->addAction(action);
-
- action=new QAction(i18nc("@action:inmenu", "Remove"), m_browser);
- connect(action, SIGNAL(triggered()), this, SLOT(removeRule()));
- m_browser->addAction(action);
-
- m_browser->setAlternatingRowColors(true);
-
- connect(m_qaModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), this, SIGNAL(rulesChanged()));
-}
-
-QaView::~QaView()
-{
-}
-
-bool QaView::loadRules(QString filename)
-{
- if (filename.isEmpty())
- filename=Project::instance()->qaPath();
-
- bool ok=m_qaModel->loadRules(filename);
- if (ok)
- m_filename=filename;
- return ok;
-}
-
-bool QaView::saveRules(QString filename)
-{
- return m_qaModel->saveRules(filename.isEmpty()?m_filename:filename);
-}
-
-QVector< Rule > QaView::rules() const
-{
- return m_qaModel->toVector();
-}
-
-
-void QaView::addRule()
-{
- QModelIndex newRule=m_qaModel->appendRow();
- m_browser->selectionModel()->select(newRule, QItemSelectionModel::ClearAndSelect);
- m_browser->edit(newRule);
-}
-
-void QaView::removeRule()
-{
- foreach(const QModelIndex& rowIndex, m_browser->selectionModel()->selectedRows())
- m_qaModel->removeRow(rowIndex);
-}
-
-int findMatchingRule(const QVector<Rule>& rules, const QString& source, const QString& target,
- QVector<StartLen>& positions)
-{
- for(QVector<Rule>::const_iterator it=rules.constBegin();it!=rules.constEnd();it++)
- {
- if (it->sources.first().indexIn(source)!=-1)
- {
- if (it->falseFriends.first().indexIn(target)!=-1)
- {
- if (positions.size())
- {
- positions[0].start=it->sources.first().pos();
- positions[0].len=it->sources.first().matchedLength();
- positions[1].start=it->falseFriends.first().pos();
- positions[1].len=it->falseFriends.first().matchedLength();
- }
- return it-rules.constBegin();
- }
- }
- }
- return -1;
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef QAVIEW_H
-#define QAVIEW_H
-
-#include <QDockWidget>
-#include <QTreeView>
-#include <QtXml/qdom.h>
-
-#include "rule.h"
-
-class QaModel;
-
-class QaView: public QDockWidget
-{
- Q_OBJECT
-
-public:
- QaView(QWidget*);
- ~QaView();
-
- bool loadRules(QString filename=QString());
- bool saveRules(QString filename=QString());
- QVector<Rule> rules() const;
-
-public slots:
- void addRule();
- void removeRule();
-
-signals:
- void rulesChanged();
-
-private:
- QTreeView* m_browser;
- QaModel* m_qaModel;
- QString m_filename;
-
- QVector<Rule> m_rules;
-};
-
-int findMatchingRule(const QVector<Rule>& rules, const QString& source, const QString& target,
- QVector<StartLen>& positions);
-
-#endif // QAVIEW_H
-
-
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>QueryOptions</class>
- <widget class="QWidget" name="QueryOptions">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>600</width>
- <height>278</height>
- </rect>
- </property>
- <layout class="QVBoxLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QLabel" name="label">
- <property name="text">
- <string>TM:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="dbName"/>
- </item>
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <layout class="QHBoxLayout" name="queryLayout">
- <property name="sizeConstraint">
- <enum>QLayout::SetMinimumSize</enum>
- </property>
- <item>
- <layout class="QGridLayout" name="mainQueryLayout">
- <item row="1" column="1">
- <widget class="KLineEdit" name="querySource">
- <property name="toolTip">
- <string>Search expression for source language part.
-Press Enter to start the search.
-Press Ctrl+L to go to this control.</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="KLineEdit" name="queryTarget">
- <property name="toolTip">
- <string>Search expression for target language part.
-Press Enter to start the search.</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="querySourceLabel">
- <property name="text">
- <string>Source:</string>
- </property>
- <property name="buddy">
- <cstring>querySource</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="queryTargetLabel">
- <property name="text">
- <string>Target:</string>
- </property>
- <property name="buddy">
- <cstring>queryTarget</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="QCheckBox" name="invertTarget">
- <property name="toolTip">
- <string>Show results that do not match search expression</string>
- </property>
- <property name="text">
- <string>Invert</string>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="QCheckBox" name="invertSource">
- <property name="toolTip">
- <string>Show results that do not match search expression</string>
- </property>
- <property name="text">
- <string>Invert</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QGridLayout" name="optionsLayout">
- <item row="1" column="1">
- <widget class="QLabel" name="label_2">
- <property name="toolTip">
- <string/>
- </property>
- <property name="text">
- <string>File mask:</string>
- </property>
- <property name="buddy">
- <cstring>filemask</cstring>
- </property>
- </widget>
- </item>
- <item row="1" column="2">
- <widget class="KLineEdit" name="filemask">
- <property name="sizePolicy">
- <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Show only results from files with path matching specified mask</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="label_s">
- <property name="text">
- <string>Query syntax:</string>
- </property>
- <property name="buddy">
- <cstring>queryStyle</cstring>
- </property>
- </widget>
- </item>
- <item row="2" column="2">
- <widget class="KComboBox" name="queryStyle">
- <property name="currentIndex">
- <number>-1</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="line_2">
- <property name="orientation">
- <enum>Qt::Vertical</enum>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="buttonsLayout">
- <item>
- <widget class="QPushButton" name="doFind">
- <property name="text">
- <string>&Search</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="doUpdateTM">
- <property name="toolTip">
- <string>Reads all project files into translation memory, updating old entries. The scanning will work in background.</string>
- </property>
- <property name="text">
- <string>&Rescan project files</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QTreeView" name="treeView">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="alternatingRowColors">
- <bool>true</bool>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="wordWrap">
- <bool>true</bool>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>KComboBox</class>
- <extends>QComboBox</extends>
- <header>kcombobox.h</header>
- </customwidget>
- <customwidget>
- <class>KLineEdit</class>
- <extends>QLineEdit</extends>
- <header>klineedit.h</header>
- </customwidget>
- </customwidgets>
- <tabstops>
- <tabstop>querySource</tabstop>
- <tabstop>queryTarget</tabstop>
- <tabstop>doFind</tabstop>
- <tabstop>invertSource</tabstop>
- <tabstop>invertTarget</tabstop>
- <tabstop>filemask</tabstop>
- <tabstop>queryStyle</tabstop>
- <tabstop>doUpdateTM</tabstop>
- <tabstop>treeView</tabstop>
- <tabstop>dbName</tabstop>
- </tabstops>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef QARULE_H
-#define QARULE_H
-
-#include <QVector>
-#include <QString>
-#include <QRegExp>
-
-struct StringRule
-{
- QVector<QString> sources;
- QVector<QString> targets;
- QVector<QString> falseFriends;
-};
-
-struct Rule
-{
- QVector<QRegExp> sources;
- QVector<QRegExp> targets;
- QVector<QRegExp> falseFriends;
-};
-
-struct StartLen
-{
- short start;
- short len;
-
- StartLen(short s=0, short l=0):start(s), len(l){}
-};
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-
-**************************************************************************** */
-
-#ifndef TMENTRY_H
-#define TMENTRY_H
-
-#include "catalogstring.h"
-
-#include <QString>
-#include <QtCore/qdatetime.h>
-
-namespace TM {
-
-struct TMEntry
-{
- CatalogString source;
- CatalogString target;
-
- QString ctxt;
- QString file;
- QDate date;
- QDate changeDate;
- QString changeAuthor;
-
- //the remaining are used only for results
- qlonglong id;
- short score:16;//100.00%==10000
- ushort hits:15;
- bool obsolete:1;
- QString dbName;
-
- QString diff;
-
- //different databases can have different settings:
- QString accelExpr;
- QString markupExpr;
-
- bool operator<(const TMEntry& other) const
- {
- if (score==other.score)
- {
- if (hits==other.hits)
- return date<other.date;
- return hits<other.hits;
- }
- return score<other.score;
- }
-
- TMEntry():hits(0){}
-};
-
-}
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#include "tmmanager.h"
-#include "ui_managedatabases.h"
-#include "dbfilesmodel.h"
-#include "tmtab.h"
-#include "jobs.h"
-#include "tmscanapi.h"
-#include "project.h"
-#include "languagelistmodel.h"
-
-#include <QTimer>
-#include <QSortFilterProxyModel>
-#include <kfiledialog.h>
-#include <kdebug.h>
-// #include <kstandarddirs.h>
-#include <threadweaver/ThreadWeaver.h>
-#include <kstandarddirs.h>
-
-using namespace TM;
-
-TMManagerWin::TMManagerWin(QWidget *parent)
- : KMainWindow(parent)
-{
- setAttribute(Qt::WA_DeleteOnClose, false);
- setCaption(i18nc("@title:window", "Translation Memories"));
- setCentralWidget(new QWidget(this));
- Ui_TMManager ui_tmManager;
- ui_tmManager.setupUi(centralWidget());
-
- ui_tmManager.list->setModel(DBFilesModel::instance());
- ui_tmManager.list->setRootIndex(DBFilesModel::instance()->rootIndex());
- m_tmListWidget=ui_tmManager.list;
-
- connect(ui_tmManager.addData, SIGNAL(clicked(bool)),this,SLOT(addDir()));
- connect(ui_tmManager.create, SIGNAL(clicked(bool)),this,SLOT(addDB()));
- connect(ui_tmManager.importTMX,SIGNAL(clicked(bool)),this,SLOT(importTMX()));
- connect(ui_tmManager.exportTMX,SIGNAL(clicked(bool)),this,SLOT(exportTMX()));
- connect(ui_tmManager.remove, SIGNAL(clicked(bool)),this,SLOT(removeDB()));
-
- QTimer::singleShot(100,this,SLOT(initLater()));
-}
-
-
-void TMManagerWin::initLater()
-{
- connect(m_tmListWidget,SIGNAL(activated(QModelIndex)),this,SLOT(slotItemActivated(QModelIndex)));
-
- QPersistentModelIndex* projectDBIndex=DBFilesModel::instance()->projectDBIndex();
- if (projectDBIndex)
- m_tmListWidget->setCurrentIndex(*projectDBIndex);
-}
-
-void TMManagerWin::addDir()
-{
- QModelIndex index=m_tmListWidget->currentIndex();
- if (!index.isValid())
- return;
-
- QString dir=KFileDialog::getExistingDirectory(KUrl("kfiledialog:///tm-food"),this,
- i18nc("@title:window","Select Directory to be scanned"));
- if (!dir.isEmpty())
- {
- QList<QUrl> dirs; dirs.append(QUrl(dir));
- scanRecursive(dirs,index.sibling(index.row(), 0).data().toString());
- }
-}
-
-
-DBPropertiesDialog::DBPropertiesDialog(QWidget* parent, const QString& dbName)
- : KDialog(parent), Ui_DBParams()
- , m_connectionOptionsValid(false)
-{
- setAttribute(Qt::WA_DeleteOnClose, true);
- setCaption( dbName.isEmpty()?i18nc("@title:window","New Translation Memory"):i18nc("@title:window","Translation Memory Properties"));
- setButtons( KDialog::Ok | KDialog::Cancel);
- enableButtonOk(false);
-
- setupUi(mainWidget());
- name->setFocus();
- connect(name, SIGNAL(textChanged(QString)), this, SLOT(feedbackRegardingAcceptable()));
-
- sourceLang->setModel(LanguageListModel::instance()->sortModel());
- targetLang->setModel(LanguageListModel::instance()->sortModel());
-
- if (dbName.isEmpty())
- {
- accel->setText(Project::instance()->accel());
- markup->setText(Project::instance()->markup());
- sourceLang->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode( Project::instance()->sourceLangCode() ));
- targetLang->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode( Project::instance()->targetLangCode() ));
- }
-
- connectionBox->hide();
- connect(dbType, SIGNAL(activated(int)), this, SLOT(setConnectionBoxVisible(int)));
- m_checkDelayer.setInterval(2000);
- m_checkDelayer.setSingleShot(true);
- connect(&m_checkDelayer, SIGNAL(timeout()), this, SLOT(checkConnectionOptions()));
- connect(this->dbName, SIGNAL(textChanged(QString)), &m_checkDelayer, SLOT(start()));
- connect(dbHost->lineEdit(), SIGNAL(textChanged(QString)), &m_checkDelayer, SLOT(start()));
- connect(dbUser, SIGNAL(textChanged(QString)), &m_checkDelayer, SLOT(start()));
- connect(dbPasswd, SIGNAL(textChanged(QString)), &m_checkDelayer, SLOT(start()));
-
- QStringList drivers=QSqlDatabase::drivers();
- if (drivers.contains("QPSQL"))
- dbType->addItem("PostgreSQL");
-}
-
-void DBPropertiesDialog::setConnectionBoxVisible(int type)
-{
- connectionBox->setVisible(type);
- contentBox->setVisible(!type || m_connectionOptionsValid);
-}
-
-void DBPropertiesDialog::feedbackRegardingAcceptable()
-{
- enableButtonOk(contentBox->isVisible() && !name->text().isEmpty());
-}
-
-void DBPropertiesDialog::checkConnectionOptions()
-{
- m_connectionOptionsValid=false;
- if (!connectionBox->isVisible() || name->text().isEmpty() || dbHost->currentText().isEmpty() || dbName->text().isEmpty() || dbUser->text().isEmpty())
- return;
-
- OpenDBJob::ConnectionParams connParams;
- connParams.driver="QPSQL";
- connParams.host=dbHost->currentText();
- connParams.db=dbName->text();
- connParams.user=dbUser->text();
- connParams.passwd=dbPasswd->text();
-
- OpenDBJob* openDBJob=new OpenDBJob(name->text(), TM::Remote, /*reconnect*/true, connParams);
- connect(openDBJob,SIGNAL(done(ThreadWeaver::Job*)),openDBJob,SLOT(deleteLater()));
- connect(openDBJob,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(openJobDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(openDBJob);
-}
-
-void DBPropertiesDialog::openJobDone(ThreadWeaver::Job* job)
-{
- if (!connectionBox->isVisible()) //smth happened while we were trying to connect
- return;
-
- OpenDBJob* openDBJob=static_cast<OpenDBJob*>(job);
- contentBox->setVisible(openDBJob->m_connectionSuccessful);
- enableButtonOk(openDBJob->m_connectionSuccessful);
- if (!openDBJob->m_connectionSuccessful)
- return;
-
- sourceLang->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode(openDBJob->m_tmConfig.sourceLangCode));
- targetLang->setCurrentIndex(LanguageListModel::instance()->sortModelRowForLangCode(openDBJob->m_tmConfig.targetLangCode));
- markup->setText(openDBJob->m_tmConfig.markup);
- accel->setText(openDBJob->m_tmConfig.accel);
- contentBox->show();
-
- dbHost->lineEdit()->setText(openDBJob->m_connParams.host);
- dbName->setText(openDBJob->m_connParams.db);
- dbUser->setText(openDBJob->m_connParams.user);
- dbPasswd->setText(openDBJob->m_connParams.passwd);
-}
-
-void DBPropertiesDialog::accept()
-{
- if (name->text().isEmpty() || !contentBox->isVisible())
- return;
-
- if (connectionBox->isVisible())
- {
- QFile rdb(KStandardDirs::locateLocal("appdata", name->text() + REMOTETM_DATABASE_EXTENSION));
- if (!rdb.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
- return;
-
- QTextStream rdbParams(&rdb);
- rdbParams<<"QPSQL"<<"\n";
- rdbParams<<dbHost->currentText()<<"\n";
- rdbParams<<dbName->text()<<"\n";
- rdbParams<<dbUser->text()<<"\n";
- rdbParams<<dbPasswd->text()<<"\n";
- }
-
- OpenDBJob* openDBJob=new OpenDBJob(name->text(), TM::DbType(connectionBox->isVisible()), true);
- connect(openDBJob,SIGNAL(done(ThreadWeaver::Job*)),DBFilesModel::instance(),SLOT(updateProjectTmIndex()));
-
- openDBJob->m_setParams=true;
- openDBJob->m_tmConfig.markup=markup->text();
- openDBJob->m_tmConfig.accel=accel->text();
- openDBJob->m_tmConfig.sourceLangCode=LanguageListModel::instance()->langCodeForSortModelRow(sourceLang->currentIndex());
- openDBJob->m_tmConfig.targetLangCode=LanguageListModel::instance()->langCodeForSortModelRow(targetLang->currentIndex());
-
- DBFilesModel::instance()->openDB(openDBJob);
- KDialog::accept();
-}
-
-void TMManagerWin::addDB()
-{
- DBPropertiesDialog* dialog=new DBPropertiesDialog(this);
- dialog->show();
-}
-
-void TMManagerWin::removeDB()
-{
- QModelIndex index=m_tmListWidget->currentIndex();
- if (index.isValid())
- DBFilesModel::instance()->removeTM(index);
-}
-
-
-void TMManagerWin::importTMX()
-{
- QString path=KFileDialog::getOpenFileName(KUrl("kfiledialog:///tmx"),
- i18n("*.tmx *.xml|TMX files\n*|All files"),
- this,
- i18nc("@title:window","Select TMX file to be imported into selected database"));
-
- QModelIndex index=m_tmListWidget->currentIndex();
- if (!index.isValid())
- return;
- QString dbName=index.sibling(index.row(), 0).data().toString();
-
- if (!path.isEmpty())
- {
- ImportTmxJob* j=new ImportTmxJob(path,dbName);
- connect(j,SIGNAL(failed(ThreadWeaver::Job*)),j,SLOT(deleteLater()));
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),j,SLOT(deleteLater()));
-
- ThreadWeaver::Weaver::instance()->enqueue(j);
- DBFilesModel::instance()->openDB(dbName); //update stats after it finishes
- }
-}
-
-
-void TMManagerWin::exportTMX()
-{
- //TODO ask whether to save full paths of files, or just their names
- QString path=KFileDialog::getSaveFileName(KUrl("kfiledialog:///tmx"),
- i18n("*.tmx *.xml|TMX files\n*|All files"),
- this,
- i18nc("@title:window","Select TMX file to export selected database to"));
-
- QModelIndex index=m_tmListWidget->currentIndex();
- if (!index.isValid())
- return;
- QString dbName=index.sibling(index.row(), 0).data().toString();
-
- if (!path.isEmpty())
- {
- ExportTmxJob* j=new ExportTmxJob(path,dbName);
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),j,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(j);
- }
-}
-
-void TMManagerWin::slotItemActivated(const QModelIndex&)
-{
- //QString dbName=DBFilesModel::instance()->data(m_tmListWidget->currentIndex()).toString();
-/* TMWindow* win=new TMWindow;
- win->selectDB(m_tmListWidget->currentIndex().row());
- win->show();*/
-}
-
-
-
-#include "moc_tmmanager.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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.
-
- In addition, as a special exception, the copyright holders give
- permission to link the code of this program with any edition of
- the Qt library by Trolltech AS, Norway (or with modified versions
- of Qt that use the same license as Qt), and distribute linked
- combinations including the two. You must obey the GNU General
- Public License in all respects for all of the code used other than
- Qt. If you modify this file, you may extend this exception to
- your version of the file, but you are not obligated to do so. If
- you do not wish to do so, delete this exception statement from
- your version.
-
-**************************************************************************** */
-
-#ifndef TMMANAGER_H
-#define TMMANAGER_H
-
-#include <kmainwindow.h>
-#include <QtCore/qabstractitemmodel.h>
-#include <QTimer>
-
-#include <QTreeView>
-
-#include "ui_dbparams.h"
-#include <kdialog.h>
-namespace ThreadWeaver {class Job;};
-
-namespace TM {
-/**
- * Window for managing Translation Memory databases
- */
-class TMManagerWin: public KMainWindow
-{
- Q_OBJECT
-public:
- TMManagerWin(QWidget *parent = 0);
- ~TMManagerWin(){};
-private slots:
- void addDir();
- void addDB();
- void importTMX();
- void exportTMX();
- void removeDB();
-
- void initLater();
- void slotItemActivated(const QModelIndex&);
-private:
- QTreeView* m_tmListWidget;
-};
-
-//TODO remote tms
-class DBPropertiesDialog: public KDialog, Ui_DBParams
-{
- Q_OBJECT
-public:
- DBPropertiesDialog(QWidget* parent, const QString& name=QString());
-private:
- //void slotButtonClicked(int button);
- void accept();
-private slots:
- void setConnectionBoxVisible(int type);
- void openJobDone(ThreadWeaver::Job*);
- void checkConnectionOptions();
- void feedbackRegardingAcceptable();
-private:
- bool m_connectionOptionsValid;
- QTimer m_checkDelayer;
-};
-
-
-
-}
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "tmscanapi.h"
-#include "jobs.h"
-#include "catalog.h"
-#include "prefs_lokalize.h"
-
-#include <kdebug.h>
-#include <kio/global.h>
-#include <kjob.h>
-#include <kjobtrackerinterface.h>
-#include <threadweaver/ThreadWeaver.h>
-#include "dbfilesmodel.h"
-#include <project.h>
-
-namespace TM {
- static QVector<ScanJob*> doScanRecursive(const QDir& dir, const QString& dbName, KJob* metaJob);
-}
-
-using namespace TM;
-
-RecursiveScanJob::RecursiveScanJob(const QString& dbName, QObject* parent)
- : KJob(parent)
- , m_dbName(dbName)
-{
- setCapabilities(KJob::Killable);
-}
-
-bool RecursiveScanJob::doKill()
-{
- foreach(ScanJob* job, m_jobs)
- ThreadWeaver::Weaver::instance()->dequeue(job);
- return true;
-}
-
-void RecursiveScanJob::setJobs(const QVector<ScanJob*>& jobs)
-{
- m_jobs=jobs;
- setTotalAmount(KJob::Files,jobs.size());
-
- if (!jobs.size())
- kill(KJob::EmitResult);
-}
-
-void RecursiveScanJob::scanJobFinished(ThreadWeaver::Job* j)
-{
- ScanJob* job=static_cast<ScanJob*>(j);
-
- setProcessedAmount(KJob::Files,processedAmount(KJob::Files)+1);
- emitPercent(processedAmount(KJob::Files),totalAmount(KJob::Files));
-
- setProcessedAmount(KJob::Bytes,processedAmount(KJob::Bytes)+job->m_size);
- emitSpeed(1000*processedAmount(KJob::Bytes)/m_time.elapsed());
-
-
- if (processedAmount(KJob::Files)==totalAmount(KJob::Files))
- {
- emitResult();
- kWarning()<<"finished in"<<m_time.elapsed()<<"msecs";
- }
-}
-
-void RecursiveScanJob::start()
-{
- m_time.start();
- emit description(this,
- i18n("Adding files to Lokalize translation memory"),
- qMakePair(i18n("TM"), m_dbName));
-}
-
-int TM::scanRecursive(const QList<QUrl>& urls, const QString& dbName)
-{
- RecursiveScanJob* metaJob = new RecursiveScanJob(dbName);
- KIO::getJobTracker()->registerJob(metaJob);
- metaJob->start();
-
- QVector<ScanJob*> result;
- int i=urls.size();
- while(--i>=0)
- {
- const QUrl& url=urls.at(i);
- if (url.isEmpty() || url.path().isEmpty() ) //NOTE is this a Qt bug?
- continue;
- if (Catalog::extIsSupported(url.path()))
- {
- ScanJob* job=new ScanJob(KUrl(url),dbName);
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),metaJob,SLOT(scanJobFinished(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- result.append(job);
- }
- else
- result+=doScanRecursive(QDir(url.toLocalFile()),dbName,metaJob);
- }
-
- metaJob->setJobs(result);
- DBFilesModel::instance()->openDB(dbName); //update stats after it finishes
-
- return result.size();
-}
-
-//returns gross number of jobs started
-static QVector<ScanJob*> TM::doScanRecursive(const QDir& dir, const QString& dbName,KJob* metaJob)
-{
- QVector<ScanJob*> result;
- QStringList subDirs(dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot|QDir::Readable));
- int i=subDirs.size();
- while(--i>=0)
- result+=TM::doScanRecursive(QDir(dir.filePath(subDirs.at(i))),dbName,metaJob);
-
- QStringList filters=Catalog::supportedExtensions();
- i=filters.size();
- while(--i>=0)
- filters[i].prepend('*');
- QStringList files(dir.entryList(filters,QDir::Files|QDir::NoDotAndDotDot|QDir::Readable));
- i=files.size();
-
- while(--i>=0)
- {
- ScanJob* job=new ScanJob(KUrl(dir.filePath(files.at(i))),dbName);
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- QObject::connect(job,SIGNAL(done(ThreadWeaver::Job*)),metaJob,SLOT(scanJobFinished(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- result.append(job);
- }
-
- return result;
-}
-
-bool dragIsAcceptable(const QList<QUrl>& urls)
-{
- int i=urls.size();
- while(--i>=0)
- {
- bool ok=Catalog::extIsSupported(urls.at(i).path());
- if (!ok)
- {
- QFileInfo info(urls.at(i).toLocalFile());
- ok=info.exists() && info.isDir();
- }
- if (ok)
- return true;
- }
- return false;
-}
-
-
-QString shorterFilePath(const QString path)
-{
- QString pDir=Project::instance()->projectDir();
- if (path.contains(pDir))//TODO cache projectDir?
- return KUrl::relativePath(pDir,path).mid(2);
- return path;
-}
-
-
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef SCANAPI_H
-#define SCANAPI_H
-
-#include <kjob.h>
-#include <QDir>
-#include <QUrl>
-#include <QtCore/qdatetime.h>
-#include <QVector>
-
-namespace ThreadWeaver{class Job;}
-
-bool dragIsAcceptable(const QList<QUrl>& urls);
-QString shorterFilePath(const QString path);
-
-
-namespace TM {
-class ScanJob;
-
-///wrapper. returns gross number of jobs started
-int scanRecursive(const QList<QUrl>& urls, const QString& dbName);
-
-class RecursiveScanJob: public KJob
-{
- Q_OBJECT
-public:
- RecursiveScanJob(const QString& dbName,QObject* parent=0);
- void setJobs(const QVector<ScanJob*>& jobs);
- void start();
-
-public slots:
- void scanJobFinished(ThreadWeaver::Job*);
-protected:
- bool doKill();
-
-private:
- QString m_dbName;
- QTime m_time;
- QVector<ScanJob*> m_jobs;
-};
-
-}
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "tmtab.h"
-#include "ui_queryoptions.h"
-#include "project.h"
-#include "dbfilesmodel.h"
-#include "tmscanapi.h"
-#include "qaview.h"
-
-#include <QApplication>
-#include <QDesktopWidget>
-#include <QTreeView>
-#include <QSqlQueryModel>
-#include <QSqlQuery>
-#include <QSqlRecord>
-#include <QButtonGroup>
-#include <QClipboard>
-#include <QShortcut>
-#include <QtGui/qevent.h>
-#include <QSortFilterProxyModel>
-#include <QStyledItemDelegate>
-#include <QTextDocument>
-#include <QTextCodec>
-#include <QStringListModel>
-
-#include <KColorScheme>
-#include <kactioncategory.h>
-#include <kaction.h>
-#include <klocale.h>
-#include <kstandarddirs.h>
-#include <kxmlguifactory.h>
-#include <threadweaver/ThreadWeaver.h>
-#include <fastsizehintitemdelegate.h>
-
-
-using namespace TM;
-//static int BIG_COUNTER=0;
-
-//TODO do things for case when user explicitly wants to find & accel mark
-
-//BEGIN TMDBModel
-TMDBModel::TMDBModel(QObject* parent)
- : QSqlQueryModel(parent)
- , m_queryType(WordOrder)
- , m_totalResultCount(0)
-{
- setHeaderData(TMDBModel::Source, Qt::Horizontal, i18nc("@title:column Original text","Source"));
- setHeaderData(TMDBModel::Target, Qt::Horizontal, i18nc("@title:column Text in target language","Target"));
- setHeaderData(TMDBModel::Context, Qt::Horizontal, i18nc("@title:column","Context"));
- setHeaderData(TMDBModel::Filepath, Qt::Horizontal, i18nc("@title:column","File"));
- setHeaderData(TMDBModel::TransationStatus, Qt::Horizontal, i18nc("@title:column","Translation Status"));
-}
-
-void TMDBModel::setDB(const QString& str)
-{
- m_dbName=str;
-}
-
-void TMDBModel::setQueryType(int type)
-{
- m_queryType=(QueryType)type;
-}
-
-void TMDBModel::setFilter(const QString& source, const QString& target,
- bool invertSource, bool invertTarget,
- const QString& filemask
- )
-{
- QString escapedSource(source);escapedSource.replace('\'',"''");
- QString escapedTarget(target);escapedTarget.replace('\'',"''");
- QString invertSourceStr; if (invertSource) invertSourceStr="NOT ";
- QString invertTargetStr; if (invertTarget) invertTargetStr="NOT ";
- QString escapedFilemask(filemask);escapedFilemask.replace('\'',"''");
- QString sourceQuery;
- QString targetQuery;
- QString fileQuery;
-
- if (m_queryType==SubStr)
- {
- escapedSource.replace('%',"\b%");escapedSource.replace('_',"\b_");
- escapedTarget.replace('%',"\b%");escapedTarget.replace('_',"\b_");
- if (!escapedSource.isEmpty())
- sourceQuery="AND source_strings.source " + invertSourceStr + "LIKE '%" + escapedSource + "%' ESCAPE '\b' ";
- if (!escapedTarget.isEmpty())
- targetQuery="AND target_strings.target " + invertTargetStr + "LIKE '%" + escapedTarget + "%' ESCAPE '\b' ";
- }
- else if (m_queryType==WordOrder)
- {
- /*escapedSource.replace('%',"\b%");escapedSource.replace('_',"\b_");
- escapedTarget.replace('%',"\b%");escapedTarget.replace('_',"\b_");*/
- QStringList sourceList=escapedSource.split(QRegExp("\\W"),QString::SkipEmptyParts);
- QStringList targetList=escapedTarget.split(QRegExp("\\W"),QString::SkipEmptyParts);
-
- if (!sourceList.isEmpty())
- sourceQuery="AND source_strings.source "+invertSourceStr+"LIKE '%"+sourceList.join("%' AND source_strings.source "+invertSourceStr+"LIKE '%")+"%' ";
- if (!targetList.isEmpty())
- targetQuery="AND target_strings.target "+invertTargetStr+"LIKE '%"+targetList.join("%' AND target_strings.target "+invertTargetStr+"LIKE '%")+"%' ";
- }
- else
- {
- if (!escapedSource.isEmpty())
- sourceQuery="AND source_strings.source " + invertSourceStr + "GLOB '" + escapedSource + "' ";
- if (!escapedTarget.isEmpty())
- targetQuery="AND target_strings.target " + invertTargetStr + "GLOB '" + escapedTarget + "' ";
-
- }
- if (!filemask.isEmpty())
- fileQuery="AND files.path GLOB '" + escapedFilemask + "' ";
-
- QString fromPart="FROM main JOIN source_strings ON (source_strings.id=main.source) "
- "JOIN target_strings ON (target_strings.id=main.target), files "
- "WHERE files.id=main.file "
- +sourceQuery
- +targetQuery
- +fileQuery;
-
- ExecQueryJob* job=new ExecQueryJob(
- "SELECT source_strings.source, target_strings.target, "
- "main.ctxt, files.path, "
- "source_strings.source_accel, target_strings.target_accel, main.bits "
- +fromPart,m_dbName);
-
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotQueryExecuted(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
-
-
- job=new ExecQueryJob("SELECT count(*) "+fromPart,m_dbName);
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotQueryExecuted(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(job);
-
- m_totalResultCount=0;
-}
-
-void TMDBModel::slotQueryExecuted(ThreadWeaver::Job* j)
-{
- ExecQueryJob* job=static_cast<ExecQueryJob*>(j);
- if (job->query->lastQuery().startsWith("SELECT count(*) "))
- {
- job->query->next();
- m_totalResultCount=job->query->value(0).toInt();
- emit finalResultCountFetched(m_totalResultCount);
- return;
- }
- setQuery(*(job->query));
- emit resultsFetched();
-}
-
-bool TMDBModel::rowIsApproved(int row) const
-{
- bool ok;
- qlonglong bits=record(row).value(TMDBModel::_Bits).toLongLong(&ok);
- return !(ok && bits&4);
-}
-
-int TMDBModel::translationStatus(const QModelIndex& item) const
-{
- if (QSqlQueryModel::data(item.sibling(item.row(),Target), Qt::DisplayRole).toString().isEmpty())
- return 2;
- return int(!rowIsApproved(item.row()));
-}
-
-#define TM_DELIMITER '\v'
-QVariant TMDBModel::data(const QModelIndex& item, int role) const
-{
- bool doHtml=(role==FastSizeHintItemDelegate::HtmlDisplayRole);
- if (doHtml)
- role=Qt::DisplayRole;
- else if (role==Qt::FontRole && item.column()==TMDBModel::Target) //TODO Qt::ForegroundRole -- brush for orphaned entries
- {
- QFont font=QApplication::font();
- font.setItalic(!rowIsApproved(item.row()));
- return font;
- }
- else if (role==FullPathRole && item.column()==TMDBModel::Filepath)
- return QSqlQueryModel::data(item, Qt::DisplayRole);
- else if (role==TransStateRole)
- return translationStatus(item);
-
- QVariant result=QSqlQueryModel::data(item, role);
-/* if (role==Qt::SizeHintRole && !result.isValid())
- BIG_COUNTER++;*/
- if (role!=Qt::DisplayRole)
- return result;
-
- if (item.column()==TMDBModel::Context)//context
- {
- QString r=result.toString();
- int pos=r.indexOf(TM_DELIMITER);
- if (pos!=-1)
- result=r.remove(pos, r.size());
- }
- else if (item.column()<TMDBModel::Context && !record(item.row()).isNull(TMDBModel::_SourceAccel+item.column()) )//source, target
- {
- const QVariant& posVar=record(item.row()).value(TMDBModel::_SourceAccel+item.column());
- int pos=-1;
- bool ok = false;
- if (posVar.isValid())
- pos=posVar.toInt(&ok);
- if (ok && pos!=-1)
- {
- QString r=result.toString();
- r.insert(pos,Project::instance()->accel());
- result=r;
- }
- }
- else if (item.column()==TMDBModel::Filepath)
- {
- return shorterFilePath(result.toString());
- }
- else if (item.column()==TMDBModel::TransationStatus)
- {
- static QString statuses[]={i18nc("@info:status 'non-fuzzy' in gettext terminology","Ready"),
- i18nc("@info:status 'fuzzy' in gettext terminology","Needs review"),
- i18nc("@info:status","Untranslated")};
- return statuses[translationStatus(item)];
- }
- if (doHtml && item.column()<TMDBModel::Context)
- return convertToHtml(result.toString(), item.column()==TMDBModel::Target && !rowIsApproved(item.row()));
- else
- return result;
-}
-
-//END TMDBModel
-
-//BEGIN TMResultsSortFilterProxyModel
-class TMResultsSortFilterProxyModel: public QSortFilterProxyModel
-{
-public:
- TMResultsSortFilterProxyModel(QObject *parent)
- : QSortFilterProxyModel(parent)
- {}
- void setRules(const QVector<Rule>& rules);
- void fetchMore(const QModelIndex& parent);
- QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
-
-protected:
- bool lessThan(const QModelIndex& left, const QModelIndex& right) const;
- bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const;
-
-private:
- QVector<Rule> m_rules;
- mutable QMap<int,int> m_matchingRulesForSourceRow;
- //mutable QMap<int, QVector<StartLen> > m_highlightDataForSourceRow;
-};
-
-bool TMResultsSortFilterProxyModel::lessThan(const QModelIndex& left, const QModelIndex& right) const
-{
- if (left.column()==TMDBModel::TransationStatus)
- {
- int l=left.data(TMDBModel::TransStateRole).toInt();
- int r=right.data(TMDBModel::TransStateRole).toInt();
- return l<r;
- }
- return QSortFilterProxyModel::lessThan(left, right);
-}
-
-void TMResultsSortFilterProxyModel::fetchMore(const QModelIndex& parent)
-{
- int oldSourceRowCount=sourceModel()->rowCount();
- int oldRowCount=rowCount();
- QSortFilterProxyModel::fetchMore(parent);
-
- if (m_rules.isEmpty())
- return;
-
- while (oldRowCount==rowCount())
- {
- QSortFilterProxyModel::fetchMore(parent);
- if (sourceModel()->rowCount()==oldSourceRowCount)
- break;
- oldSourceRowCount=sourceModel()->rowCount();
- }
- qDebug()<<"row count"<<sourceModel()->rowCount()<<" filtered:"<<rowCount();
- emit layoutChanged();
-}
-
-void TMResultsSortFilterProxyModel::setRules(const QVector<Rule>& rules)
-{
- m_rules=rules;
- m_matchingRulesForSourceRow.clear();
- invalidateFilter();
-}
-
-QVariant TMResultsSortFilterProxyModel::data(const QModelIndex& index, int role) const
-{
- QVariant result=QSortFilterProxyModel::data(index, role);
-
- if (m_rules.isEmpty() || role!=FastSizeHintItemDelegate::HtmlDisplayRole)
- return result;
-
- if (index.column()!=TMDBModel::Source && index.column()!=TMDBModel::Target)
- return result;
-
- int source_row=mapToSource(index).row();
- QString string=result.toString();
-
- QVector<QRegExp> regExps;
- if (index.column()==TMDBModel::Source)
- regExps=m_rules[m_matchingRulesForSourceRow[source_row]].sources;
- else
- regExps=m_rules[m_matchingRulesForSourceRow[source_row]].falseFriends;
-
- foreach(const QRegExp& re, regExps)
- {
- int pos=re.indexIn(string);
- if (pos!=-1)
- return string.replace(pos, re.matchedLength(), "<b>" + re.cap(0) + "</b>");
- }
-
- //StartLen sl=m_highlightDataForSourceRow.value(source_row).at(index.column());
-
- return result;
-}
-
-bool TMResultsSortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
-{
- if (m_rules.isEmpty())
- return true;
-
- QString source=sourceModel()->index(source_row, TMDBModel::Source, source_parent).data().toString();
- QString target=sourceModel()->index(source_row, TMDBModel::Target, source_parent).data().toString();
-
- static QVector<StartLen> dummy_positions;
- int i=findMatchingRule(m_rules, source, target, dummy_positions);
- bool accept=(i!=-1);
- if (accept)
- m_matchingRulesForSourceRow[source_row]=i;
-
- return accept;
-}
-//END TMResultsSortFilterProxyModel
-
-class QueryStylesModel: public QStringListModel
-{
-public:
- explicit QueryStylesModel(QObject* parent = 0);
- QVariant data(const QModelIndex& item, int role) const;
-};
-
-QueryStylesModel::QueryStylesModel(QObject* parent): QStringListModel(parent)
-{
- setStringList(QStringList(i18n("Substring"))<<i18n("Google-like")<<i18n("Wildcard"));
-}
-
-QVariant QueryStylesModel::data(const QModelIndex& item, int role) const
-{
- if (role==Qt::ToolTipRole)
- {
- static QString tooltips[]={i18n("Case insensitive"),
- i18n("Space is AND operator. Case insensitive."),
- i18n("Shell globs (* and ?). Case sensitive.")};
- return tooltips[item.row()];
- }
- return QStringListModel::data(item, role);
-}
-
-
-//BEGIN TMWindow
-TMTab::TMTab(QWidget *parent)
- : LokalizeSubwindowBase2(parent)
- , m_proxyModel(new TMResultsSortFilterProxyModel(this))
- , m_partToAlsoTryLater(DocPosition::UndefPart)
- , m_dbusId(-1)
-{
- //setCaption(i18nc("@title:window","Translation Memory"),false);
- setWindowTitle(i18nc("@title:window","Translation Memory"));
- setAcceptDrops(true);
-
- ui_queryOptions=new Ui_QueryOptions;
- QWidget* w=new QWidget(this);
- ui_queryOptions->setupUi(w);
- setCentralWidget(w);
- ui_queryOptions->queryLayout->setStretchFactor(ui_queryOptions->mainQueryLayout,42);
-
- connect(ui_queryOptions->querySource,SIGNAL(returnPressed()),this,SLOT(performQuery()));
- connect(ui_queryOptions->queryTarget,SIGNAL(returnPressed()),this,SLOT(performQuery()));
- connect(ui_queryOptions->filemask,SIGNAL(returnPressed()), this,SLOT(performQuery()));
- connect(ui_queryOptions->doFind,SIGNAL(clicked()), this,SLOT(performQuery()));
- connect(ui_queryOptions->doUpdateTM,SIGNAL(clicked()), this,SLOT(updateTM()));
-
- QShortcut* sh=new QShortcut(Qt::CTRL+Qt::Key_L, this);
- connect(sh,SIGNAL(activated()),ui_queryOptions->querySource,SLOT(setFocus()));
- setFocusProxy(ui_queryOptions->querySource);
-
- QTreeView* view=ui_queryOptions->treeView;
- view->setContextMenuPolicy(Qt::ActionsContextMenu);
-
- QAction* a=new QAction(i18n("Copy source to clipboard"),view);
- a->setShortcut(Qt::CTRL + Qt::Key_S);
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(copySource()));
- view->addAction(a);
-
- a=new QAction(i18n("Copy target to clipboard"),view);
- a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(copyTarget()));
- view->addAction(a);
-
- a=new QAction(i18n("Open file"),view);
- a->setShortcut(QKeySequence(Qt::Key_Return));
- a->setShortcutContext(Qt::WidgetWithChildrenShortcut);
- connect(a,SIGNAL(activated()), this, SLOT(openFile()));
- connect(view,SIGNAL(activated(QModelIndex)), this, SLOT(openFile()));
- view->addAction(a);
-
- //view->addAction(KStandardAction::copy(this),this,SLOT(),this);
- //QKeySequence::Copy?
- //QShortcut* shortcut = new QShortcut(Qt::CTRL + Qt::Key_P,view,0,0,Qt::WidgetWithChildrenShortcut);
- //connect(shortcut,SIGNAL(activated()), this, SLOT(copyText()));
-
- m_model = new TMDBModel(this);
- m_model->setDB(Project::instance()->projectID());
-
- m_proxyModel->setDynamicSortFilter(true);
- m_proxyModel->setSourceModel(m_model);
- view->setModel(m_proxyModel);
- view->sortByColumn(TMDBModel::Filepath,Qt::AscendingOrder);
- view->setSortingEnabled(true);
- view->setColumnHidden(TMDBModel::_SourceAccel,true);
- view->setColumnHidden(TMDBModel::_TargetAccel,true);
- view->setColumnHidden(TMDBModel::_Bits,true);
-
- QVector<bool> singleLineColumns(TMDBModel::ColumnCount, false);
- singleLineColumns[TMDBModel::Filepath]=true;
- singleLineColumns[TMDBModel::TransationStatus]=true;
- singleLineColumns[TMDBModel::Context]=true;
-
- QVector<bool> richTextColumns(TMDBModel::ColumnCount, false);
- richTextColumns[TMDBModel::Source]=true;
- richTextColumns[TMDBModel::Target]=true;
- view->setItemDelegate(new FastSizeHintItemDelegate(this,singleLineColumns,richTextColumns));
- connect(m_model,SIGNAL(resultsFetched()),view->itemDelegate(),SLOT(reset()));
- connect(m_model,SIGNAL(modelReset()),view->itemDelegate(),SLOT(reset()));
- //connect(m_model,SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),view->itemDelegate(),SLOT(reset()));
- connect(m_proxyModel,SIGNAL(layoutChanged()),view->itemDelegate(),SLOT(reset()));
- connect(m_proxyModel,SIGNAL(layoutChanged()),this,SLOT(displayTotalResultCount()));
-
-
- connect(m_model,SIGNAL(resultsFetched()),this,SLOT(handleResults()));
- connect(m_model,SIGNAL(finalResultCountFetched(int)),this,SLOT(displayTotalResultCount()));
-
- ui_queryOptions->queryStyle->setModel(new QueryStylesModel(this));
- connect(ui_queryOptions->queryStyle,SIGNAL(currentIndexChanged(int)),m_model,SLOT(setQueryType(int)));
-
- ui_queryOptions->dbName->setModel(DBFilesModel::instance());
- ui_queryOptions->dbName->setRootModelIndex(DBFilesModel::instance()->rootIndex());
- int pos=ui_queryOptions->dbName->findText(Project::instance()->projectID());
- if (pos>=0)
- ui_queryOptions->dbName->setCurrentIndex(pos);
- connect(ui_queryOptions->dbName, SIGNAL(activated(QString)), m_model, SLOT(setDB(QString)));
- //connect(ui_queryOptions->dbName, SIGNAL(activated(QString)), this, SLOT(performQuery()));
-
-//BEGIN resizeColumnToContents
- static const int maxInitialWidths[4]={QApplication::desktop()->availableGeometry().width()/3,QApplication::desktop()->availableGeometry().width()/3, 50, 200};
- int column=sizeof(maxInitialWidths)/sizeof(int);
- while (--column>=0)
- view->setColumnWidth(column, maxInitialWidths[column]);
-
-//END resizeColumnToContents
-
- int i=6;
- while (--i>ID_STATUS_PROGRESS)
- statusBarItems.insert(i,QString());
-
- setXMLFile("translationmemoryrui.rc",true);
- dbusObjectPath();
-
-
- KAction *action;
- KActionCollection* ac=actionCollection();
- KActionCategory* tm=new KActionCategory(i18nc("@title actions category","Translation Memory"), ac);
-
- action = tm->addAction("tools_tm_manage",Project::instance(),SLOT(showTMManager()));
- action->setText(i18nc("@action:inmenu","Manage translation memories"));
-
- m_qaView = new QaView(this);
- m_qaView->hide();
- addDockWidget(Qt::RightDockWidgetArea, m_qaView);
- tm->addAction( QLatin1String("showqa_action"), m_qaView->toggleViewAction() );
-
- connect(m_qaView, SIGNAL(rulesChanged()), this, SLOT(setQAMode()));
- connect(m_qaView->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(setQAMode(bool)));
-
-
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- view->header()->restoreState(QByteArray::fromBase64( cg.readEntry("TMSearchResultsHeaderState", QByteArray()) ));
-}
-
-TMTab::~TMTab()
-{
- KConfig config;
- KConfigGroup cg(&config,"MainWindow");
- cg.writeEntry("TMSearchResultsHeaderState",ui_queryOptions->treeView->header()->saveState().toBase64());
-
- delete ui_queryOptions;
- ids.removeAll(m_dbusId);
-}
-
-void TMTab::updateTM()
-{
- QList<QUrl> urls;
- urls.append(Project::instance()->poDir());
- scanRecursive(urls,Project::instance()->projectID());
-}
-
-void TMTab::performQuery()
-{
- m_model->setFilter(ui_queryOptions->querySource->text(), ui_queryOptions->queryTarget->text(),
- ui_queryOptions->invertSource->isChecked(), ui_queryOptions->invertTarget->isChecked(),
- ui_queryOptions->filemask->text()
- );
- QApplication::setOverrideCursor(Qt::BusyCursor);
-}
-
-void TMTab::handleResults()
-{
- QApplication::restoreOverrideCursor();
- QString filemask=ui_queryOptions->filemask->text();
- //ui_queryOptions->regexSource->text(),ui_queryOptions->regexTarget->text()
- int rowCount=m_model->rowCount();
- if (rowCount==0)
- {
- kDebug()<<"m_model->rowCount()==0";
- //try harder
- if(m_partToAlsoTryLater!=DocPosition::UndefPart)
- {
- if (m_partToAlsoTryLater==DocPosition::Comment)
- {
- QString text=ui_queryOptions->queryTarget->text();
- if (text.isEmpty())
- text=ui_queryOptions->querySource->text();
- if (text.isEmpty())
- m_partToAlsoTryLater=DocPosition::UndefPart;
- else
- findGuiText(text);
- return;
- }
- KLineEdit* const source_target_query[]={ui_queryOptions->queryTarget,ui_queryOptions->querySource};
- source_target_query[m_partToAlsoTryLater==DocPosition::Source]->setText(source_target_query[m_partToAlsoTryLater!=DocPosition::Source]->text());
- source_target_query[m_partToAlsoTryLater!=DocPosition::Source]->clear();
- m_partToAlsoTryLater=ui_queryOptions->filemask->text().isEmpty()?
- DocPosition::UndefPart:
- DocPosition::Comment; //leave a note that we should also try w/o package if the current one doesn't succeed
- return performQuery();
- }
- if(!filemask.isEmpty() && !filemask.contains('*'))
- {
- ui_queryOptions->filemask->setText('*'+filemask+'*');
- return performQuery();
- }
- }
- kDebug()<<"=DocPosition::UndefPart";
- m_partToAlsoTryLater=DocPosition::UndefPart;
-
- ui_queryOptions->treeView->setFocus();
-}
-
-void TMTab::displayTotalResultCount()
-{
- int total=m_model->totalResultCount();
- int filtered=m_proxyModel->rowCount();
- if (filtered==m_model->rowCount())
- statusBarItems.insert(1,i18nc("@info:status message entries","Total: %1",total));
- else
- statusBarItems.insert(1,i18nc("@info:status message entries","Total: %1 (%2)",filtered,total));
-}
-
-static void copy(Ui_QueryOptions* ui_queryOptions, int column)
-{
- QApplication::clipboard()->setText( ui_queryOptions->treeView->currentIndex().sibling(ui_queryOptions->treeView->currentIndex().row(),column).data().toString());
-}
-
-void TMTab::copySource()
-{
- copy(ui_queryOptions, TMDBModel::Source);
-}
-
-void TMTab::copyTarget()
-{
- copy(ui_queryOptions, TMDBModel::Target);
-}
-
-void TMTab::openFile()
-{
- QModelIndex item=ui_queryOptions->treeView->currentIndex();
- emit fileOpenRequested(item.sibling(item.row(),TMDBModel::Filepath).data(Qt::UserRole).toString(),
- item.sibling(item.row(),TMDBModel::Source).data().toString(),
- item.sibling(item.row(),TMDBModel::Context).data().toString());
-}
-
-
-
-void TMTab::setQAMode(bool enable)
-{
- static_cast<FastSizeHintItemDelegate*>(ui_queryOptions->treeView->itemDelegate())->reset();
-
- if (!enable)
- {
- m_proxyModel->setRules(QVector<Rule>());
- return;
- }
-
- m_proxyModel->setRules(m_qaView->rules());
-
- /*QDomElement docElem = m_categories.at(0).toElement();
-
- QDomNode n = docElem.firstChildElement();
- while(!n.isNull())
- {
- QDomElement e = n.toElement();
- qDebug() << e.tagName();
- n = n.nextSiblingElement();
- }*/
-
- performQuery();
-}
-
-
-//END TMWindow
-
-
-
-#if 0
-bool QueryResultDelegate::editorEvent(QEvent* event,
- QAbstractItemModel* model,
- const QStyleOptionViewItem& /*option*/,
- const QModelIndex& index)
-{
- kWarning()<<"QEvent"<<event;
- if (event->type()==QEvent::Shortcut)
- {
- kWarning()<<"QEvent::Shortcut"<<index.data().canConvert(QVariant::String);
- if (static_cast<QShortcutEvent*>(event)->key().matches(QKeySequence::Copy)
- && index.data().canConvert(QVariant::String))
- {
- QApplication::clipboard()->setText(index.data().toString());
- kWarning()<<"index.data().toString()";
- }
- }
- else if (event->type()==QEvent::MouseButtonRelease)
- {
- QMouseEvent* mEvent=static_cast<QMouseEvent*>(event);
- if (mEvent->button()==Qt::MiddleButton)
- {
- }
- }
- else if (event->type()==QEvent::KeyPress)
- {
- QKeyEvent* kEvent=static_cast<QKeyEvent*>(event);
- if (kEvent->key()==Qt::Key_Return)
- {
- if (kEvent->modifiers()==Qt::NoModifier)
- {
- }
- }
- }
- else
- return false;
-
- event->accept();
- return true;
-
-}
-
-#endif
-
-
-
-
-void TMTab::dragEnterEvent(QDragEnterEvent* event)
-{
- if(dragIsAcceptable(event->mimeData()->urls()))
- event->acceptProposedAction();
-}
-
-void TMTab::dropEvent(QDropEvent *event)
-{
- if (scanRecursive(event->mimeData()->urls(),Project::instance()->projectID()))
- event->acceptProposedAction();
-}
-
-#include "translationmemoryadaptor.h"
-
-//BEGIN DBus interface
-QList<int> TMTab::ids;
-
-QString TMTab::dbusObjectPath()
-{
- if ( m_dbusId==-1 )
- {
- new TranslationMemoryAdaptor(this);
-
- int i=0;
- while(i<ids.size()&&i==ids.at(i))
- ++i;
- ids.insert(i,i);
- m_dbusId=i;
- QDBusConnection::sessionBus().registerObject("/ThisIsWhatYouWant/TranslationMemory/" + QString::number(m_dbusId), this);
- }
-
- return "/ThisIsWhatYouWant/TranslationMemory/" + QString::number(m_dbusId);
-}
-
-
-void TMTab::lookup(QString source, QString target)
-{
- source.remove(Project::instance()->accel());
- target.remove(Project::instance()->accel());
- ui_queryOptions->querySource->setText(source);
- ui_queryOptions->queryTarget->setText(target);
- ui_queryOptions->invertSource->setChecked(false);
- ui_queryOptions->invertTarget->setChecked(false);
- ui_queryOptions->queryStyle->setCurrentIndex(TMDBModel::SubStr);
- performQuery();
-}
-
-// void TMTab::lookup(DocPosition::Part part, QString text)
-// {
-// lookup(part==DocPosition::Source?text:QString(),part==DocPosition::Target?text:QString());
-// }
-
-bool TMTab::findGuiTextPackage(QString text, QString package)
-{
- //std::cout<<package.toLatin1().constData()<<text.toLatin1().constData()<<std::endl;
- kWarning()<<package<<text;
- KLineEdit* const source_target_query[]={ui_queryOptions->queryTarget,ui_queryOptions->querySource};
- static const DocPosition::Part source_target[]={DocPosition::Target,DocPosition::Source};
- QTextCodec* latin1=QTextCodec::codecForMib(4);
- DocPosition::Part tryNowPart=source_target[latin1->canEncode(text)];
- m_partToAlsoTryLater=source_target[tryNowPart==DocPosition::Target];
-
- text.remove(Project::instance()->accel());
- ui_queryOptions->querySource->clear();
- ui_queryOptions->queryTarget->clear();
- source_target_query[tryNowPart==DocPosition::Source]->setText(text);
- ui_queryOptions->invertSource->setChecked(false);
- ui_queryOptions->invertTarget->setChecked(false);
- if (!package.isEmpty()) package='*'+package+'*';
- ui_queryOptions->filemask->setText(package);
- ui_queryOptions->queryStyle->setCurrentIndex(TMDBModel::Glob);
- performQuery();
-
- return true;
-}
-
-//END DBus interface
-
-#include "moc_tmtab.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2011 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef TMTAB_H
-#define TMTAB_H
-
-#include "lokalizesubwindowbase.h"
-#include "pos.h"
-
-#include <KMainWindow>
-#include <KXMLGUIClient>
-#include <KUrl>
-
-#include <QSqlQueryModel>
-#include <QSqlDatabase>
-#include <QComboBox>
-#include <QTreeView>
-#include <QSortFilterProxyModel>
-#include <QCheckBox>
-
-namespace ThreadWeaver{class Job;}
-
-class QaView;
-class KLineEdit;
-class TMResultsSortFilterProxyModel;
-
-QT_BEGIN_NAMESPACE
-class Ui_QueryOptions;
-QT_END_NAMESPACE
-
-namespace TM {
-class TMDBModel;
-
-/**
- * Translation Memory tab
- */
-class TMTab: public LokalizeSubwindowBase2
-{
- Q_OBJECT
- Q_CLASSINFO("D-Bus Interface", "org.kde.Lokalize.TranslationMemory")
- //qdbuscpp2xml -m -s tm/tmtab.h -o tm/org.kde.lokalize.TranslationMemory.xml
-
-public:
- TMTab(QWidget *parent);
- ~TMTab();
-
- void hideDocks(){};
- void showDocks(){};
- KXMLGUIClient* guiClient(){return (KXMLGUIClient*)this;}
- QString dbusObjectPath();
- int dbusId(){return m_dbusId;}
-
-
-public slots:
- Q_SCRIPTABLE bool findGuiText(QString text){return findGuiTextPackage(text,QString());}
- Q_SCRIPTABLE bool findGuiTextPackage(QString text, QString package);
- Q_SCRIPTABLE void lookup(QString source, QString target);
- //void lookup(DocPosition::Part, QString text);
-
-public slots:
- void performQuery();
- void updateTM();
- void copySource();
- void copyTarget();
- void openFile();
- void handleResults();
- void displayTotalResultCount();
- void setQAMode(bool enabled=true);
-
-signals:
- void fileOpenRequested(const KUrl& url, const QString& source, const QString& ctxt);
-
-private:
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent*);
-
-
-private:
- Ui_QueryOptions* ui_queryOptions;
- TMDBModel* m_model;
- TMResultsSortFilterProxyModel *m_proxyModel;
- QaView* m_qaView;
-
- DocPosition::Part m_partToAlsoTryLater;
- //QString m_dbusObjectPath;
- int m_dbusId;
- static QList<int> ids;
-};
-
-
-class TMDBModel: public QSqlQueryModel
-{
- Q_OBJECT
-public:
-
- enum TMDBModelColumns
- {
- Source=0,
- Target,
- Context,
- Filepath,
- _SourceAccel,
- _TargetAccel,
- _Bits,
- TransationStatus,
- ColumnCount
- };
-
- enum QueryType
- {
- SubStr=0,
- WordOrder,
- Glob
- };
-
- enum Roles
- {
- FullPathRole=Qt::UserRole,
- TransStateRole=Qt::UserRole+1,
- //HtmlDisplayRole=FastSizeHintItemDelegate::HtmlDisplayRole
- };
-
- TMDBModel(QObject* parent);
- ~TMDBModel(){}
-
- QVariant data(const QModelIndex& item, int role=Qt::DisplayRole) const;
- int columnCount(const QModelIndex& parent=QModelIndex()) const{Q_UNUSED(parent); return ColumnCount;}
- int totalResultCount()const{return m_totalResultCount;}
-
-public slots:
- void setFilter(const QString& source, const QString& target,
- bool invertSource, bool invertTarget,
- const QString& filemask
- );
- void setQueryType(int);
- void setDB(const QString&);
- void slotQueryExecuted(ThreadWeaver::Job*);
-
-signals:
- void resultsFetched();
- void finalResultCountFetched(int);
-
-
-private:
- bool rowIsApproved(int row) const;
- int translationStatus(const QModelIndex& item) const;
-
-private:
- QueryType m_queryType;
- QString m_dbName;
- int m_totalResultCount;
-};
-
-//const QString& sourceRefine, const QString& targetRefine
-
-}
-
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "tmview.h"
-
-#include "jobs.h"
-#include "tmscanapi.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "project.h"
-#include "prefs_lokalize.h"
-#include "dbfilesmodel.h"
-#include "diff.h"
-#include "xlifftextedit.h"
-
-#include <klocale.h>
-#include <kdebug.h>
-#include <threadweaver/ThreadWeaver.h>
-#include <kglobalsettings.h>
-#include <kpassivepopup.h>
-#include <kaction.h>
-#include <kmessagebox.h>
-
-#include <QTextBrowser>
-#include <QDateTime>
-#include <QDragEnterEvent>
-#include <QFileInfo>
-#include <QDir>
-#include <QSignalMapper>
-#include <QTimer>
-#include <QToolTip>
-#include <QMenu>
-
-#ifdef NDEBUG
-#undef NDEBUG
-#endif
-#define DEBUG
-using namespace TM;
-
-
-struct DiffInfo
-{
- DiffInfo(int reserveSize);
-
- QString diffClean;
- QString old;
- //Formatting info:
- QByteArray diffIndex;
- //Map old string-->d.diffClean
- QVector<int> old2DiffClean;
-};
-
-DiffInfo::DiffInfo(int reserveSize)
-{
- diffClean.reserve(reserveSize);
- old.reserve(reserveSize);
- diffIndex.reserve(reserveSize);
- old2DiffClean.reserve(reserveSize);
-}
-
-
-
-/**
- * 0 - common
- + - add
- - - del
- M - modified
-
- so the string is like 00000MM00+++---000
- (M appears afterwards)
-*/
-static DiffInfo getDiffInfo(const QString& diff)
-{
- DiffInfo d(diff.size());
-
- QChar sep('{');
- char state='0';
- //walk through diff string char-by-char
- //calculate old and others
- int pos=-1;
- while (++pos<diff.size())
- {
- if (diff.at(pos)==sep)
- {
- if (diff.indexOf("{KBABELDEL}",pos)==pos)
- {
- state='-';
- pos+=10;
- }
- else if (diff.indexOf("{KBABELADD}",pos)==pos)
- {
- state='+';
- pos+=10;
- }
- else if (diff.indexOf("{/KBABEL",pos)==pos)
- {
- state='0';
- pos+=11;
- }
- }
- else
- {
- if (state!='+')
- {
- d.old.append(diff.at(pos));
- d.old2DiffClean.append(d.diffIndex.count());
- }
- d.diffIndex.append(state);
- d.diffClean.append(diff.at(pos));
- }
- }
- return d;
-}
-
-
-void TextBrowser::mouseDoubleClickEvent(QMouseEvent* event)
-{
- QTextBrowser::mouseDoubleClickEvent(event);
-
- QString sel=textCursor().selectedText();
- if (!(sel.isEmpty()||sel.contains(' ')))
- emit textInsertRequested(sel);
-}
-
-
-TMView::TMView(QWidget* parent, Catalog* catalog, const QVector<KAction*>& actions)
- : QDockWidget ( i18nc("@title:window","Translation Memory"), parent)
- , m_browser(new TextBrowser(this))
- , m_catalog(catalog)
- , m_currentSelectJob(0)
- , m_actions(actions)
- , m_normTitle(i18nc("@title:window","Translation Memory"))
- , m_hasInfoTitle(m_normTitle+" [*]")
- , m_hasInfo(false)
- , m_isBatching(false)
- , m_markAsFuzzy(false)
-{
- setObjectName("TMView");
- setWidget(m_browser);
-
- m_browser->document()->setDefaultStyleSheet("p.close_match { font-weight:bold; }");
- m_browser->viewport()->setBackgroundRole(QPalette::Background);
-
- QTimer::singleShot(0,this,SLOT(initLater()));
- connect(m_catalog,SIGNAL(signalFileLoaded(KUrl)),
- this,SLOT(slotFileLoaded(KUrl)));
-}
-
-TMView::~TMView()
-{
- int i=m_jobs.size();
- while (--i>=0)
- ThreadWeaver::Weaver::instance()->dequeue(m_jobs.takeLast());
-}
-
-void TMView::initLater()
-{
- setAcceptDrops(true);
-
- QSignalMapper* signalMapper=new QSignalMapper(this);
- int i=m_actions.size();
- while(--i>=0)
- {
- connect(m_actions.at(i),SIGNAL(triggered()),signalMapper,SLOT(map()));
- signalMapper->setMapping(m_actions.at(i), i);
- }
- connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(slotUseSuggestion(int)));
-
- setToolTip(i18nc("@info:tooltip","Double-click any word to insert it into translation"));
-
- DBFilesModel::instance();
-
- connect(m_browser,SIGNAL(textInsertRequested(QString)),this,SIGNAL(textInsertRequested(QString)));
- connect(m_browser,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(contextMenu(QPoint)));
- //TODO ? kdisplayPaletteChanged
-// connect(KGlobalSettings::self(),,SIGNAL(kdisplayPaletteChanged()),this,SLOT(slotPaletteChanged()));
-
-}
-
-void TMView::dragEnterEvent(QDragEnterEvent* event)
-{
- if (dragIsAcceptable(event->mimeData()->urls()))
- event->acceptProposedAction();
-}
-
-void TMView::dropEvent(QDropEvent *event)
-{
- if (scanRecursive(event->mimeData()->urls(),Project::instance()->projectID()))
- event->acceptProposedAction();
-}
-
-void TMView::slotFileLoaded(const KUrl& url)
-{
- const QString& pID=Project::instance()->projectID();
-
- if (Settings::scanToTMOnOpen())
- {
- ScanJob* job=new ScanJob(url,pID);
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- }
-
- if (!Settings::prefetchTM()
- &&!m_isBatching)
- return;
-
- m_cache.clear();
- int i=m_jobs.size();
- while (--i>=0)
- ThreadWeaver::Weaver::instance()->dequeue(m_jobs.takeLast());
-
- DocPosition pos;
- while(switchNext(m_catalog,pos))
- {
- if (!m_catalog->isEmpty(pos.entry)
- &&m_catalog->isApproved(pos.entry))
- continue;
- SelectJob* j=initSelectJob(m_catalog, pos, pID);
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotCacheSuggestions(ThreadWeaver::Job*)));
- m_jobs.append(j);
- }
-
- //dummy job for the finish indication
- BatchSelectFinishedJob* m_seq=new BatchSelectFinishedJob(this);
- connect(m_seq,SIGNAL(done(ThreadWeaver::Job*)),m_seq,SLOT(deleteLater()));
- connect(m_seq,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotBatchSelectDone(ThreadWeaver::Job*)));
- ThreadWeaver::Weaver::instance()->enqueue(m_seq);
- m_jobs.append(m_seq);
-}
-
-void TMView::slotCacheSuggestions(ThreadWeaver::Job* j)
-{
- m_jobs.removeAll(j);
- SelectJob* job=static_cast<SelectJob*>(j);
- kDebug()<<job->m_pos.entry;
- if (job->m_pos.entry==m_pos.entry)
- slotSuggestionsCame(j);
-
- m_cache[DocPos(job->m_pos)]=job->m_entries.toVector();
-}
-
-void TMView::slotBatchSelectDone(ThreadWeaver::Job* /*j*/)
-{
- m_jobs.clear();
- if (!m_isBatching)
- return;
-
- bool insHappened=false;
- DocPosition pos;
- while(switchNext(m_catalog,pos))
- {
- if (!(m_catalog->isEmpty(pos.entry)
- ||!m_catalog->isApproved(pos.entry))
- )
- continue;
- const QVector<TMEntry>& suggList=m_cache.value(DocPos(pos));
- if (suggList.isEmpty())
- continue;
- const TMEntry& entry=suggList.first();
- if (entry.score<9900)//hacky
- continue;
- {
- bool forceFuzzy=(suggList.size()>1&&suggList.at(1).score>=10000)
- ||entry.score<10000;
- bool ctxtMatches=entry.score==1001;
- if (!m_catalog->isApproved(pos.entry))
- {
- ///m_catalog->push(new DelTextCmd(m_catalog,pos,m_catalog->msgstr(pos)));
- removeTargetSubstring(m_catalog, pos, 0, m_catalog->targetWithTags(pos).string.size());
- if ( ctxtMatches || !(m_markAsFuzzy||forceFuzzy) )
- SetStateCmd::push(m_catalog,pos,true);
- }
- else if ((m_markAsFuzzy&&!ctxtMatches)||forceFuzzy)
- {
- SetStateCmd::push(m_catalog,pos,false);
- }
- ///m_catalog->push(new InsTextCmd(m_catalog,pos,entry.target));
- insertCatalogString(m_catalog, pos, entry.target, 0);
-
- if (Q_UNLIKELY( m_pos.entry==pos.entry&&pos.form==m_pos.form ))
- emit refreshRequested();
-
- }
- if (!insHappened)
- {
- insHappened=true;
- m_catalog->beginMacro(i18nc("@item Undo action","Batch translation memory filling"));
- }
- }
- QString msg=i18nc("@info","Batch translation has been completed.");
- if (insHappened)
- m_catalog->endMacro();
- else
- {
- // xgettext: no-c-format
- msg+=' ';
- msg+=i18nc("@info","No suggestions with exact matches were found.");
- }
-
- KPassivePopup::message(KPassivePopup::Balloon,
- i18nc("@title","Batch translation complete"),
- msg,
- this);
-}
-
-void TMView::slotBatchTranslate()
-{
- m_isBatching=true;
- m_markAsFuzzy=false;
- if (!Settings::prefetchTM())
- slotFileLoaded(m_catalog->url());
- else if (m_jobs.isEmpty())
- return slotBatchSelectDone(0);
- KPassivePopup::message(KPassivePopup::Balloon,
- i18nc("@title","Batch translation"),
- i18nc("@info","Batch translation has been scheduled."),
- this);
-
-}
-
-void TMView::slotBatchTranslateFuzzy()
-{
- m_isBatching=true;
- m_markAsFuzzy=true;
- if (!Settings::prefetchTM())
- slotFileLoaded(m_catalog->url());
- else if (m_jobs.isEmpty())
- slotBatchSelectDone(0);
- KPassivePopup::message(KPassivePopup::Balloon,
- i18nc("@title","Batch translation"),
- i18nc("@info","Batch translation has been scheduled."),
- this);
-
-}
-
-void TMView::slotNewEntryDisplayed(const DocPosition& pos)
-{
- if (m_catalog->numberOfEntries()<=pos.entry)
- return;//because of Qt::QueuedConnection
-
- ThreadWeaver::Weaver::instance()->dequeue(m_currentSelectJob);
-
- //update DB
- //m_catalog->flushUpdateDBBuffer();
- //this is called via subscribtion
-
- if (pos.entry!=-1)
- m_pos=pos;
- m_browser->clear();
- if (Settings::prefetchTM()
- &&m_cache.contains(DocPos(m_pos)))
- {
- QTimer::singleShot(0,this,SLOT(displayFromCache()));
- }
- m_currentSelectJob=initSelectJob(m_catalog, m_pos);
- connect(m_currentSelectJob,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotSuggestionsCame(ThreadWeaver::Job*)));
-}
-
-void TMView::displayFromCache()
-{
- if (m_prevCachePos.entry==m_pos.entry
- &&m_prevCachePos.form==m_pos.form)
- return;
- SelectJob* temp=initSelectJob(m_catalog, m_pos, QString(), 0);
- temp->m_entries=m_cache.value(DocPos(m_pos)).toList();
- slotSuggestionsCame(temp);
- temp->deleteLater();
- m_prevCachePos=m_pos;
-}
-
-void TMView::slotSuggestionsCame(ThreadWeaver::Job* j)
-{
- QTime time;time.start();
-
- SelectJob& job=*(static_cast<SelectJob*>(j));
- if (job.m_pos.entry!=m_pos.entry)
- return;
-
- Catalog& catalog=*m_catalog;
- if (catalog.numberOfEntries()<=m_pos.entry)
- return;//because of Qt::QueuedConnection
-
-
- //BEGIN query other DBs handling
- Project* project=Project::instance();
- const QString& projectID=project->projectID();
- //check if this is an additional query, from secondary DBs
- if (job.m_dbName!=projectID)
- {
- job.m_entries+=m_entries;
- qSort(job.m_entries.begin(), job.m_entries.end(), qGreater<TMEntry>());
- int limit=qMin(Settings::suggCount(),job.m_entries.size());
- int i=job.m_entries.size();
- while(--i>=limit)
- job.m_entries.removeLast();
- }
- else if (job.m_entries.isEmpty()||job.m_entries.first().score<8500)
- {
- //be careful, as we switched to QDirModel!
- const DBFilesModel& dbFilesModel=*(DBFilesModel::instance());
- QModelIndex root=dbFilesModel.rootIndex();
- int i=dbFilesModel.rowCount(root);
- //kWarning()<<"query other DBs,"<<i<<"total";
- while (--i>=0)
- {
- const QString& dbName=dbFilesModel.data(dbFilesModel.index(i,0,root)).toString();
- if (projectID!=dbName && dbFilesModel.m_configurations.value(dbName).targetLangCode==catalog.targetLangCode())
- {
- SelectJob* j=initSelectJob(m_catalog, m_pos, dbName);
- connect(j,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotSuggestionsCame(ThreadWeaver::Job*)));
- m_jobs.append(j);
- }
- }
- }
- //END query other DBs handling
-
- m_entries=job.m_entries;
-
- int limit=job.m_entries.size();
-
- if (!limit)
- {
- if (m_hasInfo)
- {
- m_hasInfo=false;
- setWindowTitle(m_normTitle);
- }
- return;
- }
- if (!m_hasInfo)
- {
- m_hasInfo=true;
- setWindowTitle(m_hasInfoTitle);
- }
-
- setUpdatesEnabled(false);
- m_browser->clear();
- m_entryPositions.clear();
-
- //m_entries=job.m_entries;
- //m_browser->insertHtml("<html>");
-
- int i=0;
- QTextBlockFormat blockFormatBase;
- QTextBlockFormat blockFormatAlternate; blockFormatAlternate.setBackground(QPalette().alternateBase());
- QTextCharFormat noncloseMatchCharFormat;
- QTextCharFormat closeMatchCharFormat; closeMatchCharFormat.setFontWeight(QFont::Bold);
- forever
- {
- QTextCursor cur=m_browser->textCursor();
- QString html;
- html.reserve(1024);
-
- const TMEntry& entry=job.m_entries.at(i);
- html+=(entry.score>9500)?"<p class='close_match'>":"<p>";
- //kDebug()<<entry.target.string<<entry.hits;
-
- html+=QString("/%1%/ ").arg(entry.score > 10000 ? 100: float(entry.score)/100);
-
- //int sourceStartPos=cur.position();
- QString result=Qt::escape(entry.diff);
- //result.replace("&","&");
- //result.replace("<","<");
- //result.replace(">",">");
- result.replace("{KBABELADD}","<font style=\"background-color:"+Settings::addColor().name()+";color:black\">");
- result.replace("{/KBABELADD}","</font>");
- result.replace("{KBABELDEL}","<font style=\"background-color:"+Settings::delColor().name()+";color:black\">");
- result.replace("{/KBABELDEL}","</font>");
- result.replace("\\n","\\n<br>");
- result.replace("\\n","\\n<br>");
- html+=result;
-#if 0
- cur.insertHtml(result);
-
- cur.movePosition(QTextCursor::PreviousCharacter,QTextCursor::MoveAnchor,cur.position()-sourceStartPos);
- CatalogString catStr(entry.diff);
- catStr.string.remove("{KBABELDEL}"); catStr.string.remove("{/KBABELDEL}");
- catStr.string.remove("{KBABELADD}"); catStr.string.remove("{/KBABELADD}");
- catStr.tags=entry.source.tags;
- DiffInfo d=getDiffInfo(entry.diff);
- int j=catStr.tags.size();
- while(--j>=0)
- {
- catStr.tags[j].start=d.old2DiffClean.at(catStr.tags.at(j).start);
- catStr.tags[j].end =d.old2DiffClean.at(catStr.tags.at(j).end);
- }
- insertContent(cur,catStr,job.m_source,false);
-#endif
-
- //str.replace('&',"&"); TODO check
- html+="<br>";
- if (Q_LIKELY( i<m_actions.size() ))
- {
- m_actions.at(i)->setStatusTip(entry.target.string);
- html+=QString("[%1] ").arg(m_actions.at(i)->shortcut().toString());
- }
- else
- html+="[ - ] ";
-/*
- QString str(entry.target.string);
- str.replace('<',"<");
- str.replace('>',">");
- html+=str;
-*/
- cur.insertHtml(html); html.clear();
- cur.setCharFormat((entry.score>9500)?closeMatchCharFormat:noncloseMatchCharFormat);
- insertContent(cur,entry.target);
- m_entryPositions.insert(cur.anchor(),i);
-
- html+=i?"<br></p>":"</p>";
- cur.insertHtml(html);
-
- if (Q_UNLIKELY( ++i>=limit ))
- break;
-
- cur.insertBlock(i%2?blockFormatAlternate:blockFormatBase);
-
- }
- m_browser->insertHtml("</html>");
- setUpdatesEnabled(true);
-// kWarning()<<"ELA "<<time.elapsed()<<"BLOCK COUNT "<<m_browser->document()->blockCount();
-}
-
-
-/*
-void TMView::slotPaletteChanged()
-{
-
-}*/
-bool TMView::event(QEvent *event)
-{
- if (event->type()==QEvent::ToolTip)
- {
- QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
- //int block1=m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).blockNumber();
- QMap<int,int>::iterator block =m_entryPositions.lowerBound(m_browser->cursorForPosition(m_browser->viewport()->mapFromGlobal(helpEvent->globalPos())).anchor());
- if (block!=m_entryPositions.end() && *block<m_entries.size())
- {
- const TMEntry& tmEntry=m_entries.at(*block);
- QString file=tmEntry.file;
- if (file==m_catalog->url().toLocalFile())
- file=i18nc("File argument in tooltip, when file is current file", "this");
- QString tooltip=i18nc("@info:tooltip","File: %1<br />Addition date: %2",file, tmEntry.date.toString(Qt::ISODate));
- if (!tmEntry.changeDate.isNull() && tmEntry.changeDate!=tmEntry.date)
- tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Last change date: %1", tmEntry.changeDate.toString(Qt::ISODate));
- if (!tmEntry.changeAuthor.isEmpty())
- tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Last change author: %1", tmEntry.changeAuthor);
- tooltip+=i18nc("@info:tooltip on TM entry continues","<br />TM: %1", tmEntry.dbName);
- if (tmEntry.obsolete)
- tooltip+=i18nc("@info:tooltip on TM entry continues","<br />Is not present in the file anymore");
- QToolTip::showText(helpEvent->globalPos(),tooltip);
- return true;
- }
- }
- return QWidget::event(event);
-}
-
-void TMView::contextMenu(const QPoint& pos)
-{
- int block=*m_entryPositions.lowerBound(m_browser->cursorForPosition(pos).anchor());
- kWarning()<<block;
- if (block>=m_entries.size())
- return;
-
- const TMEntry& e=m_entries.at(block);
- enum {Remove, Open};
- QMenu popup;
- popup.addAction(i18nc("@action:inmenu", "Remove this entry"))->setData(Remove);
- if (e.file!= m_catalog->url().toLocalFile() && QFile::exists(e.file))
- popup.addAction(i18nc("@action:inmenu", "Open file containing this entry"))->setData(Open);
- QAction* r=popup.exec(m_browser->mapToGlobal(pos));
- if (!r)
- return;
- if ((r->data().toInt()==Remove) &&
- KMessageBox::Yes==KMessageBox::questionYesNo(this, i18n("<html>Do you really want to remove this entry:<br/><i>%1</i><br/>from translation memory %2?</html>", Qt::escape(e.target.string), e.dbName),
- i18nc("@title:window","Translation Memory Entry Removal")))
- {
- RemoveJob* job=new RemoveJob(e);
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),job,SLOT(deleteLater()));
- connect(job,SIGNAL(done(ThreadWeaver::Job*)),this,SLOT(slotNewEntryDisplayed()));
- ThreadWeaver::Weaver::instance()->enqueue(job);
- }
- else if (r->data().toInt()==Open)
- emit fileOpenRequested(e.file, e.source.string, e.ctxt);
-}
-
-/**
- * helper function:
- * searches to th nearest rxNum or ABBR
- * clears rxNum if ABBR is found before rxNum
- */
-static int nextPlacableIn(const QString& old, int start, QString& cap)
-{
- static QRegExp rxNum("[\\d\\.\\%]+");
- static QRegExp rxAbbr("\\w+");
-
- int numPos=rxNum.indexIn(old,start);
-// int abbrPos=rxAbbr.indexIn(old,start);
- int abbrPos=start;
- //kWarning()<<"seeing"<<old.size()<<old;
- while (((abbrPos=rxAbbr.indexIn(old,abbrPos))!=-1))
- {
- QString word=rxAbbr.cap(0);
- //check if tail contains uppoer case characters
- const QChar* c=word.unicode()+1;
- int i=word.size()-1;
- while (--i>=0)
- {
- if ((c++)->isUpper())
- break;
- }
- abbrPos+=rxAbbr.matchedLength();
- }
-
- int pos=qMin(numPos,abbrPos);
- if (pos==-1)
- pos=qMax(numPos,abbrPos);
-
-// if (pos==numPos)
-// cap=rxNum.cap(0);
-// else
-// cap=rxAbbr.cap(0);
-
- cap=(pos==numPos?rxNum:rxAbbr).cap(0);
- //kWarning()<<cap;
-
- return pos;
-}
-
-
-
-
-
-//TODO thorough testing
-
-/**
- * this tries some black magic
- * naturally, there are many assumptions that might not always be true
- */
-CatalogString TM::targetAdapted(const TMEntry& entry, const CatalogString& ref)
-{
- kWarning()<<entry.source.string<<entry.target.string<<entry.diff;
-
- QString diff=entry.diff;
- CatalogString target=entry.target;
- //QString english=entry.english;
-
-
- QRegExp rxAdd("<font style=\"background-color:[^>]*" + Settings::addColor().name() + "[^>]*\">([^>]*)</font>");
- QRegExp rxDel("<font style=\"background-color:[^>]*" + Settings::delColor().name() + "[^>]*\">([^>]*)</font>");
- //rxAdd.setMinimal(true);
- //rxDel.setMinimal(true);
-
- //first things first
- int pos=0;
- while ((pos=rxDel.indexIn(diff,pos))!=-1)
- diff.replace(pos,rxDel.matchedLength(),"\tKBABELDEL\t" + rxDel.cap(1) + "\t/KBABELDEL\t");
- pos=0;
- while ((pos=rxAdd.indexIn(diff,pos))!=-1)
- diff.replace(pos,rxAdd.matchedLength(),"\tKBABELADD\t" + rxAdd.cap(1) + "\t/KBABELADD\t");
-
- diff.replace("<","<");
- diff.replace(">",">");
-
- //possible enhancement: search for non-translated words in removedSubstrings...
- //QStringList removedSubstrings;
- //QStringList addedSubstrings;
-
-
- /*
- 0 - common
- + - add
- - - del
- M - modified
-
- so the string is like 00000MM00+++---000
- */
- DiffInfo d=getDiffInfo(diff);
-
- bool sameMarkup=Project::instance()->markup()==entry.markupExpr&&!entry.markupExpr.isEmpty();
- bool tryMarkup=entry.target.tags.size() && sameMarkup;
- //search for changed markup
- if (tryMarkup)
- {
- QRegExp rxMarkup(entry.markupExpr);
- rxMarkup.setMinimal(true);
- pos=0;
- int replacingPos=0;
- while ((pos=rxMarkup.indexIn(d.old,pos))!=-1)
- {
- //kWarning()<<"size"<<oldM.size()<<pos<<pos+rxMarkup.matchedLength();
- QByteArray diffIndexPart(d.diffIndex.mid(d.old2DiffClean.at(pos),
- d.old2DiffClean.at(pos+rxMarkup.matchedLength()-1)+1-d.old2DiffClean.at(pos)));
- //kWarning()<<"diffMPart"<<diffMPart;
- if (diffIndexPart.contains('-')
- ||diffIndexPart.contains('+'))
- {
- //form newMarkup
- QString newMarkup;
- newMarkup.reserve(diffIndexPart.size());
- int j=-1;
- while(++j<diffIndexPart.size())
- {
- if (diffIndexPart.at(j)!='-')
- newMarkup.append(d.diffClean.at(d.old2DiffClean.at(pos)+j));
- }
-
- //replace first ocurrence
- int tmp=target.string.indexOf(rxMarkup.cap(0),replacingPos);
- if (tmp!=-1)
- {
- target.replace(tmp,
- rxMarkup.cap(0).size(),
- newMarkup);
- replacingPos=tmp;
- //kWarning()<<"d.old"<<rxMarkup.cap(0)<<"new"<<newMarkup;
-
- //avoid trying this part again
- tmp=d.old2DiffClean.at(pos+rxMarkup.matchedLength()-1);
- while(--tmp>=d.old2DiffClean.at(pos))
- d.diffIndex[tmp]='M';
- //kWarning()<<"M"<<diffM;
- }
- }
-
- pos+=rxMarkup.matchedLength();
- }
- }
-
- //del, add only markup, punct, num
- //TODO further improvement: spaces, punct marked as 0
-//BEGIN BEGIN HANDLING
- QRegExp rxNonTranslatable;
- if (tryMarkup)
- rxNonTranslatable.setPattern("^((" + entry.markupExpr + ")|(\\W|\\d)+)+");
- else
- rxNonTranslatable.setPattern("^(\\W|\\d)+");
-
- //kWarning()<<"("+entry.markup+"|(\\W|\\d)+";
-
-
- //handle the beginning
- int len=d.diffIndex.indexOf('0');
- if (len>0)
- {
- QByteArray diffMPart(d.diffIndex.left(len));
- int m=diffMPart.indexOf('M');
- if (m!=-1)
- diffMPart.truncate(m);
-
-#if 0
-nono
- //first goes del, then add. so stop on second del sequence
- bool seenAdd=false;
- int j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)=='+')
- seenAdd=true;
- else if (seenAdd && diffMPart.at(j)=='-')
- {
- diffMPart.truncate(j);
- break;
- }
- }
-#endif
- //form 'oldMarkup'
- QString oldMarkup;
- oldMarkup.reserve(diffMPart.size());
- int j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)!='+')
- oldMarkup.append(d.diffClean.at(j));
- }
-
- //kWarning()<<"old"<<oldMarkup;
- rxNonTranslatable.indexIn(oldMarkup);
- oldMarkup=rxNonTranslatable.cap(0);
- if (target.string.startsWith(oldMarkup))
- {
-
- //form 'newMarkup'
- QString newMarkup;
- newMarkup.reserve(diffMPart.size());
- j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)!='-')
- newMarkup.append(d.diffClean.at(j));
- }
- //kWarning()<<"new"<<newMarkup;
- rxNonTranslatable.indexIn(newMarkup);
- newMarkup=rxNonTranslatable.cap(0);
-
- //replace
- kWarning()<<"BEGIN HANDLING. replacing"<<target.string.left(oldMarkup.size())<<"with"<<newMarkup;
- target.remove(0,oldMarkup.size());
- target.insert(0,newMarkup);
-
- //avoid trying this part again
- j=diffMPart.size();
- while(--j>=0)
- d.diffIndex[j]='M';
- //kWarning()<<"M"<<diffM;
- }
-
- }
-//END BEGIN HANDLING
-//BEGIN END HANDLING
- if (tryMarkup)
- rxNonTranslatable.setPattern("((" + entry.markupExpr + ")|(\\W|\\d)+)+$");
- else
- rxNonTranslatable.setPattern("(\\W|\\d)+$");
-
- //handle the end
- if (!d.diffIndex.endsWith('0'))
- {
- len=d.diffIndex.lastIndexOf('0')+1;
- QByteArray diffMPart(d.diffIndex.mid(len));
- int m=diffMPart.lastIndexOf('M');
- if (m!=-1)
- {
- len=m+1;
- diffMPart=diffMPart.mid(len);
- }
-
- //form 'oldMarkup'
- QString oldMarkup;
- oldMarkup.reserve(diffMPart.size());
- int j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)!='+')
- oldMarkup.append(d.diffClean.at(len+j));
- }
- //kWarning()<<"old-"<<oldMarkup;
- rxNonTranslatable.indexIn(oldMarkup);
- oldMarkup=rxNonTranslatable.cap(0);
- if (target.string.endsWith(oldMarkup))
- {
-
- //form newMarkup
- QString newMarkup;
- newMarkup.reserve(diffMPart.size());
- j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)!='-')
- newMarkup.append(d.diffClean.at(len+j));
- }
- //kWarning()<<"new"<<newMarkup;
- rxNonTranslatable.indexIn(newMarkup);
- newMarkup=rxNonTranslatable.cap(0);
-
- //replace
- target.string.chop(oldMarkup.size());
- target.string.append(newMarkup);
-
- //avoid trying this part again
- j=diffMPart.size();
- while(--j>=0)
- d.diffIndex[len+j]='M';
- //kWarning()<<"M"<<diffM;
- }
- }
-//END BEGIN HANDLING
-
- //search for numbers and stuff
- //QRegExp rxNum("[\\d\\.\\%]+");
- pos=0;
- int replacingPos=0;
- QString cap;
- QString _;
- //while ((pos=rxNum.indexIn(old,pos))!=-1)
- kWarning()<<"string:"<<target.string<<"searching for placeables in"<<d.old;
- while ((pos=nextPlacableIn(d.old,pos,cap))!=-1)
- {
- kWarning()<<"considering placable"<<cap;
- //save these so we can use rxNum in a body
- int endPos1=pos+cap.size()-1;
- int endPos=d.old2DiffClean.at(endPos1);
- int startPos=d.old2DiffClean.at(pos);
- QByteArray diffMPart=d.diffIndex.mid(startPos,
- endPos+1-startPos);
-
- kWarning()<<"starting diffMPart"<<diffMPart;
-
- //the following loop extends replacement text, e.g. for 1 -> 500 cases
- while ((++endPos<d.diffIndex.size())
- &&(d.diffIndex.at(endPos)=='+')
- &&(-1!=nextPlacableIn(QString(d.diffClean.at(endPos)),0,_))
- )
- diffMPart.append('+');
-
- kWarning()<<"diffMPart extended 1"<<diffMPart;
-// if ((pos-1>=0) && (d.old2DiffClean.at(pos)>=0))
-// {
-// kWarning()<<"d.diffIndex"<<d.diffIndex<<d.old2DiffClean.at(pos)-1;
-// kWarning()<<"(d.diffIndex.at(d.old2DiffClean.at(pos-1))=='+')"<<(d.diffIndex.at(d.old2DiffClean.at(pos-1))=='+');
-// //kWarning()<<(-1!=nextPlacableIn(QString(d.diffClean.at(d.old2DiffClean.at(pos))),0,_));
-// }
-
- //this is for the case when +'s preceed -'s:
- while ((--startPos>=0)
- &&(d.diffIndex.at(startPos)=='+')
- //&&(-1!=nextPlacableIn(QString(d.diffClean.at(d.old2DiffClean.at(pos))),0,_))
- )
- diffMPart.prepend('+');
- ++startPos;
-
- kWarning()<<"diffMPart extended 2"<<diffMPart;
-
- if ((diffMPart.contains('-')
- ||diffMPart.contains('+'))
- &&(!diffMPart.contains('M')))
- {
- //form newMarkup
- QString newMarkup;
- newMarkup.reserve(diffMPart.size());
- int j=-1;
- while(++j<diffMPart.size())
- {
- if (diffMPart.at(j)!='-')
- newMarkup.append(d.diffClean.at(startPos+j));
- }
- if (newMarkup.endsWith(' ')) newMarkup.chop(1);
- //kWarning()<<"d.old"<<cap<<"new"<<newMarkup;
-
-
- //replace first ocurrence
- int tmp=target.string.indexOf(cap,replacingPos);
- if (tmp!=-1)
- {
- kWarning()<<"replacing"<<cap<<"with"<<newMarkup;
- target.replace(tmp, cap.size(), newMarkup);
- replacingPos=tmp;
-
- //avoid trying this part again
- tmp=d.old2DiffClean.at(endPos1)+1;
- while(--tmp>=d.old2DiffClean.at(pos))
- d.diffIndex[tmp]='M';
- //kWarning()<<"M"<<diffM;
- }
- else
- kWarning()<<"newMarkup"<<newMarkup<<"wasn't used";
- }
- pos=endPos1+1;
- }
- adaptCatalogString(target, ref);
- return target;
-}
-
-void TMView::slotUseSuggestion(int i)
-{
- if (Q_UNLIKELY( i>=m_entries.size() ))
- return;
-
- CatalogString target=targetAdapted(m_entries.at(i), m_catalog->sourceWithTags(m_pos));
-
-#if 0
- QString tmp=target.string;
- tmp.replace(TAGRANGE_IMAGE_SYMBOL, '*');
- kWarning()<<"targetAdapted"<<tmp;
-
- foreach (InlineTag tag, target.tags)
- kWarning()<<"tag"<<tag.start<<tag.end;
-#endif
- if (Q_UNLIKELY( target.isEmpty() ))
- return;
-
- m_catalog->beginMacro(i18nc("@item Undo action","Use translation memory suggestion"));
-
- QString old=m_catalog->targetWithTags(m_pos).string;
- if (!old.isEmpty())
- {
- m_pos.offset=0;
- //FIXME test!
- removeTargetSubstring(m_catalog, m_pos, 0, old.size());
- //m_catalog->push(new DelTextCmd(m_catalog,m_pos,m_catalog->msgstr(m_pos)));
- }
- kWarning()<<"1"<<target.string;
-
- //m_catalog->push(new InsTextCmd(m_catalog,m_pos,target)/*,true*/);
- insertCatalogString(m_catalog, m_pos, target, 0);
-
- if (m_entries.at(i).score>9900 && !m_catalog->isApproved(m_pos.entry))
- SetStateCmd::push(m_catalog,m_pos,true);
-
- m_catalog->endMacro();
-
- emit refreshRequested();
-}
-
-
-#include "moc_tmview.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef TMVIEW_H
-#define TMVIEW_H
-
-#include "pos.h"
-#include "tmentry.h"
-
-#include <kurl.h>
-
-#include <QTextBrowser>
-#include <QDockWidget>
-#include <QMap>
-#include <QVector>
-
-class Catalog;
-class KAction;
-#include <QDropEvent>
-#include <QDragEnterEvent>
-
-namespace ThreadWeaver{class Job;}
-
-#define TM_SHORTCUTS 10
-namespace TM {
-class TextBrowser;
-class SelectJob;
-
-class TMView: public QDockWidget
-{
- Q_OBJECT
-public:
- TMView(QWidget*,Catalog*,const QVector<KAction*>&);
- ~TMView();
-
- void dragEnterEvent(QDragEnterEvent* event);
- void dropEvent(QDropEvent*);
-
- QSize sizeHint() const{return QSize(300,100);}
-signals:
-// void textReplaceRequested(const QString&);
- void refreshRequested();
- void textInsertRequested(const QString&);
- void fileOpenRequested(const KUrl& path, const QString& str, const QString& ctxt);
-
-public slots:
- void slotNewEntryDisplayed(const DocPosition& pos=DocPosition());
- void slotSuggestionsCame(ThreadWeaver::Job*);
-
- void slotUseSuggestion(int);
- void slotFileLoaded(const KUrl&);
- void displayFromCache();
-
- void slotBatchTranslate();
- void slotBatchTranslateFuzzy();
-
-private slots:
- //i think we do not wanna cache suggestions:
- //what if good sugg may be generated
- //from the entry user translated 1 minute ago?
-
- void slotBatchSelectDone(ThreadWeaver::Job*);
- void slotCacheSuggestions(ThreadWeaver::Job*);
-
- void initLater();
- void contextMenu(const QPoint & pos);
-
-private:
- bool event(QEvent *event);
-
-
-private:
- TextBrowser* m_browser;
- Catalog* m_catalog;
- DocPosition m_pos;
-
- SelectJob* m_currentSelectJob;
- QVector<KAction*> m_actions;//need them to get shortcuts
- QList<TMEntry> m_entries;
- QMap<int, int> m_entryPositions;
-
- QString m_normTitle;
- QString m_hasInfoTitle;
- bool m_hasInfo;
-
- bool m_isBatching;
- bool m_markAsFuzzy;
- QMap<DocPos, QVector<TMEntry> > m_cache;
- DocPosition m_prevCachePos;//hacky hacky
- QList<ThreadWeaver::Job*> m_jobs;//holds pointers to all the jobs for the current file
-};
-
-class TextBrowser: public QTextBrowser
-{
- Q_OBJECT
-public:
- TextBrowser(QWidget* parent):QTextBrowser(parent)
- {
- setContextMenuPolicy(Qt::CustomContextMenu);
- }
- void mouseDoubleClickEvent(QMouseEvent* event);
-signals:
- void textInsertRequested(const QString&);
-};
-
-CatalogString targetAdapted(const TMEntry& entry, const CatalogString& ref);
-
-}
-#endif
+++ /dev/null
-<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
-<kpartgui name="TranslationMemory" version="3">
-<MenuBar>
- <Menu name="tools">
- <Action name="showqa_action"/>
- <Separator/>
- <MergeLocal/>
- </Menu>
-</MenuBar>
-<ToolBar name="mainToolBar"><text>Main Toolbar</text>
- <Separator/>
- <Action name="tools_tm_manage"/>
- <Separator/>
- <Action name="showqa_action"/>
-</ToolBar>
-</kpartgui>
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#include "widgettextcaptureconfig.h"
-#include "ui_widgettextcaptureconfig.h"
-
-#include <KLocale>
-
-WidgetTextCaptureConfig::WidgetTextCaptureConfig(QWidget* parent)
- : KDialog(parent)
- , ui(new Ui_WidgetTextCapture)
-{
- setAttribute(Qt::WA_DeleteOnClose, true);
- ui->setupUi(mainWidget());
- setCaption(i18nc("@title","Widget Text Capture"));
- setButtons(KDialog::Ok | KDialog::Cancel);
-
- KConfigGroup cg(KGlobal::config(), "Development");
- bool copyWidgetText = cg.readEntry("CopyWidgetText", false);
- QString copyWidgetTextCommand = cg.readEntry("CopyWidgetTextCommand", QString());
- ui->none->setChecked(!copyWidgetText);
- ui->clipboard->setChecked(copyWidgetText && copyWidgetTextCommand.isEmpty());
- ui->search->setChecked(copyWidgetText && !copyWidgetTextCommand.isEmpty());
-
- connect(this,SIGNAL(accepted()),this,SLOT(writeConfig()));
-}
-
-WidgetTextCaptureConfig::~WidgetTextCaptureConfig()
-{
- delete ui;
-}
-
-void WidgetTextCaptureConfig::writeConfig()
-{
- KConfig konfig(QString::fromLatin1("kdeglobals"), KConfig::NoGlobals);
- KConfigGroup cg=konfig.group("Development");
- cg.writeEntry("CopyWidgetText", !ui->none->isChecked());
- if (ui->clipboard->isChecked())
- cg.writeEntry("CopyWidgetTextCommand", QString());
- else if (ui->search->isChecked())
- cg.writeEntry("CopyWidgetTextCommand", "/bin/sh `kde4-config --path data --locate lokalize/scripts/find-gui-text.sh` \"%1\" \"%2\"");
-
- konfig.sync();
-}
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#ifndef WIDGETTEXTCAPTURECONFIG_H
-#define WIDGETTEXTCAPTURECONFIG_H
-
-#include <KDialog>
-
-QT_BEGIN_NAMESPACE
-class Ui_WidgetTextCapture;
-QT_END_NAMESPACE
-
-class WidgetTextCaptureConfig: public KDialog
-{
- Q_OBJECT
-public:
- explicit WidgetTextCaptureConfig(QWidget* parent = 0);
- ~WidgetTextCaptureConfig();
-public slots:
- void writeConfig();
-private:
- Ui_WidgetTextCapture* ui;
-};
-
-#endif // WIDGETTEXTCAPTURECONFIG_H
+++ /dev/null
-<ui version="4.0" >
- <class>WidgetTextCapture</class>
- <widget class="QWidget" name="WidgetTextCapture" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>588</width>
- <height>354</height>
- </rect>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout_2" >
- <item>
- <widget class="QLabel" name="label" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Minimum" hsizetype="Minimum" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text" >
- <string><html>
-<p align="justify">To facilitate KDE translation, Lokalize can capture text from applications' user interfaces and search for translation files containing the text.</p>
-<p align="justify">When enabled, the capture can be initiated by middle mouse clicking on any non-editable GUI element (widget). After that, switch to the Lokalize window and choose the entry with this text. Even if several files contain the same string, the right one will be chosen in most cases.</p>
-<p align="justify">Remember that you need to have an up-to-date actual translation memory with all translation files indexed for this feature to work.</p></html></string>
- </property>
- <property name="wordWrap" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QGroupBox" name="groupBox" >
- <property name="sizePolicy" >
- <sizepolicy vsizetype="Minimum" hsizetype="Preferred" >
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title" >
- <string>Middle Mouse Button Click Reaction</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout" >
- <item>
- <widget class="QRadioButton" name="none" >
- <property name="text" >
- <string>None</string>
- </property>
- <property name="checked" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="search" >
- <property name="text" >
- <string>Search GUI element text in translation memory</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QRadioButton" name="clipboard" >
- <property name="text" >
- <string>Copy GUI element text to clipboard</string>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer" >
- <property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" stdset="0" >
- <size>
- <width>20</width>
- <height>40</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
+++ /dev/null
-//
-// C++ Interface: version
-//
-// Description:
-//
-//
-// Copyright: 2007-2012 Nick Shaforostoff <shafff@ukr.net>
-//
-//
-#ifndef LOKALIZE_VERSION
-#define LOKALIZE_VERSION "1.5"
-#endif
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2012 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-#undef KDE_NO_DEBUG_OUTPUT
-
-#include "xlifftextedit.h"
-#include "catalog.h"
-#include "cmd.h"
-#include "syntaxhighlighter.h"
-#include "prefs_lokalize.h"
-#include "prefs.h"
-#include "project.h"
-#include "completionstorage.h"
-
-#include <kcompletionbox.h>
-
-#include <QPixmap>
-#include <QPushButton>
-#include <QPainter>
-#include <QStyle>
-#include <QApplication>
-#include <QtGui/qstyleoption.h>
-#include <QMimeData>
-#include <QMetaType>
-
-#include <QMenu>
-#include <QtGui/qevent.h>
-#include <QToolTip>
-
-// static int im_count=0;
-// static int im_time=0;
-
-#undef KDE_NO_DEBUG_OUTPUT
-#include <QScrollBar>
-
-
-inline static QImage generateImage(const QString& str, const QFont& font)
-{
- // im_count++;
- // QTime a;a.start();
-
- QStyleOptionButton opt;
- opt.fontMetrics=QFontMetrics(font);
- opt.text=' '+str+' ';
- opt.rect=opt.fontMetrics.boundingRect(opt.text).adjusted(0,0,5,5);
- opt.rect.moveTo(0,0);
-
- QImage result(opt.rect.size(),QImage::Format_ARGB32);
- result.fill(0);//0xAARRGGBB
- QPainter painter(&result);
- QApplication::style()->drawControl(QStyle::CE_PushButton,&opt,&painter);
-
- // im_time+=a.elapsed();
- // kWarning()<<im_count<<im_time;
- return result;
-}
-
-class MyCompletionBox: public KCompletionBox
-{
-public:
- MyCompletionBox(QWidget* p):KCompletionBox(p){}
- QSize sizeHint() const;
-
- bool eventFilter(QObject* , QEvent* ); //reimplemented to deliver more keypresses to XliffTextEdit
-};
-
-QSize MyCompletionBox::sizeHint() const
-{
- int h = count()?(sizeHintForRow(0)):0;
- h=qMin(count()*h,10*h) + 2*frameWidth();
- int w = sizeHintForColumn(0) + verticalScrollBar()->width() + 2*frameWidth();
- return QSize(w, h);
-}
-
-bool MyCompletionBox::eventFilter(QObject* object, QEvent* event)
-{
- if (event->type()==QEvent::KeyPress)
- {
- QKeyEvent* e = static_cast<QKeyEvent*>(event);
- if (e->key()==Qt::Key_PageDown || e->key()==Qt::Key_PageUp)
- {
- hide();
- return false;
- }
- }
- return KCompletionBox::eventFilter(object, event);
-}
-
-
-#if 1
-class XliffTextEditSpellInterface: public KTextEditSpellInterface
-{
-public:
- XliffTextEditSpellInterface(SyntaxHighlighter* highlighter);
- ~XliffTextEditSpellInterface(){};
-
- bool isSpellCheckingEnabled() const {return m_enabled;}
- void setSpellCheckingEnabled(bool enable);
- bool shouldBlockBeSpellChecked(const QString &block) const{Q_UNUSED(block); return true;}
-private:
- bool m_enabled;
- SyntaxHighlighter* m_highlighter;
-};
-
-XliffTextEditSpellInterface::XliffTextEditSpellInterface(SyntaxHighlighter* highlighter)
- : KTextEditSpellInterface()
- , m_enabled(Settings::autoSpellcheck())
- , m_highlighter(highlighter)
-{
- m_highlighter->setActive(m_enabled);
-}
-
-void XliffTextEditSpellInterface::setSpellCheckingEnabled(bool enable)
-{
- Settings::setAutoSpellcheck(enable);
- m_enabled=enable;
- m_highlighter->setActive(enable);
- SettingsController::instance()->dirty=true;
-}
-#endif
-
-TranslationUnitTextEdit::TranslationUnitTextEdit(Catalog* catalog, DocPosition::Part part, QWidget* parent)
- : KTextEdit(parent)
- , m_currentUnicodeNumber(0)
- , m_langUsesSpaces(true)
- , m_catalog(catalog)
- , m_part(part)
- , m_highlighter(new SyntaxHighlighter(this))
- , m_completionBox(0)
-{
- setReadOnly(part==DocPosition::Source);
- setUndoRedoEnabled(false);
- setAcceptRichText(false);
-
- if (part==DocPosition::Target)
- {
- connect (document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
- connect (this,SIGNAL(cursorPositionChanged()), this, SLOT(emitCursorPositionChanged()));
- }
- connect (catalog,SIGNAL(signalFileLoaded()), this, SLOT(fileLoaded()));
- //connect (Project::instance(),SIGNAL(configChanged()), this, SLOT(projectConfigChanged()));
-
- setSpellInterface(new XliffTextEditSpellInterface(m_highlighter));
- setHighlighter(m_highlighter);
-}
-
-void TranslationUnitTextEdit::fileLoaded()
-{
- QString langCode=m_part==DocPosition::Source? m_catalog->sourceLangCode():m_catalog->targetLangCode();
-
- QLocale langLocale(langCode);
- // First try to use a locale name derived from the language code
- m_highlighter->setCurrentLanguage(langLocale.name());
- // If that fails, try to use the language code directly
- if (m_highlighter->currentLanguage().isEmpty()) {
- m_highlighter->setCurrentLanguage(langCode);
- }
-
- //"i use an english locale while translating kde pot files from english to hebrew" Bug #181989
- Qt::LayoutDirection targetLanguageDirection=Qt::LeftToRight;
- static QLocale::Language rtlLanguages[]={QLocale::Arabic, QLocale::Hebrew, QLocale::Urdu, QLocale::Persian, QLocale::Pashto};
- int i=sizeof(rtlLanguages)/sizeof(QLocale::Arabic);
- while (--i>=0 && langLocale.language()!=rtlLanguages[i])
- ;
- if (i!=-1)
- targetLanguageDirection=Qt::RightToLeft;
- setLayoutDirection(targetLanguageDirection);
-
- if (m_part==DocPosition::Source)
- return;
-
- //"Some language do not need space between words. For example Chinese."
- static QLocale::Language noSpaceLanguages[]={QLocale::Chinese};
- i=sizeof(noSpaceLanguages)/sizeof(QLocale::Chinese);
- while (--i>=0 && langLocale.language()!=noSpaceLanguages[i])
- ;
- m_langUsesSpaces=(i==-1);
-}
-
-void TranslationUnitTextEdit::reflectApprovementState()
-{
- if (m_part==DocPosition::Source || m_currentPos.entry==-1)
- return;
-
- bool approved=m_catalog->isApproved(m_currentPos.entry);
-
- m_highlighter->setApprovementState(approved);
- disconnect (document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
- m_highlighter->rehighlight();
- connect (document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
- viewport()->setBackgroundRole(approved?QPalette::Base:QPalette::AlternateBase);
-
-
- if (approved) emit approvedEntryDisplayed();
- else emit nonApprovedEntryDisplayed();
-
- bool untr=m_catalog->isEmpty(m_currentPos);
- if (untr) emit untranslatedEntryDisplayed();
- else emit translatedEntryDisplayed();
-}
-
-void TranslationUnitTextEdit::reflectUntranslatedState()
-{
- if (m_part==DocPosition::Source || m_currentPos.entry==-1)
- return;
-
- bool untr=m_catalog->isEmpty(m_currentPos);
- if (untr) emit untranslatedEntryDisplayed();
- else emit translatedEntryDisplayed();
-}
-
-
-/**
- * makes MsgEdit reflect current entry
- **/
-CatalogString TranslationUnitTextEdit::showPos(DocPosition docPosition, const CatalogString& refStr, bool keepCursor)
-{
- docPosition.part=m_part;
- m_currentPos=docPosition;
-
- CatalogString catalogString=m_catalog->catalogString(m_currentPos);
- QString target=catalogString.string;
- _oldMsgstr=target;
- //_oldMsgstrAscii=document()->toPlainText(); <-- MOVED THIS TO THE END
-
- //BEGIN pos
- QTextCursor cursor=textCursor();
- int pos=cursor.position();
- int anchor=cursor.anchor();
- //kWarning()<<"called"<<"pos"<<pos<<anchor<<"keepCursor"<<keepCursor;
- if (!keepCursor && toPlainText()!=target)
- {
- //kWarning()<<"resetting pos";
- pos=0;
- anchor=0;
- }
- //END pos
-
- disconnect (document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
- if (docPosition.part==DocPosition::Source)
- setContent(catalogString);
- else
- setContent(catalogString,refStr.string.isEmpty()?m_catalog->sourceWithTags(docPosition):refStr);
- connect (document(), SIGNAL(contentsChange(int,int,int)), this, SLOT(contentsChanged(int,int,int)));
-
- _oldMsgstrAscii=document()->toPlainText();
-
- //BEGIN pos
- QTextCursor t=textCursor();
- t.movePosition(QTextCursor::Start);
- if (pos || anchor)
- {
- //kWarning()<<"setting"<<anchor<<pos;
- // I don't know why the following (more correct) code does not work
- t.setPosition(anchor,QTextCursor::MoveAnchor);
- int length=pos-anchor;
- if (length)
- t.movePosition(length<0?QTextCursor::PreviousCharacter:QTextCursor::NextCharacter,QTextCursor::KeepAnchor,qAbs(length));
- }
- setTextCursor(t);
- //kWarning()<<"set?"<<textCursor().anchor()<<textCursor().position();
- //END pos
-
- reflectApprovementState();
- reflectUntranslatedState();
- return catalogString; //for the sake of not calling XliffStorage/doContent twice
-}
-
-void TranslationUnitTextEdit::setContent(const CatalogString& catStr, const CatalogString& refStr)
-{
- //kWarning()<<"";
- //kWarning()<<"START";
- //kWarning()<<str<<ranges.size();
- //prevent undo tracking system from recording this 'action'
- document()->blockSignals(true);
- clear();
-
- QTextCursor c=textCursor();
- insertContent(c,catStr,refStr);
-
- document()->blockSignals(false);
-
- if (m_part==DocPosition::Target)
- m_highlighter->setSourceString(refStr.string);
- else
- //reflectApprovementState() does this for Target
- m_highlighter->rehighlight(); //explicitly because we disabled signals
-}
-
-#if 0
-struct SearchFunctor
-{
- virtual int operator()(const QString& str, int startingPos);
-};
-
-int SearchFunctor::operator()(const QString& str, int startingPos)
-{
- return str.indexOf(TAGRANGE_IMAGE_SYMBOL, startingPos);
-}
-
-struct AlternativeSearchFunctor: public SearchFunctor
-{
- int operator()(const QString& str, int startingPos);
-};
-
-int AlternativeSearchFunctor::operator()(const QString& str, int startingPos)
-{
- int tagPos=str.indexOf(TAGRANGE_IMAGE_SYMBOL, startingPos);
- int diffStartPos=str.indexOf("{KBABEL", startingPos);
- int diffEndPos=str.indexOf("{/KBABEL", startingPos);
-
- int diffPos=qMin(diffStartPos,diffEndPos);
- if (diffPos==-1)
- diffPos=qMax(diffStartPos,diffEndPos);
-
- int result=qMin(tagPos,diffPos);
- if (result==-1)
- result=qMax(tagPos,diffPos);
- return result;
-}
-#endif
-
-void insertContent(QTextCursor& cursor, const CatalogString& catStr, const CatalogString& refStr, bool insertText)
-{
- //settings for TMView
- QTextCharFormat chF=cursor.charFormat();
- QFont font=cursor.document()->defaultFont();
- //font.setWeight(chF.fontWeight());
-
- QMap<int,int> posToTag;
- int i=catStr.tags.size();
- //kDebug()<<"size:"<<i;
- while(--i>=0)
- {
- //kDebug()<<"\t"<<catStr.tags.at(i).getElementName()<<catStr.tags.at(i).id<<catStr.tags.at(i).start<<catStr.tags.at(i).end;
- posToTag.insert(catStr.tags.at(i).start,i);
- posToTag.insert(catStr.tags.at(i).end,i);
- }
-
- QMap<QString,int> sourceTagIdToIndex=refStr.tagIdToIndex();
- int refTagIndexOffset=sourceTagIdToIndex.size();
-
- i=0;
- int prev=0;
- while ((i = catStr.string.indexOf(TAGRANGE_IMAGE_SYMBOL, i)) != -1)
- {
-#if 0
- SearchFunctor nextStopSymbol=AlternativeSearchFunctor();
- char state='0';
- while ((i = nextStopSymbol(catStr.string, i)) != -1)
- {
- //handle diff display for TMView
- if (catStr.string.at(i)!=TAGRANGE_IMAGE_SYMBOL)
- {
- if (catStr.string.at(i+1)=='/')
- state='0';
- else if (catStr.string.at(i+8)=='D')
- state='-';
- else
- state='+';
- continue;
- }
-#endif
- if (insertText)
- cursor.insertText(catStr.string.mid(prev,i-prev));
- else
- {
- cursor.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,i-prev);
- cursor.deleteChar();//delete TAGRANGE_IMAGE_SYMBOL to insert it properly
- }
-
- if (!posToTag.contains(i))
- {
- prev=++i;
- continue;
- }
- int tagIndex=posToTag.value(i);
- InlineTag tag=catStr.tags.at(tagIndex);
- QString name=tag.id;
- QString text;
- if (tag.type==InlineTag::mrk)
- text="*";
- else if (!tag.equivText.isEmpty())
- text=tag.equivText; //TODO add number? when? -- right now this is done for gettext qt's 156 mark
- else
- text=QString::number(sourceTagIdToIndex.contains(tag.id)?sourceTagIdToIndex.value(tag.id):(tagIndex+refTagIndexOffset));
- if (tag.start!=tag.end)
- {
- //kWarning()<<"b"<<i;
- if (tag.start==i)
- {
- //kWarning()<<"\t\tstart:"<<tag.getElementName()<<tag.id<<tag.start;
- text.append(" {");
- name.append("-start");
- }
- else
- {
- //kWarning()<<"\t\tend:"<<tag.getElementName()<<tag.id<<tag.end;
- text.prepend("} ");
- name.append("-end");
- }
- }
- if (cursor.document()->resource(QTextDocument::ImageResource, QUrl(name)).isNull())
- cursor.document()->addResource(QTextDocument::ImageResource, QUrl(name), generateImage(text,font));
- cursor.insertImage(name);//NOTE what if twice the same name?
- cursor.setCharFormat(chF);
-
- prev=++i;
- }
- cursor.insertText(catStr.string.mid(prev));
-}
-
-
-
-void TranslationUnitTextEdit::contentsChanged(int offset, int charsRemoved, int charsAdded)
-{
- //kWarning()<<"contentsChanged. offset"<<offset<<"charsRemoved"<<charsRemoved<<"charsAdded"<<charsAdded<<"_oldMsgstr"<<_oldMsgstr;
- //HACK to workaround #218246
- const QString& editTextAscii=document()->toPlainText();
- if (editTextAscii==_oldMsgstrAscii)
- {
- //kWarning()<<"stopping"<<editTextAscii<<_oldMsgstrAscii;
- return;
- }
-
-
-
- const QString& editText=toPlainText();
- if (Q_UNLIKELY( m_currentPos.entry==-1 || editText==_oldMsgstr ))
- {
- //kWarning()<<"stopping"<<m_currentPos.entry<<editText<<_oldMsgstr;
- return;
- }
-
- //ktextedit spellcheck handling:
- if (charsRemoved==0 && editText.isEmpty() && _oldMsgstr.length())
- charsRemoved=_oldMsgstr.length();
- if (charsAdded && editText.isEmpty())
- charsAdded=0;
- if (charsRemoved && _oldMsgstr.isEmpty())
- charsRemoved=0;
-
- DocPosition pos=m_currentPos;
- pos.offset=offset;
- //kWarning()<<"offset"<<offset<<"charsRemoved"<<charsRemoved<<"_oldMsgstr"<<_oldMsgstr;
-
- QString target=m_catalog->targetWithTags(pos).string;
- const QString& addedText=editText.mid(offset,charsAdded);
-
-//BEGIN XLIFF markup handling
- //protect from tag removal
- //TODO use midRef when Qt 4.8 is in distros
- bool markupRemoved=charsRemoved && QString::fromRawData(target.unicode()+offset,charsRemoved).contains(TAGRANGE_IMAGE_SYMBOL);
- bool markupAdded=charsAdded && addedText.contains(TAGRANGE_IMAGE_SYMBOL);
- if (markupRemoved || markupAdded)
- {
- bool modified=false;
- CatalogString targetWithTags=m_catalog->targetWithTags(m_currentPos);
- //special case when the user presses Del w/o selection
- if (!charsAdded && charsRemoved==1)
- {
- int i=targetWithTags.tags.size();
- while(--i>=0)
- {
- if (targetWithTags.tags.at(i).start==offset || targetWithTags.tags.at(i).end==offset)
- {
- modified=true;
- pos.offset=targetWithTags.tags.at(i).start;
- m_catalog->push(new DelTagCmd(m_catalog,pos));
- }
- }
- }
- else if (!markupAdded) //check if all { plus } tags were selected
- {
- modified=removeTargetSubstring(offset, charsRemoved, /*refresh*/false);
- if (modified&&charsAdded)
- m_catalog->push(new InsTextCmd(m_catalog,pos,addedText));
- }
-
- //kWarning()<<"calling showPos";
- showPos(m_currentPos,CatalogString(),/*keepCursor*/true);
- if (!modified)
- {
- //kWarning()<<"stop";
- return;
- }
- }
-//END XLIFF markup handling
- else
- {
- if (charsRemoved)
- m_catalog->push(new DelTextCmd(m_catalog,pos,_oldMsgstr.mid(offset,charsRemoved)));
-
- _oldMsgstr=editText;//newStr becomes OldStr
- _oldMsgstrAscii=editTextAscii;
- //kWarning()<<"char"<<editText[offset].unicode();
- if (charsAdded)
- m_catalog->push(new InsTextCmd(m_catalog,pos,addedText));
-
- }
-
-/* TODO
- if (_leds)
- {
- if (m_catalog->msgstr(pos).isEmpty()) _leds->ledUntr->on();
- else _leds->ledUntr->off();
- }
-*/
- requestToggleApprovement();
- reflectUntranslatedState();
-
- // for mergecatalog (remove entry from index)
- // and for statusbar
- emit contentsModified(m_currentPos);
-
- if (charsAdded==1)
- {
- int sp=target.lastIndexOf(CompletionStorage::instance()->rxSplit,offset-1);
- int len=(offset-sp);
- int wordCompletionLength=Settings::self()->wordCompletionLength();
- if (wordCompletionLength>=3 && len>=wordCompletionLength)
- doCompletion(offset+1);
- else if (m_completionBox)
- m_completionBox->hide();
- }
- else if (m_completionBox)
- m_completionBox->hide();
-
- //kWarning()<<"finish";
-}
-
-
-bool TranslationUnitTextEdit::removeTargetSubstring(int delStart, int delLen, bool refresh)
-{
- if (Q_UNLIKELY( m_currentPos.entry==-1 ))
- return false;
-
- if (!::removeTargetSubstring(m_catalog, m_currentPos, delStart, delLen))
- return false;
-
- requestToggleApprovement();
-
- if (refresh)
- {
- //kWarning()<<"calling showPos";
- showPos(m_currentPos,CatalogString(),/*keepCursor*/true/*false*/);
- }
- emit contentsModified(m_currentPos.entry);
- return true;
-}
-
-void TranslationUnitTextEdit::insertCatalogString(CatalogString catStr, int start, bool refresh)
-{
- CatalogString source=m_catalog->sourceWithTags(m_currentPos);
- CatalogString target=m_catalog->targetWithTags(m_currentPos);
-
-
- QHash<QString,int> id2tagIndex;
- int i=source.tags.size();
- while(--i>=0)
- id2tagIndex.insert(source.tags.at(i).id,i);
-
- foreach(const InlineTag& tag, target.tags)
- {
- if (id2tagIndex.contains(tag.id))
- source.tags[id2tagIndex.value(target.tags.at(i).id)].id="REMOVEME";
- }
-
- //iterating from the end is essential
- i=source.tags.size();
- while(--i>=0)
- if (source.tags.at(i).id=="REMOVEME")
- source.tags.removeAt(i);
-
-
- adaptCatalogString(catStr,source);
-
- ::insertCatalogString(m_catalog,m_currentPos,catStr,start);
-
- if (refresh)
- {
- //kWarning()<<"calling showPos";
- showPos(m_currentPos,CatalogString(),/*keepCursor*/true/*false*/);
- QTextCursor cursor=textCursor();
- cursor.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,catStr.string.size());
- setTextCursor(cursor);
- }
-}
-
-
-
-QMimeData* TranslationUnitTextEdit::createMimeDataFromSelection() const
-{
- QMimeData *mimeData = new QMimeData;
-
- CatalogString catalogString=m_catalog->catalogString(m_currentPos);
-
- QTextCursor cursor=textCursor();
- int start=qMin(cursor.anchor(),cursor.position());
- int end=qMax(cursor.anchor(),cursor.position());
-
- QMap<int,int> tagPlaces;
- if (fillTagPlaces(tagPlaces,catalogString,start,end-start))
- {
- //transform CatalogString
- //TODO substring method
- catalogString.string=catalogString.string.mid(start,end-start);
-
- QList<InlineTag>::iterator it=catalogString.tags.begin();
- while (it != catalogString.tags.end())
- {
- if (!tagPlaces.contains(it->start))
- it=catalogString.tags.erase(it);
- else
- {
- it->start-=start;
- it->end-=start;
- ++it;
- }
- }
-
- QByteArray a;
- QDataStream out(&a,QIODevice::WriteOnly);
- QVariant v;
- qVariantSetValue<CatalogString>(v,catalogString);
- out<<v;
- mimeData->setData("application/x-lokalize-xliff+xml",a);
- }
-
- QString text=catalogString.string;
- text.remove(TAGRANGE_IMAGE_SYMBOL);
- mimeData->setText(text);
- return mimeData;
-}
-
-void TranslationUnitTextEdit::insertFromMimeData(const QMimeData* source)
-{
- if (m_part==DocPosition::Source)
- return;
-
- if (source->hasFormat("application/x-lokalize-xliff+xml"))
- {
- //kWarning()<<"has";
- QVariant v;
- QByteArray data=source->data("application/x-lokalize-xliff+xml");
- QDataStream in(&data,QIODevice::ReadOnly);
- in>>v;
- //qWarning()<<"ins"<<qvariant_cast<CatalogString>(v).string<<qvariant_cast<CatalogString>(v).ranges.size();
-
- int start=0;
- m_catalog->beginMacro(i18nc("@item Undo action item","Insert text with markup"));
- QTextCursor cursor=textCursor();
- if (cursor.hasSelection())
- {
- start=qMin(cursor.anchor(),cursor.position());
- int end=qMax(cursor.anchor(),cursor.position());
- removeTargetSubstring(start,end-start);
- cursor.setPosition(start);
- setTextCursor(cursor);
- }
- else
- //sets right cursor position implicitly -- needed for mouse paste
- {
- QMimeData mimeData;
- mimeData.setText("");
- KTextEdit::insertFromMimeData(&mimeData);
- start=textCursor().position();
- }
-
- insertCatalogString(qvariant_cast<CatalogString>(v), start);
- m_catalog->endMacro();
- }
- else
- {
- QString text=source->text();
- text.remove(TAGRANGE_IMAGE_SYMBOL);
- insertPlainText(text);
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-static bool isMasked(const QString& str, uint col)
-{
- if(col == 0 || str.isEmpty())
- return false;
-
- uint counter=0;
- int pos=col;
-
- while(pos >= 0 && str.at(pos) == '\\')
- {
- counter++;
- pos--;
- }
-
- return !(bool)(counter%2);
-}
-
-static QString spclChars("abfnrtv'?\\");
-
-void TranslationUnitTextEdit::keyPressEvent(QKeyEvent *keyEvent)
-{
- if(keyEvent->matches(QKeySequence::MoveToPreviousPage))
- emit gotoPrevRequested();
- else if(keyEvent->matches(QKeySequence::MoveToNextPage))
- emit gotoNextRequested();
- else if(keyEvent->matches(QKeySequence::Undo))
- emit undoRequested();
- else if(keyEvent->matches(QKeySequence::Redo))
- emit redoRequested();
- else if(keyEvent->matches(QKeySequence::Find))
- emit findRequested();
- else if(keyEvent->matches(QKeySequence::FindNext))
- emit findNextRequested();
- else if(keyEvent->matches(QKeySequence::Replace))
- emit replaceRequested();
- else if (keyEvent->modifiers() == (Qt::AltModifier|Qt::ControlModifier))
- {
- if(keyEvent->key()==Qt::Key_Home)
- emit gotoFirstRequested();
- else if(keyEvent->key()==Qt::Key_End)
- emit gotoLastRequested();
- }
- else if (m_part==DocPosition::Source)
- return KTextEdit::keyPressEvent(keyEvent);
-
- //BEGIN GENERAL
- // ALT+123 feature TODO this is general so should be on another level
- else if( (keyEvent->modifiers()&Qt::AltModifier)
- &&!keyEvent->text().isEmpty()
- &&keyEvent->text().at(0).isDigit() )
- {
- QString text=keyEvent->text();
- while (!text.isEmpty()&& text.at(0).isDigit() )
- {
- m_currentUnicodeNumber = 10*m_currentUnicodeNumber+(text.at(0).digitValue());
- text.remove(0,1);
- }
- KTextEdit::keyPressEvent(keyEvent);
- }
- //END GENERAL
-
- else if (!keyEvent->modifiers()&&(keyEvent->key()==Qt::Key_Backspace||keyEvent->key()==Qt::Key_Delete))
- {
- //only for cases when:
- //-BkSpace was hit and cursor was atStart
- //-Del was hit and cursor was atEnd
- if (Q_UNLIKELY( !m_catalog->isApproved(m_currentPos.entry) && !textCursor().hasSelection() )
- && ((textCursor().atStart()&&keyEvent->key()==Qt::Key_Backspace)
- ||(textCursor().atEnd()&&keyEvent->key()==Qt::Key_Delete) ))
- requestToggleApprovement();
- else
- KTextEdit::keyPressEvent(keyEvent);
- }
- else if( keyEvent->key() == Qt::Key_Space && (keyEvent->modifiers()&Qt::AltModifier) )
- insertPlainText(QChar(0x00a0U));
- else if( keyEvent->key() == Qt::Key_Minus && (keyEvent->modifiers()&Qt::AltModifier) )
- insertPlainText(QChar(0x0000AD));
- else if (m_catalog->mimetype()!="text/x-gettext-translation")
- KTextEdit::keyPressEvent(keyEvent);
- //clever editing
- else if(keyEvent->key()==Qt::Key_Return||keyEvent->key()==Qt::Key_Enter)
- {
- if (m_completionBox&&m_completionBox->isVisible())
- {
- if (m_completionBox->currentItem())
- completionActivated(m_completionBox->currentItem()->text());
- else
- kWarning()<<"avoided a crash. a case for bug 238835!";
- m_completionBox->hide();
- return;
- }
- QString str=toPlainText();
- QTextCursor t=textCursor();
- int pos=t.position();
- QString ins;
- if( keyEvent->modifiers()&Qt::ShiftModifier )
- {
- if(pos>0
- &&!str.isEmpty()
- &&str.at(pos-1)=='\\'
- &&!isMasked(str,pos-1))
- {
- ins='n';
- }
- else
- {
- ins="\\n";
- }
- }
- else if(!(keyEvent->modifiers()&Qt::ControlModifier))
- {
- if(m_langUsesSpaces
- &&pos>0
- &&!str.isEmpty()
- &&!str.at(pos-1).isSpace())
- {
- if(str.at(pos-1)=='\\'
- &&!isMasked(str,pos-1))
- ins='\\';
- // if there is no new line at the end
- if(pos<2||str.midRef(pos-2,2)!="\\n")
- ins+=' ';
- }
- else if(str.isEmpty())
- {
- ins="\\n";
- }
- }
- if (!str.isEmpty())
- {
- ins+='\n';
- insertPlainText(ins);
- }
- else
- KTextEdit::keyPressEvent(keyEvent);
- }
- else if( (keyEvent->modifiers()&Qt::ControlModifier)?
- (keyEvent->key()==Qt::Key_D) :
- (keyEvent->key()==Qt::Key_Delete)
- && textCursor().atEnd())
- {
- kWarning()<<"workaround for Qt/X11 bug";
- QTextCursor t=textCursor();
- if(!t.hasSelection())
- {
- int pos=t.position();
- QString str=toPlainText();
- //workaround for Qt/X11 bug: if Del on NumPad is pressed, then pos is beyond end
- if (pos==str.size()) --pos;
- if(!str.isEmpty()
- &&str.at(pos) == '\\'
- &&!isMasked(str,pos)
- &&pos<str.length()-1
- &&spclChars.contains(str.at(pos+1)))
- {
- t.deleteChar();
- }
- }
-
- t.deleteChar();
- setTextCursor(t);
- }
- else if( (!keyEvent->modifiers()&&keyEvent->key()==Qt::Key_Backspace)
- || ( ( keyEvent->modifiers() & Qt::ControlModifier ) && keyEvent->key() == Qt::Key_H ) )
- {
- QTextCursor t=textCursor();
- if(!t.hasSelection())
- {
- int pos=t.position();
- QString str=toPlainText();
- if(!str.isEmpty() && pos>0 && spclChars.contains(str.at(pos-1)))
- {
- if(pos>1 && str.at(pos-2)=='\\' && !isMasked(str,pos-2))
- {
- t.deletePreviousChar();
- t.deletePreviousChar();
- setTextCursor(t);
- //kWarning()<<"set-->"<<textCursor().anchor()<<textCursor().position();
- }
- }
-
- }
- KTextEdit::keyPressEvent(keyEvent);
- }
- else if(keyEvent->key() == Qt::Key_Tab)
- insertPlainText("\\t");
- else
- KTextEdit::keyPressEvent(keyEvent);
-}
-
-void TranslationUnitTextEdit::keyReleaseEvent(QKeyEvent* e)
-{
- if ( (e->key()==Qt::Key_Alt) && m_currentUnicodeNumber >= 32 )
- {
- insertPlainText(QChar( m_currentUnicodeNumber ));
- m_currentUnicodeNumber=0;
- }
- else
- KTextEdit::keyReleaseEvent(e);
-}
-
-QString TranslationUnitTextEdit::toPlainText()
-{
- QTextCursor cursor = textCursor();
- cursor.select(QTextCursor::Document);
- QString text=cursor.selectedText();
- text.replace(QChar(8233),'\n');
-/*
- int ii=text.size();
- while(--ii>=0)
- kWarning()<<text.at(ii).unicode();
-*/
- return text;
-}
-
-
-
-void TranslationUnitTextEdit::emitCursorPositionChanged()
-{
- emit cursorPositionChanged(textCursor().columnNumber());
-}
-
-void TranslationUnitTextEdit::insertTag(InlineTag tag)
-{
- QTextCursor cursor=textCursor();
- tag.start=qMin(cursor.anchor(),cursor.position());
- tag.end=qMax(cursor.anchor(),cursor.position())+tag.isPaired();
- kWarning()<<(m_part==DocPosition::Source)<<tag.start<<tag.end;
- m_catalog->push(new InsTagCmd(m_catalog,currentPos(),tag));
- showPos(currentPos(),CatalogString(),/*keepCursor*/true);
- cursor.movePosition(QTextCursor::NextCharacter,QTextCursor::MoveAnchor,tag.end+1+tag.isPaired());
- setFocus();
-}
-
-int TranslationUnitTextEdit::strForMicePosIfUnderTag(QPoint mice, CatalogString& str, bool tryHarder)
-{
- QTextCursor cursor=cursorForPosition(mice);
- int pos=cursor.position();
- str=m_catalog->catalogString(m_currentPos);
- if (pos==-1 || pos>=str.string.size()) return -1;
- //kWarning()<<"here1"<<str.string.at(pos)<<str.string.at(pos-1)<<str.string.at(pos+1);
-
-
-// if (pos>0)
-// {
-// cursor.movePosition(QTextCursor::Left);
-// mice.setX(mice.x()+cursorRect(cursor).width()/2);
-// pos=cursorForPosition(mice).position();
-// }
-
- if (str.string.at(pos)!=TAGRANGE_IMAGE_SYMBOL)
- {
- bool cont=tryHarder && --pos>=0 && str.string.at(pos)==TAGRANGE_IMAGE_SYMBOL;
- if (!cont)
- return -1;
- }
-
- int result=str.tags.size();
- while(--result>=0 && str.tags.at(result).start!=pos && str.tags.at(result).end!=pos)
- ;
- return result;
-}
-
-void TranslationUnitTextEdit::mouseReleaseEvent(QMouseEvent* event)
-{
- if (event->button()==Qt::LeftButton)
- {
- CatalogString str;
- int pos=strForMicePosIfUnderTag(event->pos(),str);
- if (pos!=-1 && m_part==DocPosition::Source)
- {
- emit tagInsertRequested(str.tags.at(pos));
- event->accept();
- return;
- }
- }
- KTextEdit::mouseReleaseEvent(event);
-}
-
-
-void TranslationUnitTextEdit::contextMenuEvent(QContextMenuEvent *event)
-{
- CatalogString str;
- int pos=strForMicePosIfUnderTag(event->pos(),str);
- if (pos!=-1)
- {
- QString xid=str.tags.at(pos).xid;
-
- if (!xid.isEmpty())
- {
- QMenu menu;
- int entry=m_catalog->unitById(xid);
- /* QAction* findUnit=menu.addAction(entry>=m_catalog->numberOfEntries()?
- i18nc("@action:inmenu","Show the binary unit"):
- i18nc("@action:inmenu","Go to the referenced entry")); */
-
- QAction* result=menu.exec(event->globalPos());
- if (result)
- {
- kWarning()<<entry<<xid;
- if (entry>=m_catalog->numberOfEntries())
- emit binaryUnitSelectRequested(xid);
- else
- emit gotoEntryRequested(DocPosition(entry));
- event->accept();
- }
- return;
- }
- }
- if (textCursor().hasSelection())
- {
- QMenu menu;
- // QAction* lookup=menu.addAction(i18nc("@action:inmenu","Lookup selected text in translation memory"));
- if (menu.exec(event->globalPos()))
- emit tmLookupRequested(m_part,textCursor().selectedText());
- return;
- }
-
- if (m_part!=DocPosition::Target)
- return;
-
- KTextEdit::contextMenuEvent(event);
-
-#if 0
- QTextCursor wordSelectCursor=cursorForPosition(event->pos());
- wordSelectCursor.select(QTextCursor::WordUnderCursor);
- if (m_highlighter->isWordMisspelled(wordSelectCursor.selectedText()))
- {
- QMenu menu;
- QMenu suggestions;
- foreach(const QString& s, m_highlighter->suggestionsForWord(wordSelectCursor.selectedText()))
- suggestions.addAction(s);
- if (!suggestions.isEmpty())
- {
- QAction* answer=suggestions.exec(event->globalPos());
- if (answer)
- {
- m_catalog->beginMacro(i18nc("@item Undo action item","Replace text"));
- wordSelectCursor.insertText(answer->text());
- m_catalog->endMacro();
- }
- }
- }
-#endif
-
-// QMenu menu;
-// QAction* spellchecking=menu.addAction();
-// event->accept();
-}
-
-void TranslationUnitTextEdit::wheelEvent(QWheelEvent *event)
-{
- if (m_part==DocPosition::Source || !Settings::mouseWheelGo())
- return KTextEdit::wheelEvent(event);
-
- switch (event->modifiers())
- {
- case Qt::ControlModifier:
- if (event->delta() > 0)
- emit gotoPrevFuzzyRequested();
- else
- emit gotoNextFuzzyRequested();
- break;
- case Qt::AltModifier:
- if (event->delta() > 0)
- emit gotoPrevUntranslatedRequested();
- else
- emit gotoNextUntranslatedRequested();
- break;
- case Qt::ControlModifier + Qt::ShiftModifier:
- if (event->delta() > 0)
- emit gotoPrevFuzzyUntrRequested();
- else
- emit gotoNextFuzzyUntrRequested();
- break;
- case Qt::ShiftModifier:
- return KTextEdit::wheelEvent(event);
- default:
- if (event->delta() > 0)
- emit gotoPrevRequested();
- else
- emit gotoNextRequested();
- }
-}
-
-void TranslationUnitTextEdit::spellReplace()
-{
- QTextCursor wordSelectCursor=textCursor();
- wordSelectCursor.select(QTextCursor::WordUnderCursor);
- if (!m_highlighter->isWordMisspelled(wordSelectCursor.selectedText()))
- return;
-
- const QStringList& suggestions=m_highlighter->suggestionsForWord(wordSelectCursor.selectedText());
- if (suggestions.isEmpty())
- return;
-
- m_catalog->beginMacro(i18nc("@item Undo action item","Replace text"));
- wordSelectCursor.insertText(suggestions.first());
- m_catalog->endMacro();
-}
-
-bool TranslationUnitTextEdit::event(QEvent *event)
-{
- if (event->type()==QEvent::ToolTip)
- {
- QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
- CatalogString str;
- int pos=strForMicePosIfUnderTag(helpEvent->pos(),str,true);
- if (pos!=-1)
- {
- QString tooltip=str.tags.at(pos).displayName();
- QToolTip::showText(helpEvent->globalPos(),tooltip);
- return true;
- }
-
- QString langCode=m_highlighter->currentLanguage();
- bool nospell=langCode.isEmpty();
- if (nospell)
- langCode=m_part==DocPosition::Source?m_catalog->sourceLangCode():m_catalog->targetLangCode();
- QString tip=KGlobal::locale()->languageCodeToName(langCode)+" ("+langCode+")";
- if (nospell)
- tip+=" - "+i18n("no spellcheck available");
- QToolTip::showText(helpEvent->globalPos(), tip);
- }
- return KTextEdit::event(event);
-}
-
-
-
-void TranslationUnitTextEdit::tagMenu() {doTag(false);}
-void TranslationUnitTextEdit::tagImmediate(){doTag(true);}
-
-void TranslationUnitTextEdit::doTag(bool immediate)
-{
- QMenu menu;
- QAction* txt=0;
-
- CatalogString sourceWithTags=m_catalog->sourceWithTags(m_currentPos);
- int count=sourceWithTags.tags.size();
- if (count)
- {
- QMap<QString,int> tagIdToIndex=m_catalog->targetWithTags(m_currentPos).tagIdToIndex();
- bool hasActive=false;
- for (int i=0;i<count;++i)
- {
- //txt=menu.addAction(sourceWithTags.ranges.at(i));
- txt=menu.addAction(QString::number(i)/*+" "+sourceWithTags.ranges.at(i).id*/);
- txt->setData(QVariant(i));
- if (!hasActive && !tagIdToIndex.contains(sourceWithTags.tags.at(i).id))
- {
- if (immediate)
- {
- insertTag(sourceWithTags.tags.at(txt->data().toInt()));
- return;
- }
- hasActive=true;
- menu.setActiveAction(txt);
- }
- }
- if (immediate) return;
- txt=menu.exec(mapToGlobal(cursorRect().bottomRight()));
- if (!txt) return;
- insertTag(sourceWithTags.tags.at(txt->data().toInt()));
- }
- else
- {
- if (Q_UNLIKELY( Project::instance()->markup().isEmpty() ))
- return;
-
- //QRegExp tag("(<[^>]*>)+|\\&\\w+\\;");
- QRegExp tag(Project::instance()->markup());
- tag.setMinimal(true);
- QString en=m_catalog->sourceWithTags(m_currentPos).string;
- QString target(toPlainText());
- en.remove('\n');
- target.remove('\n');
- int pos=0;
- //tag.indexIn(en);
- int posInMsgStr=0;
- while ((pos=tag.indexIn(en,pos))!=-1)
- {
- /* QString str(tag.cap(0));
- str.replace("&","&&");*/
- txt=menu.addAction(tag.cap(0));
- pos+=tag.matchedLength();
-
- if (posInMsgStr!=-1 && (posInMsgStr=target.indexOf(tag.cap(0),posInMsgStr))==-1)
- {
- if (immediate)
- {
- insertPlainText(txt->text());
- return;
- }
- menu.setActiveAction(txt);
- } else if (posInMsgStr!=-1)
- posInMsgStr+=tag.matchedLength();
- }
- if (!txt || immediate)
- return;
-
- //txt=menu.exec(_msgidEdit->mapToGlobal(QPoint(0,0)));
- txt=menu.exec(mapToGlobal(cursorRect().bottomRight()));
- if (txt)
- insertPlainText(txt->text());
- }
-}
-
-
-void TranslationUnitTextEdit::source2target()
-{
- CatalogString sourceWithTags=m_catalog->sourceWithTags(m_currentPos);
- QString text=sourceWithTags.string;
- QString out;
- QString ctxt=m_catalog->context(m_currentPos.entry).first();
- QRegExp delimiter("\\s*,\\s*");
-
- //TODO ask for the fillment if the first time.
- //BEGIN KDE specific part
- if( ctxt.startsWith( "NAME OF TRANSLATORS" ) || text.startsWith( "_: NAME OF TRANSLATORS\\n" ))
- {
- if (!document()->toPlainText().split(delimiter).contains(Settings::authorLocalizedName())) {
- if (!document()->isEmpty())
- out=", ";
- out+=Settings::authorLocalizedName();
- }
- }
- else if( ctxt.startsWith( "EMAIL OF TRANSLATORS" ) || text.startsWith( "_: EMAIL OF TRANSLATORS\\n" )) {
- if (!document()->toPlainText().split(delimiter).contains(Settings::authorEmail())) {
- if (!document()->isEmpty())
- out=", ";
- out+=Settings::authorEmail();
- }
- }
- else if( /*_catalog->isGeneratedFromDocbook() &&*/ text.startsWith( "ROLES_OF_TRANSLATORS" ) )
- {
- if (!document()->isEmpty())
- out='\n';
- out+="<othercredit role=\\\"translator\\\">\n"
- "<firstname></firstname><surname></surname>\n"
- "<affiliation><address><email>"+Settings::authorEmail()+"</email></address>\n"
- "</affiliation><contrib></contrib></othercredit>";
- }
- else if( text.startsWith( "CREDIT_FOR_TRANSLATORS" ) )
- {
- if (!document()->isEmpty())
- out='\n';
- out+="<para>"+Settings::authorLocalizedName()+'\n'+
- "<email>"+Settings::authorEmail()+"</email></para>";
- }
- //END KDE specific part
-
- else {
- m_catalog->beginMacro(i18nc("@item Undo action item","Copy source to target"));
- removeTargetSubstring(0,-1,/*refresh*/false);
- insertCatalogString(sourceWithTags,0,/*refresh*/false);
- m_catalog->endMacro();
-
- showPos(m_currentPos,sourceWithTags,/*keepCursor*/false);
-
- requestToggleApprovement();
- }
- if (!out.isEmpty()) {
- QTextCursor t=textCursor();
- t.movePosition(QTextCursor::End);
- t.insertText(out);
- setTextCursor(t);
- }
-}
-
-void TranslationUnitTextEdit::requestToggleApprovement()
-{
- if (m_catalog->isApproved(m_currentPos.entry)||!Settings::autoApprove())
- return;
-
- bool skip=m_catalog->isPlural(m_currentPos);
- if (skip)
- {
- skip=false;
- DocPos pos(m_currentPos);
- for (pos.form=0;pos.form<m_catalog->numberOfPluralForms();++(pos.form))
- skip=skip||!m_catalog->isModified(pos);
- }
- if (!skip)
- emit toggleApprovementRequested();
-}
-
-
-void TranslationUnitTextEdit::cursorToStart()
-{
- QTextCursor t=textCursor();
- t.movePosition(QTextCursor::Start);
- setTextCursor(t);
-}
-
-
-void TranslationUnitTextEdit::doCompletion(int pos)
-{
- QTime a;a.start();
- QString target=m_catalog->targetWithTags(m_currentPos).string;
- int sp=target.lastIndexOf(CompletionStorage::instance()->rxSplit,pos-1);
- int len=(pos-sp)-1;
-
- QStringList s=CompletionStorage::instance()->makeCompletion(QString::fromRawData(target.unicode()+sp+1,len));
-
- if (!m_completionBox)
- {
-//BEGIN creation
- m_completionBox=new MyCompletionBox(this);
- connect(m_completionBox,SIGNAL(activated(QString)),this,SLOT(completionActivated(QString)));
- m_completionBox->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Preferred);
-//END creation
- }
- m_completionBox->setItems(s);
- if (s.size() && !s.first().isEmpty())
- {
- m_completionBox->setCurrentRow(0);
- //qApp->removeEventFilter( m_completionBox );
- if (!m_completionBox->isVisible()) //NOTE remove the ckeck if kdelibs gets adapted
- m_completionBox->show();
- m_completionBox->resize(m_completionBox->sizeHint());
- m_completionBox->move(viewport()->mapToGlobal(cursorRect().bottomRight()));
- }
- else
- m_completionBox->hide();
- kDebug()<<"hits generated in"<<a.elapsed()<<"msecs";
-}
-
-void TranslationUnitTextEdit::doExplicitCompletion()
-{
- doCompletion(textCursor().anchor());
-}
-
-void TranslationUnitTextEdit::completionActivated(const QString& semiWord)
-{
- QTextCursor cursor=textCursor();
- cursor.insertText(semiWord);
- setTextCursor(cursor);
-}
-
-#include "moc_xlifftextedit.cpp"
+++ /dev/null
-/* ****************************************************************************
- This file is part of Lokalize
-
- Copyright (C) 2007-2009 by Nick Shaforostoff <shafff@ukr.net>
-
- 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) version 3 or any later version
- accepted by the membership of KDE e.V. (or its successor approved
- by the membership of KDE e.V.), which shall act as a proxy
- defined in Section 14 of version 3 of the license.
-
- 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, see <http://www.gnu.org/licenses/>.
-
-**************************************************************************** */
-
-
-#ifndef XLIFFTEXTEDITOR_H
-#define XLIFFTEXTEDITOR_H
-
-#include "pos.h"
-#include "catalogstring.h"
-
-#include <KTextEdit>
-#include <QMouseEvent>
-class SyntaxHighlighter;//TODO rename
-class KCompletionBox;
-class MyCompletionBox;
-
-class TranslationUnitTextEdit: public KTextEdit
-{
- Q_OBJECT
-public:
- TranslationUnitTextEdit(Catalog* catalog, DocPosition::Part part, QWidget* parent=0);
- //NOTE remove this when Qt is fixed (hack for unbreakable spaces bug #162016)
- QString toPlainText();
-
- ///@returns targetWithTags for the sake of not calling XliffStorage/doContent twice
- CatalogString showPos(DocPosition pos, const CatalogString& refStr=CatalogString(), bool keepCursor=true);
- DocPosition currentPos()const {return m_currentPos;}
-
- void cursorToStart();
-
-public slots:
- void reflectApprovementState();
- void reflectUntranslatedState();
-
- bool removeTargetSubstring(int start=0, int end=-1, bool refresh=true);
- void insertCatalogString(CatalogString catStr, int start=0, bool refresh=true);
-
- void source2target();
- void tagMenu();
- void tagImmediate();
- void insertTag(InlineTag tag);
- void spellReplace();
-
- void emitCursorPositionChanged();//for leds
-
- void doExplicitCompletion();
-
-protected:
- void keyPressEvent(QKeyEvent *keyEvent);
- void keyReleaseEvent(QKeyEvent* e);
- QMimeData* createMimeDataFromSelection() const;
- void insertFromMimeData(const QMimeData* source);
- void mouseReleaseEvent(QMouseEvent* event);
-
- void contextMenuEvent(QContextMenuEvent *event);
- void wheelEvent(QWheelEvent *event);
- bool event(QEvent *event);
-
-private:
- ///@a refStr is for proper numbering
- void setContent(const CatalogString& catStr, const CatalogString& refStr=CatalogString());
-
- int strForMicePosIfUnderTag(QPoint mice, CatalogString& str, bool tryHarder=false);
-
- void requestToggleApprovement();
-
- void doTag(bool immediate);
-
- void doCompletion(int pos);
-
-private slots:
- //for Undo/Redo tracking
- void contentsChanged(int position,int charsRemoved,int charsAdded);
- void completionActivated(const QString&);
- void fileLoaded();
-
-signals:
- void toggleApprovementRequested();
- void undoRequested();
- void redoRequested();
- void findRequested();
- void findNextRequested();
- void replaceRequested();
- void gotoFirstRequested();
- void gotoLastRequested();
- void gotoPrevRequested();
- void gotoNextRequested();
- void gotoPrevFuzzyRequested();
- void gotoNextFuzzyRequested();
- void gotoPrevUntranslatedRequested();
- void gotoNextUntranslatedRequested();
- void gotoPrevFuzzyUntrRequested();
- void gotoNextFuzzyUntrRequested();
- void gotoEntryRequested(const DocPosition&);
-
-
- void tagInsertRequested(const InlineTag& tag);
-
- void binaryUnitSelectRequested(const QString&);
- void tmLookupRequested(DocPosition::Part,const QString&);
-
- void contentsModified(const DocPosition&);
- void approvedEntryDisplayed();
- void nonApprovedEntryDisplayed();
- void translatedEntryDisplayed();
- void untranslatedEntryDisplayed();
- void cursorPositionChanged(int column);
-
-private:
- int m_currentUnicodeNumber; //alt+NUM thing
- bool m_langUsesSpaces; //e.g. Chinese doesn't
-
- Catalog* m_catalog;
- DocPosition::Part m_part;
- DocPosition m_currentPos;
- SyntaxHighlighter* m_highlighter;
-
- MyCompletionBox* m_completionBox;
-
- //for undo/redo tracking
- QString _oldMsgstr;
- QString _oldMsgstrAscii; //HACK to workaround #218246
-};
-
-
-void insertContent(QTextCursor& cursor, const CatalogString& catStr, const CatalogString& refStr=CatalogString(), bool insertText=true);
-
-
-#endif
+++ /dev/null
-<?xml version='1.0' encoding='utf-8'?>
-<xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1" >
- <file original="/home/xx/Documents/test.odt" datatype="plaintext" source-language="en" >
- <body>
- <trans-unit id="000">
- <source>test symbols 
</source>
- </trans-unit>
- <trans-unit id="001" approved="yes">
- <source>test changing ids of <g id="0" >inlined markup</g>. And <g id="5" >one more</g>.</source>
- </trans-unit>
- <trans-unit id="0025" approved="yes">
- <source>test changing ids of units themseves.</source>
- </trans-unit>
- <trans-unit id="003" approved="yes">
- <source>test changing the text 2.</source>
- </trans-unit>
- <trans-unit id="004" >
- <source>test no change.</source>
- </trans-unit>
- <trans-unit id="005" >
- <source>test adding text.</source>
- </trans-unit>
- <trans-unit id="0045" >
- <source>test no change.</source>
- </trans-unit>
- <trans-unit id="006" >
- <source>test <g id="10" >removing</g> some <g id="11" >tags</g>.</source>
- </trans-unit>
- <trans-unit id="007" >
- <source>test <g id="10" ctype="italic">adding</g> attributes.</source>
- </trans-unit>
- <trans-unit id="008" >
- <source>test preserving alt-trans.</source>
- </trans-unit>
- <trans-unit id="009" >
- <source>test preserving alt-trans when text is changed 2.</source>
- </trans-unit>
- <trans-unit id="010" >
- <source>test inline <g id="7">position</g> change.</source>
- </trans-unit>
- <trans-unit id="mrkmrk" >
- <source><mrk mtype="seg" >mrk preserving <mrk mtype="internationalism" >test</mrk>: seg1</mrk><mrk mtype="seg" >seg2</mrk></source>
- </trans-unit>
- <trans-unit id="mrkmrk" >
- <source><mrk mtype="seg" >mrk1<mrk mtype="internationalism" >test</mrk>: </mrk><mrk mtype="seg" >seg2</mrk></source>
- </trans-unit>
- <bin-unit id="bin-unit" >
- <bin-source>
- <external-file href="../shots/menu-internet.png" />
- </bin-source>
- </bin-unit>
- </body>
- </file>
-</xliff>
+++ /dev/null
-<?xml version='1.0' encoding='utf-8'?>
-<xliff version="1.1" xmlns="urn:oasis:names:tc:xliff:document:1.1" >
- <file original="/home/xx/Documents/test.odt" datatype="plaintext" source-language="en" >
- <header>
- <phase-group>
- <phase contact-name="Nick Shaforostoff" tool-id="lokalize-0.3" phase-name="translation-1" contact-email="shaforostoff@kde.ru" process-name="translation" date="2009-03-08" />
- </phase-group>
- <tool tool-id="lokalize-0.3" tool-name="Lokalize" tool-version="0.3" />
- <tool tool-id="lokalize-1.0" tool-name="Lokalize" tool-version="1.0" />
- </header>
- <body>
- <trans-unit id="000" >
- <source>test symbols 
</source>
- </trans-unit>
- <trans-unit id="001" approved="yes" >
- <source>test changing ids of <g id="20" >inlined markup</g>. And <g id="5" >one more</g>.</source>
- <target phase-name="translation-1" state="translated" >xxtest changing ids of <g id="20" >inlined markup</g>. And <g id="5" >one more</g>.xx</target>
- </trans-unit>
- <trans-unit id="002" approved="yes" >
- <source>test changing ids of units themseves.</source>
- <target>xxtest changing ids of units themseves.xx</target>
- </trans-unit>
- <trans-unit id="003" approved="yes" >
- <source>test changing the text 1.</source>
- <target>xxtest changing the text 1.xx</target>
- </trans-unit>
- <trans-unit id="004" >
- <source>test no change.</source>
- <target phase-name="translation-1" state="final" >xxtest no change.xx</target>
- </trans-unit>
- <trans-unit id="0045" >
- <source>test no change.</source>
- </trans-unit>
- <trans-unit id="005" >
- <source>test <g id="10" >removing</g> <g id="11" >some</g> <g id="12" >tags</g>.</source>
- <target state="final">xxtest <g id="10" >removing</g> <g id="11" >some</g> <g id="12" >tags</g>.xx</target>
- </trans-unit>
- <trans-unit id="006" >
- <source>test <g id="10" >adding</g> attributes.</source>
- <target state="final">xxtest <g id="10" >adding</g> attributes.xx</target>
- </trans-unit>
- <trans-unit id="007" >
- <source>test preserving alt-trans.</source>
- <note priority="5" from="Nick Shaforostoff" >test notes</note>
- <alt-trans>
- <source>the test phrase</source>
- <target xml:lang="fr" >phrase de l'essai</target>
- </alt-trans>
- <alt-trans>
- <target xml:lang="fr" >un test expression</target>
- </alt-trans>
- </trans-unit>
- <trans-unit id="008" >
- <source>test preserving alt-trans when text is changed 1.</source>
- <target>xxtest preserving alt-trans when text is changed 1.xx</target>
- <note priority="5" from="Nick Shaforostoff" >test notes</note>
- <alt-trans>
- <source>the test phrase</source>
- <target xml:lang="fr" >phrase de l'essai</target>
- </alt-trans>
- <alt-trans>
- <target xml:lang="fr" >un test expression</target>
- </alt-trans>
- </trans-unit>
- <trans-unit id="009" approved="yes" >
- <source>test text removal.</source>
- <target>xxtest text removal.xx</target>
- </trans-unit>
- <trans-unit id="010" >
- <source>test <g id="7" >inline</g> position change.</source>
- <target phase-name="translation-1" state="final" >test <g id="7" >inline</g> position change.</target>
- </trans-unit>
- <trans-unit id="mrkmrk" >
- <source><mrk mtype="seg" >mrk preserving test: seg1</mrk><mrk mtype="seg" >seg2</mrk></source>
- <target phase-name="translation-1" state="translated" ><mrk mtype="internationalism" >huh?</mrk> </target>
- </trans-unit>
- <trans-unit id="mrkmrk" >
- <source><mrk mtype="seg" >mrk1<mrk mtype="internationalism" >test</mrk>: </mrk><mrk mtype="seg" >seg2</mrk></source>
- <target>xx<mrk mtype="seg" >mrk1<mrk mtype="internationalism" >test</mrk>: </mrk><mrk mtype="seg" >seg2</mrk>xx</target>
- </trans-unit>
- <bin-unit id="bin-unit" >
- <bin-source>
- <external-file href="../shots/menu-internet.png" />
- </bin-source>
- </bin-unit>
- </body>
- </file>
-</xliff>