added libkomparediff2 and kompare
2
kompare/AUTHORS
Normal file
|
@ -0,0 +1,2 @@
|
|||
Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
John Firebaugh <jfirebaugh@kde.org>
|
48
kompare/CMakeLists.txt
Normal file
|
@ -0,0 +1,48 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
project(kompare)
|
||||
|
||||
# search packages used by KDE
|
||||
find_package(KDE4 REQUIRED)
|
||||
include(KDE4Defaults)
|
||||
add_definitions (${QT_DEFINITIONS} ${KDE4_DEFINITIONS})
|
||||
|
||||
find_package(LibKompareDiff2 REQUIRED)
|
||||
include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR} ${KDE4_INCLUDES} ${LIBKOMPAREDIFF2_INCLUDE_DIR})
|
||||
|
||||
add_subdirectory( doc )
|
||||
add_subdirectory( interfaces )
|
||||
add_subdirectory( libdialogpages )
|
||||
add_subdirectory( komparenavtreepart )
|
||||
add_subdirectory( komparepart )
|
||||
add_subdirectory( pics )
|
||||
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/komparepart
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/libdialogpages
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/interfaces
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/komparenavtreepart
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/komparepart)
|
||||
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(kompare_SRCS
|
||||
main.cpp
|
||||
kompare_shell.cpp
|
||||
kompareurldialog.cpp
|
||||
)
|
||||
|
||||
kde4_add_app_icon(kompare_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/pics/hi*-app-kompare.png")
|
||||
|
||||
kde4_add_executable(kompare ${kompare_SRCS})
|
||||
|
||||
target_link_libraries(kompare kompareinterface ${LIBKOMPAREDIFF2_LIBRARIES} komparedialogpages ${KDE4_KTEXTEDITOR_LIBS} )
|
||||
|
||||
install(TARGETS kompare ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install( PROGRAMS kompare.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
|
||||
install( FILES kompareui.rc DESTINATION ${DATA_INSTALL_DIR}/kompare )
|
||||
install( FILES komparenavigationpart.desktop kompareviewpart.desktop DESTINATION ${SERVICETYPES_INSTALL_DIR} )
|
||||
|
340
kompare/COPYING
Normal file
|
@ -0,0 +1,340 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<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.
|
397
kompare/COPYING.DOC
Normal file
|
@ -0,0 +1,397 @@
|
|||
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.
|
423
kompare/ChangeLog
Normal file
|
@ -0,0 +1,423 @@
|
|||
Dec 27, 2004 : Jeff Snyder
|
||||
* Fix for bug 95640 (nothing displayed when kompare is embedded in Ark
|
||||
fixed by forcing the delivery of childEvents to komparesplitter at
|
||||
the end of its constructor
|
||||
|
||||
Dec 20, 2004 : Jeff Snyder
|
||||
* Things that have happened since 3.3:
|
||||
(this list is not complete)
|
||||
* Look & feel changed
|
||||
|
||||
Dec 20, 2004 : Jeff Snyder
|
||||
* Things that were changed sometime between Nov 25, 2003 and KDE 3.3:
|
||||
(this list is not complete)
|
||||
* KompareConnectWidget became draggable, by replacing KompareViewFrame
|
||||
with KompareSplitter.
|
||||
|
||||
Dec 20, 2004 : Jeff Snyder
|
||||
* This changelog seems to have been neglected for over a year now. I'll
|
||||
try to retroactively fix this as and when I remember things that have
|
||||
been fixed - but it'll probably never be complete and accurate for the
|
||||
Dec 2003 - Nov 2004 period. I'll be making entries concering what i'm
|
||||
doing with kompare from now onwards.
|
||||
|
||||
Nov 25, 2003 : Otto Bruggeman
|
||||
* Fix nasty looping to the end of the file when hitting previous difference on the first difference in the first file
|
||||
|
||||
Nov 25, 2003 : Laurent Montel
|
||||
* Fix memleak, QStringList is implicitly shared so no need for a reference, it is already a pointer to data thing
|
||||
|
||||
Nov 23, 2003 : Otto Bruggeman
|
||||
* Fixed version string (bug 68872)
|
||||
* Fix for 68871 (added slotNextDifference to slotApplyDifference())
|
||||
* Fix for a crash: dont call blendOriginalIntoModelList with Kompare::ShowingDiff
|
||||
|
||||
Nov 22, 2003 : Otto Bruggeman
|
||||
* Fix to make the bugs.kde.org dialog pop up instead of sending a mail to John when pressing
|
||||
Help->Report bug... Also added my homepage since it has always been kompare's home imo.
|
||||
|
||||
Nov 22, 2003 : Otto Bruggeman
|
||||
* Rework the blendFile method so it actually works and as a bonus is a bit faster
|
||||
This introduces a new form of show entire file when comparing, one that works
|
||||
And because of it, it saves files properly now because the entire file is now available even if
|
||||
you have a single line change in a million line file with only 2 context lines in the diff.
|
||||
|
||||
Nov 22, 2003 : Otto Bruggeman
|
||||
* Remove the Show entire file option. It only causes problems at the moment
|
||||
Fixes bug 68729
|
||||
|
||||
Nov 22, 2003 : Otto Bruggeman
|
||||
* Commenting out a lot of debug output, it has served it's purpose well in levenshteintable.cpp
|
||||
|
||||
Nov 21, 2003 : Otto Bruggeman
|
||||
* Also expand tabs to spaces in strings without or after Commands (in the INLINE_DIFFERENCES
|
||||
code path and yes commands is a shitty name for them but i cant think of something decent)
|
||||
|
||||
Nov 21, 2003 : Otto Bruggeman
|
||||
* Real Fix (tm) for activating the Swap source with destination action
|
||||
|
||||
Nov 21, 2003 : Otto Bruggeman
|
||||
* Fix empty line drawing in the INLINE_DIFFERENCES code path
|
||||
|
||||
Nov 20, 2003 : Otto Bruggeman
|
||||
* When swapping source with destination also change the windows caption and the statusbar text
|
||||
* Make sure that when swapping and when there are changes, all changes that were made can be
|
||||
saved, discarded or cancel the whole swap (strings are recycled from the queryClose method)
|
||||
* Give a better parent to the KIO::NetAccess::download in komparemodellist.cpp
|
||||
* Added some FIXME's for after the branching to make the urls appear in bold in the error message
|
||||
* Make queryClose not use the isModified from the part but from the modellist
|
||||
|
||||
Nov 20, 2003 : Otto Bruggeman
|
||||
* Fix for activating the Swap Source with Destination action.
|
||||
|
||||
Nov 19, 2003 : Otto Bruggeman
|
||||
* Fixed bug 68570, it needed temp vars otherwise it was overwriting source with destination and then
|
||||
overwriting that destination with source which was just changed into destination
|
||||
|
||||
Nov 17, 2003 : Otto Bruggeman
|
||||
* Fix for empty -x and -X arguments.
|
||||
* Fix bugs 58858 and 58531 by using Kompare::Custom instead of Kompare::Default
|
||||
* Fix last selected url in the kurlcomboboxes
|
||||
* Fix for inline differences when there is only 1 char left that still needs to be drawn
|
||||
* Remove support for the -a Treat all files as text diff option. This caused all sorts of weird crashes
|
||||
when parsing the diff output now with the custom options.
|
||||
* Move the per preference page code in the diffprefs constructor into seperate methods per page
|
||||
|
||||
Nov 14, 2003 : Otto Bruggeman
|
||||
* Fix to make Kompare listen to the kdisplayFontChanged signal and set the font properly and redraw with the new font.
|
||||
Found by David Faure.
|
||||
|
||||
Nov 09, 2003 : Otto Bruggeman
|
||||
* Implemented inline differences (deactivated until KDE3.2 has been branched)
|
||||
* added support for the -x and -X options to diff (deactivated until KDE3.2 has been branched)
|
||||
* Various other code cleanups/reindenting
|
||||
|
||||
Nov 09, 2003 : Otto Bruggeman
|
||||
* Code cleanups
|
||||
|
||||
Nov 02, 2003 : Otto Bruggeman
|
||||
* Fixed some more scrolling problems
|
||||
lastItem->scrollId(), add lastItem->maxHeight() and substract the minScrollId()
|
||||
That is the maxScrollId i need in the QScrollBar, took me long enough...
|
||||
|
||||
Oct 05, 2003 : Otto Bruggeman
|
||||
* Fixed the scrolling problems, a stupid regression i introduced, i cant simplify mathematic expressions apparently
|
||||
* Added an implementation for double clicking a difference in the view, but it is not properly connected yet
|
||||
void contentsMouseDoubleClickEvent ( QMouseEvent* );
|
||||
* Fixed embedding in Konqueror by implementing openURL()
|
||||
* Removed m_maxScrollId, it is not necessary and only costs time, QScrollView::contentsHeight() does the same
|
||||
* Fixed some more warnings about unused variables
|
||||
* Fixed the initial drawing of the vertical and horizontal scrollbar
|
||||
|
||||
Oct 04, 2003 : Otto Bruggeman
|
||||
* Added a call to m_modelList->openDirAndDiff to openDirAndDiff
|
||||
* Fixed some error strings by swapping the %# thingies
|
||||
* Added some useless debug output
|
||||
* Fixed KompareModelList::openDirAndDiff to use the right models variable (m_models instead of models)
|
||||
|
||||
Oct 03, 2003 : Otto Bruggeman
|
||||
* Fixed ApplyAll and UnApplyAll, stupid copy and paste error
|
||||
* Fixed some warnings about signed and unsigned
|
||||
* Fixed some warnings about unused variables
|
||||
* Fixed some redrawing issues in the connection widget
|
||||
|
||||
Sep 27, 2003 : Otto Bruggeman
|
||||
* Fixed the redrawing problems in the connect widget with a QTimer::singleShot()
|
||||
* Undid a stupid commit that changed the keyboard shortcuts for next and previous difference
|
||||
* Fixed another bug in the navigation part that made it emit a signal twice
|
||||
* Fixed a bug in the listview drawing, still one left that i cant seem to solve :(
|
||||
|
||||
Sep 27, 2003 : Otto Bruggeman
|
||||
* Moved the apply and navigation actions into the komparemodellist
|
||||
* Fixed Ingo's problem with the next and prev difference KActions
|
||||
|
||||
Sep 26, 2003 : Otto Bruggeman
|
||||
* Added a struct Info in the Kompare namespace. This one contains all the info about what kompare is doing
|
||||
* Fixed splitting the path string in diffmodel
|
||||
* Fixed showing the path in komparenavtreepart in the directory listviews
|
||||
|
||||
Sep 24, 2003 : Otto Bruggeman
|
||||
* Fixes opening diffs, comparing files after moving all that code around
|
||||
|
||||
Sep 23, 2003 : Otto Bruggeman
|
||||
* Moved a lot of url downloading to the kompare part and moved the opening and reading of the downloads to komparemodellist
|
||||
|
||||
Sep 22, 2003 : Otto Bruggeman
|
||||
* Added openStdin() to KompareShell
|
||||
* Fixed stupid implicit conversion from QString to QStringList in kompare_part.cpp
|
||||
* Added openDiff( QStringList ) to the interface and to the part
|
||||
|
||||
Sep 14, 2003 : Otto Bruggeman
|
||||
* Fixed exit status of the kompare process
|
||||
|
||||
Sep 13, 2003 : Otto Bruggeman
|
||||
* Removed some files that apparently came back after the merge
|
||||
|
||||
Sep 07, 2003 : Otto Bruggeman
|
||||
* Some changes to the interface. Made the copy ctor and assignment operator
|
||||
and added a private d-pointer
|
||||
* Removed the use of all deprecated methods and replaced them with undeprecated ones :)
|
||||
|
||||
Sep 02, 2003 : Scott Wheeler
|
||||
* Made the interface pure virtual
|
||||
|
||||
Sep 01, 2003 : Scott Wheeler
|
||||
* Fixed constness of the KompareModelList constructor
|
||||
* Fixed another 2 warnings about comapring signed with unsigned ints
|
||||
* Fixed the initialization of the difault var
|
||||
|
||||
Aug 27, 2003 : Otto Bruggeman
|
||||
* After shitloads of trouble here finally some fixes for the stupid desktop
|
||||
file stuff
|
||||
* Fixes for when there are not enough args for a certain commandline option.
|
||||
|
||||
Aug 22, 2003 : Otto Bruggeman
|
||||
* Fixed converting tabs to spaces in the view, i totally screwed up
|
||||
* View settings now get applied to the view after pressing ok.
|
||||
(Maybe i should make them apply on APlly instead of OK)
|
||||
|
||||
Aug 13, 2003 : Otto Bruggeman
|
||||
* Komkommertijd :) InitialPreference=10 for kompare.desktop as
|
||||
requested
|
||||
|
||||
Aug 10, 2003 : Otto Bruggeman
|
||||
* Backported Helge Deller's changes from head to make_it_cool
|
||||
(kompare_shell.cpp 1.33 -> 1.34). This is about roaming user fixes.
|
||||
Thanks Helge !
|
||||
|
||||
Jul 19, 2003 : Otto Bruggeman
|
||||
* Backported Ingo Klocker's changes from head to make_it_cool
|
||||
(kompare_shell.cpp 1.34 -> 1.35). This is about being able to
|
||||
configure the shortcuts from kompare_part as well. Thanks Ingo !
|
||||
|
||||
Jun 29, 2003 : Otto Bruggeman
|
||||
* Fixed bug 58144 by adding a check for comparing dirs, in that case
|
||||
destinationURL is a directory and not a file name so we need to
|
||||
recreate the filename. This involved changing some code to use a
|
||||
different enum value, so i hope i did it the right way, session
|
||||
management may be broken now when the session was stored with 3.1.2
|
||||
and restarted with 3.1.3. But that is unfortunately unfixable with a
|
||||
kconf_update script.
|
||||
|
||||
Jun 29, 2003 : Otto Bruggeman
|
||||
* Removed a lot of commented code since it is no longer used and will
|
||||
never be used again.
|
||||
* Added 2 methods to the interface: openDiff3(KURL) and
|
||||
openDiff3(QStringList)
|
||||
* Fixed context diff parsing as indicated in bugreport 57774
|
||||
(the example works now, hope there are no regressions)
|
||||
* Removed all references to MiscSettings and MiscPrefs.
|
||||
These classes will disappear RSN.
|
||||
* Fixed the history saving of the urls in the kompare dialog
|
||||
* Parser is no longer a static class but one that needs to be
|
||||
instanciated
|
||||
* Added ViewSettings to KompareProcess, maybe it is better to merge the
|
||||
diff and view settings into one class.
|
||||
|
||||
May 3, 2003 : Otto Bruggeman
|
||||
* Implemented support for -I in the regular diff options (the one in
|
||||
the kompare options dialog)
|
||||
* Fixed the braindamage i created in main.cpp so that kompare no
|
||||
longer stalls because of a missing mainwindow
|
||||
* Made the kcomparedialog more generic and renamed it to
|
||||
kompareurldialog so i can reuse it for blending too
|
||||
* Removed some braindamage in the kompare/Makefile.am
|
||||
* Some compile fixes because of changes to the CXXFLAGS
|
||||
(QRegExp::match cant be used anymore, and some other old style stuff)
|
||||
* Added an action to the menu for blending
|
||||
* moved Open file (or in this case Open Diff) to the top of the file
|
||||
menu
|
||||
* Fixed the accel conflict in the file menu between open diff and
|
||||
compare files
|
||||
|
||||
Apr 30, 2003 : Otto Bruggeman
|
||||
* Implemented blending of a diff file with the original file
|
||||
* Renamed General* View* (more appropriate)
|
||||
* Renamed m_models into m_modelList since it is more appropriate in komparepart
|
||||
* Small fixes to the view, but they break more than they fix :(
|
||||
* Added commandline options for comparing, opening a diff file and
|
||||
blending
|
||||
|
||||
Apr 20, 2003 : Otto Bruggeman
|
||||
* Fixed bug 54264 with a statusbar that gets too wide when long
|
||||
filenames are used
|
||||
* Fixed the missing endline problem in the parser (bug 56552)
|
||||
* Fixed all copyright years (probably too many but hey i'll change
|
||||
those files some time this year so it will be valid :P)
|
||||
* Added support for using a different diff program (Bug 55573)
|
||||
* Added support for using a different tabsize in the viewer (Bug 38776)
|
||||
* The interface is now final i guess so this fixes bug 42849, not
|
||||
every method is implemented but i'll get to them eventually.
|
||||
|
||||
Apr 19, 2003 : Otto Bruggeman
|
||||
* Fixed bug 56322 where openURL did not clear the models when called
|
||||
again with a new diff
|
||||
|
||||
Aug 9, 2002 : Otto Bruggeman
|
||||
* Fixed the whatsthis text for the compare button in the compare dialog
|
||||
* Fixed the history of the comboboxes in the compare dialog
|
||||
* Put the komparemodellist and all needed classes in a Diff2 namespace
|
||||
* Implemented a better parser design (see parser.cpp/h)
|
||||
* Removed the need to directly link to the komparepart for the shellapp
|
||||
* Removed the need to link directly to the komparepart for the navigationpart
|
||||
* Added support for perforce diffs in the new Parser classes
|
||||
* Added a push design for the modified status instead of a pull design
|
||||
* Added an interface to the Komparepart so people can use that to
|
||||
reuse the komparepart
|
||||
|
||||
Jul 15, 2002 : Otto Bruggeman
|
||||
* Fixed normal diff a bit more, filenames dont work yet
|
||||
* Removed some code duplication
|
||||
* Fixed diff output parsing with Common subdirectories in it
|
||||
* Fixed Copyright years in the about box (thanks Carsten Niehaus)
|
||||
* Removed the K3ShellProcess and replaced it with a K3Process
|
||||
|
||||
Feb 18, 2002 : Otto Bruggeman
|
||||
* Fixed scrolling with a wheel mouse in the kompare(list)view and
|
||||
connectwidget and added a config option for the number of lines
|
||||
that is scrolled per wheelscroll.
|
||||
* Fixed the history somehow in the compare dialog.
|
||||
* Implemented the separate directory/file widget.
|
||||
* Implemented reading from stdin by using - as file on the commandline.
|
||||
* Partly implemented a better way for ed and rcs parsing, i'll
|
||||
improve this before KDE 3.0 is released
|
||||
|
||||
Jan 10, 2002 : Otto Bruggeman
|
||||
Comparing directories works now :) You can select them from the begin
|
||||
dialog, and select a directory and then press ok. It will enter the
|
||||
directory but dont select a file so it keeps the directory.
|
||||
Known bug here is that directories need a trailing slash :(
|
||||
|
||||
Oct 07, 2001 : Otto Bruggeman
|
||||
Fix crash when part is not found, basically dont use kapp->quit()
|
||||
but use exit(int). Would be interested to know why it crashes though,
|
||||
the bt gave nothing meaningful here. I should have compiled kompare with
|
||||
debug code.
|
||||
|
||||
Sep 17/18, 2001 : Otto Bruggeman
|
||||
Fixed some stuff dont know what anymore (writing this on oct 7)
|
||||
Probably some more fixes for the klibloader.
|
||||
|
||||
Sep 17, 2001 : Otto Bruggeman
|
||||
Moved to kdesdk and renamed to kompare with preservation of history.
|
||||
Changed almost every occurence of kdiff to kompare (not in this file).
|
||||
|
||||
Sep 08, 2001 : Otto Bruggeman
|
||||
Removed the qt3back dir, changed everything over to qt3,
|
||||
qlist->qptrlist, qlistconstiterator->qptrlistconstiterator
|
||||
|
||||
Jul 29, 2001 : John Firebaugh
|
||||
Add some tests.
|
||||
Add the qregexp3 backport.
|
||||
Use qregexp3 for diff parsing -- soooo much cleaner.
|
||||
All the diff options work.
|
||||
|
||||
Jul 28, 2001 : John Firebaugh
|
||||
Directories can be selected in the compare dialog
|
||||
New base clase KDiff, holds some common stuff
|
||||
Use an enum for format in preferences
|
||||
Implement a save options dialog, displayed at "Save .diff"
|
||||
The diff can be run in any directory, the paths to source
|
||||
and destination will be automatically determined from this.
|
||||
Save all.
|
||||
|
||||
Jul 25, 2001 : John Firebaugh
|
||||
Prompt to save changes on close
|
||||
Show [modified] caption
|
||||
Clean up internal save mechanism
|
||||
|
||||
Jul 14, 2001 : John Firebaugh
|
||||
New menu item "Swap source and destination".
|
||||
Make empty selection work.
|
||||
|
||||
Jul 13, 2001 : John Firebaugh
|
||||
Text view now works in compare mode.
|
||||
Fix clicking difference to select it.
|
||||
Don't scroll to difference when clicking to select it.
|
||||
Give the diff view a nice frame.
|
||||
|
||||
Jul 12, 2001 : Otto Bruggeman
|
||||
Stats work now, maybe they need more info but i dont know what yet.
|
||||
Will think some more about it.
|
||||
|
||||
Jul 12, 2001 : John Firebaugh
|
||||
When comparing files, you can apply or unapply changes and save
|
||||
the result.
|
||||
New menu item "Show Text View" (loads the diff in embedded text viewer).
|
||||
Better status notification.
|
||||
Set the window caption when comparing.
|
||||
|
||||
Jun 27, 2001 : John Firebaugh
|
||||
Ported main view to QListView
|
||||
Remove obsolete files
|
||||
Clicking a difference in the main view selects it
|
||||
Better scrolling
|
||||
|
||||
Jun 24, 2001 : John Firebaugh
|
||||
Coverted to dock window and added navigation tree in a dock.
|
||||
Multiple file diffs are now supported. Each file will show up
|
||||
as an item in the tree, with differences as children.
|
||||
|
||||
Jun 22, 2001 : Otto Bruggeman
|
||||
Tried implementing rcs and ed but they dont work atm, same for show
|
||||
diffstats, will fix that asap.
|
||||
|
||||
May 22, 2001 : John Firebaugh
|
||||
Reworking of most of the view code. Looks pretty.
|
||||
|
||||
May 18, 2001 : Otto Bruggeman
|
||||
Context seems to work, implemented saving... might have some problems
|
||||
left (saving that is)
|
||||
|
||||
May 15, 2001 : John Firebaugh
|
||||
Make the settings work for all windows. Probably some more changes :)
|
||||
|
||||
May 14, 2001 : Otto Bruggeman
|
||||
context diff does not work atm, there is some problem with the separa-
|
||||
tion of old and new. Maybe the old and new needs to be reintegrated.
|
||||
I fixed some functions and now diffmodel does no longer need static
|
||||
functions. All loading is done from the kdiffpart and that is where
|
||||
save should go as well. Removed determineDiffFormat because it is not
|
||||
needed anymore.
|
||||
|
||||
May 13, 2001 : Otto Bruggeman
|
||||
contextdiff is better implemented it finds all stuff in the diff atm
|
||||
but it does not work.
|
||||
|
||||
May 04, 2001 : Otto Bruggeman
|
||||
cleaned up the code by moving the part to a subdir
|
||||
halfassed implementation of contextdiff, will update later today
|
||||
|
||||
Apr 10, 2001 : John Firebaugh
|
||||
use new model/view architecture (not completely implemented yet)
|
||||
NOTE: it will (should) compile, but you won't see any differences... a
|
||||
work in progress
|
||||
|
||||
Apr 05, 2001 : Otto Bruggeman
|
||||
Implemented the ability to move from chuck to chunk in the htmlview
|
||||
Cleaned up the preferences, squashed a few bugs
|
||||
|
||||
Apr 04, 2001 : Otto Bruggeman
|
||||
Normal format works as well
|
||||
|
||||
Apr 04, 2001 : Otto Bruggeman
|
||||
Finally implemented the preferences menu... i still lack some nice
|
||||
icons for it but that will be solved in the near future...
|
||||
|
||||
Mar 25, 2001 : Otto Bruggeman
|
||||
Moved the application icons to the pics dir
|
||||
|
||||
Mar 20, 2001 : Otto Bruggeman
|
||||
Fixed a stupid bug that caused the last line in the rightview not
|
||||
to be colored.
|
||||
Implemented slots for using the KHistoryCombo in the views to select
|
||||
files with.
|
||||
Still a nasty bug with regard to the initial directory in the
|
||||
KFileDialog, needs to be fixed asap but i dont know the cause.
|
||||
Still an error in the historylist and completionlist items. They are
|
||||
not shown correctly.
|
||||
|
||||
Mar 19, 2001 : Otto Bruggeman
|
||||
Added most of the preferences dialog
|
||||
Some speed improvements
|
||||
Some fixes to use the last used directory in KFileDialog
|
35
kompare/DESIGN
Normal file
|
@ -0,0 +1,35 @@
|
|||
Kompare General design:
|
||||
|
||||
Kompare is split up into 4 parts:
|
||||
- A shell around the parts
|
||||
- A library with the modellist and the parser
|
||||
- The navigation tree which uses the library
|
||||
- The view part that also uses the library
|
||||
|
||||
The diffmodel is comparable to a document and the view part is comparable
|
||||
to the view and the komparemodellist is comparable to a documentmanager.
|
||||
The navtree can be viewed as a document view manager.
|
||||
The model is fully separated from the view and all communication goes
|
||||
through signals and slots. The view gets a model that contains all differences
|
||||
for the compared files A and B. The view gets this model from the modellist,
|
||||
the central entity in the part.
|
||||
|
||||
There is an interface to the komparepart that can be used in other programs,
|
||||
simply link to the libkompareinterface.la and call its methods after you have
|
||||
instanciated a komparepart. There is also a "hidden" signal and slot interface
|
||||
that can be connected to from the shell app to get some information, and an
|
||||
interface for communication between the navigation part and the komparepart.
|
||||
|
||||
There is no need to use the interface for the communication between the
|
||||
navigation and kompare parts in the shell app.
|
||||
|
||||
Kompare has some debug areas:
|
||||
|
||||
8100 kompare
|
||||
8101 kompare (libs)
|
||||
8102 kompare (shell)
|
||||
8103 kompare (part)
|
||||
8104 kompare (list view)
|
||||
8105 kompare (nav view)
|
||||
8106 kompare (connect widget)
|
||||
|
19
kompare/Mainpage.dox
Normal file
|
@ -0,0 +1,19 @@
|
|||
/** @mainpage Kompare
|
||||
*
|
||||
* Kompare is a graphical difference viewer that allows you to visualize changes
|
||||
* to a file. Whether you're a developer comparing source code, or you just want
|
||||
* to see the difference between that research paper draft and the final document,
|
||||
* Kompare is the tool you need.
|
||||
*
|
||||
* Kompare can
|
||||
* - Compare two text files
|
||||
* - Recursively compare directories
|
||||
* - View patches generated by diff
|
||||
* - Merge a patch into an existing directory
|
||||
*
|
||||
* Kompare can either be used as a standalone application, or embedded in another
|
||||
* application - e.g. as a patch viewer in konqueror or in KDevelop.
|
||||
*
|
||||
* Kompare is part of the KDE SDK package, and it is released at the same time as
|
||||
* the rest of KDE SDK and KDE.
|
||||
*/
|
3
kompare/Messages.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
#! /bin/sh
|
||||
$EXTRACTRC *.rc */*.rc */*.ui >> rc.cpp || exit 11
|
||||
$XGETTEXT `find . -name "*.cpp" -o -name "*.h"` -o $podir/kompare.pot
|
16
kompare/README
Normal file
|
@ -0,0 +1,16 @@
|
|||
Kompare 2.0
|
||||
|
||||
Kompare is a program to view the differences between files. Features include:
|
||||
|
||||
* comparison of files or directories via a graphical interface
|
||||
* bezier-based connection widget lets you see both source and destination
|
||||
as they really appear
|
||||
* graphical viewing of patch files in normal, context, unified and
|
||||
diff formats
|
||||
* interactive application of differences
|
||||
* full network transparency
|
||||
* ability to view plain-text diff output in embedded viewer
|
||||
* easy navigation of multiple-file diffs with dockable navigation tree
|
||||
* graphical interface to commonly used diff command line options
|
||||
* switch source and destination with one command
|
||||
* diff statistics
|
|
@ -1,21 +0,0 @@
|
|||
# Maintainer: Ivailo Monev <xakepa10@gmail.com>
|
||||
|
||||
version=4.14.3
|
||||
description='Diff/Patch Frontend'
|
||||
depends=('kde-runtime' 'libkomparediff2')
|
||||
makedepends=('cmake' 'automoc4')
|
||||
sources=("http://download.kde.org/stable/$version/src/kompare-$version.tar.xz")
|
||||
|
||||
src_compile() {
|
||||
mkdir "$SOURCE_DIR/build" && cd "$SOURCE_DIR/build"
|
||||
cmake ../kompare-$version \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DKDE4_BUILD_TESTS=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=
|
||||
make
|
||||
}
|
||||
|
||||
src_install() {
|
||||
cd "$SOURCE_DIR/build"
|
||||
make DESTDIR=$INSTALL_DIR install
|
||||
}
|
34
kompare/TODO
Normal file
|
@ -0,0 +1,34 @@
|
|||
!!! Must do before a merge back into HEAD !!!
|
||||
* Write a kconfupdate script to convert the kconfigfile
|
||||
* the diff options now have their own group
|
||||
* the view options now have their own group
|
||||
* the Recent Files group has been renamed to Recent Compare Files
|
||||
|
||||
Very important:
|
||||
* Make sure unified and context actually work again !
|
||||
* Implement the rest of the interface (compare3 etc.)
|
||||
* Make sure the rest works too ! Still some problems parsing some files
|
||||
* Other various things that need to be fixed asap (before 3.2 is released)
|
||||
|
||||
In descending order of importance:
|
||||
* Add a kompare manual/document
|
||||
* add support for handediting conflicts
|
||||
* session management (should almost work)
|
||||
* implement normal, ed and rcs format (normal got busted)
|
||||
* merge text view GUI
|
||||
* clicking in the connect widget should select a difference (tricky!)
|
||||
* add support for incremental patch saving (i'll explain if anyone wants to know)
|
||||
* Add support for diff3 (that is comparing 3 files at once)
|
||||
|
||||
Special requests:
|
||||
Puetzk:
|
||||
* Editing the TO pane
|
||||
Falk:
|
||||
* Allow only part of a change to be applied to the other file
|
||||
Harlekin:
|
||||
* Add search functionality, either in source, dest or both at the same time
|
||||
HarryF:
|
||||
* emit clicked() signal when on a diff with line number
|
||||
aseigo:
|
||||
* merge from dest to source instead of only from source to dest
|
||||
(Workaround: swap source with destination and then apply the differences)
|
4
kompare/doc/CMakeLists.txt
Normal file
|
@ -0,0 +1,4 @@
|
|||
########### install files ###############
|
||||
#
|
||||
#
|
||||
kde4_create_handbook(index.docbook INSTALL_DESTINATION ${HTML_INSTALL_DIR}/en SUBDIR kompare)
|
BIN
kompare/doc/dock.png
Normal file
After Width: | Height: | Size: 489 B |
909
kompare/doc/index.docbook
Normal file
|
@ -0,0 +1,909 @@
|
|||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.2-Based Variant V1.1//EN" "dtd/kdex.dtd" [
|
||||
<!ENTITY kappname "&kompare;">
|
||||
<!ENTITY version "4.4.0">
|
||||
<!ENTITY package "kdesdk">
|
||||
<!ENTITY % addindex "IGNORE">
|
||||
<!ENTITY % English "INCLUDE">
|
||||
]>
|
||||
|
||||
<book id="kompare" lang="&language;">
|
||||
|
||||
<bookinfo>
|
||||
<title>The &kompare; Handbook</title>
|
||||
|
||||
<authorgroup>
|
||||
|
||||
<author><firstname>Sean</firstname><surname>Wheller</surname><email>sean@inwords.co.za</email></author>
|
||||
<!-- TRANS:ROLES_OF_TRANSLATORS -->
|
||||
</authorgroup>
|
||||
|
||||
<copyright>
|
||||
<year>2007</year>
|
||||
<holder>Sean Wheller</holder>
|
||||
</copyright>
|
||||
|
||||
<legalnotice>&FDLNotice;</legalnotice>
|
||||
|
||||
<date>2010-07-22</date>
|
||||
<releaseinfo>&version;</releaseinfo>
|
||||
|
||||
<!-- Abstract about this handbook -->
|
||||
|
||||
<abstract>
|
||||
<para>
|
||||
&kompare; is a &GUI; front-end program that enables differences between source files to be viewed and merged.
|
||||
&kompare; can be used to compare differences on files or the contents of folders. &kompare; supports a variety
|
||||
of diff formats and provide many options to customize the information level displayed.</para>
|
||||
<para>This document describes &kompare; version &version;.</para>
|
||||
</abstract>
|
||||
|
||||
|
||||
<keywordset>
|
||||
<keyword>KDE</keyword>
|
||||
<keyword>Kompare</keyword>
|
||||
<keyword>Diff</keyword>
|
||||
<keyword>Merge</keyword>
|
||||
<keyword>Patch</keyword>
|
||||
<keyword>Hunk</keyword>
|
||||
</keywordset>
|
||||
|
||||
</bookinfo>
|
||||
|
||||
<chapter id="introduction">
|
||||
<title>Introduction</title>
|
||||
|
||||
<para>When two or more people are working on a file and passing it back and forth between one another, it becomes difficult to
|
||||
see what changes have been made to a new version or copy of the file. Opening the new copy and the original, side-by-side in the
|
||||
application used to create it is one solution but, laborious, time consuming, and prone to error. This is where a program to show
|
||||
differences, diffs for short, is useful.</para>
|
||||
|
||||
<para>As would be expected, an appropriate name for such a program would be "diff". As it happens, the program diff is installed on
|
||||
most &Linux;-based systems and is used for exactly this purpose. Developers often use diff, as a command line tool, to show differences
|
||||
between versions of a source code file. However, the use of diff is not limited to showing differences in code source files,
|
||||
it can be used on many text-based file types.</para>
|
||||
|
||||
<para>Using diff from the command line can be confusing, learning the diff command syntax and deciphering the output can bewilder most people.
|
||||
This is where &kompare; comes into play. Providing a graphical front-end to the diff program, the interface displays source and destination files
|
||||
side-by-side with all differences automatically highlighted. From this starting point, changes in one file can be sequentially applied to the other file
|
||||
on a selective and controlled basis. Not all changes need to be applied and if you do apply a change it can always be 'unapplied'.
|
||||
When all required changes have been applied they can be saved and will display as normal in the original application used to create the file.</para>
|
||||
|
||||
<para>In addition to displaying differences between a source and destination file, &kompare; can be used to create and view a special file called a 'diff'.
|
||||
This file captures the differences between the two sources into a single file that can be used to view and apply changes to any other copy of the file.
|
||||
For example, if two people are editing a document. The first person wants to make changes and send just the changes made to the second person.
|
||||
Normally, the first person would send a complete copy of the modified document to the second person, who would then have to compare the modified document
|
||||
side-by-side with unmodified version. The process for this is much like what we have described in the previous paragraphs. With &kompare; the first person
|
||||
would first make a local copy of the file to be modified, then make changes and compare the original and modified copy. Now using &kompare; a diff file
|
||||
can be created that captures only the changes made. This can be sent to the second person in place of a whole file containing the changes.</para>
|
||||
|
||||
<para>Using &kompare; the second person can view the diff file, compare it to the local copy of the document and apply the changes made by the first person.
|
||||
So the process can go on for many versions of the document, each person making changes, creating diffs, distributing them and applying them.
|
||||
This process is commonly called "patching", a term taken from the program named "patch" which is another command line
|
||||
tool specifically designed for the purpose of applying diff files.</para>
|
||||
|
||||
<para>It sometimes happens that people edit a file at the same time. In this situation it is likely that people will make changes in the document at
|
||||
exactly the same line. This creates a problem because, without applied caution, people could be overwriting each others work as they apply the diff files they receive.
|
||||
Fortunately the developers of the diff and patch programs took this into consideration and so these tools will not allow such changes to be applied without manual intervention.
|
||||
When this state is reached, it is known as a "conflict". &kompare; will display conflicts so that you can manually resolve them, deciding
|
||||
which changes should be applied to which file.</para>
|
||||
|
||||
<para>&kompare; is also a great program for comparison of file changes on a folder level. When used to compare folders &kompare; recursively examines subfolders
|
||||
and their file contents for differences. In this use case, each file where differences are found are automatically opened and
|
||||
listed by &kompare; where easy navigation between the various files is possible.</para>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="using">
|
||||
<title>Using &kompare;</title>
|
||||
|
||||
<sect1 id="getting-started">
|
||||
<title>Getting Started</title>
|
||||
|
||||
<para>This section provides instructions for starting &kompare; and provides a quick tour to the &kompare; main interface.</para>
|
||||
|
||||
<sect2 id="starting-kompare">
|
||||
<title>Starting &kompare;</title>
|
||||
|
||||
<para>A shortcut for starting &kompare; can be found in the K menu in the Development group
|
||||
<menuchoice><guimenu>Development</guimenu><guimenuitem>Kompare</guimenuitem></menuchoice>.</para>
|
||||
|
||||
<para>When &kompare; starts the first thing it does is display a dialog from
|
||||
which to select the files you wish to compare. Special settings for the properties of the diff and the appearance thereof can also be selected.
|
||||
In the file form select a source and destination source to compare. This can be any two files, folders or a &URL; and a file.
|
||||
Once the source and destination are selected click the <guibutton>Compare</guibutton> button.</para>
|
||||
|
||||
<para>Once &kompare; has discovered the differences it will display the main interface.
|
||||
When comparing two files or a URL and a file the process takes just a few seconds. However, when comparing folders
|
||||
with many subfolders and files, this process can take awhile.</para>
|
||||
|
||||
<para>For explanation of the options available from diff and appearance forms see <xref linkend="configure-preferences"/>.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="main-interface">
|
||||
<title>The Main Interface</title>
|
||||
|
||||
<para>This section provides a quick tour of the main interface which is comprised of the following areas:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Menus</para></listitem>
|
||||
<listitem><para>Toolbar</para></listitem>
|
||||
<listitem><para>Source and Destination Folders</para></listitem>
|
||||
<listitem><para>Source and Destination Files</para></listitem>
|
||||
<listitem><para>Source and Destination Line Changes</para></listitem>
|
||||
<listitem><para>Source and Destination Text View</para></listitem>
|
||||
<listitem><para>Statusbar</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<sect3 id="menus">
|
||||
<title>Menus</title>
|
||||
<para>&kompare; provides a menu driven interface. Explanation to the menu items and their options is provided in <xref linkend="command-reference"/>.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="toolbar">
|
||||
<title>Toolbar</title>
|
||||
<para>The &kompare; toolbar provides shortcuts to the most frequently used diff and merge operations.
|
||||
The toolbar orientation, text positioning, icon size properties and which shortcut icons are displayed can be customized from the
|
||||
toolbar context menu accessed when right-clicking the toolbar with the mouse. The toolbar context menu also enables the toolbar to be hidden.
|
||||
If the toolbar is hidden and you wish to unhide it, select <menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Toolbar</guimenuitem></menuchoice>.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="source-destination-folders">
|
||||
<title>Source and Destination Folders</title>
|
||||
<para>The source folder and destination folder panes display the folders in which compared files reside.
|
||||
When many subfolders are included in the comparison, then selecting a folder will display the first document in
|
||||
that folder where a difference was found between the source and destination.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="source-destination-files">
|
||||
<title>Source and Destination Files</title>
|
||||
<para>The source and destination file pane displays files where a difference was found for the currently selected source or destination folder.
|
||||
When a folder has multiple documents containing differences, all documents with a difference are listed. The selected document is displayed.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="source-destination-lines">
|
||||
<title>Source and Destination Line Changes</title>
|
||||
<para>The source and destination line changes pane summarizes the differences found between the current source and destination documents.
|
||||
Selecting a record within the pane highlights and selects the difference. This is a useful way to navigate and inspect long documents with many differences.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="source-destination-view">
|
||||
<title>Source and Destination View</title>
|
||||
<para>The source and destination view is the main workspace of &kompare;.
|
||||
The contents and highlighted differences of the currently selected source and destination file are displayed here with line numbers.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="text-view">
|
||||
<title>Text View</title>
|
||||
<para>The <guilabel>Text View</guilabel> is not displayed by default. It can be opened by selecting
|
||||
<menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Text View</guimenuitem></menuchoice>.</para>
|
||||
<!-- Other than a notepad, what is this text view good for? -->
|
||||
</sect3>
|
||||
|
||||
<sect3 id="statusbar">
|
||||
<title>Statusbar</title>
|
||||
<para>The status bar provides a summary of the current source and destination file or folder under comparison.
|
||||
The status bar also reports the number of changes found in the current document and counts the differences that have been applied.
|
||||
Furthermore, the status bar shows the overall number of documents containing differences and the current document number selected from this set.
|
||||
For example, a comparison run over two folders may return 1890 files with differences. The currently selected document is number 18 of 1890.</para>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="viewing-differences">
|
||||
<title>Viewing Differences</title>
|
||||
|
||||
<sect2 id="managing-screen-real-estate">
|
||||
<title>Managing Screen Real-Estate</title>
|
||||
<para>&kompare; displays the source and destination file under using equal percentage of the main interface view work area.
|
||||
This view area provides some features that help optimize use of screen real-estate while viewing differences, including:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>Dual Scrollbars</term>
|
||||
<listitem><para>The most obvious feature is that scrollbars are provided both on the right and bottom edges of the view area.
|
||||
Using the scrollbars it is possible to move rapidly through the comparison.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Share Grip Handle</term>
|
||||
<listitem><para>The vertical space between the source and destination view not only makes it possible to clearly see the start and end of lines in each of the panes,
|
||||
but is also a grip handle that allows adjustment of percentage occupied between the source and destinate views that comprise the view pane.
|
||||
To change pane size for one of the views, hover the mouse pointer over the grip handle then hold down the mouse button and drag left or right.
|
||||
Naturally, increasing the area of one pane will decrease the area available to the opposite pane within the view panel area.</para>
|
||||
<para>A second horizontal handle is available between the navigation panel and the source and destination view.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Docking</term>
|
||||
<listitem><para>The navigation panel can be undocked from the main interface by clicking the <inlinemediaobject>
|
||||
<imageobject><imagedata fileref="undock.png" format="PNG"/></imageobject></inlinemediaobject> icon located top right of the panel.
|
||||
This opens it in a window of its own, allowing you to move it across the screen. You can even hide the navigation panel by clicking the <inlinemediaobject><imageobject><imagedata fileref="dock.png" format="PNG"/></imageobject></inlinemediaobject> icon.
|
||||
To display a hidden navigation bar again, click with the &RMB; into the menubar and select <guilabel>Navigation</guilabel> from the context menu.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>Statusbar Toggle</term>
|
||||
<listitem>
|
||||
<para>The status bar of the view panel can be toggled on and off by selecting <menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Statusbar</guimenuitem></menuchoice>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="switching-source-and-destination-view">
|
||||
<title>Switching Source and Destination Views</title>
|
||||
|
||||
<para>Sometimes it can be useful to consider what the file to which differences where to be applied as the source.
|
||||
For example, when comparing two modified versions of a file and discovering that the one file has many more modifications that the other.
|
||||
The file with more changed would be better as the source, since then fewer differences would need to be applied.</para>
|
||||
<para>In this case select <menuchoice><guimenu>File</guimenu><guimenuitem>Swap Source with Destination</guimenuitem></menuchoice>.
|
||||
This will switch the files displayed in all &kompare; panels.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="display-difference-statistics">
|
||||
<title>Displaying Difference Statistics</title>
|
||||
<para>For a quick overview of the differences, select <menuchoice><guimenu>File</guimenu><guimenuitem>Show Statistics</guimenuitem></menuchoice>.
|
||||
This will display the <guilabel>Diff Statistics</guilabel> dialog. The following information is provided:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><guilabel>Old file:</guilabel></term>
|
||||
<listitem><para>The file name of what is usually the source file or file that is unmodified.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>New file:</guilabel></term>
|
||||
<listitem><para>The file name of what is usually the destination file or file that is modified and to which differences will be applied.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Format:</guilabel></term>
|
||||
<listitem><para>The diff format used to display the difference (see <xref linkend="diff-format"/>).</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Number of hunks:</guilabel></term>
|
||||
<listitem>
|
||||
<para>The number of hunks found in the difference.</para>
|
||||
<para>A hunk is a <quote>c<emphasis>hunk</emphasis></quote> of lines that have been marked as different between
|
||||
source and destination and may include context lines depending on the diff format <guilabel>Lines of Context</guilabel> value (see <xref linkend="diff-format"/>).</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Number of differences</guilabel></term>
|
||||
<listitem><para>The actual number of differences found, not hunks. A hunk can contain one or more differences
|
||||
when the line change range and the context lines of any two or more changes overlap.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="navigating-the-difference-view">
|
||||
<title>Navigating the Difference View</title>
|
||||
<para>&kompare; enables rapid navigation of differences on a file level and of multiple difference files when comparing folder trees.</para>
|
||||
|
||||
<sect3 id="selecting-a-difference">
|
||||
<title>Selecting a Difference</title>
|
||||
<para>A difference can be selected using by:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>clicking a line in the Source and Destination Line Changes pane (top right of the main window).</para></listitem>
|
||||
<listitem><para>clicking the highlighted difference in the View pane.</para></listitem>
|
||||
<listitem><para>traversing the listed differences in a comparison (see <xref linkend="traversing-differences"/>).</para></listitem>
|
||||
</itemizedlist>
|
||||
<para>When a difference is selected it is considered to be <quote>in focus</quote> and is displayed in a brighter color that non-selected differences.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="traversing-differences">
|
||||
<title>Traversing Differences</title>
|
||||
<para>When a comparison finds many differences one of the best ways to approach reviewing them is to traverse the differences in a logical order, usually from top to bottom.</para>
|
||||
<para>By default &kompare; selects the first difference found in a comparison. By selecting
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Next Difference</guimenuitem></menuchoice>
|
||||
(<keycombo action="simul">&Ctrl;<keycap>Down</keycap></keycombo>) the difference following the current selection is brought into focus.
|
||||
To select the difference before the current difference
|
||||
select <menuchoice><guimenu>Difference</guimenu><guimenuitem>Previous Difference</guimenuitem></menuchoice>
|
||||
(<keycombo action="simul">&Ctrl;<keycap>Up</keycap></keycombo>).</para>
|
||||
<para>In this way it is possible to traverse differences in an orderly manner, applying and unapply differences upon review.</para>
|
||||
</sect3>
|
||||
|
||||
<sect3 id="switching-between-files">
|
||||
<title>Switching Between Files</title>
|
||||
<para>When a comparison is performed on folder level, many files may be found with differences.
|
||||
A complete list of the files compared with difference found is provided in the <quote>Source and Destination Folders</quote>,
|
||||
and <quote>Source and Destination Files</quote> panes. However, &kompare; displays differences between source and destination one comparison at time.</para>
|
||||
<para>To switch between documents in this scenario the following options are available:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Select the <quote>Source and Destination Folders</quote> pane to display file differences found in the
|
||||
<quote>Source and Destination Files</quote> pane, then select a file.</para></listitem>
|
||||
<listitem><para>Select <menuchoice><guimenu>Difference</guimenu><guimenuitem>Previous File</guimenuitem></menuchoice>
|
||||
(<keycombo action="simul">&Ctrl;<keycap>PgUp</keycap></keycombo>) or
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Next File</guimenuitem></menuchoice>
|
||||
(<keycombo action="simul">&Ctrl;<keycap>PgDown</keycap></keycombo>) to
|
||||
display the previous or next difference file found in the <quote>Source and Destination Files</quote> pane.</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</sect3>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="merging-differences">
|
||||
<title>Merging Differences</title>
|
||||
|
||||
<para>&kompare; makes the task of applying and unapplying differences as simple as point and click.
|
||||
Multiple apply and unapply operations can be performed on a difference as all operations are performed in memory and not written to the files on disk until the save operation is performed.</para>
|
||||
|
||||
<sect2 id="applying-a-difference">
|
||||
<title>Applying a Difference</title>
|
||||
<para>To apply a difference, click the highlighted difference region, then select
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Apply Difference</guimenuitem></menuchoice> (<keycombo><keycap>Space</keycap></keycombo>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="unapplying-a-difference">
|
||||
<title>Unapplying a Difference</title>
|
||||
<para>To unapply a difference, click the highlighted difference region previously applied, then select
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Unapply Difference</guimenuitem></menuchoice> (<keycombo>&Backspace;</keycombo>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="applying-all-differences">
|
||||
<title>Applying All Differences</title>
|
||||
<para>After reviewing differences between files and finding all acceptable it is possible apply them all with a single operation by selecting
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Apply All</guimenuitem></menuchoice> (<keycombo action="simul">&Ctrl;<keycap>A</keycap></keycombo>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="unapplying-all-differences">
|
||||
<title>Unapplying All Differences</title>
|
||||
<para>To revert all differences that have been applied previously select
|
||||
<menuchoice><guimenu>Difference</guimenu><guimenuitem>Unapply All</guimenuitem></menuchoice> (<keycombo action="simul">&Ctrl;<keycap>U</keycap></keycombo>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="saving-changes">
|
||||
<title>Saving Changes</title>
|
||||
<para>Once differences have been applied they can be saved by selecting
|
||||
<menuchoice><guimenu>File</guimenu><guimenuitem>Save</guimenuitem></menuchoice> or
|
||||
<menuchoice><guimenu>File</guimenu><guimenuitem>Save All</guimenuitem></menuchoice>.</para>
|
||||
<para>Applied differences are saved to both the source and destination file.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="working-with-diff-files">
|
||||
<title>Working with Diff Files</title>
|
||||
<para>Diff files contain only the changes made between files, or a set of files within a folder system, and may or may not contain a number of context lines before and after line changes.
|
||||
The sum of a line change and its context lines is known a hunk. A diff file therefore may contain multiple hunks from one or more files.
|
||||
When the context lines of two or more hunks overlap, they are considered a single hunk. Diff files can be used to:</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Apply the changes contained in the hunks to an original file.</para></listitem>
|
||||
<listitem><para>Apply the changes contained in the hunks to a file or set of original files within a folder system.</para></listitem>
|
||||
<listitem><para>Modified before being applied to an original file or set of original files within a folder system.</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
<sect2 id="creating-a-diff">
|
||||
<title>Creating a Diff</title>
|
||||
<para>To create a diff file a comparison must be displayed in &kompare;. Assuming this is the case, then select <menuchoice><guimenu>File</guimenu><guimenuitem>Save Diff...</guimenuitem></menuchoice>
|
||||
This will display the <guilabel>Diff Options</guilabel> dialog (see <xref linkend="diff-settings"/> for more information on diff formats and options).
|
||||
After configuring these options, click the <guibutton>Save</guibutton> button and save the diff to a file with the extension <filename class="extension">.diff</filename>.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="displaying-a-diff">
|
||||
<title>Displaying a Diff</title>
|
||||
<para>It is possible to display the contents of a diff file within &kompare; by opening the diff file from <menuchoice><guimenu>File</guimenu><guimenuitem>Open Diff...</guimenuitem></menuchoice>.</para>
|
||||
<para>When viewing a diff file the hunks between the source and destination file are shown, remember that only the hunks are shown, no unmodified lines will be shown.
|
||||
In some cases a diff file is created with 0 lines of context. In this case only the changed lines will be displayed.</para>
|
||||
<para>When a diff file contains hunks from multiple files &kompare; displays the hunks from each file one at a time and you can
|
||||
switch between files as though they were real files even though this information is only provided by the diff file contents.</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="applying-a-diff">
|
||||
<title>Applying Differences in a Diff File</title>
|
||||
<para>When viewing differences in a diff file it is possible to apply difference as you would when comparing source and destination files (see <xref linkend="merging-differences"/>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="blending-a-diff">
|
||||
<title>Blending a &URL; with a Diff</title>
|
||||
<para>In cases where a diff file is provided it is possible to compare the hunks in the diff against a file or folder.
|
||||
To do this select <menuchoice><guimenu>File</guimenu><guimenuitem>Blend URL with Diff...</guimenuitem></menuchoice>.
|
||||
Then input the <guilabel>File/Folder</guilabel> and <guilabel>Diff Output</guilabel> paths.</para>
|
||||
<para>When viewing differences between a source file and a diff file it is possible to apply difference as you would when comparing source and destination files (see <xref linkend="merging-differences"/>).</para>
|
||||
</sect2>
|
||||
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="configure-preferences">
|
||||
<title>Configuring Preferences</title>
|
||||
|
||||
<para>&kompare; enables users to set appearance preferences for difference formatting in the main interface and set behavioural properties of the diff program.
|
||||
The <guilabel>Preferences</guilabel> dialog can be accessed by selecting
|
||||
<menuchoice><guimenu>Settings</guimenu><guisubmenu>Configure &kompare;...</guisubmenu></menuchoice>.</para>
|
||||
|
||||
<para>To configure preferences for appearance select the <guilabel>View</guilabel> menu item (see <xref linkend="view-settings"/>).</para>
|
||||
|
||||
<para>To configure preferences for diff program properties select the <guilabel>Diff</guilabel> menu item (see <xref linkend="diff-settings"/>).</para>
|
||||
|
||||
<sect1 id="view-settings">
|
||||
<title>View Settings</title>
|
||||
<para>The <guimenu>View</guimenu> page in the <guilabel>Preferences</guilabel> dialog displays the <guilabel>Appearance</guilabel>
|
||||
and <guilabel>Fonts</guilabel> tabbed forms.</para>
|
||||
|
||||
<sect2 id="appearance">
|
||||
<title>Appearance</title>
|
||||
<para>The <guilabel>Appearance</guilabel> form provides controls to manage the <guilabel>Colors</guilabel> used
|
||||
to denote difference in the main interface, behaviour of the <guilabel>Mouse Wheel</guilabel> when jogging up and down
|
||||
and how <guilabel>Tabs to Spaces</guilabel> conversion is managed.</para>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Appearance Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-view1.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Appearance Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<variablelist>
|
||||
<title>Color Group</title>
|
||||
<para>To adjust color preferences used when displaying differences, click the color button to display the <guilabel>Select Color</guilabel> dialog for the following states:</para>
|
||||
<varlistentry>
|
||||
<term><guilabel>Removed color</guilabel></term>
|
||||
<listitem><para>Lines that have been removed, do not exist, between source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Changed color</guilabel></term>
|
||||
<listitem><para>Lines that have been changed, modified, between source and destination. </para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Added color</guilabel></term>
|
||||
<listitem><para>Lines that have been added between source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Applied color</guilabel></term>
|
||||
<listitem><para>Any of the above states where the difference has been applied between source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Mouse Wheel</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Number of lines</guilabel></term>
|
||||
<listitem><para>The number of lines to jog the differences when turning the mouse wheel forward or backward.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Tabs to Spaces</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Number of spaces to convert a tab character to</guilabel></term>
|
||||
<listitem><para>Convert each tab character to n space characters.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="fonts">
|
||||
<title>Fonts</title>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Fonts Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-view2.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Fonts Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<para>Select the font family and size to display when displaying differences.</para>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="diff-settings">
|
||||
<title>Diff Settings</title>
|
||||
<para>The <guimenu>Diff</guimenu> page in the <guilabel>Preferences</guilabel> dialog displays the <guilabel>Diff</guilabel>,
|
||||
<guilabel>Format</guilabel>, <guilabel>Options</guilabel> and <guilabel>Exclude</guilabel> tabbed forms. These forms can be used to configure the
|
||||
behavioural properties of the Diff program.</para>
|
||||
|
||||
<sect2 id="diff">
|
||||
<title>Diff</title>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Diff Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-diff1.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Diff Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<para>The command used to run the diff program (default <application>diff</application>).</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="diff-format">
|
||||
<title>Format</title>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Format Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-diff2.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Format Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<para>Adjust options for the <guilabel>Output Format</guilabel> and number of <guilabel>Lines of Context</guilabel>.</para>
|
||||
<variablelist>
|
||||
<title>Output Format</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Context</guilabel></term>
|
||||
<listitem>
|
||||
<para>The context output format adds several lines of context around the lines that differ.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><guilabel>Normal</guilabel></term>
|
||||
<listitem>
|
||||
<para>The normal output format displays differing lines without any surrounding lines of context. </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><guilabel>Unified</guilabel></term>
|
||||
<listitem>
|
||||
<para>The unified output format is a variation on the context format. It is considered better than context because the
|
||||
output is more compact than that of context as it omits redundant context lines.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<!-- not in 3.5.1
|
||||
<varlistentry>
|
||||
<term><guilabel>Side-by-side</guilabel></term>
|
||||
<listitem>
|
||||
<para>Use the side by side output format which displays files listed in two columns with a gutter between them. This option is only available from the <guilabel>Diff Options</guilabel> dialog (see <xref linkend="creating-a-diff"/>).</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
-->
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Lines of Context</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Number of context lines</guilabel></term>
|
||||
<listitem>
|
||||
<para>When performing a diff with context or unified output format use this parameter to control the number of context lines included.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="options">
|
||||
<title>Options</title>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Options Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-diff3.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Options Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<para>The <guilabel>Options</guilabel> tab form allows configuration of the options supported by the diff program.</para>
|
||||
<variablelist>
|
||||
<title>General</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Treat new files as empty</guilabel></term>
|
||||
<listitem><para>With this option enabled diff will treat a file that only exists in one of
|
||||
the directories as empty in the other directory. This means that the file is
|
||||
compared with an empty file and because of this will appear as one big
|
||||
insertion or deletion.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Look for smaller changes</guilabel></term>
|
||||
<listitem><para>Forces diff to display changes in case, punctuation, space, &etc; when checked.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Optimize for large files</guilabel></term>
|
||||
<listitem><para>Switches diff to process files with high-speed when checked.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore changes in case</guilabel></term>
|
||||
<listitem><para>Lower and Uppercase character changes are omitted when this option is checked.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore regexp</guilabel></term>
|
||||
<listitem><para>Ignore lines matching a regular expression.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>Whitespace</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>Expand tabs to spaces in output</guilabel></term>
|
||||
<listitem><para>When checked diff outputs will converts tab characters to the number of spaces defined in the
|
||||
<guilabel>Preferences</guilabel> dialog <guimenu>View</guimenu> menu <guilabel>Tabs to Spaces</guilabel> option.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore added or removed empty lines</guilabel></term>
|
||||
<listitem><para>lines of zero length that differ between source and destination are ignored when this option is checked.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore changes in the amount of whitespace</guilabel></term>
|
||||
<listitem><para>White space before, after and between lines may change depending on different editors.
|
||||
When this option is checked such changes are ignored.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore all whitespace</guilabel></term>
|
||||
<listitem><para>when checked white space differences are completely ignored.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><guilabel>Ignore changes due to tab expansion</guilabel></term>
|
||||
<listitem><para>when checked white space resulting from tab characters is ignored.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="exclude">
|
||||
<title>Exclude</title>
|
||||
<para>The <guilabel>Exclude</guilabel> form enables use of the filter options provided by the diff program.</para>
|
||||
<screenshot>
|
||||
<screeninfo>&kompare; Exclude Settings</screeninfo>
|
||||
<mediaobject>
|
||||
<imageobject>
|
||||
<imagedata fileref="settings-diff4.png" format="PNG"/>
|
||||
</imageobject>
|
||||
<textobject>
|
||||
<phrase>&kompare; Exclude Settings</phrase>
|
||||
</textobject>
|
||||
</mediaobject>
|
||||
</screenshot>
|
||||
<variablelist>
|
||||
<title>File Pattern to Exclude</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>File Pattern to Exclude</guilabel></term>
|
||||
<listitem><para>Exclude files based on wild card filtering</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
<variablelist>
|
||||
<title>File with Filenames to Exclude</title>
|
||||
<varlistentry>
|
||||
<term><guilabel>File with Filenames to Exclude</guilabel></term>
|
||||
<listitem><para>Define the filter based on the content of an externally managed file.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
||||
</chapter>
|
||||
|
||||
<chapter id="command-reference">
|
||||
<title>Command Reference</title>
|
||||
|
||||
<sect1 id="file-menu">
|
||||
<title>The File Menu</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>O</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>File</guimenu><guimenuitem>Open Diff...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Displays the <guilabel>Open</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>C</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>File</guimenu><guimenuitem>Compare Files...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Displays the <guilabel>Compare Files or Folders</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>B</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>File</guimenu><guimenuitem>Blend URL with Diff...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Displays the <guilabel>Blend File/Folder with diff Output</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>S</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>File</guimenu><guimenuitem>Save</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Writes applied differences to current source and or destination file.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>File</guimenu><guimenuitem>Save All</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Writes applied differences to all source and or destination files.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>File</guimenu><guimenuitem>Save Diff...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Displays the <guilabel>Diff Options</guilabel> dialog to define diff format and options.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>File</guimenu><guimenuitem>Swap Source with Destination</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Changes source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<guimenu>File</guimenu><guimenuitem>Show Statistics</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Displays the <guilabel>Display Statistics</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
<!-- Print Print Preview in 4.5.1-->
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>Q</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>File</guimenu><guimenuitem>Quit</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Exits &kompare;.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="difference-menu">
|
||||
<title>The Difference Menu</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>U</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Unapply All</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Unapply all differences previously applied between source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>&Backspace;</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Unapply Difference</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Revert a selected difference previously applied.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut><keycap>Space</keycap></shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Apply Difference</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Apply a selected difference.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>A</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Apply All</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Apply all differences between source and destination.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>PgUp</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Previous File</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Make the previous difference, in the list of differences, the current file in the view pane.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>PgDown</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Next File</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Make the next difference, in the list of differences, the current file in the view pane.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>Up</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Previous Difference</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Select the difference above the currently selected difference.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><menuchoice>
|
||||
<shortcut>
|
||||
<keycombo action="simul">&Ctrl;<keycap>Down</keycap></keycombo>
|
||||
</shortcut>
|
||||
<guimenu>Difference</guimenu><guimenuitem>Next Difference</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Select the difference below the currently selected difference.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="settingsmenu">
|
||||
<title>The Settings Menu</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Toolbar</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Toggle the toolbar display ON/OFF.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Statusbar</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Toggle the status bar display ON/OFF.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Show Text View</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Display the <guilabel>Text View</guilabel> pane.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure Shortcuts...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Display the <guilabel>Configure Shortcuts</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure Toolbars...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Display the <guilabel>Configure Toolbar</guilabel>.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure &kompare;...</guimenuitem></menuchoice></term>
|
||||
<listitem><para>Display the &kompare; <guilabel>Preference</guilabel> dialog.</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</sect1>
|
||||
|
||||
<sect1 id="help-menu">
|
||||
<title>The Help Menu</title>
|
||||
|
||||
&help.menu.documentation;
|
||||
</sect1>
|
||||
</chapter>
|
||||
|
||||
<chapter id="credits">
|
||||
|
||||
<title>Credits and License</title>
|
||||
|
||||
<para>
|
||||
&kompare;
|
||||
</para>
|
||||
<para>
|
||||
Program copyright 2001-2004, &John.Firebaugh; &John.Firebaugh.mail;
|
||||
and Otto Bruggeman <email>otto.bruggeman@home.nl</email>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Documentation Copyright © 2007 Sean Wheller <email>sean@inwords.co.za</email>
|
||||
</para>
|
||||
|
||||
<!-- TRANS:CREDIT_FOR_TRANSLATORS -->
|
||||
|
||||
&underFDL; <!-- FDL: do not remove -->
|
||||
&underGPL; <!-- GPL License -->
|
||||
|
||||
</chapter>
|
||||
|
||||
<appendix id="installation">
|
||||
<title>Installation</title>
|
||||
|
||||
<sect1 id="getting-kapp">
|
||||
<title>How to obtain &kompare;</title>
|
||||
|
||||
&install.intro.documentation;
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
<sect1 id="compilation">
|
||||
<title>Compilation and Installation</title>
|
||||
|
||||
&install.compile.documentation;
|
||||
|
||||
</sect1>
|
||||
|
||||
|
||||
</appendix>
|
||||
|
||||
&documentation.index;
|
||||
</book>
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
mode: sgml
|
||||
sgml-minimize-attributes:nil
|
||||
sgml-general-insert-case:lower
|
||||
sgml-indent-step:0
|
||||
sgml-indent-data:nil
|
||||
End:
|
||||
|
||||
// vim:ts=2:sw=2:tw=78:noet
|
||||
-->
|
BIN
kompare/doc/settings-diff1.png
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
kompare/doc/settings-diff2.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
kompare/doc/settings-diff3.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
kompare/doc/settings-diff4.png
Normal file
After Width: | Height: | Size: 42 KiB |
BIN
kompare/doc/settings-view1.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
kompare/doc/settings-view2.png
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
kompare/doc/undock.png
Normal file
After Width: | Height: | Size: 491 B |
18
kompare/interfaces/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(kompareinterface_LIB_SRCS kompareinterface.cpp )
|
||||
|
||||
|
||||
kde4_add_library(kompareinterface SHARED ${kompareinterface_LIB_SRCS})
|
||||
|
||||
target_link_libraries(kompareinterface ${KDE4_KDECORE_LIBS} )
|
||||
|
||||
set_target_properties(kompareinterface PROPERTIES VERSION ${GENERIC_LIB_VERSION} SOVERSION ${GENERIC_LIB_SOVERSION} )
|
||||
install(TARGETS kompareinterface ${INSTALL_TARGETS_DEFAULT_ARGS} )
|
||||
install(FILES kompareinterface.h DESTINATION ${INCLUDE_INSTALL_DIR}/kompare COMPONENT Devel )
|
||||
|
||||
|
76
kompare/interfaces/kompareinterface.cpp
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2002-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
|
||||
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 "kompareinterface.h"
|
||||
|
||||
class KompareInterfacePrivate
|
||||
{
|
||||
public:
|
||||
KompareInterfacePrivate();
|
||||
~KompareInterfacePrivate();
|
||||
KompareInterfacePrivate( const KompareInterfacePrivate& );
|
||||
KompareInterfacePrivate& operator=( const KompareInterfacePrivate& );
|
||||
|
||||
protected:
|
||||
// Add all variables for the KompareInterface class here and access them through the kip pointer
|
||||
};
|
||||
|
||||
KompareInterfacePrivate::KompareInterfacePrivate()
|
||||
{
|
||||
}
|
||||
|
||||
KompareInterfacePrivate::~KompareInterfacePrivate()
|
||||
{
|
||||
}
|
||||
|
||||
KompareInterfacePrivate::KompareInterfacePrivate( const KompareInterfacePrivate& /*kip*/ )
|
||||
{
|
||||
}
|
||||
|
||||
KompareInterfacePrivate& KompareInterfacePrivate::operator=(const KompareInterfacePrivate& /*kip*/ )
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
KompareInterface::KompareInterface()
|
||||
{
|
||||
kip = new KompareInterfacePrivate();
|
||||
}
|
||||
|
||||
KompareInterface::~KompareInterface()
|
||||
{
|
||||
delete kip;
|
||||
}
|
||||
|
||||
KompareInterface::KompareInterface( const KompareInterface& ki )
|
||||
{
|
||||
kip = new KompareInterfacePrivate( *(ki.kip) );
|
||||
}
|
||||
|
||||
KompareInterface& KompareInterface::operator=( const KompareInterface& ki )
|
||||
{
|
||||
kip = ki.kip;
|
||||
return *this;
|
||||
}
|
||||
|
||||
void KompareInterface::setEncoding( const QString& encoding )
|
||||
{
|
||||
m_encoding = encoding;
|
||||
}
|
||||
|
133
kompare/interfaces/kompareinterface.h
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
Copyright 2002-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
|
||||
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 _KOMPARE_INTERFACE_H
|
||||
#define _KOMPARE_INTERFACE_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
#include <kdemacros.h>
|
||||
|
||||
class KConfig;
|
||||
class KUrl;
|
||||
|
||||
class KompareInterfacePrivate;
|
||||
|
||||
class KDE_EXPORT KompareInterface
|
||||
{
|
||||
public:
|
||||
KompareInterface();
|
||||
virtual ~KompareInterface();
|
||||
|
||||
protected:
|
||||
KompareInterface( const KompareInterface& );
|
||||
KompareInterface& operator=(const KompareInterface& );
|
||||
|
||||
public:
|
||||
/**
|
||||
* Open and parse the diff file at url.
|
||||
*/
|
||||
virtual bool openDiff( const KUrl& diffUrl ) = 0;
|
||||
|
||||
/**
|
||||
* Open and parse the supplied diff output
|
||||
*/
|
||||
virtual bool openDiff( const QString& diffOutput ) = 0;
|
||||
|
||||
/**
|
||||
* Open and parse the diff3 file at url.
|
||||
*/
|
||||
virtual bool openDiff3( const KUrl& diff3Url ) = 0;
|
||||
|
||||
/**
|
||||
* Open and parse the supplied diff3 output
|
||||
*/
|
||||
virtual bool openDiff3( const QString& diff3Output ) = 0;
|
||||
|
||||
/**
|
||||
* Compare, with diff, source with destination, can also be used if you do not
|
||||
* know what source and destination are. The part will try to figure out what
|
||||
* they are (directory, file, diff output file) and call the
|
||||
* appropriate method(s)
|
||||
*/
|
||||
virtual void compare( const KUrl& sourceFile, const KUrl& destinationFile ) = 0;
|
||||
|
||||
/**
|
||||
* Compare a Source file to a custom Destination string
|
||||
*/
|
||||
virtual void compareFileString( const KUrl & sourceFile, const QString & destination) = 0;
|
||||
|
||||
/**
|
||||
* Compare a custom Source string to a Destination file
|
||||
*/
|
||||
virtual void compareStringFile( const QString & source, const KUrl & destinationFile) = 0;
|
||||
|
||||
/**
|
||||
* Compare, with diff, source with destination files
|
||||
*/
|
||||
virtual void compareFiles( const KUrl& sourceFile, const KUrl& destinationFile ) = 0;
|
||||
|
||||
/**
|
||||
* Compare, with diff, source with destination directories
|
||||
*/
|
||||
virtual void compareDirs ( const KUrl& sourceDir, const KUrl& destinationDir ) = 0;
|
||||
|
||||
/**
|
||||
* Compare, with diff3, originalFile with changedFile1 and changedFile2
|
||||
*/
|
||||
virtual void compare3Files( const KUrl& originalFile, const KUrl& changedFile1, const KUrl& changedFile2 ) = 0;
|
||||
|
||||
/**
|
||||
* This will show the file and the file with the diff applied
|
||||
*/
|
||||
virtual void openFileAndDiff( const KUrl& file, const KUrl& diffFile ) = 0;
|
||||
|
||||
/**
|
||||
* This will show the directory and the directory with the diff applied
|
||||
*/
|
||||
virtual void openDirAndDiff ( const KUrl& dir, const KUrl& diffFile ) = 0;
|
||||
|
||||
/**
|
||||
* This will set the encoding to use for all files that are read or for the diffoutput
|
||||
*/
|
||||
virtual void setEncoding( const QString& encoding );
|
||||
|
||||
public:
|
||||
/**
|
||||
* Warning this should be in class Part in KDE 4.0, not here !
|
||||
* Around that time the methods will disappear here
|
||||
*/
|
||||
virtual int readProperties( KConfig* config ) = 0;
|
||||
virtual int saveProperties( KConfig* config ) = 0;
|
||||
|
||||
/**
|
||||
* Warning this should be in class ReadWritePart in KDE 4.0, not here !
|
||||
* Around that time the method will disappear here
|
||||
*/
|
||||
virtual bool queryClose() = 0;
|
||||
|
||||
protected:
|
||||
// Add all variables to the KompareInterfacePrivate class and access them through the kip pointer
|
||||
KompareInterfacePrivate* kip;
|
||||
QString m_encoding;
|
||||
};
|
||||
|
||||
Q_DECLARE_INTERFACE(KompareInterface, "com.kde.Kompare.KompareInterface/4.0")
|
||||
|
||||
#endif /* _KOMPARE_INTERFACE_H */
|
37
kompare/interfaces/kompareinterfaceexport.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2007 Andreas Pakulat <apaku@gmx.de> *
|
||||
* Copyright 2006 Matt Rogers <mattr@kde.org> *
|
||||
* Copyright 2004 Jarosław Staniek <staniek@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Library General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This 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 Library General Public *
|
||||
* License along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPAREINTERFACEEXPORT_H
|
||||
#define KOMPAREINTERFACEEXPORT_H
|
||||
|
||||
/* needed for KDE_EXPORT macros */
|
||||
#include <kdemacros.h>
|
||||
|
||||
#ifndef DIFF2_EXPORT
|
||||
# ifdef MAKE_DIFF2_LIB
|
||||
# define DIFF2_EXPORT KDE_EXPORT
|
||||
# else
|
||||
# define DIFF2_EXPORT KDE_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // KOMPAREINTERFACEEXPORT_H
|
||||
|
138
kompare/kompare.desktop
Executable file
|
@ -0,0 +1,138 @@
|
|||
# KDE Config File
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Name=Kompare
|
||||
Name[af]=K-vergelyk
|
||||
Name[ast]=Kompare
|
||||
Name[bg]=Kompare
|
||||
Name[br]=Kompare
|
||||
Name[bs]=Kompare
|
||||
Name[ca]=Kompare
|
||||
Name[ca@valencia]=Kompare
|
||||
Name[cs]=Kompare
|
||||
Name[cy]=Kompare
|
||||
Name[da]=Kompare
|
||||
Name[de]=Kompare
|
||||
Name[el]=Kompare
|
||||
Name[en_GB]=Kompare
|
||||
Name[eo]=Komparilo
|
||||
Name[es]=Kompare
|
||||
Name[et]=Kompare
|
||||
Name[eu]=Kompare
|
||||
Name[fi]=Kompare
|
||||
Name[fr]=Kompare
|
||||
Name[ga]=Kompare
|
||||
Name[gl]=Kompare
|
||||
Name[he]=Kompare
|
||||
Name[hr]=Kompare
|
||||
Name[hu]=Kompare
|
||||
Name[is]=Kompare
|
||||
Name[it]=Kompare
|
||||
Name[ja]=Kompare
|
||||
Name[kk]=Kompare
|
||||
Name[km]=Kompare
|
||||
Name[ko]=Kompare
|
||||
Name[lt]=Kompare
|
||||
Name[lv]=Kompare
|
||||
Name[mr]=कंपेअर
|
||||
Name[ms]=Kompare
|
||||
Name[nb]=Kompare
|
||||
Name[nds]=Kompare
|
||||
Name[ne]=तुलना
|
||||
Name[nl]=Kompare
|
||||
Name[nn]=Kompare
|
||||
Name[pa]=ਕੇ-ਤੁਲਨਾ
|
||||
Name[pl]=Kompare
|
||||
Name[pt]=Kompare
|
||||
Name[pt_BR]=Kompare
|
||||
Name[ro]=Kompare
|
||||
Name[ru]=Kompare
|
||||
Name[sk]=Kompare
|
||||
Name[sl]=Kompare
|
||||
Name[sr]=К‑поређење
|
||||
Name[sr@ijekavian]=К‑поређење
|
||||
Name[sr@ijekavianlatin]=K‑poređenje
|
||||
Name[sr@latin]=K‑poređenje
|
||||
Name[sv]=Kompare
|
||||
Name[ta]=கோம்பெர்
|
||||
Name[tg]=Kompare
|
||||
Name[tr]=Kompare
|
||||
Name[ug]=Kompare
|
||||
Name[uk]=Kompare
|
||||
Name[vi]=Kompare
|
||||
Name[wa]=Kompare
|
||||
Name[xh]=Kompare
|
||||
Name[x-test]=xxKomparexx
|
||||
Name[zh_CN]=Kompare
|
||||
Name[zh_TW]=Kompare
|
||||
GenericName=Diff/Patch Frontend
|
||||
GenericName[af]=Diff/Lap Voorprogram
|
||||
GenericName[ast]=Interface Diff/Patch
|
||||
GenericName[bg]=Интерфейс за Diff/Patch
|
||||
GenericName[bs]=Poređenje datoteka za KDE pomoću Diff/Patch
|
||||
GenericName[ca]=Frontal del Diff/Patch
|
||||
GenericName[ca@valencia]=Frontal del Diff/Patch
|
||||
GenericName[cs]=Rozhraní pro Diff/Patch
|
||||
GenericName[cy]=Blaen Gwahaniaethau/Clytiau
|
||||
GenericName[da]=Diff/patch-grænseflade
|
||||
GenericName[de]=Oberfläche für Diff und Patch
|
||||
GenericName[el]=Πρόγραμμα Diff/Patch
|
||||
GenericName[en_GB]=Diff/Patch Frontend
|
||||
GenericName[eo]=Fasado por la programoj "diff" kaj "patch"
|
||||
GenericName[es]=Interfaz Diff/Patch
|
||||
GenericName[et]=Diff/patch kasutajaliides
|
||||
GenericName[eu]=Desberdintasun/Adabaki interfazea
|
||||
GenericName[fa]=پایانه Diff/کژنه
|
||||
GenericName[fi]=Diff/Patch-käyttöliittymä
|
||||
GenericName[fr]=Interface graphique pour « Diff » et « Patch »
|
||||
GenericName[ga]=Comhéadan Diff/Patch
|
||||
GenericName[gl]=Interface para Diff/Patch
|
||||
GenericName[he]=ממשק ל-Diff/Patch
|
||||
GenericName[hr]=Sučelje za Diff/Patch
|
||||
GenericName[hu]=Grafikus diff/patch
|
||||
GenericName[is]=Myndrænt viðmót á Diff/Patch
|
||||
GenericName[it]=Interfaccia per diff e patch
|
||||
GenericName[ja]=Diff/Patch フロントエンド
|
||||
GenericName[kk]=Diff/Patch интерфейсі
|
||||
GenericName[km]=កម្មវិធីផ្នែកខាងមុខរបស់ Diff/Patch
|
||||
GenericName[ko]=Diff/Patch 프론트엔드
|
||||
GenericName[lt]=Diff/Patch naudotojo sąsaja
|
||||
GenericName[lv]=Diff/Patch priekšpuse
|
||||
GenericName[mr]=डिफ/पेच फ्रंटएन्ड
|
||||
GenericName[ms]=Bahagian Depan Beza/Tampal
|
||||
GenericName[nb]=Diff-/Patch-grensesnitt
|
||||
GenericName[nds]=Böversiet för "diff" un "patch"
|
||||
GenericName[ne]=Diff/Patch फ्रन्टइन्ड
|
||||
GenericName[nl]=Diff/Patch-hulpprogramma
|
||||
GenericName[nn]=Diff-/Patch-grensesnitt
|
||||
GenericName[pa]=Diff/ਪੈਂਚ ਫਰੰਟਐਂਡ
|
||||
GenericName[pl]=Interfejs dla programów diff i patch
|
||||
GenericName[pt]=Interface do Diff/Patch
|
||||
GenericName[pt_BR]=Interface do Diff/Patch
|
||||
GenericName[ro]=Interfață grafică pentru „diff” și „patch”
|
||||
GenericName[ru]=Утилита сравнения файлов
|
||||
GenericName[sk]=Rozhranie Diff/Patch
|
||||
GenericName[sl]=Začelje za diff/patch
|
||||
GenericName[sr]=Прочеље за diff и patch
|
||||
GenericName[sr@ijekavian]=Прочеље за diff и patch
|
||||
GenericName[sr@ijekavianlatin]=Pročelje za diff i patch
|
||||
GenericName[sr@latin]=Pročelje za diff i patch
|
||||
GenericName[sv]=Gränssnitt för Diff/Patch
|
||||
GenericName[ta]=டிப்/ஒட்டு முன்பகுதி
|
||||
GenericName[tg]=Утилитаи баробаркунии файлҳо
|
||||
GenericName[tr]=Diff/Patch Önyüzü
|
||||
GenericName[ug]=سېلىشتۇرۇش/ياماش(Diff/Patch) نىڭ ئالدى ئۇچى
|
||||
GenericName[uk]=Інтерфейс до diff/patch
|
||||
GenericName[vi]=Diff/Patch Frontend
|
||||
GenericName[xh]=Diff/Patch Frontend
|
||||
GenericName[x-test]=xxDiff/Patch Frontendxx
|
||||
GenericName[zh_CN]=Diff/Patch 前端
|
||||
GenericName[zh_TW]=Diff/Patch 前端
|
||||
MimeType=text/x-patch;
|
||||
Exec=kompare -caption %c -o %U
|
||||
Icon=kompare
|
||||
X-DocPath=kompare/index.html
|
||||
Terminal=false
|
||||
X-DBUS-StartupType=Multi
|
||||
Categories=Qt;KDE;Development;
|
||||
InitialPreference=10
|
468
kompare/kompare_shell.cpp
Normal file
|
@ -0,0 +1,468 @@
|
|||
/***************************************************************************
|
||||
kompare_shell.cpp
|
||||
-----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
#include "kompare_shell.h"
|
||||
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtGui/QDockWidget>
|
||||
|
||||
#include <ktexteditor/document.h>
|
||||
#include <ktexteditor/view.h>
|
||||
#include <kdebug.h>
|
||||
#include <kedittoolbar.h>
|
||||
#include <kencodingfiledialog.h>
|
||||
#include <kiconloader.h>
|
||||
#include <kshortcutsdialog.h>
|
||||
#include <klibloader.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kparts/componentfactory.h>
|
||||
#include <ksqueezedtextlabel.h>
|
||||
#include <kstatusbar.h>
|
||||
#include <kstandardaction.h>
|
||||
#include <kmimetypetrader.h>
|
||||
#include <kservicetypetrader.h>
|
||||
#include <ktoggleaction.h>
|
||||
// #include <kuserprofile.h>
|
||||
#include <kactioncollection.h>
|
||||
|
||||
#include "kompareinterface.h"
|
||||
#include "kompareurldialog.h"
|
||||
|
||||
#define ID_N_OF_N_DIFFERENCES 1
|
||||
#define ID_N_OF_N_FILES 2
|
||||
#define ID_GENERAL 3
|
||||
|
||||
KompareShell::KompareShell()
|
||||
: KParts::MainWindow( ),
|
||||
m_textViewPart( 0 ),
|
||||
m_textViewWidget( 0 )
|
||||
{
|
||||
if ( !initialGeometrySet() )
|
||||
resize( 800, 480 );
|
||||
|
||||
// set the shell's ui resource file
|
||||
setXMLFile("kompareui.rc");
|
||||
|
||||
// then, setup our actions
|
||||
setupActions();
|
||||
setupStatusBar();
|
||||
|
||||
m_viewPart = KMimeTypeTrader::createInstanceFromQuery<KParts::ReadWritePart>("text/x-patch", "Kompare/ViewPart", this);
|
||||
|
||||
if ( m_viewPart )
|
||||
{
|
||||
setCentralWidget( m_viewPart->widget() );
|
||||
// and integrate the part's GUI with the shell's
|
||||
createGUI(m_viewPart);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we couldn't load our Part, we exit since the Shell by
|
||||
// itself can't do anything useful
|
||||
KMessageBox::error(this, i18n( "Could not load our KompareViewPart." ) );
|
||||
exit(2);
|
||||
}
|
||||
|
||||
m_navTreeDock = new QDockWidget( i18n( "Navigation" ), this );
|
||||
m_navTreeDock->setObjectName( "Navigation" );
|
||||
|
||||
// This part is implemented in KompareNavTreePart
|
||||
m_navTreePart = KServiceTypeTrader::createInstanceFromQuery<KParts::ReadOnlyPart>
|
||||
("KParts/ReadOnlyPart", "'Kompare/NavigationPart' in ServiceTypes", m_navTreeDock);
|
||||
|
||||
if ( m_navTreePart )
|
||||
{
|
||||
m_navTreeDock->setWidget( m_navTreePart->widget() );
|
||||
addDockWidget( Qt::TopDockWidgetArea, m_navTreeDock );
|
||||
// m_navTreeDock->manualDock( m_mainViewDock, KDockWidget::DockTop, 20 );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we couldn't load our Part, we exit since the Shell by
|
||||
// itself can't do anything useful
|
||||
KMessageBox::error(this, i18n( "Could not load our KompareNavigationPart." ) );
|
||||
exit(4);
|
||||
}
|
||||
|
||||
// Hook up the inter part communication
|
||||
connect( m_viewPart, SIGNAL( modelsChanged(const Diff2::DiffModelList*) ),
|
||||
m_navTreePart, SLOT( slotModelsChanged( const Diff2::DiffModelList*) ) );
|
||||
|
||||
connect( m_viewPart, SIGNAL( kompareInfo(Kompare::Info*) ),
|
||||
m_navTreePart, SLOT( slotKompareInfo(Kompare::Info*) ) );
|
||||
|
||||
connect( m_navTreePart, SIGNAL( selectionChanged(const Diff2::DiffModel*, const Diff2::Difference*) ),
|
||||
m_viewPart, SIGNAL( selectionChanged(const Diff2::DiffModel*, const Diff2::Difference*) ) );
|
||||
connect( m_viewPart, SIGNAL( setSelection(const Diff2::DiffModel*, const Diff2::Difference*) ),
|
||||
m_navTreePart, SLOT( slotSetSelection(const Diff2::DiffModel*, const Diff2::Difference*) ) );
|
||||
|
||||
connect( m_navTreePart, SIGNAL( selectionChanged(const Diff2::Difference*) ),
|
||||
m_viewPart, SIGNAL( selectionChanged(const Diff2::Difference*) ) );
|
||||
connect( m_viewPart, SIGNAL( setSelection(const Diff2::Difference*) ),
|
||||
m_navTreePart, SLOT( slotSetSelection(const Diff2::Difference*) ) );
|
||||
|
||||
// This is the interpart interface, it is signal and slot based so no "real" nterface here
|
||||
// All you have to do is connect the parts from your application.
|
||||
// These just point to the method with the same name in the KompareModelList or get called
|
||||
// from the method with the same name in KompareModelList.
|
||||
|
||||
// There is currently no applying possible from the navtreepart to the viewpart
|
||||
connect( m_viewPart, SIGNAL(applyDifference(bool)),
|
||||
m_navTreePart, SLOT(slotApplyDifference(bool)) );
|
||||
connect( m_viewPart, SIGNAL(applyAllDifferences(bool)),
|
||||
m_navTreePart, SLOT(slotApplyAllDifferences(bool)) );
|
||||
connect( m_viewPart, SIGNAL(applyDifference(const Diff2::Difference*, bool)),
|
||||
m_navTreePart, SLOT(slotApplyDifference(const Diff2::Difference*, bool)) );
|
||||
|
||||
// Hook up the KomparePart -> KompareShell communication
|
||||
connect( m_viewPart, SIGNAL( setStatusBarModelInfo( int, int, int, int, int ) ),
|
||||
this, SLOT( slotUpdateStatusBar( int, int, int, int, int ) ) );
|
||||
connect( m_viewPart, SIGNAL( setStatusBarText(const QString&) ),
|
||||
this, SLOT( slotSetStatusBarText(const QString&) ) );
|
||||
|
||||
connect( m_viewPart, SIGNAL(diffString(const QString&)),
|
||||
this, SLOT(slotSetDiffString(const QString&)) );
|
||||
|
||||
// Read basic main-view settings, and set to autosave
|
||||
setAutoSaveSettings( "General Options" );
|
||||
}
|
||||
|
||||
KompareShell::~KompareShell()
|
||||
{
|
||||
}
|
||||
|
||||
bool KompareShell::queryClose()
|
||||
{
|
||||
bool rv = m_viewPart->queryClose();
|
||||
if ( rv )
|
||||
KGlobal::deref();
|
||||
return rv;
|
||||
}
|
||||
|
||||
void KompareShell::openDiff(const KUrl& url)
|
||||
{
|
||||
kDebug(8102) << "Url = " << url.prettyUrl() << endl;
|
||||
m_diffURL = url;
|
||||
viewPart()->openDiff( url );
|
||||
}
|
||||
|
||||
void KompareShell::openStdin()
|
||||
{
|
||||
kDebug(8102) << "Using stdin to read the diff" << endl;
|
||||
QFile file;
|
||||
file.open( stdin, QIODevice::ReadOnly );
|
||||
QTextStream stream( &file );
|
||||
|
||||
QString diff = stream.readAll();
|
||||
|
||||
file.close();
|
||||
|
||||
viewPart()->openDiff( diff );
|
||||
|
||||
}
|
||||
|
||||
void KompareShell::compare(const KUrl& source,const KUrl& destination )
|
||||
{
|
||||
m_sourceURL = source;
|
||||
m_destinationURL = destination;
|
||||
|
||||
viewPart()->compare( source, destination );
|
||||
}
|
||||
|
||||
void KompareShell::blend( const KUrl& url1, const KUrl& diff )
|
||||
{
|
||||
m_sourceURL = url1;
|
||||
m_destinationURL = diff;
|
||||
|
||||
viewPart()->openDirAndDiff( url1, diff );
|
||||
}
|
||||
|
||||
void KompareShell::setupActions()
|
||||
{
|
||||
KAction *a;
|
||||
a = actionCollection()->addAction(KStandardAction::Open, this, SLOT(slotFileOpen()));
|
||||
a->setText( i18n( "&Open Diff..." ) );
|
||||
a = actionCollection()->addAction("file_compare_files", this, SLOT(slotFileCompareFiles()));
|
||||
a->setIcon(KIcon("document-open"));
|
||||
a->setText(i18n("&Compare Files..."));
|
||||
a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
|
||||
a = actionCollection()->addAction("file_blend_url", this, SLOT(slotFileBlendURLAndDiff()));
|
||||
a->setText(i18n("&Blend URL with Diff..."));
|
||||
a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_B));
|
||||
actionCollection()->addAction(KStandardAction::Quit, this, SLOT( slotFileClose() ));
|
||||
|
||||
createStandardStatusBarAction();
|
||||
setStandardToolBarMenuEnabled(true);
|
||||
m_showTextView = new KToggleAction(i18n("Show T&ext View"), this);
|
||||
// needs a KGuiItem, also the doc says explicitly not to do this
|
||||
// m_showTextView->setCheckedState(i18n("Hide T&ext View"));
|
||||
actionCollection()->addAction("options_show_text_view", m_showTextView);
|
||||
connect(m_showTextView, SIGNAL(triggered(bool)), SLOT(slotShowTextView()));
|
||||
|
||||
KStandardAction::keyBindings(this, SLOT(optionsConfigureKeys()), actionCollection());
|
||||
KStandardAction::configureToolbars(this, SLOT(optionsConfigureToolbars()), actionCollection());
|
||||
}
|
||||
|
||||
void KompareShell::setupStatusBar()
|
||||
{
|
||||
// Made these entries permanent so they will appear on the right side
|
||||
statusBar()->insertPermanentItem( i18n(" 0 of 0 differences "), ID_N_OF_N_DIFFERENCES, 0);
|
||||
statusBar()->insertPermanentItem( i18n(" 0 of 0 files "), ID_N_OF_N_FILES, 0);
|
||||
|
||||
m_generalLabel = new KSqueezedTextLabel( "", 0 );
|
||||
statusBar()->addWidget( m_generalLabel, 1 );
|
||||
m_generalLabel->setAlignment( Qt::AlignLeft );
|
||||
}
|
||||
|
||||
void KompareShell::slotUpdateStatusBar( int modelIndex, int differenceIndex, int modelCount, int differenceCount, int appliedCount )
|
||||
{
|
||||
kDebug(8102) << "KompareShell::updateStatusBar()" << endl;
|
||||
|
||||
QString fileStr;
|
||||
QString diffStr;
|
||||
|
||||
if ( modelIndex >= 0 )
|
||||
fileStr = i18np( " %2 of %1 file ", " %2 of %1 files ", modelCount, modelIndex + 1 );
|
||||
else
|
||||
fileStr = i18np( " %1 file ", " %1 files ", modelCount );
|
||||
|
||||
if ( differenceIndex >= 0 )
|
||||
diffStr = i18np( " %2 of %1 difference, %3 applied ", " %2 of %1 differences, %3 applied ", differenceCount ,
|
||||
differenceIndex + 1, appliedCount );
|
||||
else
|
||||
diffStr = i18np( " %1 difference ", " %1 differences ", differenceCount );
|
||||
|
||||
statusBar()->changeItem( fileStr, ID_N_OF_N_FILES );
|
||||
statusBar()->changeItem( diffStr, ID_N_OF_N_DIFFERENCES );
|
||||
}
|
||||
|
||||
void KompareShell::slotSetStatusBarText( const QString& text )
|
||||
{
|
||||
m_generalLabel->setText( text );
|
||||
}
|
||||
|
||||
void KompareShell::saveProperties(KConfigGroup &config)
|
||||
{
|
||||
// The 'config' object points to the session managed
|
||||
// config file. Anything you write here will be available
|
||||
// later when this app is restored
|
||||
if ( m_mode == Kompare::ComparingFiles )
|
||||
{
|
||||
config.writeEntry( "Mode", "ComparingFiles" );
|
||||
config.writePathEntry( "SourceUrl", m_sourceURL.url() );
|
||||
config.writePathEntry( "DestinationUrl", m_destinationURL.url() );
|
||||
}
|
||||
else if ( m_mode == Kompare::ShowingDiff )
|
||||
{
|
||||
config.writeEntry( "Mode", "ShowingDiff" );
|
||||
config.writePathEntry( "DiffUrl", m_diffURL.url() );
|
||||
}
|
||||
|
||||
viewPart()->saveProperties( config.config() );
|
||||
}
|
||||
|
||||
void KompareShell::readProperties(const KConfigGroup &config)
|
||||
{
|
||||
// The 'config' object points to the session managed
|
||||
// config file. This function is automatically called whenever
|
||||
// the app is being restored. Read in here whatever you wrote
|
||||
// in 'saveProperties'
|
||||
|
||||
QString mode = config.readEntry( "Mode", "ComparingFiles" );
|
||||
if ( mode == "ComparingFiles" )
|
||||
{
|
||||
m_mode = Kompare::ComparingFiles;
|
||||
m_sourceURL = config.readPathEntry( "SourceUrl", "" );
|
||||
m_destinationURL = config.readPathEntry( "DestinationFile", "" );
|
||||
|
||||
viewPart()->readProperties( const_cast<KConfig *>(config.config()) );
|
||||
|
||||
viewPart()->compareFiles( m_sourceURL, m_destinationURL );
|
||||
}
|
||||
else if ( mode == "ShowingDiff" )
|
||||
{
|
||||
m_mode = Kompare::ShowingDiff;
|
||||
m_diffURL = config.readPathEntry( "DiffUrl", "" );
|
||||
|
||||
viewPart()->readProperties( const_cast<KConfig *>(config.config()) );
|
||||
|
||||
m_viewPart->openUrl( m_diffURL );
|
||||
}
|
||||
else
|
||||
{ // just in case something weird has happened, don't restore the diff then
|
||||
// Bruggie: or when some idiot like me changes the possible values for mode
|
||||
// IOW, a nice candidate for a kconf_update thingy :)
|
||||
viewPart()->readProperties( const_cast<KConfig *>(config.config()) );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareShell::slotFileOpen()
|
||||
{
|
||||
// FIXME: use different filedialog which gets encoding
|
||||
KUrl url = KFileDialog::getOpenUrl( KUrl(), "text/x-patch", this );
|
||||
if( !url.isEmpty() ) {
|
||||
KompareShell* shell = new KompareShell();
|
||||
KGlobal::ref();
|
||||
shell->show();
|
||||
shell->openDiff( url );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareShell::slotFileBlendURLAndDiff()
|
||||
{
|
||||
KompareURLDialog dialog( this );
|
||||
|
||||
dialog.setCaption( i18n( "Blend File/Folder with diff Output" ) );
|
||||
dialog.setFirstGroupBoxTitle( i18n( "File/Folder" ) );
|
||||
dialog.setSecondGroupBoxTitle( i18n( "Diff Output" ) );
|
||||
|
||||
KGuiItem blendGuiItem( i18n( "Blend" ), QString(), i18n( "Blend this file or folder with the diff output" ), i18n( "If you have entered a file or folder name and a file that contains diff output in the fields in this dialog then this button will be enabled and pressing it will open kompare's main view where the output of the entered file or files from the folder are mixed with the diff output so you can then apply the difference(s) to a file or to the files. " ) );
|
||||
dialog.setButtonGuiItem( KDialog::Ok, blendGuiItem );
|
||||
|
||||
dialog.setGroup( "Recent Blend Files" );
|
||||
|
||||
dialog.setFirstURLRequesterMode( KFile::File|KFile::Directory|KFile::ExistingOnly );
|
||||
// diff output can not be a directory
|
||||
dialog.setSecondURLRequesterMode( KFile::File|KFile::ExistingOnly );
|
||||
if ( dialog.exec() == QDialog::Accepted )
|
||||
{
|
||||
m_sourceURL = dialog.getFirstURL();
|
||||
m_destinationURL = dialog.getSecondURL();
|
||||
// Leak???
|
||||
KompareShell* shell = new KompareShell();
|
||||
KGlobal::ref();
|
||||
shell->show();
|
||||
shell->viewPart()->setEncoding( dialog.encoding() );
|
||||
shell->blend( m_sourceURL, m_destinationURL );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareShell::slotFileCompareFiles()
|
||||
{
|
||||
KompareURLDialog dialog( this );
|
||||
|
||||
dialog.setCaption( i18n( "Compare Files or Folders" ) );
|
||||
dialog.setFirstGroupBoxTitle( i18n( "Source" ) );
|
||||
dialog.setSecondGroupBoxTitle( i18n( "Destination" ) );
|
||||
|
||||
KGuiItem compareGuiItem( i18n( "Compare" ), QString(), i18n( "Compare these files or folders" ), i18n( "If you have entered 2 filenames or 2 folders in the fields in this dialog then this button will be enabled and pressing it will start a comparison of the entered files or folders. " ) );
|
||||
dialog.setButtonGuiItem( KDialog::Ok, compareGuiItem );
|
||||
|
||||
dialog.setGroup( "Recent Compare Files" );
|
||||
|
||||
dialog.setFirstURLRequesterMode( KFile::File|KFile::Directory|KFile::ExistingOnly );
|
||||
dialog.setSecondURLRequesterMode( KFile::File|KFile::Directory|KFile::ExistingOnly );
|
||||
|
||||
if ( dialog.exec() == QDialog::Accepted )
|
||||
{
|
||||
m_sourceURL = dialog.getFirstURL();
|
||||
m_destinationURL = dialog.getSecondURL();
|
||||
KompareShell* shell = new KompareShell();
|
||||
KGlobal::ref();
|
||||
shell->show();
|
||||
kDebug(8102) << "The encoding is: " << dialog.encoding() << endl;
|
||||
shell->viewPart()->setEncoding( dialog.encoding() );
|
||||
shell->compare( m_sourceURL, m_destinationURL );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareShell::slotFileClose()
|
||||
{
|
||||
if ( m_viewPart->queryClose() )
|
||||
{
|
||||
KGlobal::deref();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareShell::slotShowTextView()
|
||||
{
|
||||
if ( !m_textViewWidget )
|
||||
{
|
||||
QString error;
|
||||
|
||||
// FIXME: proper error checking
|
||||
m_textViewWidget = new QDockWidget( i18n( "Text View" ), this );
|
||||
m_textViewWidget->setObjectName( "Text View" );
|
||||
// m_textViewWidget = createDockWidget( i18n("Text View"), SmallIcon( "text-x-generic") );
|
||||
m_textViewPart = KServiceTypeTrader::createInstanceFromQuery<KTextEditor::Document>(
|
||||
QString::fromLatin1("KTextEditor/Document"),
|
||||
this, this, QString(), QVariantList(), &error );
|
||||
if ( m_textViewPart )
|
||||
{
|
||||
m_textView = qobject_cast<KTextEditor::View*>( m_textViewPart->createView( this ) );
|
||||
m_textViewWidget->setWidget( static_cast<QWidget*>(m_textView) );
|
||||
m_textViewPart->setHighlightingMode( "Diff" );
|
||||
m_textViewPart->setText( m_diffString );
|
||||
}
|
||||
m_textViewWidget->show();
|
||||
connect( m_textViewWidget, SIGNAL(visibilityChanged(bool)), SLOT(slotVisibilityChanged(bool)) );
|
||||
}
|
||||
else if ( m_textViewWidget->isVisible() )
|
||||
m_textViewWidget->hide();
|
||||
else
|
||||
m_textViewWidget->show();
|
||||
|
||||
addDockWidget( Qt::BottomDockWidgetArea, m_textViewWidget );
|
||||
// m_textViewWidget->manualDock( m_mainViewDock, KDockWidget:: DockCenter );
|
||||
}
|
||||
|
||||
void KompareShell::slotVisibilityChanged( bool visible )
|
||||
{
|
||||
m_showTextView->setChecked( visible );
|
||||
}
|
||||
|
||||
void KompareShell::slotSetDiffString( const QString& diffString )
|
||||
{
|
||||
if ( m_textViewPart )
|
||||
m_textViewPart->setText( diffString );
|
||||
m_diffString = diffString;
|
||||
}
|
||||
|
||||
void KompareShell::optionsConfigureKeys()
|
||||
{
|
||||
KShortcutsDialog dlg( KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this );
|
||||
|
||||
dlg.addCollection( actionCollection() );
|
||||
if ( m_viewPart )
|
||||
dlg.addCollection( m_viewPart->actionCollection() );
|
||||
|
||||
dlg.configure();
|
||||
}
|
||||
|
||||
void KompareShell::optionsConfigureToolbars()
|
||||
{
|
||||
KConfigGroup group(KGlobal::config(), autoSaveGroup());
|
||||
saveMainWindowSettings(group);
|
||||
// use the standard toolbar editor
|
||||
KEditToolBar dlg(factory());
|
||||
connect(&dlg,SIGNAL(newToolbarConfig()),this,SLOT(newToolbarConfig()));
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void KompareShell::newToolbarConfig()
|
||||
{
|
||||
KConfigGroup group(KGlobal::config(), autoSaveGroup());
|
||||
applyMainWindowSettings(group);
|
||||
}
|
||||
|
||||
KompareInterface* KompareShell::viewPart() const
|
||||
{
|
||||
return qobject_cast<KompareInterface *>(m_viewPart);
|
||||
}
|
||||
|
||||
#include "kompare_shell.moc"
|
150
kompare/kompare_shell.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/***************************************************************************
|
||||
kompare_shell.h
|
||||
----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARESHELL_H
|
||||
#define KOMPARESHELL_H
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kparts/mainwindow.h>
|
||||
#include <kompare.h>
|
||||
|
||||
class KompareInterface;
|
||||
namespace KParts {
|
||||
class ReadOnlyPart;
|
||||
class ReadWritePart;
|
||||
}
|
||||
class KToggleAction;
|
||||
|
||||
class KSqueezedTextLabel;
|
||||
class KomparePart;
|
||||
class KompareNavTreePart;
|
||||
|
||||
namespace KTextEditor {
|
||||
class Document;
|
||||
class EditInterface;
|
||||
class View;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the application "Shell". It has a menubar, toolbar, and
|
||||
* statusbar but relies on the "Part" to do all the real work.
|
||||
*
|
||||
* Adapted the shell a bit so it now handles separate view and navigation parts
|
||||
*
|
||||
* @short Application Shell
|
||||
* @author John Firebaugh <jfirebaugh@kde.org>
|
||||
* @author Otto Bruggeman <bruggie@home.nl>
|
||||
* @version 3.2.90
|
||||
*/
|
||||
class KompareShell : public KParts::MainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/**
|
||||
* Default Constructor
|
||||
*/
|
||||
KompareShell();
|
||||
|
||||
/**
|
||||
* Default Destructor
|
||||
*/
|
||||
virtual ~KompareShell();
|
||||
|
||||
/**
|
||||
* Use this method to load whatever file/URL you have
|
||||
*/
|
||||
void openDiff( const KUrl& url );
|
||||
|
||||
/**
|
||||
* Use this method to load the diff from stdin
|
||||
*/
|
||||
void openStdin();
|
||||
|
||||
/**
|
||||
* Use this method to compare 2 URLs (files or directories)
|
||||
*/
|
||||
void compare( const KUrl& source, const KUrl& destination );
|
||||
|
||||
/**
|
||||
* Use this method to blend diff into url1 (file or directory)
|
||||
*/
|
||||
void blend( const KUrl& url1, const KUrl& diff );
|
||||
|
||||
public slots:
|
||||
void slotUpdateStatusBar( int modelIndex, int differenceIndex, int modelCount, int differenceCount, int appliedCount );
|
||||
|
||||
KompareInterface* viewPart() const;
|
||||
|
||||
protected:
|
||||
virtual bool queryClose();
|
||||
|
||||
/**
|
||||
* This method is called when it is time for the app to save its
|
||||
* properties for session management purposes.
|
||||
*/
|
||||
void saveProperties(KConfigGroup &);
|
||||
|
||||
/**
|
||||
* This method is called when this app is restored. The KConfig
|
||||
* object points to the session management config file that was saved
|
||||
* with @ref saveProperties
|
||||
*/
|
||||
void readProperties(const KConfigGroup &);
|
||||
|
||||
private slots:
|
||||
void slotSetStatusBarText( const QString& text );
|
||||
void slotFileOpen();
|
||||
void slotFileCompareFiles();
|
||||
void slotFileBlendURLAndDiff();
|
||||
void slotShowTextView();
|
||||
void slotFileClose();
|
||||
void optionsConfigureKeys();
|
||||
void optionsConfigureToolbars();
|
||||
void slotSetDiffString( const QString& diffString );
|
||||
void newToolbarConfig();
|
||||
void slotVisibilityChanged( bool visible );
|
||||
|
||||
private:
|
||||
void setupAccel();
|
||||
void setupActions();
|
||||
void setupStatusBar();
|
||||
|
||||
private:
|
||||
KUrl m_sourceURL;
|
||||
KUrl m_destinationURL;
|
||||
KUrl m_diffURL;
|
||||
|
||||
KParts::ReadWritePart* m_viewPart;
|
||||
KParts::ReadOnlyPart* m_navTreePart;
|
||||
KTextEditor::Document* m_textViewPart;
|
||||
KTextEditor::View* m_textView;
|
||||
// KTextEditor::EditInterface* m_textEditIface;
|
||||
|
||||
QDockWidget* m_textViewWidget;
|
||||
QDockWidget* m_navTreeDock;
|
||||
|
||||
KToggleAction* m_showTextView;
|
||||
|
||||
enum Kompare::Mode m_mode;
|
||||
// This is the statusbarwidget for displaying the general stuff
|
||||
KSqueezedTextLabel* m_generalLabel;
|
||||
|
||||
QString m_diffString;
|
||||
};
|
||||
|
||||
#endif // KOMPARE_H
|
4
kompare/komparenavigationpart.desktop
Normal file
|
@ -0,0 +1,4 @@
|
|||
[Desktop Entry]
|
||||
Type=ServiceType
|
||||
X-KDE-ServiceType=Kompare/NavigationPart
|
||||
X-KDE-Derived=KParts/ReadOnlyPart
|
22
kompare/komparenavtreepart/CMakeLists.txt
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../libdiff2 ${CMAKE_CURRENT_SOURCE_DIR}/../komparepart )
|
||||
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set(komparenavtreepart_PART_SRCS komparenavtreepart.cpp )
|
||||
|
||||
|
||||
kde4_add_plugin(komparenavtreepart ${komparenavtreepart_PART_SRCS})
|
||||
|
||||
|
||||
|
||||
target_link_libraries(komparenavtreepart ${KDE4_KPARTS_LIBS} ${LIBKOMPAREDIFF2_LIBRARIES} )
|
||||
|
||||
install(TARGETS komparenavtreepart DESTINATION ${PLUGIN_INSTALL_DIR} )
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install( FILES komparenavtreepart.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
|
||||
|
780
kompare/komparenavtreepart/komparenavtreepart.cpp
Normal file
|
@ -0,0 +1,780 @@
|
|||
/***************************************************************************
|
||||
KompareNavTreePart.cpp
|
||||
----------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2005,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "komparenavtreepart.h"
|
||||
|
||||
#include <QtGui/QTreeWidgetItemIterator>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <klocale.h>
|
||||
#include <kiconloader.h>
|
||||
#include <kmimetype.h>
|
||||
#include <kaboutdata.h>
|
||||
#include <kcomponentdata.h>
|
||||
#include <kpluginfactory.h>
|
||||
|
||||
#include "difference.h"
|
||||
#include "diffmodel.h"
|
||||
#include "diffmodellist.h"
|
||||
#include "komparemodellist.h"
|
||||
|
||||
#define COL_SOURCE 0
|
||||
#define COL_DESTINATION 1
|
||||
#define COL_DIFFERENCE 2
|
||||
|
||||
using namespace Diff2;
|
||||
|
||||
KompareNavTreePart::KompareNavTreePart( QWidget* parentWidget, QObject* parent, const QVariantList& )
|
||||
: KParts::ReadOnlyPart( parent ),
|
||||
m_splitter( 0 ),
|
||||
m_modelList( 0 ),
|
||||
m_srcDirTree( 0 ),
|
||||
m_destDirTree( 0 ),
|
||||
m_fileList( 0 ),
|
||||
m_changesList( 0 ),
|
||||
m_srcRootItem( 0 ),
|
||||
m_destRootItem( 0 ),
|
||||
m_selectedModel( 0 ),
|
||||
m_selectedDifference( 0 ),
|
||||
m_source( "" ),
|
||||
m_destination( "" ),
|
||||
m_info( 0 )
|
||||
{
|
||||
m_splitter = new QSplitter( Qt::Horizontal, parentWidget );
|
||||
|
||||
setWidget( m_splitter );
|
||||
|
||||
m_srcDirTree = new QTreeWidget( m_splitter );
|
||||
m_srcDirTree->setHeaderLabel( i18n("Source Folder") );
|
||||
m_srcDirTree->setRootIsDecorated( false );
|
||||
m_srcDirTree->setSortingEnabled( true );
|
||||
m_srcDirTree->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
m_destDirTree = new QTreeWidget( m_splitter );
|
||||
m_destDirTree->setHeaderLabel( i18n("Destination Folder") );
|
||||
m_destDirTree->setRootIsDecorated( false );
|
||||
m_destDirTree->setSortingEnabled( true );
|
||||
m_destDirTree->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
m_fileList = new QTreeWidget( m_splitter );
|
||||
m_fileList->setHeaderLabels( QStringList() << i18n("Source File") << i18n("Destination File") );
|
||||
m_fileList->setAllColumnsShowFocus( true );
|
||||
m_fileList->setRootIsDecorated( false );
|
||||
m_fileList->setSortingEnabled( true );
|
||||
m_fileList->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
m_changesList = new QTreeWidget( m_splitter );
|
||||
m_changesList->setHeaderLabels( QStringList() << i18n("Source Line") << i18n("Destination Line") << i18n("Difference") );
|
||||
m_changesList->setAllColumnsShowFocus( true );
|
||||
m_changesList->setRootIsDecorated( false );
|
||||
m_changesList->setSortingEnabled( true );
|
||||
m_changesList->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
connect( m_srcDirTree, SIGNAL(currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
|
||||
this, SLOT(slotSrcDirTreeSelectionChanged( QTreeWidgetItem* )) );
|
||||
connect( m_destDirTree, SIGNAL(currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
|
||||
this, SLOT(slotDestDirTreeSelectionChanged( QTreeWidgetItem* )) );
|
||||
connect( m_fileList, SIGNAL(currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
|
||||
this, SLOT(slotFileListSelectionChanged( QTreeWidgetItem* )) );
|
||||
connect( m_changesList, SIGNAL(currentItemChanged( QTreeWidgetItem*, QTreeWidgetItem* )),
|
||||
this, SLOT(slotChangesListSelectionChanged( QTreeWidgetItem* )) );
|
||||
}
|
||||
|
||||
KompareNavTreePart::~KompareNavTreePart()
|
||||
{
|
||||
m_modelList = 0;
|
||||
m_selectedModel = 0;
|
||||
m_selectedDifference = 0;
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotKompareInfo( struct Kompare::Info* info )
|
||||
{
|
||||
m_info = info;
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotModelsChanged( const DiffModelList* modelList )
|
||||
{
|
||||
kDebug(8105) << "Models (" << modelList << ") have changed... scanning the models... " << endl;
|
||||
|
||||
if ( modelList )
|
||||
{
|
||||
m_modelList = modelList;
|
||||
m_srcDirTree->clear();
|
||||
m_destDirTree->clear();
|
||||
m_fileList->clear();
|
||||
m_changesList->clear();
|
||||
buildTreeInMemory();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_modelList = modelList;
|
||||
m_srcDirTree->clear();
|
||||
m_destDirTree->clear();
|
||||
m_fileList->clear();
|
||||
m_changesList->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareNavTreePart::buildTreeInMemory()
|
||||
{
|
||||
kDebug(8105) << "BuildTreeInMemory called" << endl;
|
||||
|
||||
if ( m_modelList->count() == 0 )
|
||||
{
|
||||
kDebug(8105) << "No models... weird shit..." << endl;
|
||||
return; // avoids a crash on clear()
|
||||
}
|
||||
|
||||
if ( m_info == 0 )
|
||||
{
|
||||
kDebug(8105) << "No Info... weird shit..." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
QString srcBase;
|
||||
QString destBase;
|
||||
|
||||
DiffModel* model;
|
||||
model = m_modelList->first();
|
||||
m_selectedModel = 0L;
|
||||
|
||||
switch ( m_info->mode )
|
||||
{
|
||||
case Kompare::ShowingDiff:
|
||||
// BUG: 107489 No common root because it is a multi directory relative path diff
|
||||
// We need to detect this and create a different rootitem / or so or should we always add this?
|
||||
// Trouble we run into is that the directories do not start with a /
|
||||
// so we have an unknown top root dir
|
||||
// Thinking some more about it i guess it is best to use "" as base and simply show some string
|
||||
// like Unknown filesystem path as root text but only in the case of dirs starting without a /
|
||||
srcBase = model->sourcePath();
|
||||
destBase = model->destinationPath();
|
||||
// FIXME: these tests will not work on windows, we need something else
|
||||
if ( srcBase[0] != '/' )
|
||||
srcBase = "";
|
||||
if ( destBase[0] != '/' )
|
||||
destBase = "";
|
||||
break;
|
||||
case Kompare::ComparingFiles:
|
||||
srcBase = model->sourcePath();
|
||||
destBase = model->destinationPath();
|
||||
break;
|
||||
case Kompare::ComparingDirs:
|
||||
srcBase = m_info->localSource;
|
||||
if ( !srcBase.endsWith( '/' ) )
|
||||
srcBase += '/';
|
||||
destBase = m_info->localDestination;
|
||||
if ( !destBase.endsWith( '/' ) )
|
||||
destBase += '/';
|
||||
break;
|
||||
case Kompare::BlendingFile:
|
||||
case Kompare::BlendingDir:
|
||||
default:
|
||||
kDebug(8105) << "Oops needs to implement this..." << endl;
|
||||
}
|
||||
|
||||
// kDebug(8105) << "srcBase = " << srcBase << endl;
|
||||
// kDebug(8105) << "destBase = " << destBase << endl;
|
||||
|
||||
m_srcRootItem = new KDirLVI( m_srcDirTree, srcBase );
|
||||
m_destRootItem = new KDirLVI( m_destDirTree, destBase );
|
||||
|
||||
QString srcPath;
|
||||
QString destPath;
|
||||
|
||||
// Create the tree from the models
|
||||
DiffModelListConstIterator modelIt = m_modelList->begin();
|
||||
DiffModelListConstIterator mEnd = m_modelList->end();
|
||||
|
||||
for ( ; modelIt != mEnd; ++modelIt )
|
||||
{
|
||||
model = *modelIt;
|
||||
srcPath = model->sourcePath();
|
||||
destPath = model->destinationPath();
|
||||
|
||||
kDebug(8105) << "srcPath = " << srcPath << endl;
|
||||
kDebug(8105) << "destPath = " << destPath << endl;
|
||||
m_srcRootItem->addModel( srcPath, model, &m_modelToSrcDirItemDict );
|
||||
m_destRootItem->addModel( destPath, model, &m_modelToDestDirItemDict );
|
||||
}
|
||||
// m_srcDirTree->setSelected( m_srcDirTree->firstChild(), true );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::buildDirectoryTree()
|
||||
{
|
||||
// FIXME: afaict this can be deleted
|
||||
// kDebug(8105) << "BuildDirTree called" << endl;
|
||||
}
|
||||
|
||||
QString KompareNavTreePart::compareFromEndAndReturnSame(
|
||||
const QString& string1,
|
||||
const QString& string2 )
|
||||
{
|
||||
QString result;
|
||||
|
||||
int srcLen = string1.length();
|
||||
int destLen = string2.length();
|
||||
|
||||
while ( srcLen != 0 && destLen != 0 )
|
||||
{
|
||||
if ( string1[--srcLen] == string2[--destLen] )
|
||||
result.prepend( string1[srcLen] );
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if ( srcLen != 0 && destLen != 0 && result.startsWith( '/' ) )
|
||||
result = result.remove( 0, 1 ); // strip leading /, we need it later
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotSetSelection( const DiffModel* model, const Difference* diff )
|
||||
{
|
||||
kDebug(8105) << "KompareNavTreePart::slotSetSelection model = " << model << ", diff = " << diff << endl;
|
||||
if ( model == m_selectedModel )
|
||||
{
|
||||
// model is the same, so no need to update that...
|
||||
if ( diff != m_selectedDifference )
|
||||
{
|
||||
m_selectedDifference = diff;
|
||||
setSelectedDifference( diff );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// model is different so we need to find the right dirs, file and changeitems to select
|
||||
// if m_selectedModel == NULL then everything needs to be done as well
|
||||
if ( !m_selectedModel || model->sourcePath() != m_selectedModel->sourcePath() )
|
||||
{ // dirs are different, so we need to update the dirviews as well
|
||||
m_selectedModel = model;
|
||||
m_selectedDifference = diff;
|
||||
|
||||
setSelectedDir( model );
|
||||
setSelectedFile( model );
|
||||
setSelectedDifference( diff );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !m_selectedModel || model->sourceFile() != m_selectedModel->sourceFile() )
|
||||
{
|
||||
m_selectedModel = model;
|
||||
setSelectedFile( model );
|
||||
|
||||
m_selectedDifference = diff;
|
||||
setSelectedDifference( diff );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareNavTreePart::setSelectedDir( const DiffModel* model )
|
||||
{
|
||||
KDirLVI* currentDir;
|
||||
currentDir = m_modelToSrcDirItemDict[ model ];
|
||||
kDebug(8105) << "Manually setting selection in srcdirtree with currentDir = " << currentDir << endl;
|
||||
m_srcDirTree->blockSignals( true );
|
||||
m_srcDirTree->setCurrentItem( currentDir );
|
||||
m_srcDirTree->scrollToItem( currentDir );
|
||||
m_srcDirTree->blockSignals( false );
|
||||
|
||||
currentDir = m_modelToDestDirItemDict[ model ];
|
||||
kDebug(8105) << "Manually setting selection in destdirtree with currentDir = " << currentDir << endl;
|
||||
m_destDirTree->blockSignals( true );
|
||||
m_destDirTree->setCurrentItem( currentDir );
|
||||
m_destDirTree->scrollToItem( currentDir );
|
||||
m_destDirTree->blockSignals( false );
|
||||
|
||||
m_fileList->blockSignals( true );
|
||||
currentDir->fillFileList( m_fileList, &m_modelToFileItemDict );
|
||||
m_fileList->blockSignals( false );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::setSelectedFile( const DiffModel* model )
|
||||
{
|
||||
KFileLVI* currentFile;
|
||||
currentFile = m_modelToFileItemDict[ model ];
|
||||
kDebug(8105) << "Manually setting selection in filelist" << endl;
|
||||
m_fileList->blockSignals( true );
|
||||
m_fileList->setCurrentItem( currentFile );
|
||||
m_fileList->scrollToItem( currentFile );
|
||||
m_fileList->blockSignals( false );
|
||||
|
||||
m_changesList->blockSignals( true );
|
||||
currentFile->fillChangesList( m_changesList, &m_diffToChangeItemDict );
|
||||
m_changesList->blockSignals( false );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::setSelectedDifference( const Difference* diff )
|
||||
{
|
||||
KChangeLVI* currentDiff;
|
||||
currentDiff = m_diffToChangeItemDict[ diff ];
|
||||
kDebug(8105) << "Manually setting selection in changeslist to " << currentDiff << endl;
|
||||
m_changesList->blockSignals( true );
|
||||
m_changesList->setCurrentItem( currentDiff );
|
||||
m_changesList->scrollToItem( currentDiff );
|
||||
m_changesList->blockSignals( false );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotSetSelection( const Difference* diff )
|
||||
{
|
||||
// kDebug(8105) << "Scotty i need more power !!" << endl;
|
||||
if ( m_selectedDifference != diff )
|
||||
{
|
||||
// kDebug(8105) << "But sir, i am giving you all she's got" << endl;
|
||||
m_selectedDifference = diff;
|
||||
setSelectedDifference( diff );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotSrcDirTreeSelectionChanged( QTreeWidgetItem* item )
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
kDebug(8105) << "Sent by the sourceDirectoryTree with item = " << item << endl;
|
||||
m_srcDirTree->scrollToItem( item );
|
||||
KDirLVI* dir = static_cast<KDirLVI*>(item);
|
||||
// order the dest tree view to set its selected item to the same as here
|
||||
QString path;
|
||||
// We start with an empty path and after the call path contains the full path
|
||||
path = dir->fullPath( path );
|
||||
KDirLVI* selItem = m_destRootItem->setSelected( path );
|
||||
m_destDirTree->blockSignals( true );
|
||||
m_destDirTree->setCurrentItem( selItem );
|
||||
m_destDirTree->scrollToItem( selItem );
|
||||
m_destDirTree->blockSignals( false );
|
||||
// fill the changes list
|
||||
dir->fillFileList( m_fileList, &m_modelToFileItemDict );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotDestDirTreeSelectionChanged( QTreeWidgetItem* item )
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
kDebug(8105) << "Sent by the destinationDirectoryTree with item = " << item << endl;
|
||||
m_destDirTree->scrollToItem( item );
|
||||
KDirLVI* dir = static_cast<KDirLVI*>(item);
|
||||
// order the src tree view to set its selected item to the same as here
|
||||
QString path;
|
||||
// We start with an empty path and after the call path contains the full path
|
||||
path = dir->fullPath( path );
|
||||
KDirLVI* selItem = m_srcRootItem->setSelected( path );
|
||||
m_srcDirTree->blockSignals( true );
|
||||
m_srcDirTree->setCurrentItem( selItem );
|
||||
m_srcDirTree->scrollToItem( selItem );
|
||||
m_srcDirTree->blockSignals( false );
|
||||
// fill the changes list
|
||||
dir->fillFileList( m_fileList, &m_modelToFileItemDict );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotFileListSelectionChanged( QTreeWidgetItem* item )
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
kDebug(8105) << "Sent by the fileList with item = " << item << endl;
|
||||
|
||||
KFileLVI* file = static_cast<KFileLVI*>(item);
|
||||
m_selectedModel = file->model();
|
||||
m_changesList->blockSignals( true );
|
||||
file->fillChangesList( m_changesList, &m_diffToChangeItemDict );
|
||||
m_changesList->blockSignals( false );
|
||||
|
||||
if ( m_changesList->currentItem() )
|
||||
{
|
||||
// FIXME: This is ugly...
|
||||
m_selectedDifference = (static_cast<KChangeLVI*>(m_changesList->currentItem()))->difference();
|
||||
}
|
||||
|
||||
emit selectionChanged( m_selectedModel, m_selectedDifference );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotChangesListSelectionChanged( QTreeWidgetItem* item )
|
||||
{
|
||||
if (!item)
|
||||
return;
|
||||
|
||||
kDebug(8105) << "Sent by the changesList" << endl;
|
||||
|
||||
KChangeLVI* change = static_cast<KChangeLVI*>(item);
|
||||
m_selectedDifference = change->difference();
|
||||
|
||||
emit selectionChanged( m_selectedDifference );
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotApplyDifference( bool /*apply*/ )
|
||||
{
|
||||
KChangeLVI* clvi = m_diffToChangeItemDict[m_selectedDifference];
|
||||
if ( clvi )
|
||||
clvi->setDifferenceText();
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotApplyAllDifferences( bool /*apply*/ )
|
||||
{
|
||||
QHash<const Diff2::Difference*, KChangeLVI*>::ConstIterator it = m_diffToChangeItemDict.constBegin();
|
||||
QHash<const Diff2::Difference*, KChangeLVI*>::ConstIterator end = m_diffToChangeItemDict.constEnd();
|
||||
|
||||
kDebug(8105) << "m_diffToChangeItemDict.count() = " << m_diffToChangeItemDict.count() << endl;
|
||||
|
||||
for ( ; it != end ; ++it )
|
||||
{
|
||||
it.value()->setDifferenceText();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareNavTreePart::slotApplyDifference( const Difference* diff, bool /*apply*/ )
|
||||
{
|
||||
// this applies to the currently selected difference
|
||||
KChangeLVI* clvi = m_diffToChangeItemDict[diff];
|
||||
if ( clvi )
|
||||
clvi->setDifferenceText();
|
||||
}
|
||||
|
||||
void KChangeLVI::setDifferenceText()
|
||||
{
|
||||
QString text;
|
||||
switch( m_difference->type() ) {
|
||||
case Difference::Change:
|
||||
// Shouldn't this simply be diff->sourceLineCount() ?
|
||||
// because you change the _number of lines_ lines in source, not in dest
|
||||
if( m_difference->applied() )
|
||||
text = i18np( "Applied: Changes made to %1 line undone", "Applied: Changes made to %1 lines undone",
|
||||
m_difference->sourceLineCount() );
|
||||
else
|
||||
text = i18np( "Changed %1 line", "Changed %1 lines",
|
||||
m_difference->sourceLineCount() );
|
||||
break;
|
||||
case Difference::Insert:
|
||||
if( m_difference->applied() )
|
||||
text = i18np( "Applied: Insertion of %1 line undone", "Applied: Insertion of %1 lines undone",
|
||||
m_difference->destinationLineCount() );
|
||||
else
|
||||
text = i18np( "Inserted %1 line", "Inserted %1 lines",
|
||||
m_difference->destinationLineCount() );
|
||||
break;
|
||||
case Difference::Delete:
|
||||
if( m_difference->applied() )
|
||||
text = i18np( "Applied: Deletion of %1 line undone", "Applied: Deletion of %1 lines undone",
|
||||
m_difference->sourceLineCount() );
|
||||
else
|
||||
text = i18np( "Deleted %1 line", "Deleted %1 lines",
|
||||
m_difference->sourceLineCount() );
|
||||
break;
|
||||
default:
|
||||
kDebug(8105) << "Unknown or Unchanged enum value when checking for diff->type() in KChangeLVI's constructor" << endl;
|
||||
text = "";
|
||||
}
|
||||
|
||||
setText( 2, text );
|
||||
}
|
||||
|
||||
KChangeLVI::KChangeLVI( QTreeWidget* parent, Difference* diff ) : QTreeWidgetItem( parent )
|
||||
{
|
||||
m_difference = diff;
|
||||
|
||||
setText( 0, QString::number( diff->sourceLineNumber() ) );
|
||||
setText( 1, QString::number( diff->destinationLineNumber() ) );
|
||||
|
||||
setDifferenceText();
|
||||
}
|
||||
|
||||
bool KChangeLVI::operator<( const QTreeWidgetItem& item ) const
|
||||
{
|
||||
int column = treeWidget()->sortColumn();
|
||||
QString text1 = text(column);
|
||||
QString text2 = item.text(column);
|
||||
|
||||
// Compare the numbers.
|
||||
if (column < 2 && text1.length() != text2.length())
|
||||
return text1.length() < text2.length();
|
||||
return text1 < text2;
|
||||
}
|
||||
|
||||
KChangeLVI::~KChangeLVI()
|
||||
{
|
||||
}
|
||||
|
||||
KFileLVI::KFileLVI( QTreeWidget* parent, DiffModel* model ) : QTreeWidgetItem( parent )
|
||||
{
|
||||
m_model = model;
|
||||
|
||||
QString src = model->sourceFile();
|
||||
QString dst = model->destinationFile();
|
||||
|
||||
setText( 0, src );
|
||||
setText( 1, dst );
|
||||
setIcon( 0, SmallIcon( getIcon( src ) ) );
|
||||
setIcon( 1, SmallIcon( getIcon( dst ) ) );
|
||||
}
|
||||
|
||||
bool KFileLVI::hasExtension(const QString& extensions, const QString& fileName)
|
||||
{
|
||||
QStringList extList = extensions.split(' ');
|
||||
foreach (const QString &ext, extList) {
|
||||
if ( fileName.endsWith(ext, Qt::CaseInsensitive) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString KFileLVI::getIcon(const QString& fileName)
|
||||
{
|
||||
// C++, C
|
||||
if ( hasExtension( ".h .hpp", fileName ) ) {
|
||||
return "text-x-c++hdr";
|
||||
}
|
||||
if ( hasExtension( ".cpp", fileName ) ) {
|
||||
return "text-x-c++src";
|
||||
}
|
||||
if ( hasExtension( ".c", fileName ) ) {
|
||||
return "text-x-csrc";
|
||||
}
|
||||
// Python
|
||||
if ( hasExtension( ".py .pyw", fileName ) ) {
|
||||
return "text-x-python";
|
||||
}
|
||||
// C#
|
||||
if ( hasExtension( ".cs", fileName ) ) {
|
||||
return "text-x-csharp";
|
||||
}
|
||||
// Objective-C
|
||||
if ( hasExtension( ".m", fileName ) ) {
|
||||
return "text-x-objcsrc";
|
||||
}
|
||||
// Java
|
||||
if ( hasExtension( ".java", fileName ) ) {
|
||||
return "text-x-java";
|
||||
}
|
||||
// Script
|
||||
if ( hasExtension( ".sh", fileName ) ) {
|
||||
return "text-x-script";
|
||||
}
|
||||
// Makefile
|
||||
if ( hasExtension( ".cmake Makefile", fileName ) ) {
|
||||
return "text-x-makefile";
|
||||
}
|
||||
// Ada
|
||||
if ( hasExtension( ".ada .ads .adb", fileName ) ) {
|
||||
return "text-x-adasrc";
|
||||
}
|
||||
// Pascal
|
||||
if ( hasExtension( ".pas", fileName ) ) {
|
||||
return "text-x-pascal";
|
||||
}
|
||||
// Patch
|
||||
if ( hasExtension( ".diff", fileName ) ) {
|
||||
return "text-x-patch";
|
||||
}
|
||||
// Tcl
|
||||
if ( hasExtension( ".tcl", fileName ) ) {
|
||||
return "text-x-tcl";
|
||||
}
|
||||
// Text
|
||||
if ( hasExtension( ".txt", fileName ) ) {
|
||||
return "text-plain";
|
||||
}
|
||||
// Xml
|
||||
if ( hasExtension( ".xml", fileName ) ) {
|
||||
return "text-xml";
|
||||
}
|
||||
// unknown or no file extension
|
||||
return "text-plain";
|
||||
}
|
||||
|
||||
void KFileLVI::fillChangesList( QTreeWidget* changesList, QHash<const Diff2::Difference*, KChangeLVI*>* diffToChangeItemDict )
|
||||
{
|
||||
changesList->clear();
|
||||
diffToChangeItemDict->clear();
|
||||
|
||||
DifferenceListConstIterator diffIt = m_model->differences()->constBegin();
|
||||
DifferenceListConstIterator dEnd = m_model->differences()->constEnd();
|
||||
|
||||
for ( ; diffIt != dEnd; ++diffIt )
|
||||
{
|
||||
KChangeLVI* change = new KChangeLVI( changesList, *diffIt );
|
||||
diffToChangeItemDict->insert( *diffIt, change );
|
||||
}
|
||||
|
||||
changesList->setCurrentItem( changesList->topLevelItem( 0 ) );
|
||||
}
|
||||
|
||||
KFileLVI::~KFileLVI()
|
||||
{
|
||||
}
|
||||
|
||||
KDirLVI::KDirLVI( QTreeWidget* parent, QString& dir ) : QTreeWidgetItem( parent )
|
||||
{
|
||||
// kDebug(8105) << "KDirLVI (QTreeWidget) constructor called with dir = " << dir << endl;
|
||||
m_rootItem = true;
|
||||
m_dirName = dir;
|
||||
setIcon( 0, SmallIcon( "folder" ) );
|
||||
setExpanded( true );
|
||||
if ( m_dirName.isEmpty() )
|
||||
setText( 0, i18n( "Unknown" ) );
|
||||
else
|
||||
setText( 0, m_dirName );
|
||||
}
|
||||
|
||||
KDirLVI::KDirLVI( KDirLVI* parent, QString& dir ) : QTreeWidgetItem( parent )
|
||||
{
|
||||
// kDebug(8105) << "KDirLVI (KDirLVI) constructor called with dir = " << dir << endl;
|
||||
m_rootItem = false;
|
||||
m_dirName = dir;
|
||||
setIcon( 0, SmallIcon( "folder" ) );
|
||||
setExpanded( true );
|
||||
setText( 0, m_dirName );
|
||||
}
|
||||
|
||||
// addModel always removes it own path from the beginning
|
||||
void KDirLVI::addModel( QString& path, DiffModel* model, QHash<const Diff2::DiffModel*, KDirLVI*>* modelToDirItemDict )
|
||||
{
|
||||
// kDebug(8105) << "KDirLVI::addModel called with path = " << path << " from KDirLVI with m_dirName = " << m_dirName << endl;
|
||||
|
||||
if ( !m_dirName.isEmpty() )
|
||||
{
|
||||
if ( path.indexOf( m_dirName ) > -1 )
|
||||
path = path.remove( path.indexOf( m_dirName ), m_dirName.length() );
|
||||
}
|
||||
|
||||
// kDebug(8105) << "Path after removal of own dir (\"" << m_dirName << "\") = " << path << endl;
|
||||
|
||||
if ( path.isEmpty() ) {
|
||||
m_modelList.append( model );
|
||||
modelToDirItemDict->insert( model, this );
|
||||
return;
|
||||
}
|
||||
|
||||
KDirLVI* child;
|
||||
|
||||
QString dir = path.mid( 0, path.indexOf( "/", 0 ) + 1 );
|
||||
child = findChild( dir );
|
||||
if ( !child )
|
||||
{
|
||||
// does not exist yet so make it
|
||||
// kDebug(8105) << "KDirLVI::addModel creating new KDirLVI because not found" << endl;
|
||||
child = new KDirLVI( this, dir );
|
||||
}
|
||||
|
||||
child->addModel( path, model, modelToDirItemDict );
|
||||
}
|
||||
|
||||
KDirLVI* KDirLVI::findChild( QString dir )
|
||||
{
|
||||
// kDebug(8105) << "KDirLVI::findChild called with dir = " << dir << endl;
|
||||
KDirLVI* child;
|
||||
if ( ( child = static_cast<KDirLVI*>(this->child(0)) ) != 0L )
|
||||
{ // has children, check if dir already exists, if so addModel
|
||||
QTreeWidgetItemIterator it(child);
|
||||
while (*it) {
|
||||
child = static_cast<KDirLVI*>(*it);
|
||||
|
||||
if ( dir == child->dirName() )
|
||||
return child;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
void KDirLVI::fillFileList( QTreeWidget* fileList, QHash<const Diff2::DiffModel*, KFileLVI*>* modelToFileItemDict )
|
||||
{
|
||||
fileList->clear();
|
||||
|
||||
DiffModelListIterator modelIt = m_modelList.begin();
|
||||
DiffModelListIterator mEnd = m_modelList.end();
|
||||
for ( ;modelIt != mEnd; ++modelIt )
|
||||
{
|
||||
KFileLVI* file = new KFileLVI( fileList, *modelIt );
|
||||
modelToFileItemDict->insert( *modelIt, file );
|
||||
}
|
||||
|
||||
fileList->setCurrentItem( fileList->topLevelItem( 0 ) );
|
||||
}
|
||||
|
||||
QString KDirLVI::fullPath( QString& path )
|
||||
{
|
||||
// if ( !path.isEmpty() )
|
||||
// kDebug(8105) << "KDirLVI::fullPath called with path = " << path << endl;
|
||||
// else
|
||||
// kDebug(8105) << "KDirLVI::fullPath called with empty path..." << endl;
|
||||
|
||||
if ( m_rootItem ) // don't bother adding rootItem's dir...
|
||||
return path;
|
||||
|
||||
path = path.prepend( m_dirName );
|
||||
|
||||
KDirLVI* lviParent = dynamic_cast<KDirLVI*>( parent() );
|
||||
if ( lviParent )
|
||||
{
|
||||
path = lviParent->fullPath( path );
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
KDirLVI* KDirLVI::setSelected( QString dir )
|
||||
{
|
||||
// kDebug(8105) << "KDirLVI::setSelected called with dir = " << dir << endl;
|
||||
|
||||
// root item's dirName is never taken into account... remember that
|
||||
if ( !m_rootItem )
|
||||
{
|
||||
dir = dir.remove( 0, m_dirName.length() );
|
||||
}
|
||||
|
||||
if ( dir.isEmpty() )
|
||||
{
|
||||
return this;
|
||||
}
|
||||
KDirLVI* child = static_cast<KDirLVI*>(this->child(0));
|
||||
if ( !child )
|
||||
return 0L;
|
||||
|
||||
QTreeWidgetItemIterator it(child);
|
||||
while (*it) {
|
||||
child = static_cast<KDirLVI*>(*it);
|
||||
|
||||
if ( dir.startsWith( child->dirName() ) )
|
||||
return child->setSelected( dir );
|
||||
++it;
|
||||
}
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
KDirLVI::~KDirLVI()
|
||||
{
|
||||
m_modelList.clear();
|
||||
}
|
||||
|
||||
static KAboutData aboutData()
|
||||
{
|
||||
KAboutData about("komparenavtreepart", 0, ki18n("KompareNavTreePart"), "1.2");
|
||||
about.addAuthor(ki18n("John Firebaugh"), ki18n("Author"), "jfirebaugh@kde.org");
|
||||
about.addAuthor(ki18n("Otto Bruggeman"), ki18n("Author"), "bruggie@gmail.com" );
|
||||
return about;
|
||||
}
|
||||
|
||||
K_PLUGIN_FACTORY(KompareNavTreePartFactory,
|
||||
registerPlugin<KompareNavTreePart>();
|
||||
)
|
||||
K_EXPORT_PLUGIN( KompareNavTreePartFactory(aboutData()) )
|
||||
|
||||
#include "komparenavtreepart.moc"
|
67
kompare/komparenavtreepart/komparenavtreepart.desktop
Normal file
|
@ -0,0 +1,67 @@
|
|||
[Desktop Entry]
|
||||
Name=KompareNavTreePart
|
||||
Name[ast]=KompareNavTreePart
|
||||
Name[bg]=KompareNavTreePart
|
||||
Name[br]=KompareNavTreePart
|
||||
Name[bs]=KompareNavTreePart
|
||||
Name[ca]=KompareNavTreePart
|
||||
Name[ca@valencia]=KompareNavTreePart
|
||||
Name[cs]=KompareNavTreePart
|
||||
Name[cy]=KompareNavTreePart
|
||||
Name[da]=KompareNavTreePart
|
||||
Name[de]=KompareNavTreePart
|
||||
Name[el]=KompareNavTreePart
|
||||
Name[en_GB]=KompareNavTreePart
|
||||
Name[es]=KompareNavTreePart
|
||||
Name[et]=KompareNavTreePart
|
||||
Name[eu]=KompareNavTreePart
|
||||
Name[fi]=KompareNavTreePart
|
||||
Name[fr]=Composant de KompareNavTree
|
||||
Name[ga]=KompareNavTreePart
|
||||
Name[gl]=KompareNavTreePart
|
||||
Name[he]=KompareNavTreePart
|
||||
Name[hr]=KompareNavTreePart
|
||||
Name[hu]=KompareNavTreePart
|
||||
Name[is]=KompareNavTreePart
|
||||
Name[it]=KompareNavTreePart
|
||||
Name[ja]=KompareNavTreePart
|
||||
Name[kk]=KompareNavTreePart
|
||||
Name[km]=KompareNavTreePart
|
||||
Name[ko]=KompareNavTreePart
|
||||
Name[lt]=KompareNavTreePart
|
||||
Name[lv]=KompareNavTreePart
|
||||
Name[mr]=कंपेअर-नेव्ह-ट्री-पार्ट
|
||||
Name[ms]=KompareNavTreePart
|
||||
Name[nb]=KompareNavTreePart
|
||||
Name[nds]=KompareNavTreePart
|
||||
Name[ne]=KompareNavTreePart
|
||||
Name[nl]=KompareNavTreePart
|
||||
Name[nn]=KompareNavTreePart
|
||||
Name[pa]=KompareNavTreePart
|
||||
Name[pl]=Komponent drzewa nawigacyjnego Kompare
|
||||
Name[pt]=KompareNavTreePart
|
||||
Name[pt_BR]=KompareNavTreePart
|
||||
Name[ro]=KompareNavTreePart
|
||||
Name[ru]=KompareNavTreePart
|
||||
Name[sk]=KompareNavTreePart
|
||||
Name[sl]=KompareNavTreePart
|
||||
Name[sq]=KompareNavTreePart
|
||||
Name[sr]=KompareNavTreePart
|
||||
Name[sr@ijekavian]=KompareNavTreePart
|
||||
Name[sr@ijekavianlatin]=KompareNavTreePart
|
||||
Name[sr@latin]=KompareNavTreePart
|
||||
Name[sv]=Kompare-navigeringsträdsdel
|
||||
Name[ta]=கோம்பெர் மரம் பாகம்
|
||||
Name[tg]=KompareNavTreePart
|
||||
Name[tr]=KompareNavTreePart
|
||||
Name[ug]=KompareNavTreePart
|
||||
Name[uk]=KompareNavTreePart
|
||||
Name[xh]=KompareNavTreePart
|
||||
Name[x-test]=xxKompareNavTreePartxx
|
||||
Name[zh_CN]=KompareNavTreePart
|
||||
Name[zh_TW]=KompareNavTreePart
|
||||
MimeType=text/x-patch;
|
||||
ServiceTypes=Kompare/NavigationPart
|
||||
X-KDE-Library=komparenavtreepart
|
||||
Type=Service
|
||||
Icon=kompare
|
169
kompare/komparenavtreepart/komparenavtreepart.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
/***************************************************************************
|
||||
komparenavtreepart.h
|
||||
--------------------
|
||||
begin : Mon Feb 26 2002
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARENAVTREEPART_H
|
||||
#define KOMPARENAVTREEPART_H
|
||||
|
||||
#include <QtCore/QHash>
|
||||
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QTreeWidget>
|
||||
#include <QtGui/QTreeWidgetItem>
|
||||
|
||||
#include <kparts/part.h>
|
||||
#include <kompare.h>
|
||||
#include <diffmodellist.h>
|
||||
|
||||
namespace Diff2 {
|
||||
class DiffModel;
|
||||
class Difference;
|
||||
}
|
||||
|
||||
class KDirLVI;
|
||||
class KFileLVI;
|
||||
class KChangeLVI;
|
||||
|
||||
class KompareNavTreePart : public KParts::ReadOnlyPart
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KompareNavTreePart( QWidget* parentWidget, QObject* parent, const QVariantList& args );
|
||||
virtual ~KompareNavTreePart();
|
||||
|
||||
public:
|
||||
virtual bool openFile() { return false; };
|
||||
|
||||
public slots:
|
||||
void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void slotSetSelection( const Diff2::Difference* diff );
|
||||
void slotModelsChanged( const Diff2::DiffModelList* modelList );
|
||||
void slotKompareInfo( Kompare::Info* info );
|
||||
|
||||
signals:
|
||||
void selectionChanged( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void selectionChanged( const Diff2::Difference* diff );
|
||||
|
||||
private slots:
|
||||
void slotSrcDirTreeSelectionChanged ( QTreeWidgetItem* item );
|
||||
void slotDestDirTreeSelectionChanged( QTreeWidgetItem* item );
|
||||
void slotFileListSelectionChanged ( QTreeWidgetItem* item );
|
||||
void slotChangesListSelectionChanged( QTreeWidgetItem* item );
|
||||
|
||||
void slotApplyDifference( bool apply );
|
||||
void slotApplyAllDifferences( bool apply );
|
||||
void slotApplyDifference( const Diff2::Difference* diff, bool apply );
|
||||
|
||||
void buildTreeInMemory();
|
||||
|
||||
private:
|
||||
void setSelectedDir( const Diff2::DiffModel* model );
|
||||
void setSelectedFile( const Diff2::DiffModel* model );
|
||||
void setSelectedDifference( const Diff2::Difference* diff );
|
||||
|
||||
void buildDirectoryTree();
|
||||
|
||||
QString compareFromEndAndReturnSame( const QString& string1, const QString& string2 );
|
||||
void addDirToTreeView( enum Kompare::Target, const QString& filename );
|
||||
|
||||
QTreeWidgetItem* findDirInDirTree( const QTreeWidgetItem* parent, const QString& dir );
|
||||
|
||||
private:
|
||||
QSplitter* m_splitter;
|
||||
const Diff2::DiffModelList* m_modelList;
|
||||
|
||||
QHash<const Diff2::Difference*, KChangeLVI*> m_diffToChangeItemDict;
|
||||
QHash<const Diff2::DiffModel*, KFileLVI*> m_modelToFileItemDict;
|
||||
QHash<const Diff2::DiffModel*, KDirLVI*> m_modelToSrcDirItemDict;
|
||||
QHash<const Diff2::DiffModel*, KDirLVI*> m_modelToDestDirItemDict;
|
||||
|
||||
QTreeWidget* m_srcDirTree;
|
||||
QTreeWidget* m_destDirTree;
|
||||
QTreeWidget* m_fileList;
|
||||
QTreeWidget* m_changesList;
|
||||
|
||||
KDirLVI* m_srcRootItem;
|
||||
KDirLVI* m_destRootItem;
|
||||
|
||||
const Diff2::DiffModel* m_selectedModel;
|
||||
const Diff2::Difference* m_selectedDifference;
|
||||
|
||||
QString m_source;
|
||||
QString m_destination;
|
||||
|
||||
struct Kompare::Info* m_info;
|
||||
};
|
||||
|
||||
// These 3 classes are need to store the models into a tree so it is easier
|
||||
// to extract the info we need for the navigation widgets
|
||||
|
||||
class KChangeLVI : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
KChangeLVI( QTreeWidget* parent, Diff2::Difference* diff );
|
||||
~KChangeLVI();
|
||||
public:
|
||||
Diff2::Difference* difference() { return m_difference; };
|
||||
virtual bool operator<( const QTreeWidgetItem& item ) const;
|
||||
|
||||
void setDifferenceText();
|
||||
private:
|
||||
Diff2::Difference* m_difference;
|
||||
};
|
||||
|
||||
class KFileLVI : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
KFileLVI( QTreeWidget* parent, Diff2::DiffModel* model );
|
||||
~KFileLVI();
|
||||
public:
|
||||
Diff2::DiffModel* model() { return m_model; };
|
||||
void fillChangesList( QTreeWidget* changesList, QHash<const Diff2::Difference*, KChangeLVI*>* diffToChangeItemDict );
|
||||
private:
|
||||
bool hasExtension(const QString& extensions, const QString& fileName);
|
||||
const QString getIcon(const QString& fileName);
|
||||
private:
|
||||
Diff2::DiffModel* m_model;
|
||||
};
|
||||
|
||||
class KDirLVI : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
KDirLVI( KDirLVI* parent, QString& dir );
|
||||
KDirLVI( QTreeWidget* parent, QString& dir );
|
||||
~KDirLVI();
|
||||
public:
|
||||
void addModel( QString& dir, Diff2::DiffModel* model, QHash<const Diff2::DiffModel*, KDirLVI*>* modelToDirItemDict );
|
||||
QString& dirName() { return m_dirName; };
|
||||
QString fullPath( QString& path );
|
||||
|
||||
KDirLVI* setSelected( QString dir );
|
||||
void setSelected( bool selected ) { QTreeWidgetItem::setSelected( selected ); }
|
||||
|
||||
void fillFileList( QTreeWidget* fileList, QHash<const Diff2::DiffModel*, KFileLVI*>* modelToFileItemDict );
|
||||
bool isRootItem() { return m_rootItem; };
|
||||
|
||||
private:
|
||||
KDirLVI* findChild( QString dir );
|
||||
private:
|
||||
Diff2::DiffModelList m_modelList;
|
||||
QString m_dirName;
|
||||
bool m_rootItem;
|
||||
};
|
||||
|
||||
#endif
|
85
kompare/komparepart/CMakeLists.txt
Normal file
|
@ -0,0 +1,85 @@
|
|||
|
||||
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../libdialogpages ${CMAKE_CURRENT_SOURCE_DIR}/../interfaces )
|
||||
|
||||
|
||||
########### next target ###############
|
||||
|
||||
set( komparepart_PART_SRCS
|
||||
kompare_part.cpp
|
||||
kompareconnectwidget.cpp
|
||||
komparesplitter.cpp
|
||||
komparelistview.cpp
|
||||
kompareprefdlg.cpp
|
||||
komparesaveoptionsbase.cpp
|
||||
komparesaveoptionswidget.cpp
|
||||
kompareview.cpp )
|
||||
|
||||
|
||||
kde4_add_ui_files(komparepart_PART_SRCS komparesaveoptionsbase.ui )
|
||||
|
||||
kde4_add_plugin(komparepart ${komparepart_PART_SRCS})
|
||||
|
||||
|
||||
|
||||
target_link_libraries(komparepart ${KDE4_KPARTS_LIBS} komparedialogpages ${LIBKOMPAREDIFF2_LIBRARIES} kompareinterface )
|
||||
|
||||
install(TARGETS komparepart DESTINATION ${PLUGIN_INSTALL_DIR} )
|
||||
|
||||
|
||||
########### install files ###############
|
||||
|
||||
install( FILES komparepart.desktop DESTINATION ${SERVICES_INSTALL_DIR} )
|
||||
install( FILES komparepartui.rc DESTINATION ${DATA_INSTALL_DIR}/kompare )
|
||||
|
||||
|
||||
|
||||
|
||||
#original Makefile.am contents follow:
|
||||
|
||||
##########################################################################
|
||||
## KPART SECTION
|
||||
##########################################################################
|
||||
#
|
||||
#INCLUDES = \
|
||||
# -I$(top_srcdir)/kompare/libdialogpages \
|
||||
# -I$(top_srcdir)/kompare/interfaces \
|
||||
# $(all_includes)
|
||||
#
|
||||
#noinst_HEADERS = \
|
||||
# kompare_part.h \
|
||||
# komparesplitter.h \
|
||||
# kompareprefdlg.h \
|
||||
# komparelistview.h \
|
||||
# kompareconnectwidget.h \
|
||||
# komparesaveoptionsbase.h \
|
||||
# komparesaveoptionswidget.h \
|
||||
# kompare_qsplitter.h
|
||||
#
|
||||
## let automoc handle all of the meta source files (moc)
|
||||
#METASOURCES = AUTO
|
||||
#
|
||||
#kde_module_LTLIBRARIES = libkomparepart.la
|
||||
#
|
||||
## the Part's source, library search path, and link libraries
|
||||
#libkomparepart_la_SOURCES = \
|
||||
# kompare_part.cpp \
|
||||
# kompareconnectwidget.cpp \
|
||||
# komparesplitter.cpp \
|
||||
# komparelistview.cpp \
|
||||
# kompareprefdlg.cpp \
|
||||
# komparesaveoptionsbase.ui \
|
||||
# komparesaveoptionswidget.cpp
|
||||
#
|
||||
#libkomparepart_la_LDFLAGS = $(KDE_PLUGIN) $(all_libraries)
|
||||
#libkomparepart_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE) \
|
||||
# ../libdialogpages/libdialogpages.la \
|
||||
# ../interfaces/libkompareinterface.la
|
||||
#
|
||||
## this is where the desktop file will go
|
||||
#partdesktopdir = $(kde_servicesdir)
|
||||
#partdesktop_DATA = komparepart.desktop
|
||||
#
|
||||
## this is where the part's XML-GUI resource file goes
|
||||
#partrcdir = $(kde_datadir)/kompare
|
||||
#partrc_DATA = komparepartui.rc
|
||||
#
|
956
kompare/komparepart/kompare_part.cpp
Normal file
|
@ -0,0 +1,956 @@
|
|||
/***************************************************************************
|
||||
kompare_part.cpp
|
||||
----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2005,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
Copyright 2012 Jean-Nicolas Artaud <jeannicolasartaud@gmail.com>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "kompare_part.h"
|
||||
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QWidget>
|
||||
#include <QPainter>
|
||||
#include <QPrinter>
|
||||
#include <QPrintDialog>
|
||||
#include <QPrintPreviewDialog>
|
||||
|
||||
#include <kaboutdata.h>
|
||||
#include <kaction.h>
|
||||
#include <kactioncollection.h>
|
||||
#include <kapplication.h>
|
||||
#include <kcomponentdata.h>
|
||||
#include <kdebug.h>
|
||||
#include <kdeprintdialog.h>
|
||||
#include <kfiledialog.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kstandardaction.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <kstandardshortcut.h>
|
||||
#include <ktemporaryfile.h>
|
||||
#include <ktempdir.h>
|
||||
|
||||
#include <kio/netaccess.h>
|
||||
#include <kglobal.h>
|
||||
|
||||
#include "diffmodel.h"
|
||||
#include "komparelistview.h"
|
||||
#include "kompareconnectwidget.h"
|
||||
#include "diffsettings.h"
|
||||
#include "viewsettings.h"
|
||||
#include "kompareprefdlg.h"
|
||||
#include "komparesaveoptionswidget.h"
|
||||
#include "komparesplitter.h"
|
||||
#include "kompareview.h"
|
||||
|
||||
K_PLUGIN_FACTORY( KomparePartFactory, registerPlugin<KomparePart>(); )
|
||||
K_EXPORT_PLUGIN( KomparePartFactory )
|
||||
|
||||
ViewSettings* KomparePart::m_viewSettings = 0L;
|
||||
DiffSettings* KomparePart::m_diffSettings = 0L;
|
||||
|
||||
KomparePart::KomparePart( QWidget *parentWidget, QObject *parent, const QVariantList & /*args*/ ) :
|
||||
KParts::ReadWritePart(parent),
|
||||
m_tempDiff( 0 ),
|
||||
m_info()
|
||||
{
|
||||
if( !m_viewSettings ) {
|
||||
m_viewSettings = new ViewSettings( 0 );
|
||||
}
|
||||
if( !m_diffSettings ) {
|
||||
m_diffSettings = new DiffSettings( 0 );
|
||||
}
|
||||
|
||||
readProperties( KGlobal::config().data() );
|
||||
|
||||
m_view = new KompareView ( m_viewSettings, parentWidget );
|
||||
setWidget( m_view );
|
||||
m_splitter = m_view->splitter();
|
||||
|
||||
// This creates the "Model creator" and connects the signals and slots
|
||||
m_modelList = new Diff2::KompareModelList( m_diffSettings, m_splitter, this, "komparemodellist" , KParts::ReadWritePart::isReadWrite());
|
||||
|
||||
Q_FOREACH(QAction* action, m_modelList->actionCollection()->actions())
|
||||
{
|
||||
actionCollection()->addAction(action->objectName(), action);
|
||||
}
|
||||
connect( m_modelList, SIGNAL(status( Kompare::Status )),
|
||||
this, SLOT(slotSetStatus( Kompare::Status )) );
|
||||
connect( m_modelList, SIGNAL(setStatusBarModelInfo( int, int, int, int, int )),
|
||||
this, SIGNAL(setStatusBarModelInfo( int, int, int, int, int )) );
|
||||
connect( m_modelList, SIGNAL(error( QString )),
|
||||
this, SLOT(slotShowError( QString )) );
|
||||
connect( m_modelList, SIGNAL(applyAllDifferences( bool )),
|
||||
this, SLOT(updateActions()) );
|
||||
connect( m_modelList, SIGNAL(applyDifference( bool )),
|
||||
this, SLOT(updateActions()) );
|
||||
connect( m_modelList, SIGNAL(applyAllDifferences( bool )),
|
||||
this, SIGNAL(appliedChanged()) );
|
||||
connect( m_modelList, SIGNAL(applyDifference( bool )),
|
||||
this, SIGNAL(appliedChanged()) );
|
||||
connect( m_modelList, SIGNAL(updateActions()), this, SLOT(updateActions()) );
|
||||
|
||||
// This is the stuff to connect the "interface" of the kompare part to the model inside
|
||||
connect( m_modelList, SIGNAL(modelsChanged(const Diff2::DiffModelList*)),
|
||||
this, SIGNAL(modelsChanged(const Diff2::DiffModelList*)) );
|
||||
|
||||
connect( m_modelList, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)),
|
||||
this, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)) );
|
||||
connect( this, SIGNAL(selectionChanged(const Diff2::DiffModel*, const Diff2::Difference*)),
|
||||
m_modelList, SLOT(slotSelectionChanged(const Diff2::DiffModel*, const Diff2::Difference*)) );
|
||||
|
||||
connect( m_modelList, SIGNAL(setSelection(const Diff2::Difference*)),
|
||||
this, SIGNAL(setSelection(const Diff2::Difference*)) );
|
||||
connect( this, SIGNAL(selectionChanged(const Diff2::Difference*)),
|
||||
m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*)) );
|
||||
|
||||
connect( m_modelList, SIGNAL(applyDifference(bool)),
|
||||
this, SIGNAL(applyDifference(bool)) );
|
||||
connect( m_modelList, SIGNAL(applyAllDifferences(bool)),
|
||||
this, SIGNAL(applyAllDifferences(bool)) );
|
||||
connect( m_modelList, SIGNAL(applyDifference(const Diff2::Difference*, bool)),
|
||||
this, SIGNAL(applyDifference(const Diff2::Difference*, bool)) );
|
||||
connect( m_modelList, SIGNAL(diffString(const QString&)),
|
||||
this, SIGNAL(diffString(const QString&)) );
|
||||
|
||||
connect( this, SIGNAL(kompareInfo(Kompare::Info*)), m_modelList, SLOT(slotKompareInfo(Kompare::Info*)) );
|
||||
|
||||
// Here we connect the splitter to the modellist
|
||||
connect( m_modelList, SIGNAL(setSelection(const Diff2::DiffModel*, const Diff2::Difference*)),
|
||||
m_splitter, SLOT(slotSetSelection(const Diff2::DiffModel*, const Diff2::Difference*)) );
|
||||
// connect( m_splitter, SIGNAL(selectionChanged(const Diff2::Difference*, const Diff2::Difference*)),
|
||||
// m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*, const Diff2::Difference*)) );
|
||||
connect( m_modelList, SIGNAL(setSelection(const Diff2::Difference*)),
|
||||
m_splitter, SLOT(slotSetSelection(const Diff2::Difference*)) );
|
||||
connect( m_splitter, SIGNAL(selectionChanged(const Diff2::Difference*)),
|
||||
m_modelList, SLOT(slotSelectionChanged(const Diff2::Difference*)) );
|
||||
|
||||
connect( m_modelList, SIGNAL(applyDifference(bool)),
|
||||
m_splitter, SLOT(slotApplyDifference(bool)) );
|
||||
connect( m_modelList, SIGNAL(applyAllDifferences(bool)),
|
||||
m_splitter, SLOT(slotApplyAllDifferences(bool)) );
|
||||
connect( m_modelList, SIGNAL(applyDifference(const Diff2::Difference*, bool)),
|
||||
m_splitter, SLOT(slotApplyDifference(const Diff2::Difference*, bool)) );
|
||||
connect( this, SIGNAL(configChanged()), m_splitter, SIGNAL(configChanged()) );
|
||||
|
||||
setupActions();
|
||||
|
||||
// set our XML-UI resource file
|
||||
setXMLFile( "komparepartui.rc" );
|
||||
|
||||
// we are read-write by default -> uhm what if we are opened by lets say konq in RO mode ?
|
||||
// Then we should not be doing this...
|
||||
setReadWrite( true );
|
||||
|
||||
// we are not modified since we haven't done anything yet
|
||||
setModified( false );
|
||||
}
|
||||
|
||||
KomparePart::~KomparePart()
|
||||
{
|
||||
// This is the only place allowed to call cleanUpTemporaryFiles
|
||||
// because before there might still be a use for them (when swapping)
|
||||
cleanUpTemporaryFiles();
|
||||
}
|
||||
|
||||
void KomparePart::setupActions()
|
||||
{
|
||||
// create our actions
|
||||
|
||||
m_saveAll = actionCollection()->addAction("file_save_all", this, SLOT(saveAll()));
|
||||
m_saveAll->setIcon(KIcon("document-save-all"));
|
||||
m_saveAll->setText(i18n("Save &All"));
|
||||
m_saveDiff = actionCollection()->addAction("file_save_diff", this, SLOT(saveDiff()));
|
||||
m_saveDiff->setText(i18n("Save &Diff..."));
|
||||
m_swap = actionCollection()->addAction("file_swap", this, SLOT(slotSwap()));
|
||||
m_swap->setText(i18n("Swap Source with Destination"));
|
||||
m_diffStats = actionCollection()->addAction("file_diffstats", this, SLOT(slotShowDiffstats()));
|
||||
m_diffStats->setText(i18n("Show Statistics"));
|
||||
m_diffRefresh = actionCollection()->addAction("file_refreshdiff", this, SLOT(slotRefreshDiff()));
|
||||
m_diffRefresh->setIcon(KIcon("view-refresh"));
|
||||
m_diffRefresh->setText(i18n("Refresh Diff"));
|
||||
m_diffRefresh->setShortcut(KStandardShortcut::reload());
|
||||
|
||||
m_print = actionCollection()->addAction(KStandardAction::Print, this, SLOT( slotFilePrint() ));
|
||||
m_printPreview = actionCollection()->addAction(KStandardAction::PrintPreview, this, SLOT( slotFilePrintPreview() ));
|
||||
KStandardAction::preferences(this, SLOT(optionsPreferences()), actionCollection());
|
||||
}
|
||||
|
||||
void KomparePart::updateActions()
|
||||
{
|
||||
m_saveAll->setEnabled ( m_modelList->hasUnsavedChanges() );
|
||||
m_saveDiff->setEnabled ( m_modelList->mode() == Kompare::ComparingFiles || m_modelList->mode() == Kompare::ComparingDirs );
|
||||
m_swap->setEnabled ( m_modelList->mode() == Kompare::ComparingFiles || m_modelList->mode() == Kompare::ComparingDirs );
|
||||
m_diffRefresh->setEnabled ( m_modelList->mode() == Kompare::ComparingFiles || m_modelList->mode() == Kompare::ComparingDirs );
|
||||
m_diffStats->setEnabled ( m_modelList->modelCount() > 0 );
|
||||
m_print->setEnabled ( m_modelList->modelCount() > 0 ); // If modellist has models then we have something to print, it's that simple.
|
||||
m_printPreview->setEnabled( m_modelList );
|
||||
}
|
||||
|
||||
void KomparePart::setEncoding( const QString& encoding )
|
||||
{
|
||||
kDebug(8103) << "Encoding: " << encoding << endl;
|
||||
m_modelList->setEncoding( encoding );
|
||||
}
|
||||
|
||||
bool KomparePart::openDiff( const KUrl& url )
|
||||
{
|
||||
kDebug(8103) << "Url = " << url.url() << endl;
|
||||
|
||||
m_info.mode = Kompare::ShowingDiff;
|
||||
m_info.source = url;
|
||||
bool result = false;
|
||||
fetchURL( url, true );
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
if ( !m_info.localSource.isEmpty() )
|
||||
{
|
||||
kDebug(8103) << "Download succeeded " << endl;
|
||||
result = m_modelList->openDiff( m_info.localSource );
|
||||
updateActions();
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
}
|
||||
else
|
||||
{
|
||||
kDebug(8103) << "Download failed !" << endl;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool KomparePart::openDiff( const QString& diffOutput )
|
||||
{
|
||||
bool value = false;
|
||||
|
||||
m_info.mode = Kompare::ShowingDiff;
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
if ( m_modelList->parseAndOpenDiff( diffOutput ) == 0 )
|
||||
{
|
||||
value = true;
|
||||
updateActions();
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
bool KomparePart::openDiff3( const KUrl& diff3Url )
|
||||
{
|
||||
// FIXME: Implement this !!!
|
||||
kDebug(8103) << "Not implemented yet. Filename is: " << diff3Url.prettyUrl() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KomparePart::openDiff3( const QString& diff3Output )
|
||||
{
|
||||
// FIXME: Implement this !!!
|
||||
kDebug(8103) << "Not implemented yet. diff3 output is: " << endl;
|
||||
kDebug(8103) << diff3Output << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool KomparePart::exists( const QString& url )
|
||||
{
|
||||
QFileInfo fi( url );
|
||||
return fi.exists();
|
||||
}
|
||||
|
||||
bool KomparePart::fetchURL( const KUrl& url, bool addToSource )
|
||||
{
|
||||
// Default value if there is an error is "", we rely on it!
|
||||
QString tempFileName( "" );
|
||||
// Only in case of error do we set result to false, don't forget!!
|
||||
bool result = true;
|
||||
KTempDir* tmpDir = 0;
|
||||
|
||||
if ( !url.isLocalFile() )
|
||||
{
|
||||
KIO::UDSEntry node;
|
||||
KIO::NetAccess::stat( url, node, widget() );
|
||||
if ( !node.isDir() )
|
||||
{
|
||||
if ( ! KIO::NetAccess::download( url, tempFileName, widget() ) )
|
||||
{
|
||||
slotShowError( i18n( "<qt>The URL <b>%1</b> cannot be downloaded.</qt>", url.prettyUrl() ) );
|
||||
tempFileName = ""; // Not sure if download has already touched this tempFileName when there is an error
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tmpDir = new KTempDir(KStandardDirs::locateLocal("tmp", "kompare"));
|
||||
tmpDir->setAutoRemove( true ); // Yes this is the default but just to make sure
|
||||
if ( ! KIO::NetAccess::dircopy( url, KUrl( tmpDir->name() ), widget() ) )
|
||||
{
|
||||
slotShowError( i18n( "<qt>The URL <b>%1</b> cannot be downloaded.</qt>", url.prettyUrl() ) );
|
||||
delete tmpDir;
|
||||
tmpDir = 0;
|
||||
result = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
tempFileName = tmpDir->name();
|
||||
kDebug(8101) << "tempFileName = " << tempFileName << endl;
|
||||
// If a directory is copied into KTempDir then the directory in
|
||||
// here is what I need to add to tempFileName
|
||||
QDir dir( tempFileName );
|
||||
QStringList entries = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
|
||||
if ( entries.size() == 1 ) // More than 1 entry in here means big problems!!!
|
||||
{
|
||||
if ( !tempFileName.endsWith( '/' ) )
|
||||
tempFileName += '/';
|
||||
tempFileName += entries.at( 0 );
|
||||
tempFileName += '/';
|
||||
}
|
||||
else
|
||||
{
|
||||
kDebug(8101) << "Yikes, nothing downloaded?" << endl;
|
||||
delete tmpDir;
|
||||
tmpDir = 0;
|
||||
tempFileName = "";
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// is Local already, check if exists
|
||||
if ( exists( url.toLocalFile() ) )
|
||||
tempFileName = url.toLocalFile();
|
||||
else
|
||||
{
|
||||
slotShowError( i18n( "<qt>The URL <b>%1</b> does not exist on your system.</qt>", url.prettyUrl() ) );
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( addToSource )
|
||||
{
|
||||
m_info.localSource = tempFileName;
|
||||
m_info.sourceKTempDir = tmpDir;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_info.localDestination = tempFileName;
|
||||
m_info.destinationKTempDir = tmpDir;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void KomparePart::cleanUpTemporaryFiles()
|
||||
{
|
||||
kDebug(8101) << "Cleaning temporary files." << endl;
|
||||
if ( !m_info.localSource.isEmpty() )
|
||||
{
|
||||
if ( m_info.sourceKTempDir == 0 )
|
||||
KIO::NetAccess::removeTempFile( m_info.localSource );
|
||||
else
|
||||
{
|
||||
delete m_info.sourceKTempDir;
|
||||
m_info.sourceKTempDir = 0;
|
||||
}
|
||||
m_info.localSource = "";
|
||||
}
|
||||
if ( !m_info.localDestination.isEmpty() )
|
||||
{
|
||||
if ( m_info.destinationKTempDir == 0 )
|
||||
KIO::NetAccess::removeTempFile( m_info.localDestination );
|
||||
else
|
||||
{
|
||||
delete m_info.destinationKTempDir;
|
||||
m_info.destinationKTempDir = 0;
|
||||
}
|
||||
m_info.localDestination = "";
|
||||
}
|
||||
}
|
||||
|
||||
void KomparePart::compare( const KUrl& source, const KUrl& destination )
|
||||
{
|
||||
// FIXME: This is silly, i can use NetAccess::stat to figure out what it is and not
|
||||
// wait until i am in the modellist to determine the mode we're supposed to be in.
|
||||
// That should make the code more readable
|
||||
// I should store the KTempDir(s)/File(s) in the Info struct as well and delete it at the right time
|
||||
m_info.source = source;
|
||||
m_info.destination = destination;
|
||||
|
||||
// FIXME: (Not urgent) But turn this into an enum, for now i cant find a nice name for the enum that has Source and Destination as values
|
||||
// For now we do not do error checking, user has already been notified and if the localString is empty then we dont diff
|
||||
fetchURL( source, true );
|
||||
fetchURL( destination, false );
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::compareFileString( const KUrl & sourceFile, const QString & destination)
|
||||
{
|
||||
//Set the modeto specify that the source is a file, and the destination is a string
|
||||
m_info.mode = Kompare::ComparingFileString;
|
||||
|
||||
m_info.source = sourceFile;
|
||||
m_info.localDestination = destination;
|
||||
|
||||
fetchURL(sourceFile, true);
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::compareStringFile( const QString & source, const KUrl & destinationFile)
|
||||
{
|
||||
//Set the modeto specify that the source is a file, and the destination is a string
|
||||
m_info.mode = Kompare::ComparingStringFile;
|
||||
|
||||
m_info.localSource = source;
|
||||
m_info.destination = destinationFile;
|
||||
|
||||
fetchURL(destinationFile, false);
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::compareFiles( const KUrl& sourceFile, const KUrl& destinationFile )
|
||||
{
|
||||
m_info.mode = Kompare::ComparingFiles;
|
||||
|
||||
m_info.source = sourceFile;
|
||||
m_info.destination = destinationFile;
|
||||
|
||||
// FIXME: (Not urgent) But turn this into an enum, for now i cant find a nice name for the enum that has Source and Destination as values
|
||||
// For now we do not do error checking, user has already been notified and if the localString is empty then we dont diff
|
||||
fetchURL( sourceFile, true );
|
||||
fetchURL( destinationFile, false );
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::compareDirs( const KUrl& sourceDirectory, const KUrl& destinationDirectory )
|
||||
{
|
||||
m_info.mode = Kompare::ComparingDirs;
|
||||
|
||||
m_info.source = sourceDirectory;
|
||||
m_info.destination = destinationDirectory;
|
||||
|
||||
fetchURL( sourceDirectory, true );
|
||||
fetchURL( destinationDirectory, false );
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::compare3Files( const KUrl& /*originalFile*/, const KUrl& /*changedFile1*/, const KUrl& /*changedFile2*/ )
|
||||
{
|
||||
// FIXME: actually implement this some day :)
|
||||
updateActions();
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
void KomparePart::openFileAndDiff( const KUrl& file, const KUrl& diffFile )
|
||||
{
|
||||
m_info.source = file;
|
||||
m_info.destination = diffFile;
|
||||
|
||||
fetchURL( file, true );
|
||||
fetchURL( diffFile, false );
|
||||
m_info.mode = Kompare::BlendingFile;
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
compareAndUpdateAll();
|
||||
}
|
||||
|
||||
void KomparePart::openDirAndDiff ( const KUrl& dir, const KUrl& diffFile )
|
||||
{
|
||||
m_info.source = dir;
|
||||
m_info.destination = diffFile;
|
||||
|
||||
fetchURL( dir, true );
|
||||
fetchURL( diffFile, false );
|
||||
m_info.mode = Kompare::BlendingDir;
|
||||
|
||||
emit kompareInfo( &m_info );
|
||||
|
||||
if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
|
||||
{
|
||||
m_modelList->openDirAndDiff();
|
||||
//Must this be in here? couldn't we use compareAndUpdateAll as well?
|
||||
updateActions();
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
}
|
||||
}
|
||||
|
||||
bool KomparePart::openFile()
|
||||
{
|
||||
// This is called from openURL
|
||||
// This is a little inefficient but i will do it anyway
|
||||
openDiff( url() );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool KomparePart::saveAll()
|
||||
{
|
||||
bool result = m_modelList->saveAll();
|
||||
updateActions();
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
return result;
|
||||
}
|
||||
|
||||
void KomparePart::saveDiff()
|
||||
{
|
||||
KDialog dlg( widget() );
|
||||
dlg.setObjectName( "save_options" );
|
||||
dlg.setModal( true );
|
||||
dlg.setWindowTitle( i18n("Diff Options") );
|
||||
dlg.setButtons( KDialog::Ok|KDialog::Cancel );
|
||||
KompareSaveOptionsWidget* w = new KompareSaveOptionsWidget(
|
||||
m_info.localSource,
|
||||
m_info.localDestination,
|
||||
m_diffSettings, &dlg );
|
||||
dlg.setMainWidget( w );
|
||||
dlg.setButtonGuiItem( KDialog::Ok, KStandardGuiItem::save() );
|
||||
|
||||
if( dlg.exec() ) {
|
||||
w->saveOptions();
|
||||
KSharedConfig::Ptr config = componentData().config();
|
||||
saveProperties( config.data() );
|
||||
config->sync();
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
KUrl url = KFileDialog::getSaveUrl( m_info.destination.url(),
|
||||
i18n("*.diff *.dif *.patch|Patch Files"), widget(), i18n( "Save .diff" ) );
|
||||
if ( KIO::NetAccess::exists( url, KIO::NetAccess::DestinationSide, widget() ) )
|
||||
{
|
||||
int result = KMessageBox::warningYesNoCancel( widget(), i18n("The file exists or is write-protected; do you want to overwrite it?"), i18n("File Exists"), KGuiItem(i18n("Overwrite")), KGuiItem(i18n("Do Not Overwrite")) );
|
||||
if ( result == KMessageBox::Cancel )
|
||||
{
|
||||
break;
|
||||
}
|
||||
else if ( result == KMessageBox::No )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
kDebug(8103) << "URL = " << url.prettyUrl() << endl;
|
||||
kDebug(8103) << "Directory = " << w->directory() << endl;
|
||||
kDebug(8103) << "DiffSettings = " << m_diffSettings << endl;
|
||||
|
||||
m_modelList->saveDiff( url.url(), w->directory(), m_diffSettings );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
kDebug(8103) << "URL = " << url.prettyUrl() << endl;
|
||||
kDebug(8103) << "Directory = " << w->directory() << endl;
|
||||
kDebug(8103) << "DiffSettings = " << m_diffSettings << endl;
|
||||
|
||||
m_modelList->saveDiff( url.url(), w->directory(), m_diffSettings );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KomparePart::slotFilePrint()
|
||||
{
|
||||
QPrinter printer;
|
||||
printer.setOrientation( QPrinter::Landscape );
|
||||
QPrintDialog* dlg = KdePrint::createPrintDialog( &printer, m_splitter );
|
||||
|
||||
if ( dlg->exec() == QDialog::Accepted )
|
||||
{
|
||||
// do some printing in qprinter
|
||||
slotPaintRequested( &printer );
|
||||
}
|
||||
|
||||
delete dlg;
|
||||
}
|
||||
|
||||
void KomparePart::slotFilePrintPreview()
|
||||
{
|
||||
QPrinter printer;
|
||||
printer.setOrientation( QPrinter::Landscape );
|
||||
QPrintPreviewDialog dlg( &printer );
|
||||
|
||||
connect( &dlg, SIGNAL(paintRequested(QPrinter*)), this, SLOT(slotPaintRequested(QPrinter*)) );
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void KomparePart::slotPaintRequested( QPrinter* printer )
|
||||
{
|
||||
kDebug(8103) << "Now paint something..." << endl;
|
||||
QPainter p;
|
||||
p.begin( printer );
|
||||
|
||||
QSize widgetWidth = m_view->size();
|
||||
kDebug(8103) << "printer.width() = " << printer->width() << endl;
|
||||
kDebug(8103) << "widgetWidth.width() = " << widgetWidth.width() << endl;
|
||||
qreal factor = ((qreal)printer->width())/((qreal)widgetWidth.width());
|
||||
|
||||
kDebug(8103) << "factor = " << factor << endl;
|
||||
|
||||
p.scale( factor, factor );
|
||||
m_view->render( &p );
|
||||
|
||||
p.end();
|
||||
kDebug(8103) << "Done painting something..." << endl;
|
||||
}
|
||||
|
||||
KAboutData* KomparePart::createAboutData()
|
||||
{
|
||||
KAboutData *about = new KAboutData("kompare", 0, ki18n("KomparePart"), "4.0");
|
||||
about->addAuthor(ki18n("John Firebaugh"), ki18n("Author"), "jfirebaugh@kde.org");
|
||||
about->addAuthor(ki18n("Otto Bruggeman"), ki18n("Author"), "bruggie@gmail.com" );
|
||||
about->addAuthor(ki18n("Kevin Kofler"), ki18n("Author"), "kevin.kofler@chello.at" );
|
||||
return about;
|
||||
}
|
||||
|
||||
void KomparePart::slotSetStatus( enum Kompare::Status status )
|
||||
{
|
||||
updateActions();
|
||||
|
||||
switch( status ) {
|
||||
case Kompare::RunningDiff:
|
||||
emit setStatusBarText( i18n( "Running diff..." ) );
|
||||
break;
|
||||
case Kompare::Parsing:
|
||||
emit setStatusBarText( i18n( "Parsing diff output..." ) );
|
||||
break;
|
||||
case Kompare::FinishedParsing:
|
||||
updateStatus();
|
||||
break;
|
||||
case Kompare::FinishedWritingDiff:
|
||||
updateStatus();
|
||||
emit diffURLChanged();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void KomparePart::updateCaption()
|
||||
{
|
||||
QString source = m_info.source.prettyUrl();
|
||||
QString destination = m_info.destination.prettyUrl();
|
||||
|
||||
QString text;
|
||||
|
||||
switch ( m_info.mode )
|
||||
{
|
||||
case Kompare::ComparingFiles :
|
||||
case Kompare::ComparingDirs :
|
||||
case Kompare::BlendingFile :
|
||||
case Kompare::BlendingDir :
|
||||
text = source + " -- " + destination; // no need to translate this " -- "
|
||||
break;
|
||||
case Kompare::ShowingDiff :
|
||||
text = source;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit setWindowCaption( text );
|
||||
}
|
||||
|
||||
void KomparePart::updateStatus()
|
||||
{
|
||||
QString source = m_info.source.prettyUrl();
|
||||
QString destination = m_info.destination.prettyUrl();
|
||||
|
||||
QString text;
|
||||
|
||||
switch ( m_info.mode )
|
||||
{
|
||||
case Kompare::ComparingFiles :
|
||||
text = i18n( "Comparing file %1 with file %2" ,
|
||||
source ,
|
||||
destination );
|
||||
break;
|
||||
case Kompare::ComparingDirs :
|
||||
text = i18n( "Comparing files in %1 with files in %2" ,
|
||||
source ,
|
||||
destination );
|
||||
break;
|
||||
case Kompare::ShowingDiff :
|
||||
text = i18n( "Viewing diff output from %1", source );
|
||||
break;
|
||||
case Kompare::BlendingFile :
|
||||
text = i18n( "Blending diff output from %1 into file %2" ,
|
||||
source ,
|
||||
destination );
|
||||
break;
|
||||
case Kompare::BlendingDir :
|
||||
text = i18n( "Blending diff output from %1 into folder %2" ,
|
||||
m_info.source.prettyUrl() ,
|
||||
m_info.destination.prettyUrl() );
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
emit setStatusBarText( text );
|
||||
}
|
||||
|
||||
void KomparePart::compareAndUpdateAll()
|
||||
{
|
||||
if ( !m_info.localSource.isEmpty() && !m_info.localDestination.isEmpty() )
|
||||
{
|
||||
switch(m_info.mode)
|
||||
{
|
||||
default:
|
||||
case Kompare::UnknownMode:
|
||||
m_modelList->compare();
|
||||
break;
|
||||
|
||||
case Kompare::ComparingStringFile:
|
||||
case Kompare::ComparingFileString:
|
||||
case Kompare::ComparingFiles:
|
||||
case Kompare::ComparingDirs:
|
||||
m_modelList->compare(m_info.mode);
|
||||
break;
|
||||
|
||||
case Kompare::BlendingFile:
|
||||
m_modelList->openFileAndDiff();
|
||||
break;
|
||||
}
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
}
|
||||
updateActions();
|
||||
}
|
||||
|
||||
void KomparePart::slotShowError( QString error )
|
||||
{
|
||||
KMessageBox::error( widget(), error );
|
||||
}
|
||||
|
||||
void KomparePart::slotSwap()
|
||||
{
|
||||
if ( m_modelList->hasUnsavedChanges() )
|
||||
{
|
||||
int query = KMessageBox::warningYesNoCancel
|
||||
(
|
||||
widget(),
|
||||
i18n( "You have made changes to the destination file(s).\n"
|
||||
"Would you like to save them?" ),
|
||||
i18n( "Save Changes?" ),
|
||||
KStandardGuiItem::save(),
|
||||
KStandardGuiItem::discard()
|
||||
);
|
||||
|
||||
if ( query == KMessageBox::Yes )
|
||||
m_modelList->saveAll();
|
||||
|
||||
if ( query == KMessageBox::Cancel )
|
||||
return; // Abort prematurely so no swapping
|
||||
}
|
||||
|
||||
// Swap the info in the Kompare::Info struct
|
||||
m_info.swapSourceWithDestination();
|
||||
|
||||
// Update window caption and statusbar text
|
||||
updateCaption();
|
||||
updateStatus();
|
||||
|
||||
m_modelList->swap();
|
||||
}
|
||||
|
||||
void KomparePart::slotRefreshDiff()
|
||||
{
|
||||
if ( m_modelList->hasUnsavedChanges() )
|
||||
{
|
||||
int query = KMessageBox::warningYesNoCancel
|
||||
(
|
||||
widget(),
|
||||
i18n( "You have made changes to the destination file(s).\n"
|
||||
"Would you like to save them?" ),
|
||||
i18n( "Save Changes?" ),
|
||||
KStandardGuiItem::save(),
|
||||
KStandardGuiItem::discard()
|
||||
);
|
||||
|
||||
if ( query == KMessageBox::Cancel )
|
||||
return; // Abort prematurely so no refreshing
|
||||
|
||||
if ( query == KMessageBox::Yes )
|
||||
m_modelList->saveAll();
|
||||
}
|
||||
|
||||
// For this to work properly you have to refetch the files from their (remote) locations
|
||||
cleanUpTemporaryFiles();
|
||||
fetchURL( m_info.source, true );
|
||||
fetchURL( m_info.destination, false );
|
||||
m_modelList->refresh();
|
||||
}
|
||||
|
||||
void KomparePart::slotShowDiffstats( void )
|
||||
{
|
||||
// Fetch all the args needed for komparestatsmessagebox
|
||||
// oldfile, newfile, diffformat, noofhunks, noofdiffs
|
||||
|
||||
QString oldFile;
|
||||
QString newFile;
|
||||
QString diffFormat;
|
||||
int filesInDiff;
|
||||
int noOfHunks;
|
||||
int noOfDiffs;
|
||||
|
||||
oldFile = m_modelList->selectedModel() ? m_modelList->selectedModel()->sourceFile() : QString( "" );
|
||||
newFile = m_modelList->selectedModel() ? m_modelList->selectedModel()->destinationFile() : QString( "" );
|
||||
|
||||
if ( m_modelList->selectedModel() )
|
||||
{
|
||||
switch( m_info.format ) {
|
||||
case Kompare::Unified :
|
||||
diffFormat = i18n( "Unified" );
|
||||
break;
|
||||
case Kompare::Context :
|
||||
diffFormat = i18n( "Context" );
|
||||
break;
|
||||
case Kompare::RCS :
|
||||
diffFormat = i18n( "RCS" );
|
||||
break;
|
||||
case Kompare::Ed :
|
||||
diffFormat = i18n( "Ed" );
|
||||
break;
|
||||
case Kompare::Normal :
|
||||
diffFormat = i18n( "Normal" );
|
||||
break;
|
||||
case Kompare::UnknownFormat :
|
||||
default:
|
||||
diffFormat = i18n( "Unknown" );
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
diffFormat = "";
|
||||
}
|
||||
|
||||
filesInDiff = m_modelList->modelCount();
|
||||
|
||||
noOfHunks = m_modelList->selectedModel() ? m_modelList->selectedModel()->hunkCount() : 0;
|
||||
noOfDiffs = m_modelList->selectedModel() ? m_modelList->selectedModel()->differenceCount() : 0;
|
||||
|
||||
if ( m_modelList->modelCount() == 0 ) { // no diff loaded yet
|
||||
KMessageBox::information( 0L, i18n(
|
||||
"No diff file, or no 2 files have been diffed. "
|
||||
"Therefore no stats are available."),
|
||||
i18n("Diff Statistics"), QString(), 0 );
|
||||
}
|
||||
else if ( m_modelList->modelCount() == 1 ) { // 1 file in diff, or 2 files compared
|
||||
KMessageBox::information( 0L, i18n(
|
||||
"Statistics:\n"
|
||||
"\n"
|
||||
"Old file: %1\n"
|
||||
"New file: %2\n"
|
||||
"\n"
|
||||
"Format: %3\n"
|
||||
"Number of hunks: %4\n"
|
||||
"Number of differences: %5",
|
||||
oldFile, newFile, diffFormat,
|
||||
noOfHunks, noOfDiffs),
|
||||
i18n("Diff Statistics"), QString(), 0 );
|
||||
} else { // more than 1 file in diff, or 2 directories compared
|
||||
KMessageBox::information( 0L, ki18n(
|
||||
"Statistics:\n"
|
||||
"\n"
|
||||
"Number of files in diff file: %1\n"
|
||||
"Format: %2\n"
|
||||
"\n"
|
||||
"Current old file: %3\n"
|
||||
"Current new file: %4\n"
|
||||
"\n"
|
||||
"Number of hunks: %5\n"
|
||||
"Number of differences: %6")
|
||||
.subs(filesInDiff).subs(diffFormat).subs(oldFile)
|
||||
.subs(newFile).subs(noOfHunks).subs(noOfDiffs)
|
||||
.toString(),
|
||||
i18n("Diff Statistics"), QString(), 0 );
|
||||
}
|
||||
}
|
||||
|
||||
bool KomparePart::queryClose()
|
||||
{
|
||||
if ( !m_modelList->hasUnsavedChanges() ) return true;
|
||||
|
||||
int query = KMessageBox::warningYesNoCancel
|
||||
(
|
||||
widget(),
|
||||
i18n("You have made changes to the destination file(s).\n"
|
||||
"Would you like to save them?" ),
|
||||
i18n( "Save Changes?" ),
|
||||
KStandardGuiItem::save(),
|
||||
KStandardGuiItem::discard()
|
||||
);
|
||||
|
||||
if( query == KMessageBox::Cancel )
|
||||
return false;
|
||||
|
||||
if( query == KMessageBox::Yes )
|
||||
return m_modelList->saveAll();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int KomparePart::readProperties( KConfig *config )
|
||||
{
|
||||
m_viewSettings->loadSettings( config );
|
||||
m_diffSettings->loadSettings( config );
|
||||
emit configChanged();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int KomparePart::saveProperties( KConfig *config )
|
||||
{
|
||||
m_viewSettings->saveSettings( config );
|
||||
m_diffSettings->saveSettings( config );
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KomparePart::optionsPreferences()
|
||||
{
|
||||
// show preferences
|
||||
KomparePrefDlg pref( m_viewSettings, m_diffSettings );
|
||||
|
||||
connect( &pref, SIGNAL(configChanged()), this, SIGNAL(configChanged()) );
|
||||
|
||||
if ( pref.exec() )
|
||||
emit configChanged();
|
||||
}
|
||||
|
||||
#include "kompare_part.moc"
|
241
kompare/komparepart/kompare_part.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
/***************************************************************************
|
||||
kompare_part.h
|
||||
--------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2005,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPAREPART_H
|
||||
#define KOMPAREPART_H
|
||||
|
||||
#include <kparts/factory.h>
|
||||
#include <kparts/part.h>
|
||||
#include <QVariantList>
|
||||
#include <kompare.h>
|
||||
|
||||
#include "kompareinterface.h"
|
||||
|
||||
class QPrinter;
|
||||
class QWidget;
|
||||
|
||||
class KTemporaryFile;
|
||||
class KUrl;
|
||||
class KAboutData;
|
||||
class KAction;
|
||||
|
||||
namespace Diff2 {
|
||||
class Difference;
|
||||
class DiffModel;
|
||||
class DiffModelList;
|
||||
class KompareModelList;
|
||||
}
|
||||
class DiffSettings;
|
||||
class ViewSettings;
|
||||
class KompareSplitter;
|
||||
class KompareView;
|
||||
|
||||
/**
|
||||
* This is a "Part". It does all the real work in a KPart
|
||||
* application.
|
||||
*
|
||||
* @short Main Part
|
||||
* @author John Firebaugh <jfirebaugh@kde.org>
|
||||
* @author Otto Bruggeman <bruggie@home.nl>
|
||||
* @version 0.3
|
||||
*/
|
||||
class KomparePart : public KParts::ReadWritePart,
|
||||
public KompareInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_INTERFACES(KompareInterface)
|
||||
public:
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
KomparePart( QWidget *parentWidget, QObject *parent, const QVariantList & /*args*/);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~KomparePart();
|
||||
|
||||
// Sessionmanagement stuff, added to the kompare iface
|
||||
// because they are not in the Part class where they belong
|
||||
// Should be added when bic changes are allowed again (kde 4.0)
|
||||
virtual int readProperties( KConfig *config );
|
||||
virtual int saveProperties( KConfig *config );
|
||||
// this one is called when the shell_app is about to close.
|
||||
// we need it now to save the properties of the part when apps don't (can't)
|
||||
// use the readProperties and saveProperties methods
|
||||
virtual bool queryClose();
|
||||
|
||||
// Do we really want to expose this ???
|
||||
const Diff2::KompareModelList* model() const { return m_modelList; };
|
||||
|
||||
static KAboutData *createAboutData();
|
||||
|
||||
public:
|
||||
// Reimplemented from the KompareInterface
|
||||
/**
|
||||
* Open and parse the diff file at diffUrl.
|
||||
*/
|
||||
virtual bool openDiff( const KUrl& diffUrl );
|
||||
|
||||
/** Added on request of Harald Fernengel */
|
||||
virtual bool openDiff( const QString& diffOutput );
|
||||
|
||||
/** Open and parse the diff3 file at diff3Url */
|
||||
virtual bool openDiff3( const KUrl& diff3URL );
|
||||
|
||||
/** Open and parse the file diff3Output with the output of diff3 */
|
||||
virtual bool openDiff3( const QString& diff3Output );
|
||||
|
||||
/** Compare, with diff, source with destination */
|
||||
virtual void compare( const KUrl& sourceFile, const KUrl& destinationFile );
|
||||
|
||||
/** Compare a Source file to a custom Destination string */
|
||||
virtual void compareFileString( const KUrl & sourceFile, const QString & destination);
|
||||
|
||||
/** Compare a custom Source string to a Destination file */
|
||||
virtual void compareStringFile( const QString & source, const KUrl & destinationFile);
|
||||
|
||||
/** Compare, with diff, source with destination */
|
||||
virtual void compareFiles( const KUrl& sourceFile, const KUrl& destinationFile );
|
||||
|
||||
/** Compare, with diff, source with destination */
|
||||
virtual void compareDirs ( const KUrl& sourceDir, const KUrl& destinationDir );
|
||||
|
||||
/** Compare, with diff3, originalFile with changedFile1 and changedFile2 */
|
||||
virtual void compare3Files( const KUrl& originalFile, const KUrl& changedFile1, const KUrl& changedFile2 );
|
||||
|
||||
/** This will show the file and the file with the diff applied */
|
||||
virtual void openFileAndDiff( const KUrl& file, const KUrl& diffFile );
|
||||
|
||||
/** This will show the directory and the directory with the diff applied */
|
||||
virtual void openDirAndDiff ( const KUrl& dir, const KUrl& diffFile );
|
||||
|
||||
/** Reimplementing this because this one knows more about the real part then the interface */
|
||||
virtual void setEncoding( const QString& encoding );
|
||||
|
||||
// This is the interpart interface, it is signal and slot based so no "real" interface here
|
||||
// All you have to do is connect the parts from your application.
|
||||
// These just point to their counterpart in the KompareModelList or get called from their
|
||||
// counterpart in KompareModelList.
|
||||
signals:
|
||||
void modelsChanged( const Diff2::DiffModelList* models );
|
||||
|
||||
void setSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void setSelection( const Diff2::Difference* diff );
|
||||
|
||||
void selectionChanged( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void selectionChanged( const Diff2::Difference* diff );
|
||||
|
||||
void applyDifference( bool apply );
|
||||
void applyAllDifferences( bool apply );
|
||||
void applyDifference( const Diff2::Difference*, bool apply );
|
||||
|
||||
void configChanged();
|
||||
|
||||
/*
|
||||
** This is emitted when a difference is clicked in the kompare view. You can connect to
|
||||
** it so you can use it to jump to this particular line in the editor in your app.
|
||||
*/
|
||||
void differenceClicked( int lineNumber );
|
||||
|
||||
// Stuff that can probably be removed by putting it in the part where it belongs in my opinion
|
||||
public slots:
|
||||
/** Save all destinations. */
|
||||
bool saveAll();
|
||||
|
||||
/** Save the results of a comparison as a diff file. */
|
||||
void saveDiff();
|
||||
|
||||
/** To enable printing, the part has the only interesting printable content so putting it here */
|
||||
void slotFilePrint();
|
||||
void slotFilePrintPreview();
|
||||
|
||||
signals:
|
||||
void appliedChanged();
|
||||
void diffURLChanged();
|
||||
void kompareInfo( Kompare::Info* info );
|
||||
void setStatusBarModelInfo( int modelIndex, int differenceIndex, int modelCount, int differenceCount, int appliedCount );
|
||||
// void setStatusBarText( const QString& text );
|
||||
void diffString(const QString&);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* This is the method that gets called when the file is opened,
|
||||
* when using openURL( const KUrl& ) or in our case also openDiff( const KUrl& );
|
||||
* return true when everything went ok, false if there were problems
|
||||
*/
|
||||
virtual bool openFile();
|
||||
// ... Uhm we return true without saving ???
|
||||
virtual bool saveFile() { return true; };
|
||||
|
||||
// patchFile
|
||||
bool patchFile(KUrl&);
|
||||
bool patchDir();
|
||||
|
||||
protected slots:
|
||||
void slotSetStatus( Kompare::Status status );
|
||||
void slotShowError( QString error );
|
||||
|
||||
void slotSwap();
|
||||
void slotShowDiffstats();
|
||||
void slotRefreshDiff();
|
||||
void optionsPreferences();
|
||||
|
||||
void updateActions();
|
||||
void updateCaption();
|
||||
void updateStatus();
|
||||
void compareAndUpdateAll();
|
||||
|
||||
void slotPaintRequested( QPrinter* );
|
||||
|
||||
private:
|
||||
void cleanUpTemporaryFiles();
|
||||
void setupActions();
|
||||
bool exists( const QString& url );
|
||||
bool isDirectory( const KUrl& url );
|
||||
// FIXME (like in cpp file not urgent) Replace with enum, cant find a proper
|
||||
// name now but it is private anyway so can not be used from outside
|
||||
bool fetchURL( const KUrl& url, bool isSource );
|
||||
|
||||
private:
|
||||
// Uhm why were these static again ???
|
||||
// Ah yes, so multiple instances of kompare use the
|
||||
// same settings after one of them changes them
|
||||
static ViewSettings* m_viewSettings;
|
||||
static DiffSettings* m_diffSettings;
|
||||
|
||||
Diff2::KompareModelList* m_modelList;
|
||||
|
||||
KompareView* m_view;
|
||||
KompareSplitter* m_splitter;
|
||||
|
||||
KAction* m_saveAll;
|
||||
KAction* m_saveDiff;
|
||||
KAction* m_swap;
|
||||
KAction* m_diffStats;
|
||||
KAction* m_diffRefresh;
|
||||
KAction* m_print;
|
||||
KAction* m_printPreview;
|
||||
|
||||
KTemporaryFile* m_tempDiff;
|
||||
|
||||
struct Kompare::Info m_info;
|
||||
};
|
||||
|
||||
#endif // KOMPAREPART_H
|
258
kompare/komparepart/kompareconnectwidget.cpp
Normal file
|
@ -0,0 +1,258 @@
|
|||
/***************************************************************************
|
||||
kompareconnectwidget.cpp
|
||||
------------------------
|
||||
begin : Tue Jun 26 2001
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2001-2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "kompareconnectwidget.h"
|
||||
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QPaintEvent>
|
||||
#include <QFrame>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include "viewsettings.h"
|
||||
#include "komparelistview.h"
|
||||
#include "komparesplitter.h"
|
||||
|
||||
using namespace Diff2;
|
||||
|
||||
KompareConnectWidgetFrame::KompareConnectWidgetFrame( ViewSettings* settings,
|
||||
KompareSplitter* parent,
|
||||
const char* name ) :
|
||||
QSplitterHandle(Qt::Horizontal, (QSplitter *)parent),
|
||||
m_wid ( settings, this, name ),
|
||||
m_label ( " ", this ), // putting a space here because Qt 4 computes different size hints for empty labels
|
||||
m_layout ( this )
|
||||
{
|
||||
setObjectName( name );
|
||||
setSizePolicy ( QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Ignored) );
|
||||
m_wid.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored) );
|
||||
m_label.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
|
||||
m_label.setMargin(3);
|
||||
QFrame* bottomLine = new QFrame(this);
|
||||
bottomLine->setFrameShape(QFrame::HLine);
|
||||
bottomLine->setFrameShadow ( QFrame::Plain );
|
||||
bottomLine->setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
|
||||
bottomLine->setFixedHeight(1);
|
||||
m_layout.setSpacing(0);
|
||||
m_layout.setMargin(0);
|
||||
m_layout.addWidget(&m_label);
|
||||
m_layout.addWidget(bottomLine);
|
||||
m_layout.addWidget(&m_wid);
|
||||
}
|
||||
|
||||
KompareConnectWidgetFrame::~KompareConnectWidgetFrame()
|
||||
{
|
||||
}
|
||||
|
||||
QSize KompareConnectWidgetFrame::sizeHint() const
|
||||
{
|
||||
return QSize(50, style()->pixelMetric( QStyle::PM_ScrollBarExtent ) );
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int kMouseOffset;
|
||||
|
||||
void KompareConnectWidgetFrame::mouseMoveEvent( QMouseEvent *e )
|
||||
{
|
||||
|
||||
if ( !(e->state()&Qt::LeftButton) )
|
||||
return;
|
||||
|
||||
QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
|
||||
- kMouseOffset;
|
||||
|
||||
((KompareSplitter*)s)->moveSplitter( pos, id() );
|
||||
}
|
||||
|
||||
void KompareConnectWidgetFrame::mousePressEvent( QMouseEvent *e )
|
||||
{
|
||||
if ( e->button() == Qt::LeftButton )
|
||||
kMouseOffset = s->pick( e->pos() );
|
||||
QSplitterHandle::mousePressEvent(e);
|
||||
}
|
||||
|
||||
void KompareConnectWidgetFrame::mouseReleaseEvent( QMouseEvent *e )
|
||||
{
|
||||
if ( !opaque() && e->button() == Qt::LeftButton ) {
|
||||
QCOORD pos = s->pick( parentWidget()->mapFromGlobal(e->globalPos()) )
|
||||
- kMouseOffset;
|
||||
((KompareSplitter*)s)->moveSplitter( pos, id() );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
KompareConnectWidget::KompareConnectWidget( ViewSettings* settings, QWidget* parent, const char* name )
|
||||
: QWidget(parent),
|
||||
m_settings( settings ),
|
||||
m_selectedModel( 0 ),
|
||||
m_selectedDifference( 0 )
|
||||
{
|
||||
setObjectName(name);
|
||||
// connect( m_settings, SIGNAL( settingsChanged() ), this, SLOT( slotDelayedRepaint() ) );
|
||||
setAttribute( Qt::WA_NoSystemBackground, true );
|
||||
setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Minimum ) );
|
||||
setFocusProxy( parent->parentWidget() );
|
||||
}
|
||||
|
||||
KompareConnectWidget::~KompareConnectWidget()
|
||||
{
|
||||
m_settings = 0;
|
||||
m_selectedModel = 0;
|
||||
m_selectedDifference = 0;
|
||||
}
|
||||
|
||||
void KompareConnectWidget::slotSetSelection( const DiffModel* model, const Difference* diff )
|
||||
{
|
||||
if( m_selectedModel == model && m_selectedDifference == diff )
|
||||
return;
|
||||
|
||||
if ( m_selectedModel == model && m_selectedDifference != diff )
|
||||
{
|
||||
m_selectedDifference = diff;
|
||||
slotDelayedRepaint();
|
||||
return;
|
||||
}
|
||||
|
||||
m_selectedModel = model;
|
||||
m_selectedDifference = diff;
|
||||
|
||||
slotDelayedRepaint();
|
||||
}
|
||||
|
||||
void KompareConnectWidget::slotDelayedRepaint()
|
||||
{
|
||||
QTimer::singleShot( 0, this, SLOT( repaint() ) );
|
||||
}
|
||||
|
||||
void KompareConnectWidget::slotSetSelection( const Difference* diff )
|
||||
{
|
||||
if ( m_selectedDifference == diff )
|
||||
return;
|
||||
|
||||
m_selectedDifference = diff;
|
||||
|
||||
slotDelayedRepaint();
|
||||
}
|
||||
|
||||
void KompareConnectWidget::paintEvent( QPaintEvent* /* e */ )
|
||||
{
|
||||
QPixmap pixbuf(size());
|
||||
QPainter paint(&pixbuf);
|
||||
QPainter* p = &paint;
|
||||
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
p->fillRect( 0, 0, pixbuf.width(), pixbuf.height(), palette().color( QPalette::Window ) );
|
||||
p->translate(QPointF(0, 0.5));
|
||||
|
||||
KompareSplitter* splitter = static_cast<KompareSplitter*>( parent()->parent() );
|
||||
int count = splitter->count();
|
||||
KompareListView *leftView = count >= 2 ? static_cast<KompareListViewFrame*>( splitter->widget(0) )->view() : 0;
|
||||
KompareListView *rightView = count >= 2 ? static_cast<KompareListViewFrame*>( splitter->widget(1) )->view() : 0;
|
||||
|
||||
if ( m_selectedModel && leftView && rightView )
|
||||
{
|
||||
int firstL = leftView->firstVisibleDifference();
|
||||
int firstR = rightView->firstVisibleDifference();
|
||||
int lastL = leftView->lastVisibleDifference();
|
||||
int lastR = rightView->lastVisibleDifference();
|
||||
|
||||
int first = firstL < 0 ? firstR : qMin( firstL, firstR );
|
||||
int last = lastL < 0 ? lastR : qMax( lastL, lastR );
|
||||
// kDebug(8106) << " left: " << firstL << " - " << lastL << endl;
|
||||
// kDebug(8106) << " right: " << firstR << " - " << lastR << endl;
|
||||
// kDebug(8106) << " drawing: " << first << " - " << last << endl;
|
||||
if ( first >= 0 && last >= 0 && first <= last )
|
||||
{
|
||||
const DifferenceList* differences = const_cast<DiffModel*>(m_selectedModel)->differences();
|
||||
QRect leftRect, rightRect;
|
||||
for ( int i = first; i <= last; ++i )
|
||||
{
|
||||
Difference* diff = differences->at(i );
|
||||
bool selected = ( diff == m_selectedDifference );
|
||||
|
||||
if ( QApplication::isRightToLeft() )
|
||||
{
|
||||
leftRect = rightView->itemRect( i );
|
||||
rightRect = leftView->itemRect( i );
|
||||
}
|
||||
else
|
||||
{
|
||||
leftRect = leftView->itemRect( i );
|
||||
rightRect = rightView->itemRect( i );
|
||||
}
|
||||
|
||||
int tl = leftRect.top();
|
||||
int tr = rightRect.top();
|
||||
int bl = leftRect.bottom();
|
||||
int br = rightRect.bottom();
|
||||
|
||||
// Bah, stupid 16-bit signed shorts in that crappy X stuff...
|
||||
tl = tl >= -32768 ? tl : -32768;
|
||||
tr = tr >= -32768 ? tr : -32768;
|
||||
bl = bl <= 32767 ? bl : 32767;
|
||||
br = br <= 32767 ? br : 32767;
|
||||
|
||||
QPainterPath topBezier = makeBezier( tl, tr );
|
||||
QPainterPath bottomBezier = makeBezier( bl, br );
|
||||
|
||||
QPainterPath poly(topBezier);
|
||||
poly.connectPath(bottomBezier.toReversed());
|
||||
poly.closeSubpath();
|
||||
|
||||
QColor bg = m_settings->colorForDifferenceType( diff->type(), selected, diff->applied() );
|
||||
p->setPen( bg );
|
||||
p->setBrush( bg );
|
||||
p->drawPath(poly);
|
||||
|
||||
if(selected)
|
||||
{
|
||||
p->setPen( bg.dark( 135 ) );
|
||||
p->setBrush( Qt::NoBrush );
|
||||
p->drawPath( topBezier );
|
||||
p->drawPath( bottomBezier.toReversed() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// p->flush();
|
||||
QPainter widgetPainter(this);
|
||||
widgetPainter.drawImage(0, 0, pixbuf.toImage());
|
||||
}
|
||||
|
||||
QPainterPath KompareConnectWidget::makeBezier( int leftHeight, int rightHeight ) const
|
||||
{
|
||||
int r = width();
|
||||
int o = (int)((double)r*0.4); // 40% of width
|
||||
|
||||
QPainterPath p(QPointF(0, leftHeight));
|
||||
if(leftHeight==rightHeight) {
|
||||
p.lineTo(QPointF(r, rightHeight));
|
||||
} else {
|
||||
p.cubicTo(QPointF(o, leftHeight), QPointF(r-o, rightHeight), QPointF(r,rightHeight));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
#include "kompareconnectwidget.moc"
|
93
kompare/komparepart/kompareconnectwidget.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
/***************************************************************************
|
||||
kompareconnectwidget.h
|
||||
----------------------
|
||||
begin : Tue Jun 26 2001
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* 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. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARECONNECTWIDGET_H
|
||||
#define KOMPARECONNECTWIDGET_H
|
||||
|
||||
#include <QtGui/QWidget>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QPaintEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QtGui/QLabel>
|
||||
|
||||
#include "komparemodellist.h"
|
||||
|
||||
namespace Diff2 {
|
||||
class DiffModel;
|
||||
}
|
||||
class ViewSettings;
|
||||
class KompareSplitter;
|
||||
|
||||
class KompareConnectWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KompareConnectWidget( ViewSettings* settings, QWidget* parent, const char* name = 0 );
|
||||
~KompareConnectWidget();
|
||||
|
||||
public slots:
|
||||
void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void slotSetSelection( const Diff2::Difference* diff );
|
||||
|
||||
void slotDelayedRepaint();
|
||||
|
||||
signals:
|
||||
void selectionChanged(const Diff2::Difference* diff);
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* e );
|
||||
QPainterPath makeBezier( int l, int r ) const;
|
||||
|
||||
private:
|
||||
ViewSettings* m_settings;
|
||||
|
||||
const Diff2::DiffModel* m_selectedModel;
|
||||
const Diff2::Difference* m_selectedDifference;
|
||||
};
|
||||
|
||||
class KompareConnectWidgetFrame : public QSplitterHandle
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KompareConnectWidgetFrame( ViewSettings* settings, KompareSplitter* parent, const char* name = 0 );
|
||||
~KompareConnectWidgetFrame();
|
||||
|
||||
QSize sizeHint() const;
|
||||
|
||||
KompareConnectWidget* wid() { return &m_wid; }
|
||||
|
||||
protected:
|
||||
// stop the parent QSplitterHandle painting
|
||||
void paintEvent( QPaintEvent* /* e */ ) { }
|
||||
|
||||
#if 0
|
||||
void mouseMoveEvent( QMouseEvent * );
|
||||
void mousePressEvent( QMouseEvent * );
|
||||
void mouseReleaseEvent( QMouseEvent * );
|
||||
#endif
|
||||
|
||||
private:
|
||||
KompareConnectWidget m_wid;
|
||||
QLabel m_label;
|
||||
QVBoxLayout m_layout;
|
||||
};
|
||||
|
||||
#endif
|
974
kompare/komparepart/komparelistview.cpp
Normal file
|
@ -0,0 +1,974 @@
|
|||
/***************************************************************************
|
||||
komparelistview.h
|
||||
-----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007-2012 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "komparelistview.h"
|
||||
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QResizeEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
#include <QtGui/QWheelEvent>
|
||||
#include <QtGui/QScrollBar>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kglobal.h>
|
||||
#include <kglobalsettings.h>
|
||||
|
||||
#include "diffmodel.h"
|
||||
#include "diffhunk.h"
|
||||
#include "difference.h"
|
||||
#include "viewsettings.h"
|
||||
#include "komparemodellist.h"
|
||||
#include "komparesplitter.h"
|
||||
|
||||
#define COL_LINE_NO 0
|
||||
#define COL_MAIN 1
|
||||
|
||||
#define BLANK_LINE_HEIGHT 3
|
||||
#define HUNK_LINE_HEIGHT 5
|
||||
|
||||
#define ITEM_MARGIN 3
|
||||
|
||||
using namespace Diff2;
|
||||
|
||||
KompareListViewFrame::KompareListViewFrame( bool isSource,
|
||||
ViewSettings* settings,
|
||||
KompareSplitter* parent,
|
||||
const char* name ):
|
||||
QFrame ( parent ),
|
||||
m_view ( isSource, settings, this, name ),
|
||||
m_label ( isSource?"Source":"Dest", this ),
|
||||
m_layout ( this )
|
||||
{
|
||||
setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored) );
|
||||
m_label.setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
|
||||
QFrame *bottomLine = new QFrame(this);
|
||||
bottomLine->setFrameShape(QFrame::HLine);
|
||||
bottomLine->setFrameShadow ( QFrame::Plain );
|
||||
bottomLine->setSizePolicy ( QSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed) );
|
||||
bottomLine->setFixedHeight(1);
|
||||
m_label.setMargin(3);
|
||||
m_layout.setSpacing(0);
|
||||
m_layout.setMargin(0);
|
||||
m_layout.addWidget(&m_label);
|
||||
m_layout.addWidget(bottomLine);
|
||||
m_layout.addWidget(&m_view);
|
||||
|
||||
connect( &m_view, SIGNAL(differenceClicked(const Diff2::Difference*)),
|
||||
parent, SLOT(slotDifferenceClicked(const Diff2::Difference*)) );
|
||||
|
||||
connect( parent, SIGNAL(scrollViewsToId(int)), &m_view, SLOT(scrollToId(int)) );
|
||||
connect( parent, SIGNAL(setXOffset(int)), &m_view, SLOT(setXOffset(int)) );
|
||||
connect( &m_view, SIGNAL(resized()), parent, SLOT(slotUpdateScrollBars()) );
|
||||
}
|
||||
|
||||
void KompareListViewFrame::slotSetModel( const DiffModel* model )
|
||||
{
|
||||
if( model )
|
||||
{
|
||||
if( view()->isSource() ) {
|
||||
if( !model->sourceRevision().isEmpty() )
|
||||
m_label.setText( model->sourceFile() + " (" + model->sourceRevision() + ')' );
|
||||
else
|
||||
m_label.setText( model->sourceFile() );
|
||||
} else {
|
||||
if( !model->destinationRevision().isEmpty() )
|
||||
m_label.setText( model->destinationFile() + " (" + model->destinationRevision() + ')' );
|
||||
else
|
||||
m_label.setText( model->destinationFile() );
|
||||
}
|
||||
} else {
|
||||
m_label.setText( QString::null ); //krazy:exclude=nullstrassign for old broken gcc
|
||||
}
|
||||
}
|
||||
|
||||
KompareListView::KompareListView( bool isSource,
|
||||
ViewSettings* settings,
|
||||
QWidget* parent, const char* name ) :
|
||||
QTreeWidget( parent ),
|
||||
m_isSource( isSource ),
|
||||
m_settings( settings ),
|
||||
m_scrollId( -1 ),
|
||||
m_selectedModel( 0 ),
|
||||
m_selectedDifference( 0 )
|
||||
{
|
||||
setObjectName( name );
|
||||
setItemDelegate( new KompareListViewItemDelegate( this ) );
|
||||
setHeaderHidden( true );
|
||||
setColumnCount( 3 ); // Line Number, Main, Blank
|
||||
setAllColumnsShowFocus( true );
|
||||
setRootIsDecorated( false );
|
||||
setIndentation( 0 );
|
||||
setFrameStyle( QFrame::NoFrame );
|
||||
setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
|
||||
setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
setFocusPolicy( Qt::NoFocus );
|
||||
setFont( m_settings->m_font );
|
||||
setFocusProxy( parent->parentWidget() );
|
||||
}
|
||||
|
||||
KompareListView::~KompareListView()
|
||||
{
|
||||
m_settings = 0;
|
||||
m_selectedModel = 0;
|
||||
m_selectedDifference = 0;
|
||||
}
|
||||
|
||||
KompareListViewItem* KompareListView::itemAtIndex( int i )
|
||||
{
|
||||
return m_items[ i ];
|
||||
}
|
||||
|
||||
int KompareListView::firstVisibleDifference()
|
||||
{
|
||||
QTreeWidgetItem* item = itemAt( QPoint( 0, 0 ) );
|
||||
|
||||
if( item == 0 )
|
||||
{
|
||||
kDebug(8104) << "no item at viewport coordinates (0,0)" << endl;
|
||||
}
|
||||
|
||||
while( item ) {
|
||||
KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
|
||||
if( lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged )
|
||||
break;
|
||||
item = itemBelow(item);
|
||||
}
|
||||
|
||||
if( item )
|
||||
return m_items.indexOf( ((KompareListViewLineItem*)item)->diffItemParent() );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int KompareListView::lastVisibleDifference()
|
||||
{
|
||||
QTreeWidgetItem* item = itemAt( QPoint( 0, visibleHeight() - 1 ) );
|
||||
|
||||
if( item == 0 )
|
||||
{
|
||||
kDebug(8104) << "no item at viewport coordinates (0," << visibleHeight() - 1 << ")" << endl;
|
||||
// find last item
|
||||
item = itemAt( QPoint( 0, 0 ) );
|
||||
if( item ) {
|
||||
QTreeWidgetItem* nextItem = item;
|
||||
do {
|
||||
item = nextItem;
|
||||
nextItem = itemBelow( item );
|
||||
} while( nextItem );
|
||||
}
|
||||
}
|
||||
|
||||
while( item ) {
|
||||
KompareListViewLineItem* lineItem = dynamic_cast<KompareListViewLineItem*>(item);
|
||||
if( lineItem && lineItem->diffItemParent()->difference()->type() != Difference::Unchanged )
|
||||
break;
|
||||
item = itemAbove(item);
|
||||
}
|
||||
|
||||
if( item )
|
||||
return m_items.indexOf( ((KompareListViewLineItem*)item)->diffItemParent() );
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
QRect KompareListView::totalVisualItemRect( QTreeWidgetItem* item )
|
||||
{
|
||||
QRect total = visualItemRect( item );
|
||||
int n = item->childCount();
|
||||
for( int i=0; i<n; i++ ) {
|
||||
QTreeWidgetItem* child = item->child( i );
|
||||
if( !child->isHidden() )
|
||||
total = total.united( totalVisualItemRect( child ) );
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
QRect KompareListView::itemRect( int i )
|
||||
{
|
||||
QTreeWidgetItem* item = itemAtIndex( i );
|
||||
return totalVisualItemRect( item );
|
||||
}
|
||||
|
||||
int KompareListView::minScrollId()
|
||||
{
|
||||
return visibleHeight() / 2;
|
||||
}
|
||||
|
||||
int KompareListView::maxScrollId()
|
||||
{
|
||||
int n = topLevelItemCount();
|
||||
if(!n) return 0;
|
||||
KompareListViewItem* item = (KompareListViewItem*)topLevelItem( n-1 );
|
||||
int maxId = item->scrollId() + item->maxHeight() - minScrollId();
|
||||
kDebug(8104) << "Max ID = " << maxId << endl;
|
||||
return maxId;
|
||||
}
|
||||
|
||||
int KompareListView::contentsHeight()
|
||||
{
|
||||
return verticalScrollBar()->maximum() + viewport()->height() - style()->pixelMetric( QStyle::PM_ScrollBarExtent );
|
||||
}
|
||||
|
||||
int KompareListView::contentsWidth()
|
||||
{
|
||||
return ( columnWidth(COL_LINE_NO) + columnWidth(COL_MAIN) );
|
||||
}
|
||||
|
||||
int KompareListView::visibleHeight()
|
||||
{
|
||||
return viewport()->height();
|
||||
}
|
||||
|
||||
int KompareListView::visibleWidth()
|
||||
{
|
||||
return viewport()->width();
|
||||
}
|
||||
|
||||
int KompareListView::contentsX()
|
||||
{
|
||||
return horizontalOffset();
|
||||
}
|
||||
|
||||
int KompareListView::contentsY()
|
||||
{
|
||||
return verticalOffset();
|
||||
}
|
||||
|
||||
int KompareListView::nextPaintOffset() const
|
||||
{
|
||||
return m_nextPaintOffset;
|
||||
}
|
||||
|
||||
void KompareListView::setNextPaintOffset(int offset)
|
||||
{
|
||||
m_nextPaintOffset = offset;
|
||||
}
|
||||
|
||||
void KompareListView::setXOffset( int x )
|
||||
{
|
||||
kDebug(8104) << "SetXOffset : Scroll to x position: " << x << endl;
|
||||
horizontalScrollBar()->setValue( x );
|
||||
}
|
||||
|
||||
void KompareListView::scrollToId( int id )
|
||||
{
|
||||
// kDebug(8104) << "ScrollToID : Scroll to id : " << id << endl;
|
||||
int n = topLevelItemCount();
|
||||
KompareListViewItem* item = 0;
|
||||
if( n ) {
|
||||
int i = 1;
|
||||
for( ; i<n; i++ ) {
|
||||
if( ((KompareListViewItem*)topLevelItem( i ))->scrollId() > id )
|
||||
break;
|
||||
}
|
||||
item = (KompareListViewItem*)topLevelItem( i-1 );
|
||||
}
|
||||
|
||||
if( item ) {
|
||||
QRect rect = totalVisualItemRect( item );
|
||||
int pos = rect.top() + verticalOffset();
|
||||
int itemId = item->scrollId();
|
||||
int height = rect.height();
|
||||
double r = (double)( id - itemId ) / (double)item->maxHeight();
|
||||
int y = pos + (int)( r * (double)height ) - minScrollId();
|
||||
// kDebug(8104) << "scrollToID: " << endl;
|
||||
// kDebug(8104) << " id = " << id << endl;
|
||||
// kDebug(8104) << " pos = " << pos << endl;
|
||||
// kDebug(8104) << " itemId = " << itemId << endl;
|
||||
// kDebug(8104) << " r = " << r << endl;
|
||||
// kDebug(8104) << " height = " << height << endl;
|
||||
// kDebug(8104) << " minID = " << minScrollId() << endl;
|
||||
// kDebug(8104) << " y = " << y << endl;
|
||||
// kDebug(8104) << "contentsHeight = " << contentsHeight() << endl;
|
||||
// kDebug(8104) << " c - y = " << contentsHeight() - y << endl;
|
||||
verticalScrollBar()->setValue( y );
|
||||
}
|
||||
|
||||
m_scrollId = id;
|
||||
}
|
||||
|
||||
int KompareListView::scrollId()
|
||||
{
|
||||
if( m_scrollId < 0 )
|
||||
m_scrollId = minScrollId();
|
||||
return m_scrollId;
|
||||
}
|
||||
|
||||
void KompareListView::setSelectedDifference( const Difference* diff, bool scroll )
|
||||
{
|
||||
kDebug(8104) << "KompareListView::setSelectedDifference(" << diff << ", " << scroll << ")" << endl;
|
||||
|
||||
// When something other than a click causes this function to be called,
|
||||
// it'll only get called once, and all is simple.
|
||||
//
|
||||
// When the user clicks on a diff, this function will get called once when
|
||||
// komparesplitter::slotDifferenceClicked runs, and again when the
|
||||
// setSelection signal from the modelcontroller arrives.
|
||||
//
|
||||
// the first call (which will always be from the splitter) will have
|
||||
// scroll==false, and the second call will bail out here.
|
||||
// Which is why clicking on a difference does not cause the listviews to
|
||||
// scroll.
|
||||
if ( m_selectedDifference == diff )
|
||||
return;
|
||||
|
||||
m_selectedDifference = diff;
|
||||
|
||||
KompareListViewItem* item = m_itemDict[ diff ];
|
||||
if( !item ) {
|
||||
kDebug(8104) << "KompareListView::slotSetSelection(): couldn't find our selection!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// why does this not happen when the user clicks on a diff? see the comment above.
|
||||
if( scroll )
|
||||
scrollToId(item->scrollId());
|
||||
setUpdatesEnabled( false );
|
||||
int x = horizontalScrollBar()->value();
|
||||
int y = verticalScrollBar()->value();
|
||||
setCurrentItem( item );
|
||||
horizontalScrollBar()->setValue( x );
|
||||
verticalScrollBar()->setValue( y );
|
||||
setUpdatesEnabled( true );
|
||||
}
|
||||
|
||||
void KompareListView::slotSetSelection( const Difference* diff )
|
||||
{
|
||||
kDebug(8104) << "KompareListView::slotSetSelection( const Difference* diff )" << endl;
|
||||
|
||||
setSelectedDifference( diff, true );
|
||||
}
|
||||
|
||||
void KompareListView::slotSetSelection( const DiffModel* model, const Difference* diff )
|
||||
{
|
||||
kDebug(8104) << "KompareListView::slotSetSelection( const DiffModel* model, const Difference* diff )" << endl;
|
||||
|
||||
if( m_selectedModel && m_selectedModel == model ) {
|
||||
slotSetSelection( diff );
|
||||
return;
|
||||
}
|
||||
|
||||
clear();
|
||||
m_items.clear();
|
||||
m_itemDict.clear();
|
||||
m_selectedModel = model;
|
||||
|
||||
DiffHunkListConstIterator hunkIt = model->hunks()->begin();
|
||||
DiffHunkListConstIterator hEnd = model->hunks()->end();
|
||||
|
||||
KompareListViewItem* item = 0;
|
||||
m_nextPaintOffset = 0;
|
||||
|
||||
for ( ; hunkIt != hEnd; ++hunkIt )
|
||||
{
|
||||
if( item )
|
||||
item = new KompareListViewHunkItem( this, item, *hunkIt, model->isBlended() );
|
||||
else
|
||||
item = new KompareListViewHunkItem( this, *hunkIt, model->isBlended() );
|
||||
|
||||
DifferenceListConstIterator diffIt = (*hunkIt)->differences().begin();
|
||||
DifferenceListConstIterator dEnd = (*hunkIt)->differences().end();
|
||||
|
||||
for ( ; diffIt != dEnd; ++diffIt )
|
||||
{
|
||||
item = new KompareListViewDiffItem( this, item, *diffIt );
|
||||
|
||||
int type = (*diffIt)->type();
|
||||
|
||||
if ( type != Difference::Unchanged )
|
||||
{
|
||||
m_items.append( (KompareListViewDiffItem*)item );
|
||||
m_itemDict.insert( *diffIt, (KompareListViewDiffItem*)item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resizeColumnToContents( COL_LINE_NO );
|
||||
resizeColumnToContents( COL_MAIN );
|
||||
|
||||
slotSetSelection( diff );
|
||||
}
|
||||
|
||||
KompareListViewDiffItem* KompareListView::diffItemAt( const QPoint& pos )
|
||||
{
|
||||
KompareListViewItem* item = static_cast<KompareListViewItem*>( itemAt( pos ) );
|
||||
if( !item )
|
||||
return 0;
|
||||
switch( item->type() ) {
|
||||
case KompareListViewItem::Hunk:
|
||||
if( item->paintHeight() ) return 0; // no diff item here
|
||||
// zero height (fake 1 pixel height), so a diff item shines through
|
||||
return static_cast<KompareListViewDiffItem*>( itemBelow( item ) );
|
||||
case KompareListViewItem::Line:
|
||||
case KompareListViewItem::Blank:
|
||||
return static_cast<KompareListViewLineItem*>( item )->diffItemParent();
|
||||
case KompareListViewItem::Container:
|
||||
return static_cast<KompareListViewLineContainerItem*>( item )->diffItemParent();
|
||||
case KompareListViewItem::Diff:
|
||||
return static_cast<KompareListViewDiffItem*>( item );
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListView::mousePressEvent( QMouseEvent* e )
|
||||
{
|
||||
QPoint vp = e->pos();
|
||||
KompareListViewDiffItem* diffItem = diffItemAt( vp );
|
||||
if( diffItem && diffItem->difference()->type() != Difference::Unchanged ) {
|
||||
emit differenceClicked( diffItem->difference() );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListView::mouseDoubleClickEvent( QMouseEvent* e )
|
||||
{
|
||||
QPoint vp = e->pos();
|
||||
KompareListViewDiffItem* diffItem = diffItemAt( vp );
|
||||
if ( diffItem && diffItem->difference()->type() != Difference::Unchanged ) {
|
||||
// FIXME: make a new signal that does both
|
||||
emit differenceClicked( diffItem->difference() );
|
||||
emit applyDifference( !diffItem->difference()->applied() );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListView::renumberLines( void )
|
||||
{
|
||||
// kDebug( 8104 ) << "Begin" << endl;
|
||||
unsigned int newLineNo = 1;
|
||||
if( !topLevelItemCount() ) return;
|
||||
KompareListViewItem* item = (KompareListViewItem*)topLevelItem( 0 );
|
||||
while( item ) {
|
||||
// kDebug( 8104 ) << "type: " << item->type() << endl;
|
||||
if ( item->type() != KompareListViewItem::Container
|
||||
&& item->type() != KompareListViewItem::Blank
|
||||
&& item->type() != KompareListViewItem::Hunk )
|
||||
{
|
||||
// kDebug( 8104 ) << QString::number( newLineNo ) << endl;
|
||||
item->setText( COL_LINE_NO, QString::number( newLineNo++ ) );
|
||||
}
|
||||
item = (KompareListViewItem*)itemBelow( item );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListView::slotApplyDifference( bool apply )
|
||||
{
|
||||
m_itemDict[ m_selectedDifference ]->applyDifference( apply );
|
||||
// now renumber the line column if this is the destination
|
||||
if ( !m_isSource )
|
||||
renumberLines();
|
||||
}
|
||||
|
||||
void KompareListView::slotApplyAllDifferences( bool apply )
|
||||
{
|
||||
QHash<const Diff2::Difference*, KompareListViewDiffItem*>::ConstIterator it = m_itemDict.constBegin();
|
||||
QHash<const Diff2::Difference*, KompareListViewDiffItem*>::ConstIterator end = m_itemDict.constEnd();
|
||||
for ( ; it != end; ++it )
|
||||
it.value()->applyDifference( apply );
|
||||
|
||||
// now renumber the line column if this is the destination
|
||||
if ( !m_isSource )
|
||||
renumberLines();
|
||||
update();
|
||||
}
|
||||
|
||||
void KompareListView::slotApplyDifference( const Difference* diff, bool apply )
|
||||
{
|
||||
m_itemDict[ diff ]->applyDifference( apply );
|
||||
// now renumber the line column if this is the destination
|
||||
if ( !m_isSource )
|
||||
renumberLines();
|
||||
}
|
||||
|
||||
void KompareListView::wheelEvent( QWheelEvent* e )
|
||||
{
|
||||
e->ignore(); // we want the parent to catch wheel events
|
||||
}
|
||||
|
||||
void KompareListView::resizeEvent( QResizeEvent* e )
|
||||
{
|
||||
QTreeWidget::resizeEvent(e);
|
||||
emit resized();
|
||||
}
|
||||
|
||||
KompareListViewItemDelegate::KompareListViewItemDelegate( QObject* parent )
|
||||
: QStyledItemDelegate( parent )
|
||||
{
|
||||
}
|
||||
|
||||
KompareListViewItemDelegate::~KompareListViewItemDelegate()
|
||||
{
|
||||
}
|
||||
|
||||
void KompareListViewItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
int column = index.column();
|
||||
QStyleOptionViewItemV4 changedOption = option;
|
||||
if( column == COL_LINE_NO )
|
||||
changedOption.displayAlignment = Qt::AlignRight;
|
||||
KompareListViewItem* item = static_cast<KompareListViewItem*>( static_cast<KompareListView*>( parent() )->itemFromIndex( index ) );
|
||||
item->paintCell( painter, changedOption, column );
|
||||
}
|
||||
|
||||
QSize KompareListViewItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
KompareListViewItem* item = static_cast<KompareListViewItem*>( static_cast<KompareListView*>( parent() )->itemFromIndex( index ) );
|
||||
QSize hint = QStyledItemDelegate::sizeHint( option, index );
|
||||
return QSize( hint.width() + ITEM_MARGIN, item->height() );
|
||||
}
|
||||
|
||||
KompareListViewItem::KompareListViewItem( KompareListView* parent, int type )
|
||||
: QTreeWidgetItem( parent, type ),
|
||||
m_scrollId( 0 ),
|
||||
m_height( 0 ),
|
||||
m_paintHeight( 0 ),
|
||||
m_paintOffset( parent->nextPaintOffset() )
|
||||
{
|
||||
// kDebug(8104) << "Created KompareListViewItem with scroll id " << m_scrollId << endl;
|
||||
}
|
||||
|
||||
KompareListViewItem::KompareListViewItem( KompareListView* parent, KompareListViewItem* after, int type )
|
||||
: QTreeWidgetItem( parent, after, type ),
|
||||
m_scrollId( after->scrollId() + after->maxHeight() ),
|
||||
m_height( 0 ),
|
||||
m_paintHeight( 0 ),
|
||||
m_paintOffset( parent->nextPaintOffset() )
|
||||
{
|
||||
// kDebug(8104) << "Created KompareListViewItem with scroll id " << m_scrollId << endl;
|
||||
}
|
||||
|
||||
KompareListViewItem::KompareListViewItem( KompareListViewItem* parent, int type )
|
||||
: QTreeWidgetItem( parent, type ),
|
||||
m_scrollId( 0 ),
|
||||
m_height( 0 ),
|
||||
m_paintHeight( 0 ),
|
||||
m_paintOffset( parent->kompareListView()->nextPaintOffset() )
|
||||
{
|
||||
}
|
||||
|
||||
KompareListViewItem::KompareListViewItem( KompareListViewItem* parent, KompareListViewItem* /*after*/, int type )
|
||||
: QTreeWidgetItem( parent, type ),
|
||||
m_scrollId( 0 ),
|
||||
m_height( 0 ),
|
||||
m_paintHeight( 0 ),
|
||||
m_paintOffset( parent->kompareListView()->nextPaintOffset() )
|
||||
{
|
||||
}
|
||||
|
||||
int KompareListViewItem::height() const
|
||||
{
|
||||
return m_height;
|
||||
}
|
||||
|
||||
void KompareListViewItem::setHeight( int h )
|
||||
{
|
||||
m_height = m_paintHeight = h;
|
||||
// QTreeWidget doesn't like zero height, fudge around it.
|
||||
m_height -= m_paintOffset;
|
||||
if( m_height <= 0 ) {
|
||||
kompareListView()->setNextPaintOffset( 1 - m_height );
|
||||
m_height = 1;
|
||||
} else kompareListView()->setNextPaintOffset( 0 );
|
||||
}
|
||||
|
||||
int KompareListViewItem::paintHeight() const
|
||||
{
|
||||
return m_paintHeight;
|
||||
}
|
||||
|
||||
int KompareListViewItem::paintOffset() const
|
||||
{
|
||||
return m_paintOffset;
|
||||
}
|
||||
|
||||
bool KompareListViewItem::isCurrent() const
|
||||
{
|
||||
return treeWidget()->currentItem() == this;
|
||||
}
|
||||
|
||||
KompareListView* KompareListViewItem::kompareListView() const
|
||||
{
|
||||
return (KompareListView*)treeWidget();
|
||||
}
|
||||
|
||||
void KompareListViewItem::paintCell( QPainter* p, const QStyleOptionViewItem& option, int column )
|
||||
{
|
||||
// Default implementation for zero-height items.
|
||||
// We have to paint the item which shines through or we'll end up with glitches.
|
||||
KompareListViewItem* nextItem = (KompareListViewItem*)kompareListView()->itemBelow(this);
|
||||
if( nextItem ) {
|
||||
QStyleOptionViewItemV4 changedOption = option;
|
||||
changedOption.rect.translate( 0, height() );
|
||||
nextItem->paintCell( p, changedOption, column );
|
||||
}
|
||||
}
|
||||
|
||||
KompareListViewDiffItem::KompareListViewDiffItem( KompareListView* parent, Difference* difference )
|
||||
: KompareListViewItem( parent, Diff ),
|
||||
m_difference( difference ),
|
||||
m_sourceItem( 0L ),
|
||||
m_destItem( 0L )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
KompareListViewDiffItem::KompareListViewDiffItem( KompareListView* parent, KompareListViewItem* after, Difference* difference )
|
||||
: KompareListViewItem( parent, after, Diff ),
|
||||
m_difference( difference ),
|
||||
m_sourceItem( 0L ),
|
||||
m_destItem( 0L )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
KompareListViewDiffItem::~KompareListViewDiffItem()
|
||||
{
|
||||
m_difference = 0;
|
||||
}
|
||||
|
||||
void KompareListViewDiffItem::init()
|
||||
{
|
||||
setHeight( 0 );
|
||||
setExpanded( true );
|
||||
int nextPaintOffset = kompareListView()->nextPaintOffset();
|
||||
m_destItem = new KompareListViewLineContainerItem( this, false );
|
||||
kompareListView()->setNextPaintOffset(nextPaintOffset);
|
||||
m_sourceItem = new KompareListViewLineContainerItem( this, true );
|
||||
setVisibility();
|
||||
}
|
||||
|
||||
void KompareListViewDiffItem::setVisibility()
|
||||
{
|
||||
m_sourceItem->setHidden( !(kompareListView()->isSource() || m_difference->applied()) );
|
||||
m_destItem->setHidden( !m_sourceItem->isHidden() );
|
||||
}
|
||||
|
||||
void KompareListViewDiffItem::applyDifference( bool apply )
|
||||
{
|
||||
kDebug(8104) << "KompareListViewDiffItem::applyDifference( " << apply << " )" << endl;
|
||||
setVisibility();
|
||||
}
|
||||
|
||||
int KompareListViewDiffItem::maxHeight()
|
||||
{
|
||||
int lines = qMax( m_difference->sourceLineCount(), m_difference->destinationLineCount() );
|
||||
if( lines == 0 )
|
||||
return BLANK_LINE_HEIGHT;
|
||||
else
|
||||
return lines * treeWidget()->fontMetrics().height();
|
||||
}
|
||||
|
||||
KompareListViewLineContainerItem::KompareListViewLineContainerItem( KompareListViewDiffItem* parent, bool isSource )
|
||||
: KompareListViewItem( parent, Container ),
|
||||
m_blankLineItem( 0 ),
|
||||
m_isSource( isSource )
|
||||
{
|
||||
// kDebug(8104) << "isSource ? " << (isSource ? " Yes!" : " No!") << endl;
|
||||
setHeight( 0 );
|
||||
setExpanded( true );
|
||||
|
||||
int lines = lineCount();
|
||||
int line = lineNumber();
|
||||
// kDebug(8104) << "LineNumber : " << lineNumber() << endl;
|
||||
if( lines == 0 ) {
|
||||
m_blankLineItem = new KompareListViewBlankLineItem( this );
|
||||
return;
|
||||
}
|
||||
|
||||
for( int i = 0; i < lines; i++, line++ ) {
|
||||
new KompareListViewLineItem( this, line, lineAt( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
KompareListViewLineContainerItem::~KompareListViewLineContainerItem()
|
||||
{
|
||||
}
|
||||
|
||||
KompareListViewDiffItem* KompareListViewLineContainerItem::diffItemParent() const
|
||||
{
|
||||
return (KompareListViewDiffItem*)parent();
|
||||
}
|
||||
|
||||
int KompareListViewLineContainerItem::lineCount() const
|
||||
{
|
||||
return m_isSource ? diffItemParent()->difference()->sourceLineCount() :
|
||||
diffItemParent()->difference()->destinationLineCount();
|
||||
}
|
||||
|
||||
int KompareListViewLineContainerItem::lineNumber() const
|
||||
{
|
||||
return m_isSource ? diffItemParent()->difference()->sourceLineNumber() :
|
||||
diffItemParent()->difference()->destinationLineNumber();
|
||||
}
|
||||
|
||||
DifferenceString* KompareListViewLineContainerItem::lineAt( int i ) const
|
||||
{
|
||||
return m_isSource ? diffItemParent()->difference()->sourceLineAt( i ) :
|
||||
diffItemParent()->difference()->destinationLineAt( i );
|
||||
}
|
||||
|
||||
KompareListViewLineItem::KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, DifferenceString* text )
|
||||
: KompareListViewItem( parent, Line )
|
||||
{
|
||||
init( line, text );
|
||||
}
|
||||
|
||||
KompareListViewLineItem::KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, DifferenceString* text, int type )
|
||||
: KompareListViewItem( parent, type )
|
||||
{
|
||||
init( line, text );
|
||||
}
|
||||
|
||||
KompareListViewLineItem::~KompareListViewLineItem()
|
||||
{
|
||||
m_text = 0;
|
||||
}
|
||||
|
||||
void KompareListViewLineItem::init( int line, DifferenceString* text )
|
||||
{
|
||||
setHeight( treeWidget()->fontMetrics().height() );
|
||||
setText( COL_LINE_NO, QString::number( line ) );
|
||||
setText( COL_MAIN, text->string() );
|
||||
m_text = text;
|
||||
}
|
||||
|
||||
void KompareListViewLineItem::paintCell( QPainter* p, const QStyleOptionViewItem& option, int column )
|
||||
{
|
||||
int width = option.rect.width();
|
||||
Qt::Alignment align = option.displayAlignment;
|
||||
|
||||
p->setRenderHint(QPainter::Antialiasing);
|
||||
p->translate(option.rect.topLeft());
|
||||
p->translate(0, -paintOffset());
|
||||
|
||||
QColor bg( Qt::white ); // Always make the background white when it is not a real difference
|
||||
if ( diffItemParent()->difference()->type() == Difference::Unchanged )
|
||||
{
|
||||
if ( column == COL_LINE_NO )
|
||||
{
|
||||
bg = QColor( Qt::lightGray );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bg = kompareListView()->settings()->colorForDifferenceType(
|
||||
diffItemParent()->difference()->type(),
|
||||
diffItemParent()->isCurrent(),
|
||||
diffItemParent()->difference()->applied() );
|
||||
}
|
||||
|
||||
// Paint background
|
||||
p->fillRect( 0, 0, width, paintHeight(), bg );
|
||||
|
||||
// Paint foreground
|
||||
if ( diffItemParent()->difference()->type() == Difference::Unchanged )
|
||||
p->setPen( QColor( Qt::darkGray ) ); // always make normal text gray
|
||||
else
|
||||
p->setPen( QColor( Qt::black ) ); // make text with changes black
|
||||
|
||||
paintText( p, bg, column, width, align );
|
||||
|
||||
// Paint darker lines around selected item
|
||||
if ( diffItemParent()->isCurrent() )
|
||||
{
|
||||
p->translate(0.5,0.5);
|
||||
p->setPen( bg.dark(135) );
|
||||
QTreeWidgetItem* parentItem = parent();
|
||||
if ( this == parentItem->child( 0 ) )
|
||||
p->drawLine( 0, 0, width, 0 );
|
||||
if ( this == parentItem->child( parentItem->childCount() - 1 ) )
|
||||
p->drawLine( 0, paintHeight() - 1, width, paintHeight() - 1 );
|
||||
}
|
||||
|
||||
p->resetTransform();
|
||||
}
|
||||
|
||||
void KompareListViewLineItem::paintText( QPainter* p, const QColor& bg, int column, int width, int align )
|
||||
{
|
||||
if ( column == COL_MAIN )
|
||||
{
|
||||
QString textChunk;
|
||||
int offset = ITEM_MARGIN;
|
||||
int prevValue = 0;
|
||||
int charsDrawn = 0;
|
||||
int chunkWidth;
|
||||
QBrush changeBrush( bg, Qt::Dense3Pattern );
|
||||
QBrush normalBrush( bg, Qt::SolidPattern );
|
||||
QBrush brush;
|
||||
|
||||
if ( m_text->string().isEmpty() )
|
||||
{
|
||||
p->fillRect( 0, 0, width, paintHeight(), normalBrush );
|
||||
return;
|
||||
}
|
||||
|
||||
p->fillRect( 0, 0, offset, paintHeight(), normalBrush );
|
||||
|
||||
if ( !m_text->markerList().isEmpty() )
|
||||
{
|
||||
MarkerListConstIterator markerIt = m_text->markerList().begin();
|
||||
MarkerListConstIterator mEnd = m_text->markerList().end();
|
||||
Marker* m = *markerIt;
|
||||
|
||||
for ( ; markerIt != mEnd; ++markerIt )
|
||||
{
|
||||
m = *markerIt;
|
||||
textChunk = m_text->string().mid( prevValue, m->offset() - prevValue );
|
||||
// kDebug(8104) << "TextChunk = \"" << textChunk << "\"" << endl;
|
||||
// kDebug(8104) << "c->offset() = " << c->offset() << endl;
|
||||
// kDebug(8104) << "prevValue = " << prevValue << endl;
|
||||
expandTabs(textChunk, kompareListView()->settings()->m_tabToNumberOfSpaces, charsDrawn);
|
||||
charsDrawn += textChunk.length();
|
||||
prevValue = m->offset();
|
||||
if ( m->type() == Marker::End )
|
||||
{
|
||||
QFont font( p->font() );
|
||||
font.setBold( true );
|
||||
p->setFont( font );
|
||||
// p->setPen( Qt::blue );
|
||||
brush = changeBrush;
|
||||
}
|
||||
else
|
||||
{
|
||||
QFont font( p->font() );
|
||||
font.setBold( false );
|
||||
p->setFont( font );
|
||||
// p->setPen( Qt::black );
|
||||
brush = normalBrush;
|
||||
}
|
||||
chunkWidth = p->fontMetrics().width( textChunk );
|
||||
p->fillRect( offset, 0, chunkWidth, paintHeight(), brush );
|
||||
p->drawText( offset, 0,
|
||||
chunkWidth, paintHeight(),
|
||||
align, textChunk );
|
||||
offset += chunkWidth;
|
||||
}
|
||||
}
|
||||
if ( prevValue < m_text->string().length() )
|
||||
{
|
||||
// Still have to draw some string without changes
|
||||
textChunk = m_text->string().mid( prevValue, qMax( 1, m_text->string().length() - prevValue ) );
|
||||
expandTabs(textChunk, kompareListView()->settings()->m_tabToNumberOfSpaces, charsDrawn);
|
||||
// kDebug(8104) << "TextChunk = \"" << textChunk << "\"" << endl;
|
||||
QFont font( p->font() );
|
||||
font.setBold( false );
|
||||
p->setFont( font );
|
||||
chunkWidth = p->fontMetrics().width( textChunk );
|
||||
p->fillRect( offset, 0, chunkWidth, paintHeight(), normalBrush );
|
||||
p->drawText( offset, 0,
|
||||
chunkWidth, paintHeight(),
|
||||
align, textChunk );
|
||||
offset += chunkWidth;
|
||||
}
|
||||
p->fillRect( offset, 0, width - offset, paintHeight(), normalBrush );
|
||||
}
|
||||
else
|
||||
{
|
||||
p->fillRect( 0, 0, width, paintHeight(), bg );
|
||||
p->drawText( ITEM_MARGIN, 0,
|
||||
width - ITEM_MARGIN, paintHeight(),
|
||||
align, text( column ) );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListViewLineItem::expandTabs(QString& text, int tabstop, int startPos) const
|
||||
{
|
||||
int index;
|
||||
while((index = text.indexOf(QChar(9)))!= -1)
|
||||
text.replace(index, 1, QString(tabstop-((startPos+index)%tabstop),' '));
|
||||
}
|
||||
|
||||
KompareListViewDiffItem* KompareListViewLineItem::diffItemParent() const
|
||||
{
|
||||
KompareListViewLineContainerItem* p = (KompareListViewLineContainerItem*)parent();
|
||||
return p->diffItemParent();
|
||||
}
|
||||
|
||||
KompareListViewBlankLineItem::KompareListViewBlankLineItem( KompareListViewLineContainerItem* parent )
|
||||
: KompareListViewLineItem( parent, 0, new DifferenceString(), Blank )
|
||||
{
|
||||
setHeight( BLANK_LINE_HEIGHT );
|
||||
}
|
||||
|
||||
void KompareListViewBlankLineItem::paintText( QPainter* p, const QColor& bg, int column, int width, int /* align */ )
|
||||
{
|
||||
if ( column == COL_MAIN )
|
||||
{
|
||||
QBrush normalBrush( bg, Qt::SolidPattern );
|
||||
p->fillRect( 0, 0, width, paintHeight(), normalBrush );
|
||||
}
|
||||
}
|
||||
|
||||
KompareListViewHunkItem::KompareListViewHunkItem( KompareListView* parent, DiffHunk* hunk, bool zeroHeight )
|
||||
: KompareListViewItem( parent, Hunk ),
|
||||
m_zeroHeight( zeroHeight ),
|
||||
m_hunk( hunk )
|
||||
{
|
||||
setHeight( maxHeight() );
|
||||
setFlags( flags() & ~Qt::ItemIsSelectable );
|
||||
}
|
||||
|
||||
KompareListViewHunkItem::KompareListViewHunkItem( KompareListView* parent, KompareListViewItem* after, DiffHunk* hunk, bool zeroHeight )
|
||||
: KompareListViewItem( parent, after, Hunk ),
|
||||
m_zeroHeight( zeroHeight ),
|
||||
m_hunk( hunk )
|
||||
{
|
||||
setHeight( maxHeight() );
|
||||
setFlags( flags() & ~Qt::ItemIsSelectable );
|
||||
}
|
||||
|
||||
KompareListViewHunkItem::~KompareListViewHunkItem()
|
||||
{
|
||||
m_hunk = 0;
|
||||
}
|
||||
|
||||
int KompareListViewHunkItem::maxHeight()
|
||||
{
|
||||
if( m_zeroHeight ) {
|
||||
return 0;
|
||||
} else if( m_hunk->function().isEmpty() ) {
|
||||
return HUNK_LINE_HEIGHT;
|
||||
} else {
|
||||
return treeWidget()->fontMetrics().height();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareListViewHunkItem::paintCell( QPainter* p, const QStyleOptionViewItem& option, int column )
|
||||
{
|
||||
if( m_zeroHeight ) {
|
||||
KompareListViewItem::paintCell( p, option, column );
|
||||
} else {
|
||||
int x = option.rect.left();
|
||||
int y = option.rect.top() - paintOffset();
|
||||
int width = option.rect.width();
|
||||
Qt::Alignment align = option.displayAlignment;
|
||||
|
||||
p->fillRect( x, y, width, paintHeight(), QColor( Qt::lightGray ) ); // Hunk headers should be lightgray
|
||||
p->setPen( QColor( Qt::black ) ); // Text color in hunk should be black
|
||||
if( column == COL_MAIN ) {
|
||||
p->drawText( x + ITEM_MARGIN, y, width - ITEM_MARGIN, paintHeight(),
|
||||
align, m_hunk->function() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "komparelistview.moc"
|
271
kompare/komparepart/komparelistview.h
Normal file
|
@ -0,0 +1,271 @@
|
|||
/***************************************************************************
|
||||
komparelistview.h
|
||||
-----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARELISTVIEW_H
|
||||
#define KOMPARELISTVIEW_H
|
||||
|
||||
#include <QHash>
|
||||
#include <QLabel>
|
||||
#include <QResizeEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QVBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QFrame>
|
||||
#include <QTreeWidget>
|
||||
#include <QStyledItemDelegate>
|
||||
|
||||
namespace Diff2 {
|
||||
class DiffModel;
|
||||
class DiffHunk;
|
||||
class Difference;
|
||||
class DifferenceString;
|
||||
}
|
||||
class ViewSettings;
|
||||
class KompareSplitter;
|
||||
class KompareListView;
|
||||
class KompareListViewItem;
|
||||
class KompareListViewItemDelegate;
|
||||
class KompareListViewDiffItem;
|
||||
class KompareListViewLineContainerItem;
|
||||
|
||||
class KompareListView : public QTreeWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class KompareListViewItemDelegate;
|
||||
|
||||
public:
|
||||
KompareListView( bool isSource, ViewSettings* settings, QWidget* parent, const char* name = 0 );
|
||||
virtual ~KompareListView();
|
||||
|
||||
KompareListViewItem* itemAtIndex( int i );
|
||||
int firstVisibleDifference();
|
||||
int lastVisibleDifference();
|
||||
QRect itemRect( int i );
|
||||
int minScrollId();
|
||||
int maxScrollId();
|
||||
int contentsHeight();
|
||||
int contentsWidth();
|
||||
int visibleHeight();
|
||||
int visibleWidth();
|
||||
int contentsX();
|
||||
int contentsY();
|
||||
int nextPaintOffset() const;
|
||||
void setNextPaintOffset(int offset);
|
||||
|
||||
bool isSource() const { return m_isSource; };
|
||||
ViewSettings* settings() const { return m_settings; };
|
||||
|
||||
void setSelectedDifference( const Diff2::Difference* diff, bool scroll );
|
||||
|
||||
public slots:
|
||||
void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void slotSetSelection( const Diff2::Difference* diff );
|
||||
void setXOffset( int x );
|
||||
void scrollToId( int id );
|
||||
int scrollId();
|
||||
void slotApplyDifference( bool apply );
|
||||
void slotApplyAllDifferences( bool apply );
|
||||
void slotApplyDifference( const Diff2::Difference* diff, bool apply );
|
||||
|
||||
signals:
|
||||
void differenceClicked( const Diff2::Difference* diff );
|
||||
void applyDifference( bool apply );
|
||||
void resized();
|
||||
|
||||
protected:
|
||||
virtual void wheelEvent( QWheelEvent* e );
|
||||
virtual void resizeEvent( QResizeEvent* e );
|
||||
virtual void mousePressEvent ( QMouseEvent * e );
|
||||
virtual void mouseDoubleClickEvent ( QMouseEvent* );
|
||||
virtual void mouseReleaseEvent ( QMouseEvent * ) {};
|
||||
virtual void mouseMoveEvent ( QMouseEvent * ) {};
|
||||
|
||||
private:
|
||||
QRect totalVisualItemRect( QTreeWidgetItem* item );
|
||||
KompareListViewDiffItem* diffItemAt( const QPoint& pos );
|
||||
void renumberLines( void );
|
||||
|
||||
QList<KompareListViewDiffItem*> m_items;
|
||||
QHash<const Diff2::Difference*, KompareListViewDiffItem*> m_itemDict;
|
||||
bool m_isSource;
|
||||
ViewSettings* m_settings;
|
||||
int m_scrollId;
|
||||
int m_maxMainWidth;
|
||||
const Diff2::DiffModel* m_selectedModel;
|
||||
const Diff2::Difference* m_selectedDifference;
|
||||
int m_nextPaintOffset;
|
||||
};
|
||||
|
||||
class KompareListViewFrame : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KompareListViewFrame( bool isSource, ViewSettings* settings, KompareSplitter* parent, const char* name = 0 );
|
||||
virtual ~KompareListViewFrame() {};
|
||||
KompareListView* view() { return &m_view; };
|
||||
|
||||
public slots:
|
||||
void slotSetModel( const Diff2::DiffModel* model );
|
||||
|
||||
private:
|
||||
KompareListView m_view;
|
||||
QLabel m_label;
|
||||
QVBoxLayout m_layout;
|
||||
};
|
||||
|
||||
class KompareListViewItemDelegate : public QStyledItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KompareListViewItemDelegate( QObject* parent );
|
||||
virtual ~KompareListViewItemDelegate();
|
||||
virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
};
|
||||
|
||||
class KompareListViewItem : public QTreeWidgetItem
|
||||
{
|
||||
public:
|
||||
KompareListViewItem( KompareListView* parent, int type );
|
||||
KompareListViewItem( KompareListView* parent, KompareListViewItem* after, int type );
|
||||
KompareListViewItem( KompareListViewItem* parent, int type );
|
||||
KompareListViewItem( KompareListViewItem* parent, KompareListViewItem* after, int type );
|
||||
|
||||
virtual void paintCell( QPainter* p, const QStyleOptionViewItem& option, int column );
|
||||
|
||||
void repaint();
|
||||
int height() const;
|
||||
void setHeight( int h );
|
||||
int paintHeight() const;
|
||||
int paintOffset() const;
|
||||
bool isCurrent() const;
|
||||
int scrollId() const { return m_scrollId; };
|
||||
|
||||
virtual int maxHeight() = 0;
|
||||
|
||||
KompareListView* kompareListView() const;
|
||||
|
||||
enum ListViewItemType { Diff = QTreeWidgetItem::UserType + 1, Container = QTreeWidgetItem::UserType + 2, Line = QTreeWidgetItem::UserType + 3, Blank = QTreeWidgetItem::UserType + 4, Hunk = QTreeWidgetItem::UserType + 5 };
|
||||
|
||||
private:
|
||||
int m_scrollId;
|
||||
int m_height;
|
||||
int m_paintHeight;
|
||||
int m_paintOffset;
|
||||
};
|
||||
|
||||
class KompareListViewDiffItem : public KompareListViewItem
|
||||
{
|
||||
public:
|
||||
KompareListViewDiffItem( KompareListView* parent, Diff2::Difference* difference );
|
||||
KompareListViewDiffItem( KompareListView* parent, KompareListViewItem* after, Diff2::Difference* difference );
|
||||
~KompareListViewDiffItem();
|
||||
|
||||
void applyDifference( bool apply );
|
||||
|
||||
Diff2::Difference* difference() { return m_difference; };
|
||||
|
||||
virtual int maxHeight();
|
||||
|
||||
private:
|
||||
void init();
|
||||
void setVisibility();
|
||||
|
||||
private:
|
||||
Diff2::Difference* m_difference;
|
||||
KompareListViewLineContainerItem* m_sourceItem;
|
||||
KompareListViewLineContainerItem* m_destItem;
|
||||
};
|
||||
|
||||
class KompareListViewLineItem;
|
||||
class KompareListViewBlankLineItem;
|
||||
|
||||
class KompareListViewLineContainerItem : public KompareListViewItem
|
||||
{
|
||||
public:
|
||||
KompareListViewLineContainerItem( KompareListViewDiffItem* parent, bool isSource );
|
||||
~KompareListViewLineContainerItem();
|
||||
|
||||
virtual int maxHeight() { return 0; }
|
||||
|
||||
KompareListViewDiffItem* diffItemParent() const;
|
||||
|
||||
private:
|
||||
int lineCount() const;
|
||||
int lineNumber() const;
|
||||
Diff2::DifferenceString* lineAt( int i ) const;
|
||||
|
||||
private:
|
||||
KompareListViewBlankLineItem* m_blankLineItem;
|
||||
bool m_isSource;
|
||||
};
|
||||
|
||||
class KompareListViewLineItem : public KompareListViewItem
|
||||
{
|
||||
public:
|
||||
KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, Diff2::DifferenceString* text );
|
||||
KompareListViewLineItem( KompareListViewLineContainerItem* parent, int line, Diff2::DifferenceString* text, int type );
|
||||
~KompareListViewLineItem();
|
||||
|
||||
virtual int maxHeight() { return 0; }
|
||||
|
||||
virtual void paintCell( QPainter* p, const QStyleOptionViewItem& option, int column );
|
||||
|
||||
KompareListViewDiffItem* diffItemParent() const;
|
||||
|
||||
protected:
|
||||
virtual void paintText( QPainter* p, const QColor& bg, int column, int width, int align );
|
||||
|
||||
private:
|
||||
void init( int line, Diff2::DifferenceString* text );
|
||||
void expandTabs(QString& text, int tabstop, int startPos = 0) const;
|
||||
|
||||
private:
|
||||
Diff2::DifferenceString* m_text;
|
||||
};
|
||||
|
||||
class KompareListViewBlankLineItem : public KompareListViewLineItem
|
||||
{
|
||||
public:
|
||||
KompareListViewBlankLineItem( KompareListViewLineContainerItem* parent );
|
||||
|
||||
protected:
|
||||
virtual void paintText( QPainter* p, const QColor& bg, int column, int width, int align );
|
||||
};
|
||||
|
||||
class KompareListViewHunkItem : public KompareListViewItem
|
||||
{
|
||||
public:
|
||||
KompareListViewHunkItem( KompareListView* parent, Diff2::DiffHunk* hunk, bool zeroHeight = false );
|
||||
KompareListViewHunkItem( KompareListView* parent, KompareListViewItem* after, Diff2::DiffHunk* hunk, bool zeroHeight= false );
|
||||
~KompareListViewHunkItem();
|
||||
|
||||
virtual void paintCell( QPainter* p, const QStyleOptionViewItem& option, int column );
|
||||
|
||||
virtual int maxHeight();
|
||||
|
||||
private:
|
||||
bool m_zeroHeight;
|
||||
Diff2::DiffHunk* m_hunk;
|
||||
};
|
||||
|
||||
#endif
|
72
kompare/komparepart/komparepart.desktop
Normal file
|
@ -0,0 +1,72 @@
|
|||
[Desktop Entry]
|
||||
GenericComment=A part to graphically show the difference between 2 files
|
||||
Name=KomparePart
|
||||
Name[af]=K-vergelyk-deel
|
||||
Name[ast]=KomparePart
|
||||
Name[bg]=KomparePart
|
||||
Name[br]=KomparePart
|
||||
Name[bs]=KomparePart
|
||||
Name[ca]=KomparePart
|
||||
Name[ca@valencia]=KomparePart
|
||||
Name[cs]=KomparePart
|
||||
Name[cy]=KomparePart
|
||||
Name[da]=KomparePart
|
||||
Name[de]=Einbettungsfähige Komponente von Kompare
|
||||
Name[el]=KomparePart
|
||||
Name[en_GB]=KomparePart
|
||||
Name[eo]=Komparo-parto
|
||||
Name[es]=KomparePart
|
||||
Name[et]=KomparePart
|
||||
Name[eu]=KomparePart
|
||||
Name[fi]=KomparePart
|
||||
Name[fr]=Composant de Kompare
|
||||
Name[ga]=KomparePart
|
||||
Name[gl]=KomparePart
|
||||
Name[he]=רכיב Kompare
|
||||
Name[hr]=KomparePart
|
||||
Name[hu]=KomparePart
|
||||
Name[is]=KomparePart
|
||||
Name[it]=KomparePart
|
||||
Name[ja]=KomparePart
|
||||
Name[kk]=KomparePart
|
||||
Name[km]=KomparePart
|
||||
Name[ko]=KomparePart
|
||||
Name[lt]=KomparePart
|
||||
Name[lv]=KomparePart
|
||||
Name[mr]=कंपेअर-पार्ट
|
||||
Name[ms]=KomparePart
|
||||
Name[nb]=KomparePart
|
||||
Name[nds]=KomparePart
|
||||
Name[ne]=KomparePart
|
||||
Name[nl]=KomparePart
|
||||
Name[nn]=KomparePart
|
||||
Name[pa]=KomparePart
|
||||
Name[pl]=Moduł Kompare
|
||||
Name[pt]=KomparePart
|
||||
Name[pt_BR]=KomparePart
|
||||
Name[ro]=Componentă Kompare
|
||||
Name[ru]=Компонент утилиты сравнения файлов
|
||||
Name[sk]=KomparePart
|
||||
Name[sl]=KomparePart
|
||||
Name[sq]=KomparePart
|
||||
Name[sr]=К‑поређење део
|
||||
Name[sr@ijekavian]=К‑поређење део
|
||||
Name[sr@ijekavianlatin]=K‑poređenje deo
|
||||
Name[sr@latin]=K‑poređenje deo
|
||||
Name[sv]=Kompare-del
|
||||
Name[ta]=கோம்பெர் உறுப்பு
|
||||
Name[tg]=Қисмати утилитҳои баробаркунии файлҳо
|
||||
Name[tr]=KomparePart
|
||||
Name[ug]=KomparePart
|
||||
Name[uk]=KomparePart
|
||||
Name[vi]=KomparePart
|
||||
Name[xh]=KomparePart
|
||||
Name[x-test]=xxKomparePartxx
|
||||
Name[zh_CN]=KomparePart
|
||||
Name[zh_TW]=KomparePart
|
||||
MimeType=text/x-patch;
|
||||
ServiceTypes=Kompare/ViewPart,KParts/ReadWritePart,KParts/ReadOnlyPart
|
||||
X-KDE-Library=komparepart
|
||||
Type=Service
|
||||
Icon=kompare
|
||||
InitialPreference=10
|
48
kompare/komparepart/komparepartui.rc
Normal file
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
|
||||
<kpartgui name="kompare_part" version="6">
|
||||
<MenuBar>
|
||||
<Menu name="file"><text>&File</text>
|
||||
<Action name="file_save"/>
|
||||
<Action name="file_save_all"/>
|
||||
<Action name="file_save_as"/>
|
||||
<Action name="file_save_diff"/>
|
||||
<Separator/>
|
||||
<Action name="file_refreshdiff"/>
|
||||
<Action name="file_swap"/>
|
||||
<Action name="file_diffstats"/>
|
||||
<Separator/>
|
||||
<Action name="file_print"/>
|
||||
<Action name="file_print_preview"/>
|
||||
</Menu>
|
||||
<Menu name="difference"><text>&Difference</text>
|
||||
<Action name="difference_unapplyall"/>
|
||||
<Action name="difference_unapply"/>
|
||||
<Action name="difference_apply"/>
|
||||
<Action name="difference_applyall"/>
|
||||
<Separator/>
|
||||
<Action name="difference_previousfile"/>
|
||||
<Action name="difference_nextfile"/>
|
||||
<Separator/>
|
||||
<Action name="difference_previous"/>
|
||||
<Action name="difference_next"/>
|
||||
</Menu>
|
||||
<Menu name="settings"><text>&Settings</text>
|
||||
<Action name="options_configure"/>
|
||||
</Menu>
|
||||
</MenuBar>
|
||||
<ToolBar name="mainToolBar">
|
||||
<Action name="file_save"/>
|
||||
<Action name="file_save_all"/>
|
||||
<Separator/>
|
||||
<Action name="difference_previousfile"/>
|
||||
<Action name="difference_nextfile"/>
|
||||
<Separator/>
|
||||
<Action name="difference_previous"/>
|
||||
<Action name="difference_next"/>
|
||||
<Separator/>
|
||||
<Action name="difference_unapplyall"/>
|
||||
<Action name="difference_unapply"/>
|
||||
<Action name="difference_apply"/>
|
||||
<Action name="difference_applyall"/>
|
||||
</ToolBar>
|
||||
</kpartgui>
|
160
kompare/komparepart/kompareprefdlg.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
/***************************************************************************
|
||||
kompareprefdlg.cpp
|
||||
------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "kompareprefdlg.h"
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kiconloader.h>
|
||||
#include <klocale.h>
|
||||
#include <ktabwidget.h>
|
||||
#include <ktoolinvocation.h>
|
||||
|
||||
#include "diffpage.h"
|
||||
#include "viewpage.h"
|
||||
|
||||
// implementation
|
||||
|
||||
KomparePrefDlg::KomparePrefDlg( ViewSettings* viewSets, DiffSettings* diffSets ) : KPageDialog( 0 )
|
||||
{
|
||||
setFaceType( KPageDialog::List );
|
||||
setWindowTitle( i18n( "Preferences" ) );
|
||||
setButtons( Help|Default|Ok|Apply|Cancel );
|
||||
setDefaultButton( Ok );
|
||||
setModal( true );
|
||||
showButtonSeparator( true );
|
||||
|
||||
// ok i need some stuff in that pref dlg...
|
||||
//setIconListAllVisible(true);
|
||||
|
||||
m_viewPage = new ViewPage();
|
||||
KPageWidgetItem *item = addPage( m_viewPage, i18n( "View" ) );
|
||||
item->setIcon( KIcon( "preferences-desktop-theme" ) );
|
||||
item->setHeader( i18n( "View Settings" ) );
|
||||
m_viewPage->setSettings( viewSets );
|
||||
|
||||
m_diffPage = new DiffPage();
|
||||
item = addPage( m_diffPage, i18n( "Diff" ) );
|
||||
item->setIcon( KIcon( "text-x-patch" ) );
|
||||
item->setHeader( i18n( "Diff Settings" ) );
|
||||
m_diffPage->setSettings( diffSets );
|
||||
|
||||
// frame = addVBoxPage( i18n( "" ), i18n( "" ), UserIcon( "" ) );
|
||||
|
||||
connect( this, SIGNAL(defaultClicked()), SLOT(slotDefault()) );
|
||||
connect( this, SIGNAL(helpClicked()), SLOT(slotHelp()) );
|
||||
connect( this, SIGNAL(applyClicked()), SLOT(slotApply()) );
|
||||
connect( this, SIGNAL(okClicked()), SLOT(slotOk()) );
|
||||
connect( this, SIGNAL(cancelClicked()), SLOT(slotCancel()) );
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
KomparePrefDlg::~KomparePrefDlg()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void KomparePrefDlg::slotDefault()
|
||||
{
|
||||
kDebug(8103) << "SlotDefault called -> Settings should be restored to defaults..." << endl;
|
||||
// restore all defaults in the options...
|
||||
m_viewPage->setDefaults();
|
||||
m_diffPage->setDefaults();
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void KomparePrefDlg::slotHelp()
|
||||
{
|
||||
// figure out the current active page
|
||||
QWidget* currentpage = currentPage()->widget();
|
||||
if ( dynamic_cast<ViewPage*>(currentpage) )
|
||||
{
|
||||
// figure out the active tab
|
||||
int currentTab = static_cast<ViewPage*>(currentpage)->m_tabWidget->currentIndex();
|
||||
switch ( currentTab )
|
||||
{
|
||||
case 0:
|
||||
KToolInvocation::invokeHelp( "appearance" );
|
||||
break;
|
||||
case 1:
|
||||
KToolInvocation::invokeHelp( "fonts" );
|
||||
break;
|
||||
default:
|
||||
KToolInvocation::invokeHelp( "view-settings" );
|
||||
}
|
||||
}
|
||||
else if ( dynamic_cast<DiffPage*>(currentpage) )
|
||||
{
|
||||
// figure out the active tab
|
||||
int currentTab = static_cast<DiffPage*>(currentpage)->m_tabWidget->currentIndex();
|
||||
switch ( currentTab )
|
||||
{
|
||||
case 0:
|
||||
KToolInvocation::invokeHelp( "diff" );
|
||||
break;
|
||||
case 1:
|
||||
KToolInvocation::invokeHelp( "diff-format" );
|
||||
break;
|
||||
case 2:
|
||||
KToolInvocation::invokeHelp( "options" );
|
||||
break;
|
||||
case 3:
|
||||
KToolInvocation::invokeHelp( "exclude" );
|
||||
break;
|
||||
default:
|
||||
KToolInvocation::invokeHelp( "diff-settings" );
|
||||
}
|
||||
}
|
||||
else // Fallback since we had not added the code for the page/tab or forgotten about it
|
||||
KToolInvocation::invokeHelp( "configure-preferences" );
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void KomparePrefDlg::slotApply()
|
||||
{
|
||||
kDebug(8103) << "SlotApply called -> Settings should be applied..." << endl;
|
||||
// well apply the settings that are currently selected
|
||||
m_viewPage->apply();
|
||||
m_diffPage->apply();
|
||||
|
||||
emit configChanged();
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void KomparePrefDlg::slotOk()
|
||||
{
|
||||
kDebug(8103) << "SlotOk called -> Settings should be applied..." << endl;
|
||||
// Apply the settings that are currently selected
|
||||
m_viewPage->apply();
|
||||
m_diffPage->apply();
|
||||
|
||||
//accept();
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void KomparePrefDlg::slotCancel()
|
||||
{
|
||||
// discard the current settings and use the present ones
|
||||
m_viewPage->restore();
|
||||
m_diffPage->restore();
|
||||
|
||||
//reject();
|
||||
}
|
||||
|
||||
#include "kompareprefdlg.moc"
|
56
kompare/komparepart/kompareprefdlg.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/***************************************************************************
|
||||
kompareprefdlg.h
|
||||
----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPAREPREFDLG_H
|
||||
#define KOMPAREPREFDLG_H
|
||||
|
||||
#include <kpagedialog.h>
|
||||
|
||||
class DiffPage;
|
||||
class DiffSettings;
|
||||
class ViewPage;
|
||||
class ViewSettings;
|
||||
|
||||
class KomparePrefDlg : public KPageDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KomparePrefDlg( ViewSettings*, DiffSettings* );
|
||||
~KomparePrefDlg();
|
||||
|
||||
protected slots:
|
||||
/** No descriptions */
|
||||
virtual void slotOk();
|
||||
/** No descriptions */
|
||||
virtual void slotApply();
|
||||
/** No descriptions */
|
||||
virtual void slotHelp();
|
||||
/** No descriptions */
|
||||
virtual void slotDefault();
|
||||
/** No descriptions */
|
||||
virtual void slotCancel();
|
||||
|
||||
signals:
|
||||
void configChanged();
|
||||
|
||||
private:
|
||||
ViewPage* m_viewPage;
|
||||
DiffPage* m_diffPage;
|
||||
};
|
||||
|
||||
#endif
|
48
kompare/komparepart/komparesaveoptionsbase.cpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/***************************************************************************
|
||||
komparesaveoptionsbase.cpp
|
||||
--------------------------
|
||||
Converted from komparesaveoptionsbase.ui using uic3, Tue Dec 4 2007
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
** 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.
|
||||
***************************************************************************/
|
||||
|
||||
#include "komparesaveoptionsbase.h"
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
/*
|
||||
* Constructs a KompareSaveOptionsBase as a child of 'parent', with the
|
||||
* name 'name' and widget flags set to 'f'.
|
||||
*/
|
||||
KompareSaveOptionsBase::KompareSaveOptionsBase(QWidget* parent, Qt::WindowFlags fl)
|
||||
: QWidget(parent, fl)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroys the object and frees any allocated resources
|
||||
*/
|
||||
KompareSaveOptionsBase::~KompareSaveOptionsBase()
|
||||
{
|
||||
// no need to delete child widgets, Qt does it all for us
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the strings of the subwidgets using the current
|
||||
* language.
|
||||
*/
|
||||
void KompareSaveOptionsBase::languageChange()
|
||||
{
|
||||
retranslateUi(this);
|
||||
}
|
||||
|
37
kompare/komparepart/komparesaveoptionsbase.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/***************************************************************************
|
||||
komparesaveoptionsbase.h
|
||||
------------------------
|
||||
Converted from komparesaveoptionsbase.ui using uic3, Tue Dec 4 2007
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
** 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.
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARESAVEOPTIONSBASE_H
|
||||
#define KOMPARESAVEOPTIONSBASE_H
|
||||
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
#include "ui_komparesaveoptionsbase.h"
|
||||
|
||||
class KompareSaveOptionsBase : public QWidget, public Ui::KompareSaveOptionsBase
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KompareSaveOptionsBase(QWidget* parent = 0, Qt::WindowFlags fl = 0);
|
||||
~KompareSaveOptionsBase();
|
||||
|
||||
protected slots:
|
||||
virtual void languageChange();
|
||||
|
||||
};
|
||||
|
||||
#endif // KOMPARESAVEOPTIONSBASE_H
|
284
kompare/komparepart/komparesaveoptionsbase.ui
Normal file
|
@ -0,0 +1,284 @@
|
|||
<ui version="4.0" stdsetdef="1" >
|
||||
<class>KompareSaveOptionsBase</class>
|
||||
<widget class="QWidget" name="KompareSaveOptionsBase" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>558</width>
|
||||
<height>399</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item rowspan="1" row="1" column="0" colspan="2" >
|
||||
<widget class="QGroupBox" name="GroupBox2" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>1</hsizetype>
|
||||
<vsizetype>1</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Run Diff In</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="KUrlRequester" name="m_directoryRequester" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>7</hsizetype>
|
||||
<vsizetype>5</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item rowspan="1" row="2" column="0" colspan="2" >
|
||||
<widget class="QGroupBox" name="m_CommandLineGB" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy>
|
||||
<hsizetype>3</hsizetype>
|
||||
<vsizetype>3</vsizetype>
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Command Line</string>
|
||||
</property>
|
||||
<property name="alignment" >
|
||||
<set>Qt::AlignVCenter|Qt::AlignLeft</set>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_CommandLineLabel" >
|
||||
<property name="text" >
|
||||
<string>cd dir && diff -udHprNa -- source destination</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1" >
|
||||
<widget class="QGroupBox" name="m_OptionsGB" >
|
||||
<property name="title" >
|
||||
<string>Options</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_SmallerChangesCB" >
|
||||
<property name="text" >
|
||||
<string>Look for smaller changes</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_LargeFilesCB" >
|
||||
<property name="text" >
|
||||
<string>Optimize for large files</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_IgnoreCaseCB" >
|
||||
<property name="text" >
|
||||
<string>Ignore changes in case</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_ExpandTabsCB" >
|
||||
<property name="text" >
|
||||
<string>Expand tabs to spaces</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_IgnoreEmptyLinesCB" >
|
||||
<property name="text" >
|
||||
<string>Ignore added or removed empty lines</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_IgnoreWhiteSpaceCB" >
|
||||
<property name="text" >
|
||||
<string>Ignore changes in whitespace</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_FunctionNamesCB" >
|
||||
<property name="text" >
|
||||
<string>Show function names</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_RecursiveCB" >
|
||||
<property name="text" >
|
||||
<string>Compare folders recursively</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_NewFilesCB" >
|
||||
<property name="text" >
|
||||
<string>Treat new files as empty</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="tristate" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<widget class="QGroupBox" name="m_FormatGB" >
|
||||
<property name="title" >
|
||||
<string>Format</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>11</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_ContextRB" >
|
||||
<property name="text" >
|
||||
<string>Context</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_EdRB" >
|
||||
<property name="text" >
|
||||
<string>Ed</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_NormalRB" >
|
||||
<property name="text" >
|
||||
<string>Normal</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_RCSRB" >
|
||||
<property name="text" >
|
||||
<string>RCS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_UnifiedRB" >
|
||||
<property name="text" >
|
||||
<string>Unified</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="m_SideBySideRB" >
|
||||
<property name="text" >
|
||||
<string>Side-by-side</string>
|
||||
</property>
|
||||
<property name="checked" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<property name="margin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="spacing" >
|
||||
<number>6</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_ContextLinesLabel" >
|
||||
<property name="text" >
|
||||
<string>Number of context lines:</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_ContextLinesSB" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="maximum" >
|
||||
<number>65535</number>
|
||||
</property>
|
||||
<property name="value" >
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</ui>
|
225
kompare/komparepart/komparesaveoptionswidget.cpp
Normal file
|
@ -0,0 +1,225 @@
|
|||
/***************************************************************************
|
||||
komparesaveoptionswidget.cpp
|
||||
----------------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "komparesaveoptionswidget.h"
|
||||
|
||||
#include <QtGui/QCheckBox>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QRadioButton>
|
||||
#include <QtGui/QSpinBox>
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kfiledialog.h>
|
||||
#include <kurlrequester.h>
|
||||
|
||||
#include "diffsettings.h"
|
||||
|
||||
KompareSaveOptionsWidget::KompareSaveOptionsWidget( QString source, QString destination,
|
||||
DiffSettings * settings, QWidget * parent )
|
||||
: KompareSaveOptionsBase( parent )
|
||||
, m_source( source )
|
||||
, m_destination( destination )
|
||||
, m_FormatBG( new QButtonGroup(this) )
|
||||
{
|
||||
setObjectName("save options");
|
||||
|
||||
m_settings = settings;
|
||||
|
||||
m_directoryRequester->setMode(
|
||||
KFile::ExistingOnly | KFile::Directory | KFile::LocalOnly );
|
||||
|
||||
KUrl sourceURL;
|
||||
KUrl destinationURL;
|
||||
sourceURL.setPath( source );
|
||||
destinationURL.setPath( destination );
|
||||
|
||||
// Find a common root.
|
||||
KUrl root( sourceURL );
|
||||
while( root.isValid() && !root.isParentOf( destinationURL ) && root != root.upUrl() ) {
|
||||
root = root.upUrl();
|
||||
}
|
||||
|
||||
// If we found a common root, change to that directory and
|
||||
// strip the common part from source and destination.
|
||||
if( root.isValid() && root != root.upUrl() ) {
|
||||
m_directoryRequester->setUrl( root.url() );
|
||||
}
|
||||
|
||||
connect( m_SmallerChangesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_LargeFilesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_IgnoreCaseCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_ExpandTabsCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_IgnoreEmptyLinesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_IgnoreWhiteSpaceCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_FunctionNamesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_RecursiveCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_NewFilesCB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_ContextRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_EdRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_NormalRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_RCSRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_UnifiedRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_SideBySideRB, SIGNAL(toggled(bool)), SLOT(updateCommandLine()) );
|
||||
connect( m_ContextLinesSB, SIGNAL(valueChanged(int)), SLOT(updateCommandLine()) );
|
||||
connect( m_directoryRequester, SIGNAL(textChanged(const QString&)), SLOT(updateCommandLine()) );
|
||||
|
||||
m_FormatBG->setExclusive(true);
|
||||
m_FormatBG->addButton(m_ContextRB, Kompare::Context);
|
||||
m_FormatBG->addButton(m_EdRB, Kompare::Ed);
|
||||
m_FormatBG->addButton(m_NormalRB, Kompare::Normal);
|
||||
m_FormatBG->addButton(m_UnifiedRB, Kompare::Unified);
|
||||
m_FormatBG->addButton(m_RCSRB, Kompare::RCS);
|
||||
m_FormatBG->addButton(m_SideBySideRB, Kompare::SideBySide);
|
||||
|
||||
loadOptions();
|
||||
}
|
||||
|
||||
KompareSaveOptionsWidget::~KompareSaveOptionsWidget()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString KompareSaveOptionsWidget::directory() const
|
||||
{
|
||||
return KUrl( m_directoryRequester->url() ).toLocalFile();
|
||||
}
|
||||
|
||||
void KompareSaveOptionsWidget::updateCommandLine()
|
||||
{
|
||||
QString cmdLine = "diff";
|
||||
|
||||
QString options = "";
|
||||
|
||||
switch( static_cast<Kompare::Format>( m_FormatBG->checkedId() ) ) {
|
||||
case Kompare::Unified :
|
||||
cmdLine += " -U " + QString::number( m_ContextLinesSB->value() );
|
||||
break;
|
||||
case Kompare::Context :
|
||||
cmdLine += " -C " + QString::number( m_ContextLinesSB->value() );
|
||||
break;
|
||||
case Kompare::RCS :
|
||||
options += 'n';
|
||||
break;
|
||||
case Kompare::Ed :
|
||||
options += 'e';
|
||||
break;
|
||||
case Kompare::SideBySide:
|
||||
options += 'y';
|
||||
break;
|
||||
case Kompare::Normal :
|
||||
case Kompare::UnknownFormat :
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( m_SmallerChangesCB->isChecked() ) {
|
||||
options += 'd';
|
||||
}
|
||||
|
||||
if ( m_LargeFilesCB->isChecked() ) {
|
||||
options += 'H';
|
||||
}
|
||||
|
||||
if ( m_IgnoreCaseCB->isChecked() ){
|
||||
options += 'i';
|
||||
}
|
||||
|
||||
if ( m_ExpandTabsCB->isChecked() ) {
|
||||
options += 't';
|
||||
}
|
||||
|
||||
if ( m_IgnoreEmptyLinesCB->isChecked() ) {
|
||||
options += 'B';
|
||||
}
|
||||
|
||||
if ( m_IgnoreWhiteSpaceCB->isChecked() ) {
|
||||
options += 'b';
|
||||
}
|
||||
|
||||
if ( m_FunctionNamesCB->isChecked() ) {
|
||||
options += 'p';
|
||||
}
|
||||
|
||||
// if ( ) {
|
||||
// cmdLine += " -w";
|
||||
// }
|
||||
|
||||
if ( m_RecursiveCB->isChecked() ) {
|
||||
options += 'r';
|
||||
}
|
||||
|
||||
if( m_NewFilesCB->isChecked() ) {
|
||||
options += 'N';
|
||||
}
|
||||
|
||||
// if( m_AllTextCB->isChecked() ) {
|
||||
// options += 'a';
|
||||
// }
|
||||
|
||||
if( options.length() > 0 ) {
|
||||
cmdLine += " -" + options;
|
||||
}
|
||||
|
||||
cmdLine += " -- ";
|
||||
cmdLine += constructRelativePath( m_directoryRequester->url().pathOrUrl(), m_source );
|
||||
cmdLine += ' ';
|
||||
cmdLine += constructRelativePath( m_directoryRequester->url().pathOrUrl(), m_destination );
|
||||
|
||||
m_CommandLineLabel->setText( cmdLine );
|
||||
}
|
||||
|
||||
void KompareSaveOptionsWidget::loadOptions()
|
||||
{
|
||||
m_SmallerChangesCB->setChecked ( m_settings->m_createSmallerDiff );
|
||||
m_LargeFilesCB->setChecked ( m_settings->m_largeFiles );
|
||||
m_IgnoreCaseCB->setChecked ( m_settings->m_ignoreChangesInCase );
|
||||
m_ExpandTabsCB->setChecked ( m_settings->m_convertTabsToSpaces );
|
||||
m_IgnoreEmptyLinesCB->setChecked( m_settings->m_ignoreEmptyLines );
|
||||
m_IgnoreWhiteSpaceCB->setChecked( m_settings->m_ignoreWhiteSpace );
|
||||
m_FunctionNamesCB->setChecked ( m_settings->m_showCFunctionChange );
|
||||
m_RecursiveCB->setChecked ( m_settings->m_recursive );
|
||||
m_NewFilesCB->setChecked ( m_settings->m_newFiles );
|
||||
// m_AllTextCB->setChecked ( m_settings->m_allText );
|
||||
|
||||
m_ContextLinesSB->setValue ( m_settings->m_linesOfContext );
|
||||
|
||||
m_FormatBG->button(m_settings->m_format)->setChecked(true);
|
||||
|
||||
updateCommandLine();
|
||||
}
|
||||
|
||||
void KompareSaveOptionsWidget::saveOptions()
|
||||
{
|
||||
m_settings->m_createSmallerDiff = m_SmallerChangesCB->isChecked();
|
||||
m_settings->m_largeFiles = m_LargeFilesCB->isChecked();
|
||||
m_settings->m_ignoreChangesInCase = m_IgnoreCaseCB->isChecked();
|
||||
m_settings->m_convertTabsToSpaces = m_ExpandTabsCB->isChecked();
|
||||
m_settings->m_ignoreEmptyLines = m_IgnoreEmptyLinesCB->isChecked();
|
||||
m_settings->m_ignoreWhiteSpace = m_IgnoreWhiteSpaceCB->isChecked();
|
||||
m_settings->m_showCFunctionChange = m_FunctionNamesCB->isChecked();
|
||||
m_settings->m_recursive = m_RecursiveCB->isChecked();
|
||||
m_settings->m_newFiles = m_NewFilesCB->isChecked();
|
||||
// m_settings->m_allText = m_AllTextCB->isChecked();
|
||||
|
||||
m_settings->m_linesOfContext = m_ContextLinesSB->value();
|
||||
|
||||
m_settings->m_format = static_cast<Kompare::Format>( m_FormatBG->checkedId() );
|
||||
|
||||
}
|
||||
|
||||
#include "komparesaveoptionswidget.moc"
|
51
kompare/komparepart/komparesaveoptionswidget.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/***************************************************************************
|
||||
komparesaveoptionswidget.h
|
||||
--------------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPARESAVEOPTIONSWIDGET_H
|
||||
#define KOMPARESAVEOPTIONSWIDGET_H
|
||||
|
||||
#include <kurl.h>
|
||||
#include <kompare.h>
|
||||
|
||||
#include "komparesaveoptionsbase.h"
|
||||
|
||||
class DiffSettings;
|
||||
class QButtonGroup;
|
||||
|
||||
class KompareSaveOptionsWidget : public KompareSaveOptionsBase, public KompareFunctions
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
KompareSaveOptionsWidget( QString source, QString destination, DiffSettings* settings, QWidget* parent );
|
||||
~KompareSaveOptionsWidget();
|
||||
|
||||
void saveOptions();
|
||||
QString directory() const;
|
||||
|
||||
protected slots:
|
||||
void updateCommandLine();
|
||||
|
||||
private:
|
||||
void loadOptions();
|
||||
|
||||
DiffSettings* m_settings;
|
||||
QString m_source;
|
||||
QString m_destination;
|
||||
QButtonGroup* m_FormatBG;
|
||||
};
|
||||
|
||||
#endif
|
492
kompare/komparepart/komparesplitter.cpp
Normal file
|
@ -0,0 +1,492 @@
|
|||
/**************************************************************************
|
||||
** komparesplitter.cpp
|
||||
** -------------------
|
||||
** begin : Wed Jan 14 2004
|
||||
** Copyright 2004-2005 Jeff Snyder <jeff-webcvsspam@caffeinated.me.uk>
|
||||
** Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
// associated header
|
||||
#include "komparesplitter.h"
|
||||
|
||||
// qt
|
||||
#include <QtGui/QStyle>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QScrollBar>
|
||||
#include <QtCore/QMap>
|
||||
#include <QtGui/QSplitter>
|
||||
#include <QtGui/QApplication>
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QResizeEvent>
|
||||
#include <QtCore/QChildEvent>
|
||||
#include <QtCore/QEvent>
|
||||
#include <QtGui/QWheelEvent>
|
||||
|
||||
// kde
|
||||
#include <kdebug.h>
|
||||
#include <kapplication.h>
|
||||
#include <kglobalsettings.h>
|
||||
|
||||
// kompare
|
||||
#include "komparelistview.h"
|
||||
#include "viewsettings.h"
|
||||
#include "kompareconnectwidget.h"
|
||||
#include "diffmodel.h"
|
||||
#include "difference.h"
|
||||
|
||||
using namespace Diff2;
|
||||
|
||||
KompareSplitter::KompareSplitter( ViewSettings *settings, QWidget *parent ) :
|
||||
QSplitter( Qt::Horizontal, parent ),
|
||||
m_settings( settings )
|
||||
{
|
||||
QFrame *scrollFrame = static_cast<QFrame *>(parent);
|
||||
|
||||
// Set up the scrollFrame
|
||||
scrollFrame->setFrameStyle( QFrame::NoFrame | QFrame::Plain );
|
||||
scrollFrame->setLineWidth(scrollFrame->style()->pixelMetric(QStyle::PM_DefaultFrameWidth));
|
||||
QGridLayout *pairlayout = new QGridLayout(scrollFrame);
|
||||
pairlayout->setSpacing(0);
|
||||
pairlayout->setContentsMargins( 0, 0, 0, 0 );
|
||||
m_vScroll = new QScrollBar( Qt::Vertical, scrollFrame );
|
||||
pairlayout->addWidget( m_vScroll, 0, 1 );
|
||||
m_hScroll = new QScrollBar( Qt::Horizontal, scrollFrame );
|
||||
pairlayout->addWidget( m_hScroll, 1, 0 );
|
||||
|
||||
new KompareListViewFrame(true, m_settings, this, "source");
|
||||
new KompareListViewFrame(false, m_settings, this, "destination");
|
||||
pairlayout->addWidget( this, 0, 0 );
|
||||
|
||||
// set up our looks
|
||||
setLineWidth( style()->pixelMetric( QStyle::PM_DefaultFrameWidth ) );
|
||||
|
||||
setHandleWidth(50);
|
||||
setChildrenCollapsible( false );
|
||||
setFrameStyle( QFrame::NoFrame );
|
||||
setSizePolicy( QSizePolicy (QSizePolicy::Ignored, QSizePolicy::Ignored ));
|
||||
setOpaqueResize( true );
|
||||
setFocusPolicy( Qt::WheelFocus );
|
||||
|
||||
connect( this, SIGNAL(configChanged()), SLOT(slotConfigChanged()) );
|
||||
connect( this, SIGNAL(configChanged()), SLOT(slotDelayedRepaintHandles()) );
|
||||
connect( this, SIGNAL(configChanged()), SLOT(slotDelayedUpdateScrollBars()) );
|
||||
|
||||
// scrolling
|
||||
connect( m_vScroll, SIGNAL(valueChanged(int)), SLOT(slotScrollToId(int)) );
|
||||
connect( m_vScroll, SIGNAL(sliderMoved(int)), SLOT(slotScrollToId(int)) );
|
||||
connect( m_hScroll, SIGNAL(valueChanged(int)), SIGNAL(setXOffset(int)) );
|
||||
connect( m_hScroll, SIGNAL(sliderMoved(int)), SIGNAL(setXOffset(int)) );
|
||||
|
||||
m_scrollTimer=new QTimer(this);
|
||||
m_restartTimer = false;
|
||||
connect (m_scrollTimer, SIGNAL(timeout()), SLOT(timerTimeout()) );
|
||||
|
||||
// we need to receive childEvents now so that d->list is ready for when
|
||||
// slotSetSelection(...) arrives
|
||||
kapp->sendPostedEvents(this, QEvent::ChildAdded);
|
||||
|
||||
// init stuff
|
||||
slotUpdateScrollBars();
|
||||
}
|
||||
|
||||
KompareSplitter::~KompareSplitter()
|
||||
{
|
||||
}
|
||||
|
||||
QSplitterHandle* KompareSplitter::createHandle()
|
||||
{
|
||||
return new KompareConnectWidgetFrame(m_settings, this);
|
||||
}
|
||||
|
||||
void KompareSplitter::slotDelayedRepaintHandles()
|
||||
{
|
||||
QTimer::singleShot(0, this, SLOT(slotRepaintHandles()));
|
||||
}
|
||||
|
||||
void KompareSplitter::slotRepaintHandles()
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 1; i < end; ++i )
|
||||
handle(i)->update();
|
||||
}
|
||||
|
||||
void KompareSplitter::timerTimeout()
|
||||
{
|
||||
if ( m_restartTimer )
|
||||
m_restartTimer = false;
|
||||
else
|
||||
m_scrollTimer->stop();
|
||||
|
||||
slotDelayedRepaintHandles();
|
||||
|
||||
emit scrollViewsToId( m_scrollTo );
|
||||
slotRepaintHandles();
|
||||
m_vScroll->setValue( m_scrollTo );
|
||||
}
|
||||
|
||||
void KompareSplitter::slotScrollToId( int id )
|
||||
{
|
||||
m_scrollTo = id;
|
||||
|
||||
if( m_restartTimer )
|
||||
return;
|
||||
|
||||
if( m_scrollTimer->isActive() )
|
||||
{
|
||||
m_restartTimer = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
emit scrollViewsToId( id );
|
||||
slotRepaintHandles();
|
||||
m_vScroll->setValue( id );
|
||||
m_scrollTimer->start( 30 );
|
||||
}
|
||||
}
|
||||
|
||||
void KompareSplitter::slotDelayedUpdateScrollBars()
|
||||
{
|
||||
QTimer::singleShot( 0, this, SLOT( slotUpdateScrollBars() ) );
|
||||
}
|
||||
|
||||
void KompareSplitter::slotUpdateScrollBars()
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
KompareListView* lv = listView(i);
|
||||
int minHScroll = minHScrollId();
|
||||
if (lv->contentsX() < minHScroll) {
|
||||
lv->setXOffset(minHScroll);
|
||||
}
|
||||
}
|
||||
|
||||
int m_scrollDistance = m_settings->m_scrollNoOfLines * lineHeight();
|
||||
int m_pageSize = pageSize();
|
||||
|
||||
if( needVScrollBar() )
|
||||
{
|
||||
m_vScroll->show();
|
||||
|
||||
m_vScroll->blockSignals( true );
|
||||
m_vScroll->setRange( minVScrollId(),
|
||||
maxVScrollId() );
|
||||
m_vScroll->setValue( scrollId() );
|
||||
m_vScroll->setSingleStep( m_scrollDistance );
|
||||
m_vScroll->setPageStep( m_pageSize );
|
||||
m_vScroll->blockSignals( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vScroll->hide();
|
||||
}
|
||||
|
||||
if( needHScrollBar() )
|
||||
{
|
||||
m_hScroll->show();
|
||||
m_hScroll->blockSignals( true );
|
||||
m_hScroll->setRange( minHScrollId(), maxHScrollId() );
|
||||
m_hScroll->setValue( maxContentsX() );
|
||||
m_hScroll->setSingleStep( 10 );
|
||||
m_hScroll->setPageStep( minVisibleWidth() - 10 );
|
||||
m_hScroll->blockSignals( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hScroll->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareSplitter::slotDelayedUpdateVScrollValue()
|
||||
{
|
||||
QTimer::singleShot( 0, this, SLOT( slotUpdateVScrollValue() ) );
|
||||
}
|
||||
|
||||
void KompareSplitter::slotUpdateVScrollValue()
|
||||
{
|
||||
m_vScroll->setValue( scrollId() );
|
||||
}
|
||||
|
||||
void KompareSplitter::keyPressEvent( QKeyEvent* e )
|
||||
{
|
||||
//keyboard scrolling
|
||||
switch ( e->key() ) {
|
||||
case Qt::Key_Right:
|
||||
case Qt::Key_L:
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderSingleStepAdd );
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
case Qt::Key_H:
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderSingleStepSub );
|
||||
break;
|
||||
case Qt::Key_Up:
|
||||
case Qt::Key_K:
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderSingleStepSub );
|
||||
break;
|
||||
case Qt::Key_Down:
|
||||
case Qt::Key_J:
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderSingleStepAdd );
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderPageStepAdd );
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderPageStepSub );
|
||||
break;
|
||||
}
|
||||
e->accept();
|
||||
slotRepaintHandles();
|
||||
}
|
||||
|
||||
void KompareSplitter::wheelEvent( QWheelEvent* e )
|
||||
{
|
||||
if ( e->orientation() == Qt::Vertical )
|
||||
{
|
||||
if ( e->modifiers() & Qt::ControlModifier ) {
|
||||
if ( e->delta() < 0 ) // scroll down one page
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderPageStepAdd );
|
||||
else // scroll up one page
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderPageStepSub );
|
||||
} else {
|
||||
if ( e->delta() < 0 ) // scroll down
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderSingleStepAdd );
|
||||
else // scroll up
|
||||
m_vScroll->triggerAction( QAbstractSlider::SliderSingleStepSub );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( e->modifiers() & Qt::ControlModifier ) {
|
||||
if ( e->delta() < 0 ) // scroll right one page
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderPageStepAdd );
|
||||
else // scroll left one page
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderPageStepSub );
|
||||
} else {
|
||||
if ( e->delta() < 0 ) // scroll to the right
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderSingleStepAdd );
|
||||
else // scroll to the left
|
||||
m_hScroll->triggerAction( QAbstractSlider::SliderSingleStepSub );
|
||||
}
|
||||
}
|
||||
e->accept();
|
||||
slotDelayedRepaintHandles();
|
||||
}
|
||||
|
||||
/* FIXME: this should return/the scrollId() from the listview containing the
|
||||
* /base/ of the diff. but there's bigger issues with that atm.
|
||||
*/
|
||||
|
||||
int KompareSplitter::scrollId()
|
||||
{
|
||||
if(widget(0))
|
||||
return listView(0)->scrollId();
|
||||
return minVScrollId();
|
||||
}
|
||||
|
||||
int KompareSplitter::lineHeight()
|
||||
{
|
||||
if(widget(0))
|
||||
return listView(0)->fontMetrics().height();
|
||||
return 1;
|
||||
}
|
||||
|
||||
int KompareSplitter::pageSize()
|
||||
{
|
||||
if(widget(0)) {
|
||||
KompareListView *view = listView(0);
|
||||
return view->visibleHeight() - view->style()->pixelMetric( QStyle::PM_ScrollBarExtent );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool KompareSplitter::needVScrollBar()
|
||||
{
|
||||
int pagesize = pageSize();
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
KompareListView *view = listView(i);
|
||||
if( view ->contentsHeight() > pagesize)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int KompareSplitter::minVScrollId()
|
||||
{
|
||||
|
||||
int min = -1;
|
||||
int mSId;
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
mSId = listView(i)->minScrollId();
|
||||
if (mSId < min || min == -1)
|
||||
min = mSId;
|
||||
}
|
||||
return ( min == -1 ) ? 0 : min;
|
||||
}
|
||||
|
||||
int KompareSplitter::maxVScrollId()
|
||||
{
|
||||
int max = 0;
|
||||
int mSId;
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
mSId = listView(i)->maxScrollId();
|
||||
if ( mSId > max )
|
||||
max = mSId;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
bool KompareSplitter::needHScrollBar()
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
KompareListView *view = listView(i);
|
||||
if ( view->contentsWidth() > view->visibleWidth() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int KompareSplitter::minHScrollId()
|
||||
{
|
||||
// hardcode an offset to hide the tree controls
|
||||
return 6;
|
||||
}
|
||||
|
||||
int KompareSplitter::maxHScrollId()
|
||||
{
|
||||
int max = 0;
|
||||
int mHSId;
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
KompareListView *view = listView(i);
|
||||
mHSId = view->contentsWidth() - view->visibleWidth();
|
||||
if ( mHSId > max )
|
||||
max = mHSId;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
int KompareSplitter::maxContentsX()
|
||||
{
|
||||
int max = 0;
|
||||
int mCX;
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
mCX = listView(i)->contentsX();
|
||||
if ( mCX > max )
|
||||
max = mCX;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
int KompareSplitter::minVisibleWidth()
|
||||
{
|
||||
// Why the hell do we want to know this?
|
||||
// ah yes, it is because we use it to set the "page size" for horiz. scrolling.
|
||||
// despite the fact that *none* has a pgright and pgleft key :P
|
||||
// But we do have mousewheels with horizontal scrolling functionality,
|
||||
// pressing shift and scrolling then goes left and right one page at the time
|
||||
int min = -1;
|
||||
int vW;
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
vW = listView(i)->visibleWidth();
|
||||
if ( vW < min || min == -1 )
|
||||
min = vW;
|
||||
}
|
||||
return ( min == -1 ) ? 0 : min;
|
||||
}
|
||||
|
||||
KompareListView* KompareSplitter::listView( int index )
|
||||
{
|
||||
return static_cast<KompareListViewFrame*>(widget(index))->view();
|
||||
}
|
||||
|
||||
KompareConnectWidget* KompareSplitter::connectWidget( int index )
|
||||
{
|
||||
return static_cast<KompareConnectWidgetFrame*>(handle(index))->wid();
|
||||
}
|
||||
|
||||
void KompareSplitter::slotSetSelection( const DiffModel* model, const Difference* diff )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
connectWidget(i)->slotSetSelection( model, diff );
|
||||
listView(i)->slotSetSelection( model, diff );
|
||||
static_cast<KompareListViewFrame*>(widget(i))->slotSetModel( model );
|
||||
}
|
||||
|
||||
slotDelayedRepaintHandles();
|
||||
slotDelayedUpdateScrollBars();
|
||||
}
|
||||
|
||||
void KompareSplitter::slotSetSelection( const Difference* diff )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
connectWidget(i)->slotSetSelection( diff );
|
||||
listView(i)->slotSetSelection( diff );
|
||||
}
|
||||
|
||||
slotDelayedRepaintHandles();
|
||||
slotDelayedUpdateScrollBars();
|
||||
}
|
||||
|
||||
void KompareSplitter::slotApplyDifference( bool apply )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i )
|
||||
listView(i)->slotApplyDifference( apply );
|
||||
slotDelayedRepaintHandles();
|
||||
}
|
||||
|
||||
void KompareSplitter::slotApplyAllDifferences( bool apply )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i )
|
||||
listView(i)->slotApplyAllDifferences( apply );
|
||||
slotDelayedRepaintHandles();
|
||||
slotScrollToId( m_scrollTo ); // FIXME!
|
||||
}
|
||||
|
||||
void KompareSplitter::slotApplyDifference( const Difference* diff, bool apply )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i )
|
||||
listView(i)->slotApplyDifference( diff, apply );
|
||||
slotDelayedRepaintHandles();
|
||||
}
|
||||
|
||||
void KompareSplitter::slotDifferenceClicked( const Difference* diff )
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i )
|
||||
listView(i)->setSelectedDifference( diff, false );
|
||||
emit selectionChanged( diff );
|
||||
}
|
||||
|
||||
void KompareSplitter::slotConfigChanged()
|
||||
{
|
||||
const int end = count();
|
||||
for ( int i = 0; i < end; ++i ) {
|
||||
KompareListView *view = listView(i);
|
||||
view->setFont( m_settings->m_font );
|
||||
view->update();
|
||||
}
|
||||
}
|
||||
#include "komparesplitter.moc"
|
121
kompare/komparepart/komparesplitter.h
Normal file
|
@ -0,0 +1,121 @@
|
|||
/***************************************************************************
|
||||
komparesplitter.h
|
||||
-----------------
|
||||
begin : Wed Jan 14 2004
|
||||
Copyright 2004 Jeff Snyder <jeff@caffeinated.me.uk>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _KOMPARESPLITTER_H_
|
||||
#define _KOMPARESPLITTER_H_
|
||||
|
||||
#include <QtGui/QSplitter>
|
||||
|
||||
#include "komparemodellist.h"
|
||||
|
||||
class QSplitterHandle;
|
||||
class QTimer;
|
||||
class QScrollBar;
|
||||
class QWheelEvent;
|
||||
class QKeyEvent;
|
||||
|
||||
namespace Diff2 {
|
||||
class DiffModel;
|
||||
class Difference;
|
||||
}
|
||||
class ViewSettings;
|
||||
|
||||
class KompareListView;
|
||||
class KompareConnectWidget;
|
||||
|
||||
class KompareSplitter : public QSplitter
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KompareSplitter(ViewSettings *settings, QWidget *parent);
|
||||
~KompareSplitter();
|
||||
|
||||
signals:
|
||||
void configChanged();
|
||||
|
||||
void scrollViewsToId( int id );
|
||||
void setXOffset( int x );
|
||||
|
||||
void selectionChanged( const Diff2::Difference* diff );
|
||||
|
||||
public slots:
|
||||
void slotScrollToId( int id );
|
||||
void slotDelayedUpdateScrollBars();
|
||||
void slotUpdateScrollBars();
|
||||
void slotDelayedUpdateVScrollValue();
|
||||
void slotUpdateVScrollValue();
|
||||
void keyPressEvent( QKeyEvent* e );
|
||||
|
||||
void slotApplyDifference( bool apply );
|
||||
void slotApplyAllDifferences( bool apply );
|
||||
void slotApplyDifference( const Diff2::Difference* diff, bool apply );
|
||||
|
||||
void slotSetSelection( const Diff2::DiffModel* model, const Diff2::Difference* diff );
|
||||
void slotSetSelection( const Diff2::Difference* diff );
|
||||
|
||||
void slotDifferenceClicked( const Diff2::Difference* diff );
|
||||
|
||||
void slotConfigChanged();
|
||||
|
||||
protected:
|
||||
void wheelEvent( QWheelEvent* e );
|
||||
|
||||
ViewSettings* settings() const { return m_settings; }
|
||||
|
||||
protected slots:
|
||||
void slotDelayedRepaintHandles();
|
||||
void slotRepaintHandles();
|
||||
void timerTimeout();
|
||||
|
||||
private:
|
||||
// override from QSplitter
|
||||
QSplitterHandle* createHandle();
|
||||
|
||||
void setCursor( int id, const QCursor& cursor );
|
||||
void unsetCursor( int id );
|
||||
|
||||
protected:
|
||||
KompareListView* listView( int index );
|
||||
KompareConnectWidget* connectWidget( int index );
|
||||
|
||||
private:
|
||||
|
||||
// Scrollbars. all this just for the goddamn scrollbars. i hate them.
|
||||
int scrollId();
|
||||
int lineHeight();
|
||||
int pageSize();
|
||||
bool needVScrollBar();
|
||||
int minVScrollId();
|
||||
int maxVScrollId();
|
||||
bool needHScrollBar();
|
||||
int minHScrollId();
|
||||
int maxHScrollId();
|
||||
int maxContentsX();
|
||||
int minVisibleWidth();
|
||||
|
||||
QTimer* m_scrollTimer;
|
||||
bool m_restartTimer;
|
||||
int m_scrollTo;
|
||||
|
||||
ViewSettings* m_settings;
|
||||
QScrollBar* m_vScroll;
|
||||
QScrollBar* m_hScroll;
|
||||
|
||||
friend class KompareConnectWidgetFrame;
|
||||
};
|
||||
#endif //_KOMPARESPLITTER_H_
|
28
kompare/komparepart/kompareview.cpp
Normal file
|
@ -0,0 +1,28 @@
|
|||
/**************************************************************************
|
||||
** kompareview.cpp
|
||||
** ---------------
|
||||
** begin : Thu Nov 3 2011
|
||||
** Copyright 2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
// associated header
|
||||
#include "kompareview.h"
|
||||
|
||||
// kompare
|
||||
#include "komparesplitter.h"
|
||||
|
||||
KompareView::KompareView(ViewSettings *settings, QWidget *parent) :
|
||||
QFrame( parent )
|
||||
{
|
||||
setObjectName( "scrollFrame" );
|
||||
m_splitter = new KompareSplitter( settings, this );
|
||||
}
|
39
kompare/komparepart/kompareview.h
Normal file
|
@ -0,0 +1,39 @@
|
|||
/**************************************************************************
|
||||
** kompareview.h
|
||||
** -------------
|
||||
** begin : Thu Nov 3 2011
|
||||
** Copyright 2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
***************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef _KOMPAREVIEW_H_
|
||||
#define _KOMPAREVIEW_H_
|
||||
|
||||
#include <QtGui/QFrame>
|
||||
|
||||
#include "komparemodellist.h"
|
||||
|
||||
class ViewSettings;
|
||||
class KompareSplitter;
|
||||
|
||||
class KompareView : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
KompareView(ViewSettings *settings, QWidget *parent);
|
||||
~KompareView() {}
|
||||
KompareSplitter *splitter() { return m_splitter; }
|
||||
|
||||
private:
|
||||
KompareSplitter *m_splitter;
|
||||
};
|
||||
#endif //_KOMPARESPLITTER_H_
|
33
kompare/kompareui.rc
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd">
|
||||
<kpartgui name="kompare_shell" version="9">
|
||||
<MenuBar>
|
||||
<Menu noMerge="1" name="file"><text>&File</text>
|
||||
<Action name="file_open"/>
|
||||
<Action name="file_compare_files"/>
|
||||
<Action name="file_blend_url"/>
|
||||
<Separator/>
|
||||
<Merge/>
|
||||
<Separator/>
|
||||
<Action name="file_quit"/>
|
||||
</Menu>
|
||||
<Merge/>
|
||||
<Menu noMerge="1" name="settings"><text>&Settings</text>
|
||||
<Merge name="StandardToolBarMenuHandler" />
|
||||
<Action name="options_show_toolbar"/>
|
||||
<Action name="options_show_statusbar"/>
|
||||
<Action name="options_show_text_view"/>
|
||||
<Merge name="show_merge"/>
|
||||
<Separator/>
|
||||
<Action name="options_configure_keybinding"/>
|
||||
<Action name="options_configure_toolbars"/>
|
||||
<Merge name="configure_merge"/>
|
||||
<Merge/>
|
||||
</Menu>
|
||||
</MenuBar>
|
||||
<ToolBar noMerge="1" name="mainToolBar"><text>Main Toolbar</text>
|
||||
<Action name="file_compare_files"/>
|
||||
<Separator/>
|
||||
<Merge/>
|
||||
<Action name="help"/>
|
||||
</ToolBar>
|
||||
</kpartgui>
|
190
kompare/kompareurldialog.cpp
Normal file
|
@ -0,0 +1,190 @@
|
|||
/***************************************************************************
|
||||
kompareurldialog.cpp
|
||||
--------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2005,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
#include "kompareurldialog.h"
|
||||
#include <QShowEvent>
|
||||
|
||||
#include <QGroupBox>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kglobal.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kurlcombobox.h>
|
||||
#include <kurlrequester.h>
|
||||
|
||||
#include "diffpage.h"
|
||||
#include "diffsettings.h"
|
||||
#include "filespage.h"
|
||||
#include "filessettings.h"
|
||||
#include "viewpage.h"
|
||||
#include "viewsettings.h"
|
||||
|
||||
KompareURLDialog::KompareURLDialog( QWidget *parent, Qt::WFlags flags )
|
||||
: KPageDialog( parent, flags )
|
||||
{
|
||||
setFaceType( List );
|
||||
KSharedConfig::Ptr cfg = KGlobal::config();
|
||||
|
||||
m_filesPage = new FilesPage();
|
||||
KPageWidgetItem *filesItem = addPage( m_filesPage, i18n( "Files" ) );
|
||||
filesItem->setIcon( KIcon( "text-plain" ) );
|
||||
filesItem->setHeader( i18n( "Here you can enter the files you want to compare." ) );
|
||||
m_filesSettings = new FilesSettings( this );
|
||||
m_filesSettings->loadSettings( cfg.data() );
|
||||
m_filesPage->setSettings( m_filesSettings );
|
||||
|
||||
m_diffPage = new DiffPage();
|
||||
KPageWidgetItem *diffItem = addPage( m_diffPage, i18n( "Diff" ) );
|
||||
diffItem->setIcon( KIcon( "text-x-patch" ) );
|
||||
diffItem->setHeader( i18n( "Here you can change the options for comparing the files." ) );
|
||||
m_diffSettings = new DiffSettings( this );
|
||||
m_diffSettings->loadSettings( cfg.data() );
|
||||
m_diffPage->setSettings( m_diffSettings );
|
||||
|
||||
m_viewPage = new ViewPage();
|
||||
KPageWidgetItem *viewItem = addPage( m_viewPage, i18n( "Appearance" ) );
|
||||
viewItem->setIcon( KIcon( "preferences-desktop-theme" ) );
|
||||
viewItem->setHeader( i18n( "Here you can change the options for the view." ) );
|
||||
m_viewSettings = new ViewSettings( this );
|
||||
m_viewSettings->loadSettings( cfg.data() );
|
||||
m_viewPage->setSettings( m_viewSettings );
|
||||
|
||||
adjustSize();
|
||||
|
||||
showButtonSeparator( true );
|
||||
|
||||
connect( m_filesPage->firstURLRequester(), SIGNAL( textChanged( const QString& ) ),
|
||||
this, SLOT( slotEnableOk() ) );
|
||||
connect( m_filesPage->secondURLRequester(), SIGNAL( textChanged( const QString& ) ),
|
||||
this, SLOT( slotEnableOk() ) );
|
||||
|
||||
}
|
||||
|
||||
KompareURLDialog::~KompareURLDialog()
|
||||
{
|
||||
}
|
||||
|
||||
void KompareURLDialog::showEvent ( QShowEvent * event )
|
||||
{
|
||||
if ( !event->spontaneous () )
|
||||
{
|
||||
slotEnableOk();
|
||||
}
|
||||
}
|
||||
|
||||
void KompareURLDialog::slotButtonClicked( int button )
|
||||
{
|
||||
if ( button == KDialog::Cancel )
|
||||
{
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
// BUG: 124121 File with filenames to be excluded does not exist so diff complains and no diffs are generated
|
||||
kDebug(8102) << "Test to see if the file is an actual file that is given in the file with filenames to exclude field" << endl;
|
||||
if ( m_diffPage->m_excludeFileNameGroupBox->isChecked() )
|
||||
{
|
||||
kDebug(8102) << "Ok the checkbox is active..." << endl;
|
||||
if ( QFileInfo( m_diffPage->m_excludeFileURLComboBox->currentText() ).isDir() )
|
||||
{
|
||||
kDebug(8102) << "Don't enter directory names where filenames are expected..." << endl;
|
||||
KMessageBox::sorry( this, i18n( "File used for excluding files cannot be found, please specify another file." ) );
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Room for more checks for invalid input
|
||||
|
||||
m_filesPage->setURLsInComboBoxes();
|
||||
|
||||
KSharedConfig::Ptr cfg = KGlobal::config();
|
||||
|
||||
m_filesPage->apply();
|
||||
m_diffPage->apply();
|
||||
m_viewPage->apply();
|
||||
|
||||
m_filesSettings->saveSettings( cfg.data() );
|
||||
m_diffSettings->saveSettings( cfg.data() );
|
||||
m_viewSettings->saveSettings( cfg.data() );
|
||||
|
||||
cfg->sync();
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
void KompareURLDialog::slotEnableOk()
|
||||
{
|
||||
enableButtonOk( !m_filesPage->firstURLRequester()->url().isEmpty() &&
|
||||
!m_filesPage->secondURLRequester()->url().isEmpty() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first URL, which was entered.
|
||||
* @return first URL
|
||||
*/
|
||||
KUrl KompareURLDialog::getFirstURL() const
|
||||
{
|
||||
return KUrl( m_filesPage->firstURLRequester()->url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second URL, which was entered.
|
||||
* @return second URL
|
||||
*/
|
||||
KUrl KompareURLDialog::getSecondURL() const
|
||||
{
|
||||
return KUrl( m_filesPage->secondURLRequester()->url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the encoding.
|
||||
* @return encoding
|
||||
*/
|
||||
QString KompareURLDialog::encoding() const
|
||||
{
|
||||
return m_filesPage->encoding();
|
||||
}
|
||||
|
||||
void KompareURLDialog::setFirstGroupBoxTitle( const QString& title )
|
||||
{
|
||||
m_filesPage->setFirstGroupBoxTitle( title );
|
||||
}
|
||||
|
||||
void KompareURLDialog::setSecondGroupBoxTitle( const QString& title )
|
||||
{
|
||||
m_filesPage->setSecondGroupBoxTitle( title );
|
||||
}
|
||||
|
||||
void KompareURLDialog::setGroup( const QString& groupName )
|
||||
{
|
||||
m_filesSettings->setGroup( groupName );
|
||||
m_filesSettings->loadSettings( KGlobal::config().data() );
|
||||
m_filesPage->setSettings( m_filesSettings );
|
||||
}
|
||||
|
||||
void KompareURLDialog::setFirstURLRequesterMode( unsigned int mode )
|
||||
{
|
||||
m_filesPage->setFirstURLRequesterMode( mode );
|
||||
}
|
||||
|
||||
void KompareURLDialog::setSecondURLRequesterMode( unsigned int mode )
|
||||
{
|
||||
m_filesPage->setSecondURLRequesterMode( mode );
|
||||
}
|
||||
|
||||
#include "kompareurldialog.moc"
|
||||
|
74
kompare/kompareurldialog.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************
|
||||
kcompareurldialog.h
|
||||
-------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef KOMPAREURLDIALOG_H
|
||||
#define KOMPAREURLDIALOG_H
|
||||
|
||||
#include <kpagedialog.h>
|
||||
#include <kurl.h>
|
||||
|
||||
|
||||
|
||||
class FilesPage;
|
||||
class FilesSettings;
|
||||
class DiffPage;
|
||||
class DiffSettings;
|
||||
class ViewPage;
|
||||
class ViewSettings;
|
||||
|
||||
/**
|
||||
* Definition of class KompareURLDialog.
|
||||
* @author Otto Bruggeman
|
||||
* @author John Firebaugh
|
||||
*/
|
||||
class KompareURLDialog : public KPageDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit KompareURLDialog( QWidget *parent= 0, Qt::WFlags flags= 0 );
|
||||
~KompareURLDialog();
|
||||
|
||||
KUrl getFirstURL() const;
|
||||
KUrl getSecondURL() const;
|
||||
QString encoding() const;
|
||||
|
||||
void setFirstGroupBoxTitle ( const QString& title );
|
||||
void setSecondGroupBoxTitle( const QString& title );
|
||||
|
||||
void setGroup( const QString& groupName );
|
||||
|
||||
void setFirstURLRequesterMode ( unsigned int mode );
|
||||
void setSecondURLRequesterMode( unsigned int mode );
|
||||
|
||||
protected slots:
|
||||
virtual void slotButtonClicked( int button );
|
||||
|
||||
private slots:
|
||||
void slotEnableOk();
|
||||
protected:
|
||||
void showEvent ( QShowEvent * event );
|
||||
private:
|
||||
FilesPage* m_filesPage;
|
||||
FilesSettings* m_filesSettings;
|
||||
DiffPage* m_diffPage;
|
||||
DiffSettings* m_diffSettings;
|
||||
ViewPage* m_viewPage;
|
||||
ViewSettings* m_viewSettings;
|
||||
};
|
||||
|
||||
#endif
|
4
kompare/kompareviewpart.desktop
Normal file
|
@ -0,0 +1,4 @@
|
|||
[Desktop Entry]
|
||||
Type=ServiceType
|
||||
X-KDE-ServiceType=Kompare/ViewPart
|
||||
X-KDE-Derived=KParts/ReadOnlyPart
|
23
kompare/libdialogpages/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
|
||||
########### next target ###############
|
||||
|
||||
set(dialogpages_PART_SRCS
|
||||
filessettings.cpp
|
||||
viewsettings.cpp
|
||||
pagebase.cpp
|
||||
diffpage.cpp
|
||||
filespage.cpp
|
||||
viewpage.cpp )
|
||||
|
||||
|
||||
kde4_add_library(komparedialogpages SHARED ${dialogpages_PART_SRCS})
|
||||
|
||||
include_directories(${LIBKOMPAREDIFF2_INCLUDE_DIR})
|
||||
|
||||
target_link_libraries(komparedialogpages ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${LIBKOMPAREDIFF2_LIBRARIES})
|
||||
|
||||
set_target_properties(komparedialogpages PROPERTIES VERSION ${GENERIC_LIB_VERSION}
|
||||
SOVERSION ${GENERIC_LIB_SOVERSION} )
|
||||
|
||||
install(TARGETS komparedialogpages ${INSTALL_TARGETS_DEFAULT_ARGS})
|
||||
|
37
kompare/libdialogpages/dialogpagesexport.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2007 Andreas Pakulat <apaku@gmx.de> *
|
||||
* Copyright 2006 Matt Rogers <mattr@kde.org> *
|
||||
* Copyright 2004 Jarosław Staniek <staniek@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Library General Public License as *
|
||||
* published by the Free Software Foundation; either version 2 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* This 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 Library General Public *
|
||||
* License along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef LIBDIALOGPAGESEXPORT_H
|
||||
#define LIBDIALOGPAGESEXPORT_H
|
||||
|
||||
/* needed for KDE_EXPORT macros */
|
||||
#include <kdemacros.h>
|
||||
|
||||
#ifndef DIALOGPAGES_EXPORT
|
||||
# ifdef MAKE_KOMPAREDIALOGPAGES_LIB
|
||||
# define DIALOGPAGES_EXPORT KDE_EXPORT
|
||||
# else
|
||||
# define DIALOGPAGES_EXPORT KDE_IMPORT
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
411
kompare/libdialogpages/diffpage.cpp
Normal file
|
@ -0,0 +1,411 @@
|
|||
/***************************************************************************
|
||||
diffprefs.cpp
|
||||
-------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "diffpage.h"
|
||||
|
||||
#include <QtGui/QCheckBox>
|
||||
#include <QGroupBox>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QRadioButton>
|
||||
#include <QtGui/QSpinBox>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
#include <QtGui/QToolTip>
|
||||
#include <QButtonGroup>
|
||||
|
||||
#include <kbuttongroup.h>
|
||||
#include <kapplication.h>
|
||||
#include <kcombobox.h>
|
||||
#include <kdialog.h>
|
||||
#include <keditlistwidget.h>
|
||||
#include <klineedit.h>
|
||||
#include <klocale.h>
|
||||
#include <kurlcombobox.h>
|
||||
#include <kurlrequester.h>
|
||||
#include <kservicetypetrader.h>
|
||||
#include <ktabwidget.h>
|
||||
|
||||
#include <kparts/componentfactory.h>
|
||||
#include <kregexpeditorinterface.h>
|
||||
#include <kglobal.h>
|
||||
|
||||
#include "diffsettings.h"
|
||||
|
||||
DiffPage::DiffPage() : PageBase(), m_ignoreRegExpDialog( 0 )
|
||||
{
|
||||
m_tabWidget = new KTabWidget( this );
|
||||
|
||||
addDiffTab();
|
||||
|
||||
addFormatTab();
|
||||
|
||||
addOptionsTab();
|
||||
|
||||
addExcludeTab();
|
||||
}
|
||||
|
||||
DiffPage::~DiffPage()
|
||||
{
|
||||
m_settings = 0;
|
||||
}
|
||||
|
||||
void DiffPage::setSettings( DiffSettings* setts )
|
||||
{
|
||||
m_settings = setts;
|
||||
|
||||
m_diffURLRequester->setUrl( m_settings->m_diffProgram );
|
||||
|
||||
m_newFilesCheckBox->setChecked ( m_settings->m_newFiles );
|
||||
m_smallerCheckBox->setChecked ( m_settings->m_createSmallerDiff );
|
||||
m_largerCheckBox->setChecked ( m_settings->m_largeFiles );
|
||||
m_tabsCheckBox->setChecked ( m_settings->m_convertTabsToSpaces );
|
||||
m_caseCheckBox->setChecked ( m_settings->m_ignoreChangesInCase );
|
||||
m_linesCheckBox->setChecked ( m_settings->m_ignoreEmptyLines );
|
||||
m_whitespaceCheckBox->setChecked ( m_settings->m_ignoreWhiteSpace );
|
||||
m_allWhitespaceCheckBox->setChecked ( m_settings->m_ignoreAllWhiteSpace );
|
||||
m_ignoreTabExpansionCheckBox->setChecked( m_settings->m_ignoreChangesDueToTabExpansion );
|
||||
|
||||
m_ignoreRegExpCheckBox->setChecked ( m_settings->m_ignoreRegExp );
|
||||
m_ignoreRegExpEdit->setCompletedItems( m_settings->m_ignoreRegExpTextHistory );
|
||||
m_ignoreRegExpEdit->setText ( m_settings->m_ignoreRegExpText );
|
||||
|
||||
m_locSpinBox->setValue( m_settings->m_linesOfContext );
|
||||
|
||||
m_modeButtonGroup->button( m_settings->m_format )->setChecked( true );
|
||||
|
||||
m_excludeFilePatternGroupBox->setChecked ( m_settings->m_excludeFilePattern );
|
||||
slotExcludeFilePatternToggled ( m_settings->m_excludeFilePattern );
|
||||
m_excludeFilePatternEditListBox->insertStringList( m_settings->m_excludeFilePatternList );
|
||||
|
||||
m_excludeFileNameGroupBox->setChecked( m_settings->m_excludeFilesFile );
|
||||
slotExcludeFileToggled ( m_settings->m_excludeFilesFile );
|
||||
m_excludeFileURLComboBox->setUrls( m_settings->m_excludeFilesFileHistoryList );
|
||||
m_excludeFileURLComboBox->setUrl ( KUrl( m_settings->m_excludeFilesFileURL ) );
|
||||
}
|
||||
|
||||
DiffSettings* DiffPage::settings( void )
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void DiffPage::restore()
|
||||
{
|
||||
// this shouldn't do a thing...
|
||||
}
|
||||
|
||||
void DiffPage::apply()
|
||||
{
|
||||
m_settings->m_diffProgram = m_diffURLRequester->url().pathOrUrl();
|
||||
|
||||
m_settings->m_newFiles = m_newFilesCheckBox->isChecked();
|
||||
m_settings->m_largeFiles = m_largerCheckBox->isChecked();
|
||||
m_settings->m_createSmallerDiff = m_smallerCheckBox->isChecked();
|
||||
m_settings->m_convertTabsToSpaces = m_tabsCheckBox->isChecked();
|
||||
m_settings->m_ignoreChangesInCase = m_caseCheckBox->isChecked();
|
||||
m_settings->m_ignoreEmptyLines = m_linesCheckBox->isChecked();
|
||||
m_settings->m_ignoreWhiteSpace = m_whitespaceCheckBox->isChecked();
|
||||
m_settings->m_ignoreAllWhiteSpace = m_allWhitespaceCheckBox->isChecked();
|
||||
m_settings->m_ignoreChangesDueToTabExpansion = m_ignoreTabExpansionCheckBox->isChecked();
|
||||
|
||||
m_settings->m_ignoreRegExp = m_ignoreRegExpCheckBox->isChecked();
|
||||
m_settings->m_ignoreRegExpText = m_ignoreRegExpEdit->text();
|
||||
m_settings->m_ignoreRegExpTextHistory = m_ignoreRegExpEdit->completionObject()->items();
|
||||
|
||||
m_settings->m_linesOfContext = m_locSpinBox->value();
|
||||
|
||||
m_settings->m_format = static_cast<Kompare::Format>( m_modeButtonGroup->checkedId() );
|
||||
|
||||
m_settings->m_excludeFilePattern = m_excludeFilePatternGroupBox->isChecked();
|
||||
m_settings->m_excludeFilePatternList = m_excludeFilePatternEditListBox->items();
|
||||
|
||||
m_settings->m_excludeFilesFile = m_excludeFileNameGroupBox->isChecked();
|
||||
m_settings->m_excludeFilesFileURL = m_excludeFileURLComboBox->currentText();
|
||||
m_settings->m_excludeFilesFileHistoryList = m_excludeFileURLComboBox->urls();
|
||||
|
||||
m_settings->saveSettings( KGlobal::config().data() );
|
||||
}
|
||||
|
||||
void DiffPage::setDefaults()
|
||||
{
|
||||
m_diffURLRequester->setUrl( KUrl( "diff" ) );
|
||||
m_newFilesCheckBox->setChecked( true );
|
||||
m_smallerCheckBox->setChecked( true );
|
||||
m_largerCheckBox->setChecked( true );
|
||||
m_tabsCheckBox->setChecked( false );
|
||||
m_caseCheckBox->setChecked( false );
|
||||
m_linesCheckBox->setChecked( false );
|
||||
m_whitespaceCheckBox->setChecked( false );
|
||||
m_allWhitespaceCheckBox->setChecked( false );
|
||||
m_ignoreTabExpansionCheckBox->setChecked( false );
|
||||
m_ignoreRegExpCheckBox->setChecked( false );
|
||||
|
||||
m_ignoreRegExpEdit->setText( QString() );
|
||||
|
||||
m_locSpinBox->setValue( 3 );
|
||||
|
||||
m_modeButtonGroup->button( Kompare::Unified )->setChecked( true );
|
||||
|
||||
m_excludeFilePatternGroupBox->setChecked( false );
|
||||
|
||||
m_excludeFileNameGroupBox->setChecked( false );
|
||||
}
|
||||
|
||||
void DiffPage::slotShowRegExpEditor()
|
||||
{
|
||||
if ( ! m_ignoreRegExpDialog )
|
||||
m_ignoreRegExpDialog = KServiceTypeTrader::createInstanceFromQuery<QDialog>( "KRegExpEditor/KRegExpEditor", QString(), this );
|
||||
|
||||
KRegExpEditorInterface *iface = qobject_cast<KRegExpEditorInterface *>( m_ignoreRegExpDialog );
|
||||
|
||||
if ( !iface )
|
||||
return;
|
||||
|
||||
iface->setRegExp( m_ignoreRegExpEdit->text() );
|
||||
bool ok = m_ignoreRegExpDialog->exec();
|
||||
|
||||
if ( ok )
|
||||
m_ignoreRegExpEdit->setText( iface->regExp() );
|
||||
}
|
||||
|
||||
void DiffPage::slotExcludeFilePatternToggled( bool on )
|
||||
{
|
||||
m_excludeFilePatternEditListBox->setEnabled( on );
|
||||
}
|
||||
|
||||
void DiffPage::slotExcludeFileToggled( bool on )
|
||||
{
|
||||
m_excludeFileURLComboBox->setEnabled( on );
|
||||
m_excludeFileURLRequester->setEnabled( on );
|
||||
}
|
||||
|
||||
void DiffPage::addDiffTab()
|
||||
{
|
||||
QWidget* page = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
// add diff program selector
|
||||
m_diffProgramGroup = new QGroupBox( page );
|
||||
layout->addWidget( m_diffProgramGroup );
|
||||
QVBoxLayout* bgLayout = new QVBoxLayout( m_diffProgramGroup );
|
||||
m_diffProgramGroup->setTitle( i18n( "Diff Program" ) );
|
||||
//m_diffProgramGroup->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_diffURLRequester = new KUrlRequester( m_diffProgramGroup);
|
||||
m_diffURLRequester->setObjectName("diffURLRequester" );
|
||||
m_diffURLRequester->setWhatsThis( i18n( "You can select a different diff program here. On Solaris the standard diff program does not support all the options that the GNU version does. This way you can select that version." ) );
|
||||
bgLayout->addWidget( m_diffURLRequester );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Diff" ) );
|
||||
}
|
||||
|
||||
void DiffPage::addFormatTab()
|
||||
{
|
||||
QWidget* page = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
// add diff modes
|
||||
m_modeButtonGroup = new QButtonGroup( page );
|
||||
QGroupBox *box = new QGroupBox( page );
|
||||
box->setWhatsThis( i18n( "Select the format of the output generated by diff. Unified is the one that is used most frequently because it is very readable. The KDE developers like this format the best so use it for sending patches." ) );
|
||||
layout->addWidget( box );
|
||||
QVBoxLayout* bgLayout = new QVBoxLayout( box );
|
||||
box->setTitle( i18n( "Output Format" ) );
|
||||
//m_modeButtonGroup->setMargin( KDialog::marginHint() );
|
||||
|
||||
QRadioButton *radioButton = new QRadioButton( i18n( "Context" ), box );
|
||||
m_modeButtonGroup->addButton( radioButton, Kompare::Context);
|
||||
bgLayout->addWidget( radioButton );
|
||||
radioButton = new QRadioButton( i18n( "Normal" ), box );
|
||||
m_modeButtonGroup->addButton( radioButton, Kompare::Normal);
|
||||
bgLayout->addWidget( radioButton );
|
||||
radioButton = new QRadioButton( i18n( "Unified" ), box );
|
||||
m_modeButtonGroup->addButton( radioButton, Kompare::Unified);
|
||||
bgLayout->addWidget( radioButton );
|
||||
|
||||
// #lines of context (loc)
|
||||
QGroupBox* groupBox = new QGroupBox( page );
|
||||
QHBoxLayout *groupLayout = new QHBoxLayout;
|
||||
groupBox->setLayout( groupLayout );
|
||||
layout->addWidget( groupBox );
|
||||
groupBox->setTitle( i18n( "Lines of Context" ) );
|
||||
groupBox->setWhatsThis( i18n( "The number of context lines is normally 2 or 3. This makes the diff readable and applicable in most cases. More than 3 lines will only bloat the diff unnecessarily." ) );
|
||||
//groupBox->setMargin( KDialog::marginHint() );
|
||||
|
||||
QLabel* label = new QLabel( i18n( "Number of context lines:" ));
|
||||
groupLayout->addWidget( label );
|
||||
label->setWhatsThis( i18n( "The number of context lines is normally 2 or 3. This makes the diff readable and applicable in most cases. More than 3 lines will only bloat the diff unnecessarily." ) );
|
||||
m_locSpinBox = new QSpinBox( groupBox );
|
||||
m_locSpinBox->setRange( 0, 100 );
|
||||
groupLayout->addWidget( m_locSpinBox );
|
||||
m_locSpinBox->setWhatsThis( i18n( "The number of context lines is normally 2 or 3. This makes the diff readable and applicable in most cases. More than 3 lines will only bloat the diff unnecessarily." ) );
|
||||
label->setBuddy( m_locSpinBox );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Format" ) );
|
||||
}
|
||||
|
||||
void DiffPage::addOptionsTab()
|
||||
{
|
||||
QWidget* page = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
// add diff options
|
||||
KButtonGroup* optionButtonGroup = new KButtonGroup( page );
|
||||
layout->addWidget( optionButtonGroup );
|
||||
QVBoxLayout* bgLayout = new QVBoxLayout( optionButtonGroup );
|
||||
optionButtonGroup->setTitle( i18n( "General" ) );
|
||||
//optionButtonGroup->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_newFilesCheckBox = new QCheckBox( i18n( "&Treat new files as empty" ), optionButtonGroup );
|
||||
m_newFilesCheckBox->setToolTip( i18n( "This option corresponds to the -N diff option." ) );
|
||||
m_newFilesCheckBox->setWhatsThis( i18n( "With this option enabled diff will treat a file that only exists in one of the directories as empty in the other directory. This means that the file is compared with an empty file and because of this will appear as one big insertion or deletion." ) );
|
||||
bgLayout->addWidget( m_newFilesCheckBox );
|
||||
|
||||
m_smallerCheckBox = new QCheckBox( i18n( "&Look for smaller changes" ), optionButtonGroup );
|
||||
m_smallerCheckBox->setToolTip( i18n( "This corresponds to the -d diff option." ) );
|
||||
m_smallerCheckBox->setWhatsThis( i18n( "With this option enabled diff will try a little harder (at the cost of more memory) to find fewer changes." ) );
|
||||
bgLayout->addWidget( m_smallerCheckBox );
|
||||
m_largerCheckBox = new QCheckBox( i18n( "O&ptimize for large files" ), optionButtonGroup );
|
||||
m_largerCheckBox->setToolTip( i18n( "This corresponds to the -H diff option." ) );
|
||||
m_largerCheckBox->setWhatsThis( i18n( "This option lets diff makes better diffs when using large files. The definition of large is nowhere to be found though." ) );
|
||||
bgLayout->addWidget( m_largerCheckBox );
|
||||
m_caseCheckBox = new QCheckBox( i18n( "&Ignore changes in case" ), optionButtonGroup );
|
||||
m_caseCheckBox->setToolTip( i18n( "This corresponds to the -i diff option." ) );
|
||||
m_caseCheckBox->setWhatsThis( i18n( "With this option to ignore changes in case enabled, diff will not indicate a difference when something in one file is changed into SoMEthing in the other file." ) );
|
||||
bgLayout->addWidget( m_caseCheckBox );
|
||||
|
||||
QHBoxLayout* groupLayout = new QHBoxLayout();
|
||||
layout->addLayout( groupLayout );
|
||||
groupLayout->setObjectName( "regexp_horizontal_layout" );
|
||||
groupLayout->setSpacing( -1 );
|
||||
groupLayout->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_ignoreRegExpCheckBox = new QCheckBox( i18n( "Ignore regexp:" ), page );
|
||||
m_ignoreRegExpCheckBox->setToolTip( i18n( "This option corresponds to the -I diff option." ) );
|
||||
m_ignoreRegExpCheckBox->setWhatsThis( i18n( "When this checkbox is enabled, an option to diff is given that will make diff ignore lines that match the regular expression." ) );
|
||||
groupLayout->addWidget( m_ignoreRegExpCheckBox );
|
||||
m_ignoreRegExpEdit = new KLineEdit( QString::null, page); //krazy:exclude=nullstrassign for old broken gcc
|
||||
m_ignoreRegExpEdit->setObjectName("regexplineedit" );
|
||||
m_ignoreRegExpEdit->setToolTip( i18n( "Add the regular expression here that you want to use\nto ignore lines that match it." ) );
|
||||
groupLayout->addWidget( m_ignoreRegExpEdit );
|
||||
|
||||
if ( !KServiceTypeTrader::self()->query("KRegExpEditor/KRegExpEditor").isEmpty() )
|
||||
{
|
||||
// Ok editor is available, use it
|
||||
QPushButton* ignoreRegExpEditButton = new QPushButton( i18n( "&Edit..." ), page);
|
||||
ignoreRegExpEditButton->setObjectName( "regexp_editor_button" );
|
||||
ignoreRegExpEditButton->setToolTip( i18n( "Clicking this will open a regular expression dialog where\nyou can graphically create regular expressions." ) );
|
||||
groupLayout->addWidget( ignoreRegExpEditButton );
|
||||
connect( ignoreRegExpEditButton, SIGNAL( clicked() ), this, SLOT( slotShowRegExpEditor() ) );
|
||||
}
|
||||
|
||||
KButtonGroup* moreOptionButtonGroup = new KButtonGroup( page );
|
||||
layout->addWidget( moreOptionButtonGroup );
|
||||
bgLayout = new QVBoxLayout( moreOptionButtonGroup );
|
||||
moreOptionButtonGroup->setTitle( i18n( "Whitespace" ) );
|
||||
//moreOptionButtonGroup->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_tabsCheckBox = new QCheckBox( i18n( "E&xpand tabs to spaces in output" ), moreOptionButtonGroup );
|
||||
m_tabsCheckBox->setToolTip( i18n( "This option corresponds to the -t diff option." ) );
|
||||
m_tabsCheckBox->setWhatsThis( i18n( "This option does not always produce the right result. Due to this expansion Kompare may have problems applying the change to the destination file." ) );
|
||||
bgLayout->addWidget( m_tabsCheckBox );
|
||||
m_linesCheckBox = new QCheckBox( i18n( "I&gnore added or removed empty lines" ), moreOptionButtonGroup );
|
||||
m_linesCheckBox->setToolTip( i18n( "This option corresponds to the -B diff option." ) );
|
||||
m_linesCheckBox->setWhatsThis( i18n( "This can be very useful in situations where code has been reorganized and empty lines have been added or removed to improve legibility." ) );
|
||||
bgLayout->addWidget( m_linesCheckBox );
|
||||
m_whitespaceCheckBox = new QCheckBox( i18n( "Ig&nore changes in the amount of whitespace" ), moreOptionButtonGroup );
|
||||
m_whitespaceCheckBox->setToolTip( i18n( "This option corresponds to the -b diff option." ) );
|
||||
m_whitespaceCheckBox->setWhatsThis( i18n( "If you are uninterested in differences arising due to, for example, changes in indentation, then use this option." ) );
|
||||
bgLayout->addWidget( m_whitespaceCheckBox );
|
||||
m_allWhitespaceCheckBox = new QCheckBox( i18n( "Ign&ore all whitespace" ), moreOptionButtonGroup );
|
||||
m_allWhitespaceCheckBox->setToolTip( i18n( "This option corresponds to the -w diff option." ) );
|
||||
m_allWhitespaceCheckBox->setWhatsThis( i18n( "This is useful for seeing the significant changes without being overwhelmed by all the white space changes." ) );
|
||||
bgLayout->addWidget( m_allWhitespaceCheckBox );
|
||||
m_ignoreTabExpansionCheckBox = new QCheckBox( i18n( "Igno&re changes due to tab expansion" ), moreOptionButtonGroup );
|
||||
m_ignoreTabExpansionCheckBox->setToolTip( i18n( "This option corresponds to the -E diff option." ) );
|
||||
m_ignoreTabExpansionCheckBox->setWhatsThis( i18n( "If there is a change because tabs have been expanded into spaces in the other file, then this option will make sure that these do not show up. Kompare currently has some problems applying such changes so be careful when you use this option." ) );
|
||||
bgLayout->addWidget( m_ignoreTabExpansionCheckBox );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Options" ) );
|
||||
}
|
||||
|
||||
void DiffPage::addExcludeTab()
|
||||
{
|
||||
QWidget* page = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_excludeFilePatternGroupBox = new QGroupBox( page );
|
||||
m_excludeFilePatternGroupBox->setCheckable(true);
|
||||
QHBoxLayout *excludeFileLayout = new QHBoxLayout;
|
||||
m_excludeFilePatternGroupBox->setLayout( excludeFileLayout );
|
||||
m_excludeFilePatternGroupBox->setTitle( i18n( "File Pattern to Exclude" ) );
|
||||
m_excludeFilePatternGroupBox->setToolTip( i18n( "If this is checked you can enter a shell pattern in the text box on the right or select entries from the list." ) );
|
||||
m_excludeFilePatternEditListBox = new KEditListWidget;
|
||||
excludeFileLayout->addWidget( m_excludeFilePatternEditListBox );
|
||||
m_excludeFilePatternEditListBox->setObjectName( "exclude_file_pattern_editlistbox" );
|
||||
m_excludeFilePatternEditListBox->setButtons( KEditListWidget::Add|KEditListWidget::Remove );
|
||||
m_excludeFilePatternEditListBox->setCheckAtEntering( false );
|
||||
m_excludeFilePatternEditListBox->setToolTip( i18n( "Here you can enter or remove a shell pattern or select one or more entries from the list." ) );
|
||||
layout->addWidget( m_excludeFilePatternGroupBox );
|
||||
|
||||
|
||||
connect( m_excludeFilePatternGroupBox, SIGNAL(toggled(bool)), this, SLOT(slotExcludeFilePatternToggled(bool)));
|
||||
|
||||
m_excludeFileNameGroupBox = new QGroupBox( page );
|
||||
m_excludeFileNameGroupBox->setCheckable( true );
|
||||
excludeFileLayout = new QHBoxLayout;
|
||||
m_excludeFileNameGroupBox->setLayout( excludeFileLayout );
|
||||
m_excludeFileNameGroupBox->setTitle( i18n( "File with Filenames to Exclude" ) );
|
||||
m_excludeFileNameGroupBox->setToolTip( i18n( "If this is checked you can enter a filename in the combo box below." ) );
|
||||
m_excludeFileURLComboBox = new KUrlComboBox( KUrlComboBox::Files, true );
|
||||
excludeFileLayout->addWidget( m_excludeFileURLComboBox );
|
||||
m_excludeFileURLComboBox->setObjectName( "exclude_file_urlcombo" );
|
||||
m_excludeFileURLComboBox->setToolTip( i18n( "Here you can enter the URL of a file with shell patterns to ignore during the comparison of the folders." ) );
|
||||
m_excludeFileURLRequester = new KUrlRequester( m_excludeFileURLComboBox,m_excludeFileNameGroupBox );
|
||||
excludeFileLayout->addWidget( m_excludeFileURLRequester );
|
||||
m_excludeFileURLRequester->setObjectName("exclude_file_name_urlrequester" );
|
||||
m_excludeFileURLRequester->setToolTip( i18n( "Any file you select in the dialog that pops up when you click it will be put in the dialog to the left of this button." ) );
|
||||
layout->addWidget( m_excludeFileNameGroupBox );
|
||||
|
||||
connect( m_excludeFileNameGroupBox, SIGNAL(toggled(bool)), this, SLOT(slotExcludeFileToggled(bool)));
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Exclude" ) );
|
||||
}
|
||||
|
||||
#include "diffpage.moc"
|
||||
|
||||
//kate: replace-tabs 0; indent-width 4; tab-width 4;
|
103
kompare/libdialogpages/diffpage.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/***************************************************************************
|
||||
diffprefs.h
|
||||
-----------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef DIFFPAGE_H
|
||||
#define DIFFPAGE_H
|
||||
|
||||
#include "pagebase.h"
|
||||
#include "dialogpagesexport.h"
|
||||
|
||||
class QCheckBox;
|
||||
class QDialog;
|
||||
class QSpinBox;
|
||||
class QStringList;
|
||||
class QButtonGroup;
|
||||
class QGroupBox;
|
||||
|
||||
class KLineEdit;
|
||||
class KEditListWidget;
|
||||
class KTabWidget;
|
||||
class KUrlComboBox;
|
||||
class KUrlRequester;
|
||||
|
||||
class DiffSettings;
|
||||
|
||||
class DIALOGPAGES_EXPORT DiffPage : public PageBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DiffPage();
|
||||
~DiffPage();
|
||||
|
||||
public:
|
||||
void setSettings( DiffSettings* );
|
||||
DiffSettings* settings( void );
|
||||
|
||||
public:
|
||||
virtual void restore();
|
||||
virtual void apply();
|
||||
virtual void setDefaults();
|
||||
|
||||
protected slots:
|
||||
void slotShowRegExpEditor();
|
||||
void slotExcludeFilePatternToggled( bool );
|
||||
void slotExcludeFileToggled( bool );
|
||||
|
||||
private:
|
||||
void addDiffTab();
|
||||
void addFormatTab();
|
||||
void addOptionsTab();
|
||||
void addExcludeTab();
|
||||
|
||||
public:
|
||||
DiffSettings* m_settings;
|
||||
|
||||
KUrlRequester* m_diffURLRequester;
|
||||
|
||||
QCheckBox* m_newFilesCheckBox;
|
||||
QCheckBox* m_smallerCheckBox;
|
||||
QCheckBox* m_largerCheckBox;
|
||||
QCheckBox* m_tabsCheckBox;
|
||||
QCheckBox* m_caseCheckBox;
|
||||
QCheckBox* m_linesCheckBox;
|
||||
QCheckBox* m_whitespaceCheckBox;
|
||||
QCheckBox* m_allWhitespaceCheckBox;
|
||||
QCheckBox* m_ignoreTabExpansionCheckBox;
|
||||
|
||||
QCheckBox* m_ignoreRegExpCheckBox;
|
||||
KLineEdit* m_ignoreRegExpEdit;
|
||||
QStringList* m_ignoreRegExpEditHistory;
|
||||
QDialog* m_ignoreRegExpDialog;
|
||||
|
||||
QGroupBox* m_excludeFilePatternGroupBox;
|
||||
KEditListWidget* m_excludeFilePatternEditListBox;
|
||||
|
||||
QGroupBox* m_excludeFileNameGroupBox;
|
||||
KUrlComboBox* m_excludeFileURLComboBox;
|
||||
KUrlRequester* m_excludeFileURLRequester;
|
||||
|
||||
// loc == lines of context
|
||||
QSpinBox* m_locSpinBox;
|
||||
|
||||
QButtonGroup* m_modeButtonGroup;
|
||||
QGroupBox* m_diffProgramGroup;
|
||||
|
||||
KTabWidget* m_tabWidget;
|
||||
};
|
||||
|
||||
#endif
|
162
kompare/libdialogpages/filespage.cpp
Normal file
|
@ -0,0 +1,162 @@
|
|||
/***************************************************************************
|
||||
filespage.cpp
|
||||
-------------
|
||||
begin : Sun Apr 18 2004
|
||||
Copyright 2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "filespage.h"
|
||||
|
||||
#include <QtGui/QLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QHBoxLayout>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kcharsets.h>
|
||||
#include <kconfig.h>
|
||||
#include <kdebug.h>
|
||||
#include <kdialog.h>
|
||||
#include <klocale.h>
|
||||
#include <kurlcombobox.h>
|
||||
#include <kurlrequester.h>
|
||||
|
||||
#include "filessettings.h"
|
||||
|
||||
FilesPage::FilesPage() : PageBase()
|
||||
{
|
||||
QWidget* page = new QWidget( this );
|
||||
QVBoxLayout* layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
m_firstGB = new QGroupBox( "You have to set this moron :)", page );
|
||||
layout->addWidget( m_firstGB );
|
||||
QHBoxLayout* gb1Layout = new QHBoxLayout( m_firstGB );
|
||||
m_firstURLComboBox = new KUrlComboBox( KUrlComboBox::Both, true, m_firstGB );
|
||||
m_firstURLComboBox->setObjectName( "SourceURLComboBox" );
|
||||
m_firstURLRequester = new KUrlRequester( m_firstURLComboBox, m_firstGB );
|
||||
gb1Layout->addWidget( m_firstURLRequester );
|
||||
m_firstURLRequester->setFocus();
|
||||
|
||||
m_secondGB = new QGroupBox( "This too moron !", page );
|
||||
layout->addWidget( m_secondGB );
|
||||
QHBoxLayout* gb2Layout = new QHBoxLayout( m_secondGB );
|
||||
m_secondURLComboBox = new KUrlComboBox( KUrlComboBox::Both, true, m_secondGB );
|
||||
m_secondURLComboBox->setObjectName( "DestURLComboBox" );
|
||||
m_secondURLRequester = new KUrlRequester( m_secondURLComboBox, m_secondGB );
|
||||
gb2Layout->addWidget( m_secondURLRequester );
|
||||
|
||||
m_thirdGB = new QGroupBox( i18n( "Encoding" ), page );
|
||||
layout->addWidget( m_thirdGB );
|
||||
QHBoxLayout* gb3Layout = new QHBoxLayout( m_thirdGB );
|
||||
m_encodingComboBox = new KComboBox( false, m_thirdGB );
|
||||
m_encodingComboBox->setObjectName( "encoding_combobox" );
|
||||
m_encodingComboBox->insertItem( 0, "Default" );
|
||||
m_encodingComboBox->insertItems( 1, KGlobal::charsets()->availableEncodingNames() );
|
||||
gb3Layout->addWidget( m_encodingComboBox );
|
||||
|
||||
layout->addWidget( m_firstGB );
|
||||
layout->addWidget( m_secondGB );
|
||||
layout->addWidget( m_thirdGB );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
//addTab( page, i18n( "&Files" ) );
|
||||
}
|
||||
|
||||
FilesPage::~FilesPage()
|
||||
{
|
||||
m_settings = 0;
|
||||
}
|
||||
|
||||
KUrlRequester* FilesPage::firstURLRequester() const
|
||||
{
|
||||
return m_firstURLRequester;
|
||||
}
|
||||
|
||||
KUrlRequester* FilesPage::secondURLRequester() const
|
||||
{
|
||||
return m_secondURLRequester;
|
||||
}
|
||||
|
||||
QString FilesPage::encoding() const
|
||||
{
|
||||
return m_encodingComboBox->currentText();
|
||||
}
|
||||
|
||||
void FilesPage::setFirstGroupBoxTitle( const QString& title )
|
||||
{
|
||||
m_firstGB->setTitle( title );
|
||||
}
|
||||
|
||||
void FilesPage::setSecondGroupBoxTitle( const QString& title )
|
||||
{
|
||||
m_secondGB->setTitle( title );
|
||||
}
|
||||
|
||||
void FilesPage::setURLsInComboBoxes()
|
||||
{
|
||||
// kDebug() << "first : " << m_firstURLComboBox->currentText() << endl;
|
||||
// kDebug() << "second: " << m_secondURLComboBox->currentText() << endl;
|
||||
m_firstURLComboBox->setUrl( KUrl( m_firstURLComboBox->currentText() ) );
|
||||
m_secondURLComboBox->setUrl( KUrl( m_secondURLComboBox->currentText() ) );
|
||||
}
|
||||
|
||||
|
||||
void FilesPage::setFirstURLRequesterMode( unsigned int mode )
|
||||
{
|
||||
m_firstURLRequester->setMode( (KFile::Mode) mode );
|
||||
}
|
||||
|
||||
void FilesPage::setSecondURLRequesterMode( unsigned int mode )
|
||||
{
|
||||
m_secondURLRequester->setMode( (KFile::Mode) mode );
|
||||
}
|
||||
|
||||
void FilesPage::setSettings( FilesSettings* settings )
|
||||
{
|
||||
m_settings = settings;
|
||||
|
||||
m_firstURLComboBox->setUrls( m_settings->m_recentSources );
|
||||
m_firstURLComboBox->setUrl( KUrl( m_settings->m_lastChosenSourceURL ) );
|
||||
m_secondURLComboBox->setUrls( m_settings->m_recentDestinations );
|
||||
m_secondURLComboBox->setUrl( KUrl( m_settings->m_lastChosenDestinationURL ) );
|
||||
m_encodingComboBox->setCurrentIndex( m_encodingComboBox->findText( m_settings->m_encoding, Qt::MatchFixedString ) );
|
||||
}
|
||||
|
||||
void FilesPage::restore()
|
||||
{
|
||||
// this shouldn't do a thing...
|
||||
}
|
||||
|
||||
void FilesPage::apply()
|
||||
{
|
||||
m_settings->m_recentSources = m_firstURLComboBox->urls();
|
||||
m_settings->m_lastChosenSourceURL = m_firstURLComboBox->currentText();
|
||||
m_settings->m_recentDestinations = m_secondURLComboBox->urls();
|
||||
m_settings->m_lastChosenDestinationURL = m_secondURLComboBox->currentText();
|
||||
m_settings->m_encoding = m_encodingComboBox->currentText();
|
||||
}
|
||||
|
||||
void FilesPage::setDefaults()
|
||||
{
|
||||
m_firstURLComboBox->setUrls( QStringList() );
|
||||
m_firstURLComboBox->setUrl( KUrl( "" ) );
|
||||
m_secondURLComboBox->setUrls( QStringList() );
|
||||
m_secondURLComboBox->setUrl( KUrl( "" ) );
|
||||
m_encodingComboBox->setCurrentIndex( 0 ); // "Default"
|
||||
}
|
||||
|
||||
#include "filespage.moc"
|
76
kompare/libdialogpages/filespage.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/***************************************************************************
|
||||
kcompareurldialog.h
|
||||
-------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef FILESPAGE_H
|
||||
#define FILESPAGE_H
|
||||
|
||||
#include "pagebase.h"
|
||||
#include "dialogpagesexport.h"
|
||||
|
||||
class QGroupBox;
|
||||
|
||||
class KComboBox;
|
||||
class KUrlComboBox;
|
||||
class KUrlRequester;
|
||||
|
||||
class FilesSettings;
|
||||
|
||||
class DIALOGPAGES_EXPORT FilesPage : public PageBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FilesPage();
|
||||
virtual ~FilesPage();
|
||||
|
||||
public:
|
||||
KUrlRequester* firstURLRequester() const;
|
||||
KUrlRequester* secondURLRequester() const;
|
||||
|
||||
QString encoding() const;
|
||||
|
||||
void setFirstGroupBoxTitle ( const QString& title );
|
||||
void setSecondGroupBoxTitle( const QString& title );
|
||||
|
||||
void setURLsInComboBoxes();
|
||||
|
||||
void setFirstURLRequesterMode( unsigned int mode );
|
||||
void setSecondURLRequesterMode( unsigned int mode );
|
||||
|
||||
public:
|
||||
virtual void setSettings( FilesSettings* settings );
|
||||
virtual void restore();
|
||||
virtual void apply();
|
||||
virtual void setDefaults();
|
||||
|
||||
private:
|
||||
QGroupBox* m_firstGB;
|
||||
QGroupBox* m_secondGB;
|
||||
QGroupBox* m_thirdGB;
|
||||
KUrlComboBox* m_firstURLComboBox;
|
||||
KUrlComboBox* m_secondURLComboBox;
|
||||
KUrlRequester* m_firstURLRequester;
|
||||
KUrlRequester* m_secondURLRequester;
|
||||
// Use this bool to lock the connection between both KUrlRequesters.
|
||||
// This prevents annoying behaviour
|
||||
bool m_URLChanged;
|
||||
KComboBox* m_encodingComboBox;
|
||||
|
||||
FilesSettings* m_settings;
|
||||
};
|
||||
|
||||
#endif
|
60
kompare/libdialogpages/filessettings.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
/***************************************************************************
|
||||
filessettings.cpp
|
||||
-----------------
|
||||
begin : Sun Apr 18 2004
|
||||
Copyright 2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "filessettings.h"
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kconfig.h>
|
||||
#include <kconfiggroup.h>
|
||||
|
||||
FilesSettings::FilesSettings( QWidget* parent )
|
||||
: SettingsBase( parent )
|
||||
{
|
||||
}
|
||||
|
||||
FilesSettings::~FilesSettings()
|
||||
{
|
||||
}
|
||||
|
||||
void FilesSettings::loadSettings( KConfig* config )
|
||||
{
|
||||
KConfigGroup group( config, m_configGroupName );
|
||||
|
||||
m_recentSources = group.readEntry( "Recent Sources", QStringList() );
|
||||
m_lastChosenSourceURL = group.readEntry ( "LastChosenSourceListEntry", "" );
|
||||
m_recentDestinations = group.readEntry( "Recent Destinations", QStringList() );
|
||||
m_lastChosenDestinationURL = group.readEntry ( "LastChosenDestinationListEntry", "" );
|
||||
m_encoding = group.readEntry ( "Encoding", "default" );
|
||||
}
|
||||
|
||||
void FilesSettings::saveSettings( KConfig* config )
|
||||
{
|
||||
KConfigGroup group( config, m_configGroupName );
|
||||
group.writeEntry( "Recent Sources", m_recentSources );
|
||||
group.writeEntry( "Recent Destinations", m_recentDestinations );
|
||||
group.writeEntry( "LastChosenSourceListEntry", m_lastChosenSourceURL );
|
||||
group.writeEntry( "LastChosenDestinationListEntry", m_lastChosenDestinationURL );
|
||||
group.writeEntry( "Encoding", m_encoding );
|
||||
config->sync();
|
||||
}
|
||||
|
||||
void FilesSettings::setGroup( const QString& groupName )
|
||||
{
|
||||
m_configGroupName = groupName;
|
||||
}
|
||||
|
||||
#include "filessettings.moc"
|
54
kompare/libdialogpages/filessettings.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***************************************************************************
|
||||
filessettings.h
|
||||
---------------
|
||||
begin : Sun Apr 18 2004
|
||||
Copyright 2004 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FILESSETTINGS_H
|
||||
#define FILESSETTINGS_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <settingsbase.h>
|
||||
|
||||
#include "dialogpagesexport.h"
|
||||
|
||||
class KConfig;
|
||||
|
||||
class DIALOGPAGES_EXPORT FilesSettings : public SettingsBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FilesSettings( QWidget* parent );
|
||||
virtual ~FilesSettings();
|
||||
|
||||
public:
|
||||
// some virtual functions that will be overloaded from the base class
|
||||
virtual void loadSettings( KConfig* config );
|
||||
virtual void saveSettings( KConfig* config );
|
||||
|
||||
void setGroup( const QString& groupName );
|
||||
|
||||
public:
|
||||
QString m_configGroupName;
|
||||
|
||||
QStringList m_recentSources;
|
||||
QString m_lastChosenSourceURL;
|
||||
QStringList m_recentDestinations;
|
||||
QString m_lastChosenDestinationURL;
|
||||
QString m_encoding;
|
||||
};
|
||||
|
||||
#endif // FILESSETTINGS_H
|
||||
|
105
kompare/libdialogpages/pagebase.cpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
/***************************************************************************
|
||||
prefsbase.cpp
|
||||
-------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "pagebase.h"
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtGui/QLayout>
|
||||
|
||||
PageBase::PageBase() : KVBox()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PageBase::~PageBase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
QSize PageBase::sizeHintForWidget( QWidget* widget )
|
||||
{
|
||||
//
|
||||
// The size is computed by adding the sizeHint().height() of all
|
||||
// widget children and taking the width of the widest child and adding
|
||||
// layout()->margin() and layout()->spacing()
|
||||
//
|
||||
|
||||
// this code in this method has been ripped out of a file in kbabel
|
||||
// so copyright goes to the kbabel authors.
|
||||
|
||||
QSize size;
|
||||
|
||||
int numChild = 0;
|
||||
QList<QObject*> l = widget->children();
|
||||
|
||||
|
||||
|
||||
for( int i=0; i < l.count(); i++ )
|
||||
{
|
||||
QObject *o = l.at(i);
|
||||
if( o->isWidgetType() )
|
||||
{
|
||||
numChild += 1;
|
||||
QWidget *w=((QWidget*)o);
|
||||
|
||||
QSize s = w->sizeHint();
|
||||
if( s.isEmpty() == true )
|
||||
{
|
||||
s = QSize( 50, 100 ); // Default size
|
||||
}
|
||||
size.setHeight( size.height() + s.height() );
|
||||
if( s.width() > size.width() )
|
||||
{
|
||||
size.setWidth( s.width() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( numChild > 0 )
|
||||
{
|
||||
size.setHeight( size.height() + widget->layout()->spacing()*(numChild-1) );
|
||||
size += QSize( widget->layout()->margin()*2, widget->layout()->margin()*2 + 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
size = QSize( 1, 1 );
|
||||
}
|
||||
|
||||
return( size );
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void PageBase::apply()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void PageBase::restore()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** No descriptions */
|
||||
void PageBase::setDefaults()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#include "pagebase.moc"
|
45
kompare/libdialogpages/pagebase.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/***************************************************************************
|
||||
prefsbase.h
|
||||
-----------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PAGEBASE_H
|
||||
#define PAGEBASE_H
|
||||
|
||||
#include <QtCore/QSize>
|
||||
|
||||
#include <kvbox.h>
|
||||
#include <kompare.h>
|
||||
|
||||
class PageBase : public KVBox
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PageBase();
|
||||
~PageBase();
|
||||
|
||||
public:
|
||||
/** No descriptions */
|
||||
QSize sizeHintForWidget( QWidget* widget );
|
||||
/** No descriptions */
|
||||
virtual void restore();
|
||||
/** No descriptions */
|
||||
virtual void apply();
|
||||
/** No descriptions */
|
||||
virtual void setDefaults();
|
||||
};
|
||||
|
||||
#endif
|
216
kompare/libdialogpages/viewpage.cpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
/***************************************************************************
|
||||
viewprefs.cpp
|
||||
-------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2002 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2002 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2011 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "viewpage.h"
|
||||
|
||||
#include <QtGui/QCheckBox>
|
||||
#include <QtGui/QGroupBox>
|
||||
#include <QtGui/QLabel>
|
||||
#include <QtGui/QLayout>
|
||||
#include <QtGui/QSpinBox>
|
||||
#include <QtGui/QVBoxLayout>
|
||||
#include <QtGui/QGridLayout>
|
||||
#include <QtGui/QFontComboBox>
|
||||
|
||||
#include <kapplication.h>
|
||||
#include <kcolorbutton.h>
|
||||
#include <kdialog.h>
|
||||
#include <klocale.h>
|
||||
#include <kglobal.h>
|
||||
#include <ktabwidget.h>
|
||||
|
||||
#include "viewsettings.h"
|
||||
|
||||
ViewPage::ViewPage() : PageBase()
|
||||
{
|
||||
QWidget* page;
|
||||
QVBoxLayout* layout;
|
||||
QGridLayout* gridLayout;
|
||||
QGroupBox* colorGroupBox;
|
||||
QGroupBox* snolGroupBox;
|
||||
QGroupBox* tabGroupBox;
|
||||
QLabel* label;
|
||||
|
||||
m_tabWidget = new KTabWidget( this );
|
||||
page = new QWidget( m_tabWidget );
|
||||
layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
// add a groupbox
|
||||
colorGroupBox = new QGroupBox( page );
|
||||
colorGroupBox->setTitle( i18n( "Colors" ) );
|
||||
layout->addWidget( colorGroupBox );
|
||||
//colorGroupBox->setMargin( KDialog::marginHint() );
|
||||
gridLayout = new QGridLayout( colorGroupBox );
|
||||
|
||||
// add the removeColor
|
||||
label = new QLabel( i18n( "Removed color:" ), colorGroupBox );
|
||||
m_removedColorButton = new KColorButton( colorGroupBox );
|
||||
label->setBuddy( m_removedColorButton );
|
||||
gridLayout->addWidget( label, 0, 0 );
|
||||
gridLayout->addWidget( m_removedColorButton, 0, 1 );
|
||||
|
||||
// add the changeColor
|
||||
label = new QLabel( i18n( "Changed color:" ), colorGroupBox );
|
||||
m_changedColorButton = new KColorButton( colorGroupBox );
|
||||
label->setBuddy( m_changedColorButton );
|
||||
gridLayout->addWidget( label, 1, 0 );
|
||||
gridLayout->addWidget( m_changedColorButton, 1, 1 );
|
||||
|
||||
// add the addColor
|
||||
label = new QLabel( i18n( "Added color:" ), colorGroupBox );
|
||||
m_addedColorButton = new KColorButton( colorGroupBox );
|
||||
label->setBuddy( m_addedColorButton );
|
||||
gridLayout->addWidget( label, 2, 0 );
|
||||
gridLayout->addWidget( m_addedColorButton, 2, 1 );
|
||||
|
||||
// add the appliedColor
|
||||
label = new QLabel( i18n( "Applied color:" ), colorGroupBox );
|
||||
m_appliedColorButton = new KColorButton( colorGroupBox );
|
||||
label->setBuddy( m_appliedColorButton );
|
||||
gridLayout->addWidget( label, 3, 0 );
|
||||
gridLayout->addWidget( m_appliedColorButton, 3, 1 );
|
||||
|
||||
// scroll number of lines (snol)
|
||||
snolGroupBox = new QGroupBox( page );
|
||||
QHBoxLayout *snolLayout = new QHBoxLayout;
|
||||
snolGroupBox->setLayout( snolLayout );
|
||||
snolGroupBox->setTitle( i18n( "Mouse Wheel" ) );
|
||||
layout->addWidget( snolGroupBox );
|
||||
//snolGroupBox->setMargin( KDialog::marginHint() );
|
||||
|
||||
label = new QLabel( i18n( "Number of lines:" ) );
|
||||
snolLayout->addWidget( label );
|
||||
m_snolSpinBox = new QSpinBox( snolGroupBox );
|
||||
m_snolSpinBox->setRange( 0, 50 );
|
||||
snolLayout->addWidget( m_snolSpinBox );
|
||||
label->setBuddy( m_snolSpinBox );
|
||||
|
||||
// Temporarily here for testing...
|
||||
// number of spaces for a tab character stuff
|
||||
tabGroupBox = new QGroupBox( page );
|
||||
QHBoxLayout *tabLayout = new QHBoxLayout;
|
||||
tabGroupBox->setLayout( tabLayout );
|
||||
tabGroupBox->setTitle( i18n( "Tabs to Spaces" ) );
|
||||
layout->addWidget( tabGroupBox );
|
||||
//tabGroupBox->setMargin( KDialog::marginHint() );
|
||||
|
||||
label = new QLabel( i18n( "Number of spaces to convert a tab character to:" ) );
|
||||
tabLayout->addWidget( label );
|
||||
m_tabSpinBox = new QSpinBox( tabGroupBox );
|
||||
m_tabSpinBox->setRange( 1, 16 );
|
||||
tabLayout->addWidget( m_tabSpinBox );
|
||||
label->setBuddy( m_tabSpinBox );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Appearance" ) );
|
||||
|
||||
page = new QWidget( m_tabWidget );
|
||||
layout = new QVBoxLayout( page );
|
||||
layout->setSpacing( KDialog::spacingHint() );
|
||||
layout->setMargin( KDialog::marginHint() );
|
||||
|
||||
QGroupBox* gb = new QGroupBox( page );
|
||||
QHBoxLayout *layfont = new QHBoxLayout;
|
||||
gb->setLayout( layfont );
|
||||
gb->setTitle( i18n( "Text Font" ) );
|
||||
layout->addWidget( gb );
|
||||
//gb->setMargin( KDialog::marginHint() );
|
||||
|
||||
label = new QLabel( i18n( "Font:" ) );
|
||||
m_fontCombo = new QFontComboBox;
|
||||
layfont->addWidget( label );
|
||||
layfont->addWidget( m_fontCombo );
|
||||
m_fontCombo->setObjectName( "fontcombo" );
|
||||
label->setBuddy( m_fontCombo );
|
||||
|
||||
label = new QLabel( i18n( "Size:" ) );
|
||||
layfont->addWidget( label );
|
||||
m_fontSizeSpinBox = new QSpinBox( gb );
|
||||
m_fontSizeSpinBox->setRange( 6, 24 );
|
||||
layfont->addWidget( m_fontSizeSpinBox );
|
||||
label->setBuddy( m_fontSizeSpinBox );
|
||||
|
||||
layout->addStretch( 1 );
|
||||
page->setMinimumSize( sizeHintForWidget( page ) );
|
||||
|
||||
m_tabWidget->addTab( page, i18n( "Fonts" ) );
|
||||
}
|
||||
|
||||
ViewPage::~ViewPage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ViewPage::setSettings( ViewSettings* setts )
|
||||
{
|
||||
m_settings = setts;
|
||||
|
||||
m_addedColorButton->setColor ( m_settings->m_addColor );
|
||||
m_changedColorButton->setColor( m_settings->m_changeColor );
|
||||
m_removedColorButton->setColor( m_settings->m_removeColor );
|
||||
m_appliedColorButton->setColor( m_settings->m_appliedColor );
|
||||
m_snolSpinBox->setValue ( m_settings->m_scrollNoOfLines );
|
||||
m_tabSpinBox->setValue ( m_settings->m_tabToNumberOfSpaces );
|
||||
|
||||
m_fontCombo->setCurrentFont ( m_settings->m_font.family() );
|
||||
m_fontSizeSpinBox->setValue ( m_settings->m_font.pointSize() );
|
||||
}
|
||||
|
||||
ViewSettings* ViewPage::settings( void )
|
||||
{
|
||||
return m_settings;
|
||||
}
|
||||
|
||||
void ViewPage::restore()
|
||||
{
|
||||
}
|
||||
|
||||
void ViewPage::apply()
|
||||
{
|
||||
m_settings->m_addColor = m_addedColorButton->color();
|
||||
m_settings->m_changeColor = m_changedColorButton->color();
|
||||
m_settings->m_removeColor = m_removedColorButton->color();
|
||||
m_settings->m_appliedColor = m_appliedColorButton->color();
|
||||
m_settings->m_scrollNoOfLines = m_snolSpinBox->value();
|
||||
m_settings->m_tabToNumberOfSpaces = m_tabSpinBox->value();
|
||||
|
||||
m_settings->m_font = QFont( m_fontCombo->currentFont() );
|
||||
m_settings->m_font.setPointSize( m_fontSizeSpinBox->value() );
|
||||
|
||||
m_settings->saveSettings( KGlobal::config().data() );
|
||||
}
|
||||
|
||||
void ViewPage::setDefaults()
|
||||
{
|
||||
m_addedColorButton->setColor ( ViewSettings::default_addColor );
|
||||
m_changedColorButton->setColor( ViewSettings::default_changeColor );
|
||||
m_removedColorButton->setColor( ViewSettings::default_removeColor );
|
||||
m_appliedColorButton->setColor( ViewSettings::default_appliedColor );
|
||||
m_snolSpinBox->setValue ( 3 );
|
||||
m_tabSpinBox->setValue ( 4 );
|
||||
|
||||
// TODO: port
|
||||
// m_fontCombo->setCurrentFont ( KGlobalSettings::fixedFont().family() );
|
||||
m_fontSizeSpinBox->setValue ( 10 );
|
||||
}
|
||||
|
||||
#include "viewpage.moc"
|
65
kompare/libdialogpages/viewpage.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/***************************************************************************
|
||||
generalprefs.h
|
||||
--------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef VIEWPAGE_H
|
||||
#define VIEWPAGE_H
|
||||
|
||||
#include "pagebase.h"
|
||||
#include "dialogpagesexport.h"
|
||||
|
||||
class QFontComboBox;
|
||||
class QSpinBox;
|
||||
|
||||
class KColorButton;
|
||||
class KTabWidget;
|
||||
|
||||
class ViewSettings;
|
||||
|
||||
class DIALOGPAGES_EXPORT ViewPage : public PageBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ViewPage();
|
||||
~ViewPage();
|
||||
|
||||
public:
|
||||
void setSettings( ViewSettings* );
|
||||
ViewSettings* settings( void );
|
||||
|
||||
public:
|
||||
ViewSettings* m_settings;
|
||||
|
||||
public:
|
||||
virtual void restore();
|
||||
virtual void apply();
|
||||
virtual void setDefaults();
|
||||
|
||||
public:
|
||||
KColorButton* m_removedColorButton;
|
||||
KColorButton* m_changedColorButton;
|
||||
KColorButton* m_addedColorButton;
|
||||
KColorButton* m_appliedColorButton;
|
||||
// snol == scroll number of lines
|
||||
QSpinBox* m_snolSpinBox;
|
||||
QSpinBox* m_tabSpinBox;
|
||||
QFontComboBox* m_fontCombo;
|
||||
QSpinBox* m_fontSizeSpinBox;
|
||||
KTabWidget* m_tabWidget;
|
||||
};
|
||||
|
||||
#endif
|
101
kompare/libdialogpages/viewsettings.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/***************************************************************************
|
||||
generalsettings.cpp
|
||||
-------------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#include "viewsettings.h"
|
||||
|
||||
#include <QtGui/QFont>
|
||||
|
||||
#include <kconfig.h>
|
||||
#include <kglobalsettings.h>
|
||||
#include <kconfiggroup.h>
|
||||
|
||||
using namespace Diff2;
|
||||
|
||||
const QColor ViewSettings::default_removeColor (190, 237, 190);
|
||||
const QColor ViewSettings::default_changeColor (237, 190, 190);
|
||||
const QColor ViewSettings::default_addColor (190, 190, 237);
|
||||
const QColor ViewSettings::default_appliedColor(237, 237, 190);
|
||||
|
||||
ViewSettings::ViewSettings( QWidget* parent )
|
||||
: SettingsBase( parent ),
|
||||
m_removeColor( 0, 0, 0 ),
|
||||
m_changeColor( 0, 0, 0),
|
||||
m_addColor( 0, 0, 0),
|
||||
m_appliedColor( 0, 0, 0),
|
||||
m_scrollNoOfLines( 0 ),
|
||||
m_tabToNumberOfSpaces( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
ViewSettings::~ViewSettings()
|
||||
{
|
||||
}
|
||||
|
||||
void ViewSettings::loadSettings( KConfig* config )
|
||||
{
|
||||
KConfigGroup cfg( config, "View Options" );
|
||||
m_removeColor = cfg.readEntry( "RemoveColor", default_removeColor );
|
||||
m_changeColor = cfg.readEntry( "ChangeColor", default_changeColor );
|
||||
m_addColor = cfg.readEntry( "AddColor", default_addColor );
|
||||
m_appliedColor = cfg.readEntry( "AppliedColor", default_appliedColor );
|
||||
m_scrollNoOfLines = cfg.readEntry ( "ScrollNoOfLines", 3 );
|
||||
m_tabToNumberOfSpaces = cfg.readEntry ( "TabToNumberOfSpaces", 4 );
|
||||
|
||||
QFont stdFixed = KGlobalSettings::fixedFont();
|
||||
stdFixed.setPointSize( 10 );
|
||||
m_font = cfg.readEntry ( "TextFont", stdFixed );
|
||||
}
|
||||
|
||||
void ViewSettings::saveSettings( KConfig* config )
|
||||
{
|
||||
KConfigGroup cfg( config, "View Options" );
|
||||
cfg.writeEntry( "RemoveColor", m_removeColor );
|
||||
cfg.writeEntry( "ChangeColor", m_changeColor );
|
||||
cfg.writeEntry( "AddColor", m_addColor );
|
||||
cfg.writeEntry( "AppliedColor", m_appliedColor );
|
||||
cfg.writeEntry( "ScrollNoOfLines", m_scrollNoOfLines );
|
||||
cfg.writeEntry( "TabToNumberOfSpaces", m_tabToNumberOfSpaces );
|
||||
|
||||
cfg.writeEntry( "TextFont", m_font );
|
||||
}
|
||||
|
||||
QColor ViewSettings::colorForDifferenceType( int type, bool selected, bool applied )
|
||||
{
|
||||
// FIXME: does not belong here
|
||||
QColor color;
|
||||
if( applied )
|
||||
color = m_appliedColor;
|
||||
else
|
||||
{
|
||||
type = type & 0xFFFFFFEF; // remove the AppliedByBlend
|
||||
switch( type ) {
|
||||
case Difference::Unchanged: color = Qt::white; break;
|
||||
case Difference::Change: color = m_changeColor; break;
|
||||
case Difference::Insert: color = m_addColor; break;
|
||||
case Difference::Delete: color = m_removeColor; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
if( selected )
|
||||
color = color.light( 110 );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
#include "viewsettings.moc"
|
61
kompare/libdialogpages/viewsettings.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/***************************************************************************
|
||||
generalsettings.h
|
||||
-----------------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2003 Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@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.
|
||||
**
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef VIEWSETTINGS_H
|
||||
#define VIEWSETTINGS_H
|
||||
|
||||
#include <QtGui/QColor>
|
||||
#include <QtGui/QWidget>
|
||||
|
||||
#include <difference.h>
|
||||
#include <settingsbase.h>
|
||||
|
||||
#include "dialogpagesexport.h"
|
||||
|
||||
class DIALOGPAGES_EXPORT ViewSettings : public SettingsBase
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static const QColor default_removeColor;
|
||||
static const QColor default_changeColor;
|
||||
static const QColor default_addColor;
|
||||
static const QColor default_appliedColor;
|
||||
|
||||
ViewSettings( QWidget* parent );
|
||||
~ViewSettings();
|
||||
public:
|
||||
// some virtual functions that will be overloaded from the base class
|
||||
virtual void loadSettings( KConfig* config );
|
||||
virtual void saveSettings( KConfig* config );
|
||||
QColor colorForDifferenceType( int type, bool selected = false, bool applied = false );
|
||||
|
||||
public:
|
||||
QColor m_removeColor;
|
||||
QColor m_changeColor;
|
||||
QColor m_addColor;
|
||||
QColor m_appliedColor;
|
||||
QColor m_selectedRemoveColor;
|
||||
QColor m_selectedChangeColor;
|
||||
QColor m_selectedAddColor;
|
||||
QColor m_selectedAppliedColor;
|
||||
int m_scrollNoOfLines;
|
||||
int m_tabToNumberOfSpaces;
|
||||
|
||||
QFont m_font;
|
||||
};
|
||||
|
||||
#endif // VIEWSETTINGS_H
|
232
kompare/main.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
/***************************************************************************
|
||||
main.cpp
|
||||
--------
|
||||
begin : Sun Mar 4 2001
|
||||
Copyright 2001-2005,2009 Otto Bruggeman <bruggie@gmail.com>
|
||||
Copyright 2001-2003 John Firebaugh <jfirebaugh@kde.org>
|
||||
Copyright 2007-2012 Kevin Kofler <kevin.kofler@chello.at>
|
||||
****************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
***************************************************************************/
|
||||
/**
|
||||
* @file main.cpp
|
||||
* This is the main entry point for Kompare.
|
||||
* The command line arguments are handled and the application is started.
|
||||
* @author Otto Bruggeman <otto.bruggeman@home.nl>
|
||||
* @author John Firebaugh <jfirebaugh@kde.org>
|
||||
* @author Kevin Kofler <kevin.kofler@chello.at>
|
||||
*/
|
||||
|
||||
#include <kaboutdata.h>
|
||||
#include <kcmdlineargs.h>
|
||||
#include <kdebug.h>
|
||||
#include <kfile.h>
|
||||
#include <klocale.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kdialog.h>
|
||||
|
||||
#include "kompare_part.h"
|
||||
#include "kompare_shell.h"
|
||||
#include "kompareurldialog.h"
|
||||
|
||||
/**
|
||||
* Program description.
|
||||
*/
|
||||
static const char description[] =
|
||||
I18N_NOOP("A program to view the differences between files and optionally generate a diff" );
|
||||
|
||||
/**
|
||||
* Version number.
|
||||
*/
|
||||
static const char version[] = "4.1.3";
|
||||
|
||||
/**
|
||||
* Setting up the KAboutData structure.
|
||||
* Parsing and handling of the given command line arguments.
|
||||
* @param argc the number of arguments
|
||||
* @param argv the array of arguments
|
||||
* @return exit status
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
KAboutData aboutData( "kompare", 0, ki18n("Kompare"), version, ki18n(description),
|
||||
KAboutData::License_GPL,
|
||||
ki18n("(c) 2001-2004 John Firebaugh, (c) 2001-2005,2009 Otto Bruggeman, (c) 2004-2005 Jeff Snyder, (c) 2007-2012 Kevin Kofler") );
|
||||
aboutData.addAuthor( ki18n("John Firebaugh"), ki18n("Author"), "jfirebaugh@kde.org" );
|
||||
aboutData.addAuthor( ki18n("Otto Bruggeman"), ki18n("Author"), "bruggie@gmail.com" );
|
||||
aboutData.addAuthor( ki18n("Jeff Snyder"), ki18n("Developer"), "jeff@caffeinated.me.uk" );
|
||||
aboutData.addCredit( ki18n("Kevin Kofler"), ki18n("Maintainer"), "kevin.kofler@chello.at" );
|
||||
aboutData.addCredit( ki18n("Chris Luetchford"), ki18n("Kompare icon artist"), "chris@os11.com" );
|
||||
aboutData.addCredit( ki18n("Malte Starostik"), ki18n("A lot of good advice"), "malte@kde.org" );
|
||||
aboutData.addCredit( ki18n("Bernd Gehrmann"), ki18n("Cervisia diff viewer"), "bernd@physik.hu-berlin.de" );
|
||||
|
||||
KCmdLineArgs::init(argc, argv, &aboutData);
|
||||
|
||||
KCmdLineOptions options;
|
||||
options.add("c", ki18n( "This will compare URL1 with URL2" ));
|
||||
options.add("o", ki18n( "This will open URL1 and expect it to be diff output. URL1 can also be a '-' and then it will read from standard input. Can be used for instance for cvs diff | kompare -o -. Kompare will do a check to see if it can find the original file(s) and then blend the original file(s) into the diffoutput and show that in the viewer. -n disables the check." ));
|
||||
options.add("b", ki18n( "This will blend URL2 into URL1, URL2 is expected to be diff output and URL1 the file or folder that the diffoutput needs to be blended into. " ));
|
||||
options.add("n", ki18n( "Disables the check for automatically finding the original file(s) when using '-' as URL with the -o option." ));
|
||||
options.add("e <encoding>", ki18n( "Use this to specify the encoding when calling it from the command line. It will default to the local encoding if not specified." ));
|
||||
options.add("+[URL1 [URL2]]");
|
||||
options.add("+-");
|
||||
KCmdLineArgs::addCmdLineOptions( options );
|
||||
KApplication kompare;
|
||||
bool difault = false;
|
||||
|
||||
KompareShell* ks;
|
||||
|
||||
// see if we are starting with session management
|
||||
if (kompare.isSessionRestored())
|
||||
{
|
||||
RESTORE(KompareShell)
|
||||
}
|
||||
else
|
||||
{
|
||||
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
|
||||
|
||||
ks = new KompareShell();
|
||||
ks->setObjectName( "FirstKompareShell" );
|
||||
|
||||
kDebug( 8100 ) << "Arg Count = " << args->count() << endl;
|
||||
for ( int i=0; i < args->count(); i++ )
|
||||
{
|
||||
kDebug( 8100 ) << "Argument " << (i+1) << ": " << args->arg( i ) << endl;
|
||||
}
|
||||
|
||||
if ( args->isSet( "e" ) )
|
||||
{
|
||||
// Encoding given...
|
||||
// FIXME: Need to implement this...
|
||||
}
|
||||
|
||||
if ( args->isSet( "o" ) )
|
||||
{
|
||||
kDebug( 8100 ) << "Option -o is set" << endl;
|
||||
if ( args->count() != 1 )
|
||||
{
|
||||
difault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ks->show();
|
||||
kDebug( 8100 ) << "OpenDiff..." << endl;
|
||||
if ( args->arg(0) == QLatin1String("-") )
|
||||
ks->openStdin();
|
||||
else
|
||||
ks->openDiff( args->url( 0 ) );
|
||||
difault = false;
|
||||
}
|
||||
}
|
||||
else if ( args->isSet( "c" ) )
|
||||
{
|
||||
kDebug( 8100 ) << "Option -c is set" << endl;
|
||||
if ( args->count() != 2 )
|
||||
{
|
||||
KCmdLineArgs::usage( "kompare" );
|
||||
difault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ks->show();
|
||||
KUrl url0 = args->url( 0 );
|
||||
kDebug( 8100 ) << "URL0 = " << url0.url() << endl;
|
||||
KUrl url1 = args->url( 1 );
|
||||
kDebug( 8100 ) << "URL1 = " << url1.url() << endl;
|
||||
ks->compare( url0, url1 );
|
||||
difault = false;
|
||||
}
|
||||
}
|
||||
else if ( args->isSet( "b" ) )
|
||||
{
|
||||
kDebug( 8100 ) << "Option -b is set" << endl;
|
||||
if ( args->count() != 2 )
|
||||
{
|
||||
KCmdLineArgs::usage( "kompare" );
|
||||
difault = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ks->show();
|
||||
kDebug( 8100 ) << "blend..." << endl;
|
||||
KUrl url0 = args->url( 0 );
|
||||
kDebug( 8100 ) << "URL0 = " << url0.url() << endl;
|
||||
KUrl url1 = args->url( 1 );
|
||||
kDebug( 8100 ) << "URL1 = " << url1.url() << endl;
|
||||
ks->blend( url0, url1 );
|
||||
difault = false;
|
||||
}
|
||||
}
|
||||
else if ( args->count() == 1 )
|
||||
{
|
||||
ks->show();
|
||||
|
||||
kDebug( 8100 ) << "Single file. so openDiff/openStdin is only possible..." << endl;
|
||||
if ( args->arg(0) == QLatin1String("-") )
|
||||
ks->openStdin();
|
||||
else
|
||||
ks->openDiff( args->url( 0 ) );
|
||||
|
||||
difault = false;
|
||||
}
|
||||
else if ( args->count() == 2 )
|
||||
{
|
||||
// In this case we are assuming you want to compare files/dirs
|
||||
// and not blending because that is almost impossible to detect
|
||||
ks->show();
|
||||
kDebug( 8100 ) << "Dunno, we'll have to figure it out later, trying compare for now..." << endl;
|
||||
KUrl url0 = args->url( 0 );
|
||||
kDebug( 8100 ) << "URL0 = " << url0.url() << endl;
|
||||
KUrl url1 = args->url( 1 );
|
||||
kDebug( 8100 ) << "URL1 = " << url1.url() << endl;
|
||||
ks->compare( url0, url1 );
|
||||
difault = false;
|
||||
}
|
||||
else if ( args->count() == 0 ) // no options and no args
|
||||
{
|
||||
difault = true;
|
||||
}
|
||||
|
||||
if ( difault )
|
||||
{
|
||||
KompareURLDialog dialog( 0 );
|
||||
|
||||
dialog.setCaption( i18n("Compare Files or Folders") );
|
||||
dialog.setFirstGroupBoxTitle( i18n( "Source" ) );
|
||||
dialog.setSecondGroupBoxTitle( i18n( "Destination" ) );
|
||||
|
||||
KGuiItem compareGuiItem( i18n( "Compare" ), QString(), i18n( "Compare these files or folder" ), i18n( "If you have entered 2 filenames or 2 folders in the fields in this dialog then this button will be enabled and pressing it will start a comparison of the entered files or folders. " ) );
|
||||
dialog.setButtonGuiItem( KDialog::Ok, compareGuiItem );
|
||||
|
||||
dialog.setGroup( "Recent Compare Files" );
|
||||
|
||||
dialog.setFirstURLRequesterMode( KFile::File|KFile::Directory|KFile::ExistingOnly );
|
||||
dialog.setSecondURLRequesterMode( KFile::File|KFile::Directory|KFile::ExistingOnly );
|
||||
|
||||
if( dialog.exec() == QDialog::Accepted )
|
||||
{
|
||||
ks->show();
|
||||
ks->viewPart()->setEncoding( dialog.encoding() );
|
||||
ks->compare( dialog.getFirstURL(), dialog.getSecondURL() );
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
args->clear();
|
||||
}
|
||||
|
||||
return kompare.exec();
|
||||
}
|
||||
|
||||
/* vim: set ts=4 sw=4 noet: */
|
||||
|
5
kompare/pics/CMakeLists.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
|
||||
kde4_install_icons( ${ICON_INSTALL_DIR} )
|
||||
|
||||
|
||||
|
BIN
kompare/pics/hi128-app-kompare.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
kompare/pics/hi16-app-kompare.png
Normal file
After Width: | Height: | Size: 917 B |
BIN
kompare/pics/hi22-app-kompare.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
kompare/pics/hi32-app-kompare.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
kompare/pics/hi48-app-kompare.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
kompare/pics/hisc-app-kompare.svgz
Normal file
83
kompare/tests/cvsdiff/context.diff
Normal file
|
@ -0,0 +1,83 @@
|
|||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -c -r1.2 dcopfind.cpp
|
||||
*** client/dcopfind.cpp 2001/10/31 01:17:39 1.2
|
||||
--- client/dcopfind.cpp 2002/01/16 18:07:13
|
||||
***************
|
||||
*** 36,42 ****
|
||||
static bool bAppIdOnly = 0;
|
||||
static bool bLaunchApp = 0;
|
||||
|
||||
! bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
{
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
--- 36,42 ----
|
||||
static bool bAppIdOnly = 0;
|
||||
static bool bLaunchApp = 0;
|
||||
|
||||
! bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
{
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
***************
|
||||
*** 118,124 ****
|
||||
f = fc;
|
||||
}
|
||||
|
||||
! if ( (int) types.count() != argc ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
--- 118,124 ----
|
||||
f = fc;
|
||||
}
|
||||
|
||||
! if ( types.count() != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
***************
|
||||
*** 128,136 ****
|
||||
|
||||
int i = 0;
|
||||
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
! marshall(arg, argc, args, i, *it);
|
||||
}
|
||||
! if ( (int) i != argc ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
--- 128,136 ----
|
||||
|
||||
int i = 0;
|
||||
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
! marshall(arg, args, i, *it);
|
||||
}
|
||||
! if ( (uint) i != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
***************
|
||||
*** 221,227 ****
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
! findObject( app, objid, function, argc, args );
|
||||
|
||||
return 0;
|
||||
}
|
||||
--- 221,231 ----
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
! QCStringList params;
|
||||
! for( int i = 0; i < argc; i++ )
|
||||
! params.append( args[ i ] );
|
||||
!
|
||||
! findObject( app, objid, function, params );
|
||||
|
||||
return 0;
|
||||
}
|
1046
kompare/tests/cvsdiff/contextm.diff
Normal file
24
kompare/tests/cvsdiff/ed.diff
Normal file
|
@ -0,0 +1,24 @@
|
|||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -e -r1.2 dcopfind.cpp
|
||||
224c
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
||||
.
|
||||
133c
|
||||
if ( (uint) i != args.count() ) {
|
||||
.
|
||||
131c
|
||||
marshall(arg, args, i, *it);
|
||||
.
|
||||
121c
|
||||
if ( types.count() != args.count() ) {
|
||||
.
|
||||
39c
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
.
|
692
kompare/tests/cvsdiff/edm.diff
Normal file
|
@ -0,0 +1,692 @@
|
|||
Index: client/dcop.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
|
||||
retrieving revision 1.26
|
||||
diff -e -r1.26 dcop.cpp
|
||||
343a
|
||||
|
||||
// vim: set ts=8 sts=4 sw=4 noet:
|
||||
|
||||
.
|
||||
340a
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
bool readStdin = false;
|
||||
int numOptions = 0;
|
||||
QString user;
|
||||
Session session = DefaultSession;
|
||||
QString sessionName;
|
||||
|
||||
// Scan for command-line options first
|
||||
for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
{
|
||||
if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
showHelp( 0 );
|
||||
else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
{
|
||||
readStdin = true;
|
||||
numOptions++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
{
|
||||
if( pos <= argc - 2 )
|
||||
{
|
||||
user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
numOptions +=2;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
{
|
||||
user = "*";
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
{
|
||||
session = QuerySessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
{
|
||||
session = AllSessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( argv[ pos ][ 0 ] == '-' )
|
||||
{
|
||||
cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
<< "'." << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
else
|
||||
break; // End of options
|
||||
}
|
||||
|
||||
argc -= numOptions;
|
||||
|
||||
QCStringList args;
|
||||
for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
args.append( argv[ i + 1 ] );
|
||||
|
||||
if( readStdin && args.count() < 3 )
|
||||
{
|
||||
cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
{
|
||||
cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && !args.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && user.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
<< "--all-users options!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session != DefaultSession && session != QuerySessions &&
|
||||
args.count() < 3 )
|
||||
{
|
||||
cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
<< "calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
UserList users;
|
||||
if( user == "*" )
|
||||
users = userList();
|
||||
else if( !user.isEmpty() )
|
||||
users[ user ] = userList()[ user ];
|
||||
|
||||
runDCOP( args, users, session, sessionName, readStdin );
|
||||
.
|
||||
339a
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
{
|
||||
// Check for ICE authority file and if the file can be read by us
|
||||
QString home = it.data();
|
||||
QString iceFile = it.data() + "/.ICEauthority";
|
||||
QFileInfo fi( iceFile );
|
||||
if( iceFile.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< it.key() << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
else if( fi.exists() )
|
||||
{
|
||||
if( fi.isReadable() )
|
||||
{
|
||||
char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
putenv( envStr );
|
||||
//cerr << "ice: " << envStr << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: ICE authority file " << iceFile
|
||||
<< "is not readable by you!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: Cannot find ICE authority file "
|
||||
<< iceFile << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY"
|
||||
<< " variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main loop
|
||||
// If users is an empty list we're calling for the currently logged
|
||||
// in user. In this case we don't have a session, but still want
|
||||
// to iterate the loop once.
|
||||
QStringList::Iterator sIt = sessions.begin();
|
||||
for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
{
|
||||
if( !presetDCOPServer && !users.isEmpty() )
|
||||
{
|
||||
QString dcopFile = it.data() + "/" + *sIt;
|
||||
QFile f( dcopFile );
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
dcopServer = l.first();
|
||||
|
||||
if( dcopServer.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
<< *sIt << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
delete client;
|
||||
client = new DCOPClient;
|
||||
if( !dcopServer.isEmpty() )
|
||||
client->setServerAddress( dcopServer.ascii() );
|
||||
bool success = client->attach();
|
||||
if( !success )
|
||||
{
|
||||
cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
continue;
|
||||
}
|
||||
dcop = client;
|
||||
|
||||
switch ( args.count() )
|
||||
{
|
||||
case 0:
|
||||
queryApplications("");
|
||||
break;
|
||||
case 1:
|
||||
if (endsWith(app, '*'))
|
||||
queryApplications(app);
|
||||
else
|
||||
queryObjects( app, "" );
|
||||
break;
|
||||
case 2:
|
||||
if (endsWith(objid, '*'))
|
||||
queryObjects(app, objid);
|
||||
else
|
||||
queryFunctions( app, objid );
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if( readStdin )
|
||||
{
|
||||
QCStringList::Iterator replaceArg = args.end();
|
||||
|
||||
QCStringList::Iterator it;
|
||||
for( it = args.begin(); it != args.end(); it++ )
|
||||
if( *it == "%1" )
|
||||
replaceArg = it;
|
||||
|
||||
// Read from stdin until EOF and call function for each line read
|
||||
char *buf = new char[ 1000 ];
|
||||
while ( !feof( stdin ) )
|
||||
{
|
||||
fgets( buf, 1000, stdin );
|
||||
|
||||
if( replaceArg != args.end() )
|
||||
*replaceArg = buf;
|
||||
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just call function
|
||||
// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Another sIt++ would make the loop infinite...
|
||||
if( users.isEmpty() )
|
||||
break;
|
||||
}
|
||||
|
||||
// Another it++ would make the loop infinite...
|
||||
if( it == users.end() )
|
||||
break;
|
||||
.
|
||||
308,338c
|
||||
if( !args.isEmpty() )
|
||||
app = args[ 0 ];
|
||||
if( args.count() > 1 )
|
||||
objid = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
function = args[ 2 ];
|
||||
if( args.count() > 3)
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
bool firstRun = true;
|
||||
UserList::Iterator it;
|
||||
QStringList sessions;
|
||||
bool presetDCOPServer = false;
|
||||
// char *dcopStr = 0L;
|
||||
QString dcopServer;
|
||||
|
||||
for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
{
|
||||
firstRun = false;
|
||||
|
||||
//cout << "Iterating '" << it.key() << "'" << endl;
|
||||
|
||||
if( session == QuerySessions )
|
||||
{
|
||||
QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
cout << "No active sessions";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << " for user " << *it;
|
||||
cout << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Active sessions ";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << "for user " << *it << " ";
|
||||
cout << ":" << endl;
|
||||
|
||||
QStringList::Iterator sIt;
|
||||
for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
cout << " " << *sIt << endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( getenv( "DCOPSERVER" ) )
|
||||
{
|
||||
sessions.append( getenv( "DCOPSERVER" ) );
|
||||
presetDCOPServer = true;
|
||||
}
|
||||
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
{
|
||||
sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: No active KDE sessions!" << endl
|
||||
<< "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
<< "before calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
else if( sessions.count() > 1 && session != AllSessions )
|
||||
{
|
||||
cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
<< "Please specify the correct session to use with --session or use the" << endl
|
||||
<< "--all-sessions option to broadcast to all sessions." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
.
|
||||
289,304c
|
||||
// WARNING: This part (until the closing '}') could very
|
||||
// well be broken now. As I don't know how to trigger and test
|
||||
// dcoprefs this code is *not* tested. It compiles and it looks
|
||||
// ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
int delimPos = args[ 0 ].findRev( ',' );
|
||||
if( delimPos == -1 )
|
||||
{
|
||||
cerr << "Error: '" << args[ 0 ]
|
||||
<< "' is not a valid DCOP reference." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
args[ 0 ][ delimPos ] = 0;
|
||||
app = args[ 0 ].mid( 8 );
|
||||
delimPos++;
|
||||
args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
objid = args[ 0 ].mid( delimPos );
|
||||
if( args.count() > 1 )
|
||||
function = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
.
|
||||
286,287c
|
||||
QCStringList params;
|
||||
DCOPClient *client = 0L;
|
||||
if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
.
|
||||
282a
|
||||
/**
|
||||
* Do the actual DCOP call
|
||||
*/
|
||||
void runDCOP( QCStringList args, UserList users, Session session,
|
||||
const QString sessionName, bool readStdin )
|
||||
{
|
||||
.
|
||||
279,281c
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of available DCOP sessions for the specified user
|
||||
* An empty list means no sessions are available, or an error occurred.
|
||||
*/
|
||||
QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
{
|
||||
if( home.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< user << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList result;
|
||||
QFileInfo dirInfo( home );
|
||||
if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
return result;
|
||||
|
||||
QDir d( home );
|
||||
d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
d.setNameFilter( ".DCOPserver*" );
|
||||
|
||||
const QFileInfoList *list = d.entryInfoList();
|
||||
if( !list )
|
||||
return result;
|
||||
|
||||
QFileInfoListIterator it( *list );
|
||||
QFileInfo *fi;
|
||||
|
||||
while ( ( fi = it.current() ) != 0 )
|
||||
{
|
||||
if( fi->isReadable() )
|
||||
result.append( fi->fileName() );
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
.
|
||||
274,276c
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
|
||||
for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
{
|
||||
QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
.
|
||||
272a
|
||||
UserList result;
|
||||
|
||||
QFile f( "/etc/passwd" );
|
||||
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
return result;
|
||||
}
|
||||
.
|
||||
270,271c
|
||||
/**
|
||||
* Return a list of all users and their home directories.
|
||||
* Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
*/
|
||||
static UserList userList()
|
||||
.
|
||||
268a
|
||||
/**
|
||||
* Show command-line help and exit
|
||||
*/
|
||||
void showHelp( int exitCode = 0 )
|
||||
{
|
||||
cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
<< "" << endl
|
||||
<< "Console DCOP client" << endl
|
||||
<< "" << endl
|
||||
<< "Generic options:" << endl
|
||||
<< " --help Show help about options" << endl
|
||||
<< "" << endl
|
||||
<< "Options:" << endl
|
||||
<< " --pipe Call DCOP for each line read from stdin" << endl
|
||||
<< " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
<< " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
<< " $ICEAUTHORITY, even if they are set." << endl
|
||||
<< " If the user has more than one open session, you must also" << endl
|
||||
<< " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
<< " command-line options." << endl
|
||||
<< " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
<< " server. Only failed calls to existing DCOP servers will"
|
||||
<< " generate an error message. If no DCOP server is available" << endl
|
||||
<< " at all, no error will be generated." << endl;
|
||||
|
||||
exit( exitCode );
|
||||
}
|
||||
.
|
||||
246,250c
|
||||
uint i = 0;
|
||||
for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
marshall( arg, args, i, *it );
|
||||
|
||||
if ( i != args.count() )
|
||||
{
|
||||
.
|
||||
164c
|
||||
// exit(1);
|
||||
return;
|
||||
.
|
||||
156,157c
|
||||
uint a = (*it).contains(',');
|
||||
if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
.
|
||||
139c
|
||||
if ( !ok && args.isEmpty() )
|
||||
.
|
||||
123d
|
||||
121c
|
||||
void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
.
|
||||
35a
|
||||
static QTextStream cout( stdout, IO_WriteOnly );
|
||||
static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
|
||||
/**
|
||||
* Session to send call to
|
||||
* DefaultSession - current session. Current KDE session when called without
|
||||
* --user or --all-users option. Otherwise this value ignores
|
||||
* all users with more than one active session.
|
||||
* AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
* QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
* CustomSession - Use the specified session
|
||||
*/
|
||||
enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
|
||||
.
|
||||
33a
|
||||
typedef QMap<QString, QString> UserList;
|
||||
|
||||
.
|
||||
28,30c
|
||||
#include "../kdatastream.h"
|
||||
.
|
||||
25c
|
||||
#include <qdir.h>
|
||||
#include <qfile.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qmap.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
// putenv() is not available on all platforms, so make sure the emulation
|
||||
// wrapper is available in those cases by loading config.h!
|
||||
#include <config.h>
|
||||
|
||||
.
|
||||
23c
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
.
|
||||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -e -r1.2 dcopfind.cpp
|
||||
224c
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
||||
.
|
||||
133c
|
||||
if ( (uint) i != args.count() ) {
|
||||
.
|
||||
131c
|
||||
marshall(arg, args, i, *it);
|
||||
.
|
||||
121c
|
||||
if ( types.count() != args.count() ) {
|
||||
.
|
||||
39c
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
.
|
||||
Index: client/marshall.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
|
||||
retrieving revision 1.3
|
||||
diff -e -r1.3 marshall.cpp
|
||||
347a
|
||||
QByteArray dummy_data;
|
||||
QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
|
||||
uint j = i;
|
||||
uint count = 0;
|
||||
// Parse list to get the count
|
||||
while (true) {
|
||||
if( j > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
break;
|
||||
marshall( dummy_arg, args, j, type );
|
||||
count++;
|
||||
}
|
||||
arg << (Q_UINT32) count;
|
||||
// Parse the list for real
|
||||
while (true) {
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
break;
|
||||
marshall( arg, args, i, type );
|
||||
}
|
||||
} else {
|
||||
qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
.
|
||||
319,346c
|
||||
if ( type == "int" )
|
||||
arg << s.toInt();
|
||||
else if ( type == "uint" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned int" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "long" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "long int" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "unsigned long" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "unsigned long int" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "float" )
|
||||
arg << s.toFloat();
|
||||
else if ( type == "double" )
|
||||
arg << s.toDouble();
|
||||
else if ( type == "bool" )
|
||||
arg << mkBool( s );
|
||||
else if ( type == "QString" )
|
||||
arg << s;
|
||||
else if ( type == "QCString" )
|
||||
arg << QCString( args[ i ] );
|
||||
else if ( type == "QColor" )
|
||||
arg << mkColor( s );
|
||||
else if ( type == "QPoint" )
|
||||
arg << mkPoint( s );
|
||||
else if ( type == "QSize" )
|
||||
arg << mkSize( s );
|
||||
else if ( type == "QRect" )
|
||||
arg << mkRect( s );
|
||||
else if ( type == "QVariant" ) {
|
||||
if ( s == "true" || s == "false" )
|
||||
arg << QVariant( mkBool( s ), 42 );
|
||||
else if ( s.left( 4 ) == "int(" )
|
||||
arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
else if ( s.left( 7 ) == "QPoint(" )
|
||||
arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
else if ( s.left( 6 ) == "QSize(" )
|
||||
arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 6 ) == "QRect(" )
|
||||
arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 7 ) == "QColor(" )
|
||||
arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
else
|
||||
arg << QVariant( s );
|
||||
} else if ( type.startsWith("QValueList<")) {
|
||||
type = type.mid(11, type.length() - 12);
|
||||
QStringList list;
|
||||
QString delim = s;
|
||||
if (delim == "[")
|
||||
delim = "]";
|
||||
if (delim == "(")
|
||||
delim = ")";
|
||||
.
|
||||
247,317c
|
||||
if (type == "QStringList")
|
||||
type = "QValueList<QString>";
|
||||
if (type == "QCStringList")
|
||||
type = "QValueList<QCString>";
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("Not enough arguments.");
|
||||
exit(1);
|
||||
}
|
||||
QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
.
|
||||
245c
|
||||
void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
.
|
29
kompare/tests/cvsdiff/normal.diff
Normal file
|
@ -0,0 +1,29 @@
|
|||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -r1.2 dcopfind.cpp
|
||||
39c39
|
||||
< bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
---
|
||||
> bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
121c121
|
||||
< if ( (int) types.count() != argc ) {
|
||||
---
|
||||
> if ( types.count() != args.count() ) {
|
||||
131c131
|
||||
< marshall(arg, argc, args, i, *it);
|
||||
---
|
||||
> marshall(arg, args, i, *it);
|
||||
133c133
|
||||
< if ( (int) i != argc ) {
|
||||
---
|
||||
> if ( (uint) i != args.count() ) {
|
||||
224c224,228
|
||||
< findObject( app, objid, function, argc, args );
|
||||
---
|
||||
> QCStringList params;
|
||||
> for( int i = 0; i < argc; i++ )
|
||||
> params.append( args[ i ] );
|
||||
>
|
||||
> findObject( app, objid, function, params );
|
861
kompare/tests/cvsdiff/normalm.diff
Normal file
|
@ -0,0 +1,861 @@
|
|||
Index: client/dcop.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
|
||||
retrieving revision 1.26
|
||||
diff -r1.26 dcop.cpp
|
||||
23c23,26
|
||||
< #include <qvariant.h>
|
||||
---
|
||||
> #include <ctype.h>
|
||||
> #include <stdio.h>
|
||||
> #include <stdlib.h>
|
||||
>
|
||||
25c28,39
|
||||
< #include "../kdatastream.h"
|
||||
---
|
||||
> #include <qdir.h>
|
||||
> #include <qfile.h>
|
||||
> #include <qfileinfo.h>
|
||||
> #include <qmap.h>
|
||||
> #include <qstringlist.h>
|
||||
> #include <qtextstream.h>
|
||||
> #include <qvariant.h>
|
||||
>
|
||||
> // putenv() is not available on all platforms, so make sure the emulation
|
||||
> // wrapper is available in those cases by loading config.h!
|
||||
> #include <config.h>
|
||||
>
|
||||
28,30c42
|
||||
< #include <stdlib.h>
|
||||
< #include <stdio.h>
|
||||
< #include <ctype.h>
|
||||
---
|
||||
> #include "../kdatastream.h"
|
||||
33a46,47
|
||||
> typedef QMap<QString, QString> UserList;
|
||||
>
|
||||
35a50,63
|
||||
> static QTextStream cout( stdout, IO_WriteOnly );
|
||||
> static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
>
|
||||
> /**
|
||||
> * Session to send call to
|
||||
> * DefaultSession - current session. Current KDE session when called without
|
||||
> * --user or --all-users option. Otherwise this value ignores
|
||||
> * all users with more than one active session.
|
||||
> * AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
> * QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
> * CustomSession - Use the specified session
|
||||
> */
|
||||
> enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
>
|
||||
121c149
|
||||
< void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
---
|
||||
> void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
123d150
|
||||
<
|
||||
139c166
|
||||
< if ( !ok && argc == 0 )
|
||||
---
|
||||
> if ( !ok && args.isEmpty() )
|
||||
156,157c183,184
|
||||
< int a = (*it).contains(',');
|
||||
< if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
|
||||
---
|
||||
> uint a = (*it).contains(',');
|
||||
> if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
164c191,192
|
||||
< exit(1);
|
||||
---
|
||||
> // exit(1);
|
||||
> return;
|
||||
246,250c274,279
|
||||
< int i = 0;
|
||||
< for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
< marshall(arg, argc, args, i, *it);
|
||||
< }
|
||||
< if ( i != argc ) {
|
||||
---
|
||||
> uint i = 0;
|
||||
> for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
> marshall( arg, args, i, *it );
|
||||
>
|
||||
> if ( i != args.count() )
|
||||
> {
|
||||
268a298,324
|
||||
> /**
|
||||
> * Show command-line help and exit
|
||||
> */
|
||||
> void showHelp( int exitCode = 0 )
|
||||
> {
|
||||
> cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
> << "" << endl
|
||||
> << "Console DCOP client" << endl
|
||||
> << "" << endl
|
||||
> << "Generic options:" << endl
|
||||
> << " --help Show help about options" << endl
|
||||
> << "" << endl
|
||||
> << "Options:" << endl
|
||||
> << " --pipe Call DCOP for each line read from stdin" << endl
|
||||
> << " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
> << " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
> << " $ICEAUTHORITY, even if they are set." << endl
|
||||
> << " If the user has more than one open session, you must also" << endl
|
||||
> << " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
> << " command-line options." << endl
|
||||
> << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
> << " server. Only failed calls to existing DCOP servers will"
|
||||
> << " generate an error message. If no DCOP server is available" << endl
|
||||
> << " at all, no error will be generated." << endl;
|
||||
>
|
||||
> exit( exitCode );
|
||||
> }
|
||||
270,271c326,330
|
||||
<
|
||||
< int main( int argc, char** argv )
|
||||
---
|
||||
> /**
|
||||
> * Return a list of all users and their home directories.
|
||||
> * Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
> */
|
||||
> static UserList userList()
|
||||
272a332,340
|
||||
> UserList result;
|
||||
>
|
||||
> QFile f( "/etc/passwd" );
|
||||
>
|
||||
> if( !f.open( IO_ReadOnly ) )
|
||||
> {
|
||||
> cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
> return result;
|
||||
> }
|
||||
274,276c342,347
|
||||
< if ( argc > 1 && argv[1][0] == '-' ) {
|
||||
< fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
|
||||
< exit(0);
|
||||
---
|
||||
> QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
>
|
||||
> for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
> {
|
||||
> QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
> result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
279,281c350,391
|
||||
< DCOPClient client;
|
||||
< client.attach();
|
||||
< dcop = &client;
|
||||
---
|
||||
> return result;
|
||||
> }
|
||||
>
|
||||
> /**
|
||||
> * Return a list of available DCOP sessions for the specified user
|
||||
> * An empty list means no sessions are available, or an error occurred.
|
||||
> */
|
||||
> QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
> {
|
||||
> if( home.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Cannot determine home directory for user "
|
||||
> << user << "!" << endl
|
||||
> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> return QStringList();
|
||||
> }
|
||||
>
|
||||
> QStringList result;
|
||||
> QFileInfo dirInfo( home );
|
||||
> if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
> return result;
|
||||
>
|
||||
> QDir d( home );
|
||||
> d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
> d.setNameFilter( ".DCOPserver*" );
|
||||
>
|
||||
> const QFileInfoList *list = d.entryInfoList();
|
||||
> if( !list )
|
||||
> return result;
|
||||
>
|
||||
> QFileInfoListIterator it( *list );
|
||||
> QFileInfo *fi;
|
||||
>
|
||||
> while ( ( fi = it.current() ) != 0 )
|
||||
> {
|
||||
> if( fi->isReadable() )
|
||||
> result.append( fi->fileName() );
|
||||
> ++it;
|
||||
> }
|
||||
> return result;
|
||||
> }
|
||||
282a393,398
|
||||
> /**
|
||||
> * Do the actual DCOP call
|
||||
> */
|
||||
> void runDCOP( QCStringList args, UserList users, Session session,
|
||||
> const QString sessionName, bool readStdin )
|
||||
> {
|
||||
286,287c402,404
|
||||
< char **args = 0;
|
||||
< if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
|
||||
---
|
||||
> QCStringList params;
|
||||
> DCOPClient *client = 0L;
|
||||
> if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
289,304c406,429
|
||||
< char *delim = strchr(argv[1], ',');
|
||||
< if (!delim)
|
||||
< {
|
||||
< fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
|
||||
< return 1;
|
||||
< }
|
||||
< *delim = 0;
|
||||
< app = argv[1] + 8;
|
||||
< delim++;
|
||||
< delim[strlen(delim)-1] = 0;
|
||||
< objid = delim;
|
||||
< if (argc > 2)
|
||||
< function = argv[2];
|
||||
< if (argc > 3)
|
||||
< args = &argv[3];
|
||||
< argc++;
|
||||
---
|
||||
> // WARNING: This part (until the closing '}') could very
|
||||
> // well be broken now. As I don't know how to trigger and test
|
||||
> // dcoprefs this code is *not* tested. It compiles and it looks
|
||||
> // ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
> int delimPos = args[ 0 ].findRev( ',' );
|
||||
> if( delimPos == -1 )
|
||||
> {
|
||||
> cerr << "Error: '" << args[ 0 ]
|
||||
> << "' is not a valid DCOP reference." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> args[ 0 ][ delimPos ] = 0;
|
||||
> app = args[ 0 ].mid( 8 );
|
||||
> delimPos++;
|
||||
> args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
> objid = args[ 0 ].mid( delimPos );
|
||||
> if( args.count() > 1 )
|
||||
> function = args[ 1 ];
|
||||
> if( args.count() > 2 )
|
||||
> {
|
||||
> params = args;
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> }
|
||||
308,338c433,516
|
||||
< if (argc > 1)
|
||||
< app = argv[1];
|
||||
< if (argc > 2)
|
||||
< objid = argv[2];
|
||||
< if (argc > 3)
|
||||
< function = argv[3];
|
||||
< if (argc > 4)
|
||||
< args = &argv[4];
|
||||
< }
|
||||
<
|
||||
< switch ( argc ) {
|
||||
< case 0:
|
||||
< case 1:
|
||||
< queryApplications("");
|
||||
< break;
|
||||
< case 2:
|
||||
< if (endsWith(app, '*'))
|
||||
< queryApplications(app);
|
||||
< else
|
||||
< queryObjects( app, "" );
|
||||
< break;
|
||||
< case 3:
|
||||
< if (endsWith(objid, '*'))
|
||||
< queryObjects(app, objid);
|
||||
< else
|
||||
< queryFunctions( app, objid );
|
||||
< break;
|
||||
< case 4:
|
||||
< default:
|
||||
< callFunction( app, objid, function, argc - 4, args );
|
||||
< break;
|
||||
---
|
||||
> if( !args.isEmpty() )
|
||||
> app = args[ 0 ];
|
||||
> if( args.count() > 1 )
|
||||
> objid = args[ 1 ];
|
||||
> if( args.count() > 2 )
|
||||
> function = args[ 2 ];
|
||||
> if( args.count() > 3)
|
||||
> {
|
||||
> params = args;
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> bool firstRun = true;
|
||||
> UserList::Iterator it;
|
||||
> QStringList sessions;
|
||||
> bool presetDCOPServer = false;
|
||||
> // char *dcopStr = 0L;
|
||||
> QString dcopServer;
|
||||
>
|
||||
> for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
> {
|
||||
> firstRun = false;
|
||||
>
|
||||
> //cout << "Iterating '" << it.key() << "'" << endl;
|
||||
>
|
||||
> if( session == QuerySessions )
|
||||
> {
|
||||
> QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
> if( sessions.isEmpty() )
|
||||
> {
|
||||
> cout << "No active sessions";
|
||||
> if( !( *it ).isEmpty() )
|
||||
> cout << " for user " << *it;
|
||||
> cout << endl;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cout << "Active sessions ";
|
||||
> if( !( *it ).isEmpty() )
|
||||
> cout << "for user " << *it << " ";
|
||||
> cout << ":" << endl;
|
||||
>
|
||||
> QStringList::Iterator sIt;
|
||||
> for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
> cout << " " << *sIt << endl;
|
||||
>
|
||||
> cout << endl;
|
||||
> }
|
||||
> continue;
|
||||
> }
|
||||
>
|
||||
> if( getenv( "DCOPSERVER" ) )
|
||||
> {
|
||||
> sessions.append( getenv( "DCOPSERVER" ) );
|
||||
> presetDCOPServer = true;
|
||||
> }
|
||||
>
|
||||
> if( users.count() > 1 || ( users.count() == 1 &&
|
||||
> ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
> {
|
||||
> sessions = dcopSessionList( it.key(), it.data() );
|
||||
> if( sessions.isEmpty() )
|
||||
> {
|
||||
> if( users.count() > 1 )
|
||||
> continue;
|
||||
> else
|
||||
> {
|
||||
> cerr << "ERROR: No active KDE sessions!" << endl
|
||||
> << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
> << "before calling dcop." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
> else if( sessions.count() > 1 && session != AllSessions )
|
||||
> {
|
||||
> cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
> << "Please specify the correct session to use with --session or use the" << endl
|
||||
> << "--all-sessions option to broadcast to all sessions." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
339a518,660
|
||||
> if( users.count() > 1 || ( users.count() == 1 &&
|
||||
> ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
> {
|
||||
> // Check for ICE authority file and if the file can be read by us
|
||||
> QString home = it.data();
|
||||
> QString iceFile = it.data() + "/.ICEauthority";
|
||||
> QFileInfo fi( iceFile );
|
||||
> if( iceFile.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Cannot determine home directory for user "
|
||||
> << it.key() << "!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> else if( fi.exists() )
|
||||
> {
|
||||
> if( fi.isReadable() )
|
||||
> {
|
||||
> char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
> putenv( envStr );
|
||||
> //cerr << "ice: " << envStr << endl;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cerr << "WARNING: ICE authority file " << iceFile
|
||||
> << "is not readable by you!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> if( users.count() > 1 )
|
||||
> continue;
|
||||
> else
|
||||
> {
|
||||
> cerr << "WARNING: Cannot find ICE authority file "
|
||||
> << iceFile << "!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY"
|
||||
> << " variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> // Main loop
|
||||
> // If users is an empty list we're calling for the currently logged
|
||||
> // in user. In this case we don't have a session, but still want
|
||||
> // to iterate the loop once.
|
||||
> QStringList::Iterator sIt = sessions.begin();
|
||||
> for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
> {
|
||||
> if( !presetDCOPServer && !users.isEmpty() )
|
||||
> {
|
||||
> QString dcopFile = it.data() + "/" + *sIt;
|
||||
> QFile f( dcopFile );
|
||||
> if( !f.open( IO_ReadOnly ) )
|
||||
> {
|
||||
> cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
>
|
||||
> QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
> dcopServer = l.first();
|
||||
>
|
||||
> if( dcopServer.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
> << *sIt << "!" << endl
|
||||
> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> delete client;
|
||||
> client = new DCOPClient;
|
||||
> if( !dcopServer.isEmpty() )
|
||||
> client->setServerAddress( dcopServer.ascii() );
|
||||
> bool success = client->attach();
|
||||
> if( !success )
|
||||
> {
|
||||
> cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
> continue;
|
||||
> }
|
||||
> dcop = client;
|
||||
>
|
||||
> switch ( args.count() )
|
||||
> {
|
||||
> case 0:
|
||||
> queryApplications("");
|
||||
> break;
|
||||
> case 1:
|
||||
> if (endsWith(app, '*'))
|
||||
> queryApplications(app);
|
||||
> else
|
||||
> queryObjects( app, "" );
|
||||
> break;
|
||||
> case 2:
|
||||
> if (endsWith(objid, '*'))
|
||||
> queryObjects(app, objid);
|
||||
> else
|
||||
> queryFunctions( app, objid );
|
||||
> break;
|
||||
> case 3:
|
||||
> default:
|
||||
> if( readStdin )
|
||||
> {
|
||||
> QCStringList::Iterator replaceArg = args.end();
|
||||
>
|
||||
> QCStringList::Iterator it;
|
||||
> for( it = args.begin(); it != args.end(); it++ )
|
||||
> if( *it == "%1" )
|
||||
> replaceArg = it;
|
||||
>
|
||||
> // Read from stdin until EOF and call function for each line read
|
||||
> char *buf = new char[ 1000 ];
|
||||
> while ( !feof( stdin ) )
|
||||
> {
|
||||
> fgets( buf, 1000, stdin );
|
||||
>
|
||||
> if( replaceArg != args.end() )
|
||||
> *replaceArg = buf;
|
||||
>
|
||||
> callFunction( app, objid, function, params );
|
||||
> }
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> // Just call function
|
||||
> // cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
> callFunction( app, objid, function, params );
|
||||
> }
|
||||
> break;
|
||||
> }
|
||||
> // Another sIt++ would make the loop infinite...
|
||||
> if( users.isEmpty() )
|
||||
> break;
|
||||
> }
|
||||
>
|
||||
> // Another it++ would make the loop infinite...
|
||||
> if( it == users.end() )
|
||||
> break;
|
||||
340a662,767
|
||||
> }
|
||||
>
|
||||
>
|
||||
> int main( int argc, char** argv )
|
||||
> {
|
||||
> bool readStdin = false;
|
||||
> int numOptions = 0;
|
||||
> QString user;
|
||||
> Session session = DefaultSession;
|
||||
> QString sessionName;
|
||||
>
|
||||
> // Scan for command-line options first
|
||||
> for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
> {
|
||||
> if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
> showHelp( 0 );
|
||||
> else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
> {
|
||||
> readStdin = true;
|
||||
> numOptions++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
> {
|
||||
> if( pos <= argc - 2 )
|
||||
> {
|
||||
> user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
> numOptions +=2;
|
||||
> pos++;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
> {
|
||||
> user = "*";
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
> {
|
||||
> session = QuerySessions;
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
> {
|
||||
> session = AllSessions;
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( argv[ pos ][ 0 ] == '-' )
|
||||
> {
|
||||
> cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
> << "'." << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
> else
|
||||
> break; // End of options
|
||||
> }
|
||||
>
|
||||
> argc -= numOptions;
|
||||
>
|
||||
> QCStringList args;
|
||||
> for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
> args.append( argv[ i + 1 ] );
|
||||
>
|
||||
> if( readStdin && args.count() < 3 )
|
||||
> {
|
||||
> cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
> {
|
||||
> cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session == QuerySessions && !args.isEmpty() )
|
||||
> {
|
||||
> cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session == QuerySessions && user.isEmpty() )
|
||||
> {
|
||||
> cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
> << "--all-users options!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session != DefaultSession && session != QuerySessions &&
|
||||
> args.count() < 3 )
|
||||
> {
|
||||
> cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
> << "calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> UserList users;
|
||||
> if( user == "*" )
|
||||
> users = userList();
|
||||
> else if( !user.isEmpty() )
|
||||
> users[ user ] = userList()[ user ];
|
||||
>
|
||||
> runDCOP( args, users, session, sessionName, readStdin );
|
||||
343a771,773
|
||||
>
|
||||
> // vim: set ts=8 sts=4 sw=4 noet:
|
||||
>
|
||||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -r1.2 dcopfind.cpp
|
||||
39c39
|
||||
< bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
---
|
||||
> bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
121c121
|
||||
< if ( (int) types.count() != argc ) {
|
||||
---
|
||||
> if ( types.count() != args.count() ) {
|
||||
131c131
|
||||
< marshall(arg, argc, args, i, *it);
|
||||
---
|
||||
> marshall(arg, args, i, *it);
|
||||
133c133
|
||||
< if ( (int) i != argc ) {
|
||||
---
|
||||
> if ( (uint) i != args.count() ) {
|
||||
224c224,228
|
||||
< findObject( app, objid, function, argc, args );
|
||||
---
|
||||
> QCStringList params;
|
||||
> for( int i = 0; i < argc; i++ )
|
||||
> params.append( args[ i ] );
|
||||
>
|
||||
> findObject( app, objid, function, params );
|
||||
Index: client/marshall.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
|
||||
retrieving revision 1.3
|
||||
diff -r1.3 marshall.cpp
|
||||
245c245
|
||||
< void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
|
||||
---
|
||||
> void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
247,317c247,256
|
||||
< if (type == "QStringList")
|
||||
< type = "QValueList<QString>";
|
||||
< if (type == "QCStringList")
|
||||
< type = "QValueList<QCString>";
|
||||
< if (i >= argc)
|
||||
< {
|
||||
< qWarning("Not enough arguments.");
|
||||
< exit(1);
|
||||
< }
|
||||
< QString s = QString::fromLocal8Bit(argv[i]);
|
||||
<
|
||||
< if ( type == "int" )
|
||||
< arg << s.toInt();
|
||||
< else if ( type == "uint" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "unsigned" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "unsigned int" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "long" )
|
||||
< arg << s.toLong();
|
||||
< else if ( type == "long int" )
|
||||
< arg << s.toLong();
|
||||
< else if ( type == "unsigned long" )
|
||||
< arg << s.toULong();
|
||||
< else if ( type == "unsigned long int" )
|
||||
< arg << s.toULong();
|
||||
< else if ( type == "float" )
|
||||
< arg << s.toFloat();
|
||||
< else if ( type == "double" )
|
||||
< arg << s.toDouble();
|
||||
< else if ( type == "bool" )
|
||||
< arg << mkBool( s );
|
||||
< else if ( type == "QString" )
|
||||
< arg << s;
|
||||
< else if ( type == "QCString" )
|
||||
< arg << QCString( argv[i] );
|
||||
< else if ( type == "QColor" )
|
||||
< arg << mkColor( s );
|
||||
< else if ( type == "QPoint" )
|
||||
< arg << mkPoint( s );
|
||||
< else if ( type == "QSize" )
|
||||
< arg << mkSize( s );
|
||||
< else if ( type == "QRect" )
|
||||
< arg << mkRect( s );
|
||||
< else if ( type == "QVariant" ) {
|
||||
< if ( s == "true" || s == "false" )
|
||||
< arg << QVariant( mkBool( s ), 42 );
|
||||
< else if ( s.left( 4 ) == "int(" )
|
||||
< arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
< else if ( s.left( 7 ) == "QPoint(" )
|
||||
< arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
< else if ( s.left( 6 ) == "QSize(" )
|
||||
< arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
< else if ( s.left( 6 ) == "QRect(" )
|
||||
< arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
< else if ( s.left( 7 ) == "QColor(" )
|
||||
< arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
< else
|
||||
< arg << QVariant( s );
|
||||
< } else if ( type.startsWith("QValueList<")) {
|
||||
< type = type.mid(11, type.length() - 12);
|
||||
< QStringList list;
|
||||
< QString delim = s;
|
||||
< if (delim == "[")
|
||||
< delim = "]";
|
||||
< if (delim == "(")
|
||||
< delim = ")";
|
||||
< i++;
|
||||
< QByteArray dummy_data;
|
||||
< QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
---
|
||||
> if (type == "QStringList")
|
||||
> type = "QValueList<QString>";
|
||||
> if (type == "QCStringList")
|
||||
> type = "QValueList<QCString>";
|
||||
> if( i > args.count() )
|
||||
> {
|
||||
> qWarning("Not enough arguments.");
|
||||
> exit(1);
|
||||
> }
|
||||
> QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
319,346c258,314
|
||||
< int j = i;
|
||||
< int count = 0;
|
||||
< // Parse list to get the count
|
||||
< while (true) {
|
||||
< if (j >= argc)
|
||||
< {
|
||||
< qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
< exit(1);
|
||||
< }
|
||||
< if (argv[j] == delim) break;
|
||||
< marshall(dummy_arg, argc, argv, j, type);
|
||||
< count++;
|
||||
< }
|
||||
< arg << (Q_UINT32) count;
|
||||
< // Parse the list for real
|
||||
< while (true) {
|
||||
< if (i >= argc)
|
||||
< {
|
||||
< qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
< exit(1);
|
||||
< }
|
||||
< if (argv[i] == delim) break;
|
||||
< marshall(arg, argc, argv, i, type);
|
||||
< }
|
||||
< } else {
|
||||
< qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
< exit(1);
|
||||
< }
|
||||
---
|
||||
> if ( type == "int" )
|
||||
> arg << s.toInt();
|
||||
> else if ( type == "uint" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "unsigned" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "unsigned int" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "long" )
|
||||
> arg << s.toLong();
|
||||
> else if ( type == "long int" )
|
||||
> arg << s.toLong();
|
||||
> else if ( type == "unsigned long" )
|
||||
> arg << s.toULong();
|
||||
> else if ( type == "unsigned long int" )
|
||||
> arg << s.toULong();
|
||||
> else if ( type == "float" )
|
||||
> arg << s.toFloat();
|
||||
> else if ( type == "double" )
|
||||
> arg << s.toDouble();
|
||||
> else if ( type == "bool" )
|
||||
> arg << mkBool( s );
|
||||
> else if ( type == "QString" )
|
||||
> arg << s;
|
||||
> else if ( type == "QCString" )
|
||||
> arg << QCString( args[ i ] );
|
||||
> else if ( type == "QColor" )
|
||||
> arg << mkColor( s );
|
||||
> else if ( type == "QPoint" )
|
||||
> arg << mkPoint( s );
|
||||
> else if ( type == "QSize" )
|
||||
> arg << mkSize( s );
|
||||
> else if ( type == "QRect" )
|
||||
> arg << mkRect( s );
|
||||
> else if ( type == "QVariant" ) {
|
||||
> if ( s == "true" || s == "false" )
|
||||
> arg << QVariant( mkBool( s ), 42 );
|
||||
> else if ( s.left( 4 ) == "int(" )
|
||||
> arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
> else if ( s.left( 7 ) == "QPoint(" )
|
||||
> arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
> else if ( s.left( 6 ) == "QSize(" )
|
||||
> arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
> else if ( s.left( 6 ) == "QRect(" )
|
||||
> arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
> else if ( s.left( 7 ) == "QColor(" )
|
||||
> arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
> else
|
||||
> arg << QVariant( s );
|
||||
> } else if ( type.startsWith("QValueList<")) {
|
||||
> type = type.mid(11, type.length() - 12);
|
||||
> QStringList list;
|
||||
> QString delim = s;
|
||||
> if (delim == "[")
|
||||
> delim = "]";
|
||||
> if (delim == "(")
|
||||
> delim = ")";
|
||||
347a316,349
|
||||
> QByteArray dummy_data;
|
||||
> QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
>
|
||||
> uint j = i;
|
||||
> uint count = 0;
|
||||
> // Parse list to get the count
|
||||
> while (true) {
|
||||
> if( j > args.count() )
|
||||
> {
|
||||
> qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
> exit(1);
|
||||
> }
|
||||
> if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
> break;
|
||||
> marshall( dummy_arg, args, j, type );
|
||||
> count++;
|
||||
> }
|
||||
> arg << (Q_UINT32) count;
|
||||
> // Parse the list for real
|
||||
> while (true) {
|
||||
> if( i > args.count() )
|
||||
> {
|
||||
> qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
> exit(1);
|
||||
> }
|
||||
> if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
> break;
|
||||
> marshall( arg, args, i, type );
|
||||
> }
|
||||
> } else {
|
||||
> qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
> exit(1);
|
||||
> }
|
||||
> i++;
|
24
kompare/tests/cvsdiff/rcs.diff
Normal file
|
@ -0,0 +1,24 @@
|
|||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -n -r1.2 dcopfind.cpp
|
||||
d39 1
|
||||
a39 1
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
d121 1
|
||||
a121 1
|
||||
if ( types.count() != args.count() ) {
|
||||
d131 1
|
||||
a131 1
|
||||
marshall(arg, args, i, *it);
|
||||
d133 1
|
||||
a133 1
|
||||
if ( (uint) i != args.count() ) {
|
||||
d224 1
|
||||
a224 5
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
683
kompare/tests/cvsdiff/rcsm.diff
Normal file
|
@ -0,0 +1,683 @@
|
|||
Index: client/dcop.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
|
||||
retrieving revision 1.26
|
||||
diff -n -r1.26 dcop.cpp
|
||||
d23 1
|
||||
a23 4
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
d25 1
|
||||
a25 12
|
||||
#include <qdir.h>
|
||||
#include <qfile.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qmap.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
// putenv() is not available on all platforms, so make sure the emulation
|
||||
// wrapper is available in those cases by loading config.h!
|
||||
#include <config.h>
|
||||
|
||||
d28 3
|
||||
a30 1
|
||||
#include "../kdatastream.h"
|
||||
a33 2
|
||||
typedef QMap<QString, QString> UserList;
|
||||
|
||||
a35 14
|
||||
static QTextStream cout( stdout, IO_WriteOnly );
|
||||
static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
|
||||
/**
|
||||
* Session to send call to
|
||||
* DefaultSession - current session. Current KDE session when called without
|
||||
* --user or --all-users option. Otherwise this value ignores
|
||||
* all users with more than one active session.
|
||||
* AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
* QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
* CustomSession - Use the specified session
|
||||
*/
|
||||
enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
|
||||
d121 1
|
||||
a121 1
|
||||
void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
d123 1
|
||||
d139 1
|
||||
a139 1
|
||||
if ( !ok && args.isEmpty() )
|
||||
d156 2
|
||||
a157 2
|
||||
uint a = (*it).contains(',');
|
||||
if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
d164 1
|
||||
a164 2
|
||||
// exit(1);
|
||||
return;
|
||||
d246 5
|
||||
a250 6
|
||||
uint i = 0;
|
||||
for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
marshall( arg, args, i, *it );
|
||||
|
||||
if ( i != args.count() )
|
||||
{
|
||||
a268 27
|
||||
/**
|
||||
* Show command-line help and exit
|
||||
*/
|
||||
void showHelp( int exitCode = 0 )
|
||||
{
|
||||
cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
<< "" << endl
|
||||
<< "Console DCOP client" << endl
|
||||
<< "" << endl
|
||||
<< "Generic options:" << endl
|
||||
<< " --help Show help about options" << endl
|
||||
<< "" << endl
|
||||
<< "Options:" << endl
|
||||
<< " --pipe Call DCOP for each line read from stdin" << endl
|
||||
<< " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
<< " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
<< " $ICEAUTHORITY, even if they are set." << endl
|
||||
<< " If the user has more than one open session, you must also" << endl
|
||||
<< " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
<< " command-line options." << endl
|
||||
<< " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
<< " server. Only failed calls to existing DCOP servers will"
|
||||
<< " generate an error message. If no DCOP server is available" << endl
|
||||
<< " at all, no error will be generated." << endl;
|
||||
|
||||
exit( exitCode );
|
||||
}
|
||||
d270 2
|
||||
a271 5
|
||||
/**
|
||||
* Return a list of all users and their home directories.
|
||||
* Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
*/
|
||||
static UserList userList()
|
||||
a272 9
|
||||
UserList result;
|
||||
|
||||
QFile f( "/etc/passwd" );
|
||||
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
return result;
|
||||
}
|
||||
d274 3
|
||||
a276 6
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
|
||||
for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
{
|
||||
QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
d279 3
|
||||
a281 42
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of available DCOP sessions for the specified user
|
||||
* An empty list means no sessions are available, or an error occurred.
|
||||
*/
|
||||
QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
{
|
||||
if( home.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< user << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList result;
|
||||
QFileInfo dirInfo( home );
|
||||
if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
return result;
|
||||
|
||||
QDir d( home );
|
||||
d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
d.setNameFilter( ".DCOPserver*" );
|
||||
|
||||
const QFileInfoList *list = d.entryInfoList();
|
||||
if( !list )
|
||||
return result;
|
||||
|
||||
QFileInfoListIterator it( *list );
|
||||
QFileInfo *fi;
|
||||
|
||||
while ( ( fi = it.current() ) != 0 )
|
||||
{
|
||||
if( fi->isReadable() )
|
||||
result.append( fi->fileName() );
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
a282 6
|
||||
/**
|
||||
* Do the actual DCOP call
|
||||
*/
|
||||
void runDCOP( QCStringList args, UserList users, Session session,
|
||||
const QString sessionName, bool readStdin )
|
||||
{
|
||||
d286 2
|
||||
a287 3
|
||||
QCStringList params;
|
||||
DCOPClient *client = 0L;
|
||||
if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
d289 16
|
||||
a304 24
|
||||
// WARNING: This part (until the closing '}') could very
|
||||
// well be broken now. As I don't know how to trigger and test
|
||||
// dcoprefs this code is *not* tested. It compiles and it looks
|
||||
// ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
int delimPos = args[ 0 ].findRev( ',' );
|
||||
if( delimPos == -1 )
|
||||
{
|
||||
cerr << "Error: '" << args[ 0 ]
|
||||
<< "' is not a valid DCOP reference." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
args[ 0 ][ delimPos ] = 0;
|
||||
app = args[ 0 ].mid( 8 );
|
||||
delimPos++;
|
||||
args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
objid = args[ 0 ].mid( delimPos );
|
||||
if( args.count() > 1 )
|
||||
function = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
d308 31
|
||||
a338 84
|
||||
if( !args.isEmpty() )
|
||||
app = args[ 0 ];
|
||||
if( args.count() > 1 )
|
||||
objid = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
function = args[ 2 ];
|
||||
if( args.count() > 3)
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
bool firstRun = true;
|
||||
UserList::Iterator it;
|
||||
QStringList sessions;
|
||||
bool presetDCOPServer = false;
|
||||
// char *dcopStr = 0L;
|
||||
QString dcopServer;
|
||||
|
||||
for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
{
|
||||
firstRun = false;
|
||||
|
||||
//cout << "Iterating '" << it.key() << "'" << endl;
|
||||
|
||||
if( session == QuerySessions )
|
||||
{
|
||||
QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
cout << "No active sessions";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << " for user " << *it;
|
||||
cout << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Active sessions ";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << "for user " << *it << " ";
|
||||
cout << ":" << endl;
|
||||
|
||||
QStringList::Iterator sIt;
|
||||
for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
cout << " " << *sIt << endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( getenv( "DCOPSERVER" ) )
|
||||
{
|
||||
sessions.append( getenv( "DCOPSERVER" ) );
|
||||
presetDCOPServer = true;
|
||||
}
|
||||
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
{
|
||||
sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: No active KDE sessions!" << endl
|
||||
<< "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
<< "before calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
else if( sessions.count() > 1 && session != AllSessions )
|
||||
{
|
||||
cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
<< "Please specify the correct session to use with --session or use the" << endl
|
||||
<< "--all-sessions option to broadcast to all sessions." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
a339 143
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
{
|
||||
// Check for ICE authority file and if the file can be read by us
|
||||
QString home = it.data();
|
||||
QString iceFile = it.data() + "/.ICEauthority";
|
||||
QFileInfo fi( iceFile );
|
||||
if( iceFile.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< it.key() << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
else if( fi.exists() )
|
||||
{
|
||||
if( fi.isReadable() )
|
||||
{
|
||||
char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
putenv( envStr );
|
||||
//cerr << "ice: " << envStr << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: ICE authority file " << iceFile
|
||||
<< "is not readable by you!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: Cannot find ICE authority file "
|
||||
<< iceFile << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY"
|
||||
<< " variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main loop
|
||||
// If users is an empty list we're calling for the currently logged
|
||||
// in user. In this case we don't have a session, but still want
|
||||
// to iterate the loop once.
|
||||
QStringList::Iterator sIt = sessions.begin();
|
||||
for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
{
|
||||
if( !presetDCOPServer && !users.isEmpty() )
|
||||
{
|
||||
QString dcopFile = it.data() + "/" + *sIt;
|
||||
QFile f( dcopFile );
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
dcopServer = l.first();
|
||||
|
||||
if( dcopServer.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
<< *sIt << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
delete client;
|
||||
client = new DCOPClient;
|
||||
if( !dcopServer.isEmpty() )
|
||||
client->setServerAddress( dcopServer.ascii() );
|
||||
bool success = client->attach();
|
||||
if( !success )
|
||||
{
|
||||
cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
continue;
|
||||
}
|
||||
dcop = client;
|
||||
|
||||
switch ( args.count() )
|
||||
{
|
||||
case 0:
|
||||
queryApplications("");
|
||||
break;
|
||||
case 1:
|
||||
if (endsWith(app, '*'))
|
||||
queryApplications(app);
|
||||
else
|
||||
queryObjects( app, "" );
|
||||
break;
|
||||
case 2:
|
||||
if (endsWith(objid, '*'))
|
||||
queryObjects(app, objid);
|
||||
else
|
||||
queryFunctions( app, objid );
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if( readStdin )
|
||||
{
|
||||
QCStringList::Iterator replaceArg = args.end();
|
||||
|
||||
QCStringList::Iterator it;
|
||||
for( it = args.begin(); it != args.end(); it++ )
|
||||
if( *it == "%1" )
|
||||
replaceArg = it;
|
||||
|
||||
// Read from stdin until EOF and call function for each line read
|
||||
char *buf = new char[ 1000 ];
|
||||
while ( !feof( stdin ) )
|
||||
{
|
||||
fgets( buf, 1000, stdin );
|
||||
|
||||
if( replaceArg != args.end() )
|
||||
*replaceArg = buf;
|
||||
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just call function
|
||||
// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Another sIt++ would make the loop infinite...
|
||||
if( users.isEmpty() )
|
||||
break;
|
||||
}
|
||||
|
||||
// Another it++ would make the loop infinite...
|
||||
if( it == users.end() )
|
||||
break;
|
||||
a340 106
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
bool readStdin = false;
|
||||
int numOptions = 0;
|
||||
QString user;
|
||||
Session session = DefaultSession;
|
||||
QString sessionName;
|
||||
|
||||
// Scan for command-line options first
|
||||
for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
{
|
||||
if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
showHelp( 0 );
|
||||
else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
{
|
||||
readStdin = true;
|
||||
numOptions++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
{
|
||||
if( pos <= argc - 2 )
|
||||
{
|
||||
user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
numOptions +=2;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
{
|
||||
user = "*";
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
{
|
||||
session = QuerySessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
{
|
||||
session = AllSessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( argv[ pos ][ 0 ] == '-' )
|
||||
{
|
||||
cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
<< "'." << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
else
|
||||
break; // End of options
|
||||
}
|
||||
|
||||
argc -= numOptions;
|
||||
|
||||
QCStringList args;
|
||||
for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
args.append( argv[ i + 1 ] );
|
||||
|
||||
if( readStdin && args.count() < 3 )
|
||||
{
|
||||
cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
{
|
||||
cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && !args.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && user.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
<< "--all-users options!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session != DefaultSession && session != QuerySessions &&
|
||||
args.count() < 3 )
|
||||
{
|
||||
cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
<< "calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
UserList users;
|
||||
if( user == "*" )
|
||||
users = userList();
|
||||
else if( !user.isEmpty() )
|
||||
users[ user ] = userList()[ user ];
|
||||
|
||||
runDCOP( args, users, session, sessionName, readStdin );
|
||||
a343 3
|
||||
|
||||
// vim: set ts=8 sts=4 sw=4 noet:
|
||||
|
||||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -n -r1.2 dcopfind.cpp
|
||||
d39 1
|
||||
a39 1
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
d121 1
|
||||
a121 1
|
||||
if ( types.count() != args.count() ) {
|
||||
d131 1
|
||||
a131 1
|
||||
marshall(arg, args, i, *it);
|
||||
d133 1
|
||||
a133 1
|
||||
if ( (uint) i != args.count() ) {
|
||||
d224 1
|
||||
a224 5
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
||||
Index: client/marshall.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
|
||||
retrieving revision 1.3
|
||||
diff -n -r1.3 marshall.cpp
|
||||
d245 1
|
||||
a245 1
|
||||
void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
d247 71
|
||||
a317 10
|
||||
if (type == "QStringList")
|
||||
type = "QValueList<QString>";
|
||||
if (type == "QCStringList")
|
||||
type = "QValueList<QCString>";
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("Not enough arguments.");
|
||||
exit(1);
|
||||
}
|
||||
QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
d319 28
|
||||
a346 57
|
||||
if ( type == "int" )
|
||||
arg << s.toInt();
|
||||
else if ( type == "uint" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned int" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "long" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "long int" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "unsigned long" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "unsigned long int" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "float" )
|
||||
arg << s.toFloat();
|
||||
else if ( type == "double" )
|
||||
arg << s.toDouble();
|
||||
else if ( type == "bool" )
|
||||
arg << mkBool( s );
|
||||
else if ( type == "QString" )
|
||||
arg << s;
|
||||
else if ( type == "QCString" )
|
||||
arg << QCString( args[ i ] );
|
||||
else if ( type == "QColor" )
|
||||
arg << mkColor( s );
|
||||
else if ( type == "QPoint" )
|
||||
arg << mkPoint( s );
|
||||
else if ( type == "QSize" )
|
||||
arg << mkSize( s );
|
||||
else if ( type == "QRect" )
|
||||
arg << mkRect( s );
|
||||
else if ( type == "QVariant" ) {
|
||||
if ( s == "true" || s == "false" )
|
||||
arg << QVariant( mkBool( s ), 42 );
|
||||
else if ( s.left( 4 ) == "int(" )
|
||||
arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
else if ( s.left( 7 ) == "QPoint(" )
|
||||
arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
else if ( s.left( 6 ) == "QSize(" )
|
||||
arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 6 ) == "QRect(" )
|
||||
arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 7 ) == "QColor(" )
|
||||
arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
else
|
||||
arg << QVariant( s );
|
||||
} else if ( type.startsWith("QValueList<")) {
|
||||
type = type.mid(11, type.length() - 12);
|
||||
QStringList list;
|
||||
QString delim = s;
|
||||
if (delim == "[")
|
||||
delim = "]";
|
||||
if (delim == "(")
|
||||
delim = ")";
|
||||
a347 34
|
||||
QByteArray dummy_data;
|
||||
QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
|
||||
uint j = i;
|
||||
uint count = 0;
|
||||
// Parse list to get the count
|
||||
while (true) {
|
||||
if( j > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
break;
|
||||
marshall( dummy_arg, args, j, type );
|
||||
count++;
|
||||
}
|
||||
arg << (Q_UINT32) count;
|
||||
// Parse the list for real
|
||||
while (true) {
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
break;
|
||||
marshall( arg, args, i, type );
|
||||
}
|
||||
} else {
|
||||
qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
50
kompare/tests/cvsdiff/unified.diff
Normal file
|
@ -0,0 +1,50 @@
|
|||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -u -r1.2 dcopfind.cpp
|
||||
--- client/dcopfind.cpp 2001/10/31 01:17:39 1.2
|
||||
+++ client/dcopfind.cpp 2002/01/16 18:07:51
|
||||
@@ -36,7 +36,7 @@
|
||||
static bool bAppIdOnly = 0;
|
||||
static bool bLaunchApp = 0;
|
||||
|
||||
-bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
{
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
@@ -118,7 +118,7 @@
|
||||
f = fc;
|
||||
}
|
||||
|
||||
- if ( (int) types.count() != argc ) {
|
||||
+ if ( types.count() != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -128,9 +128,9 @@
|
||||
|
||||
int i = 0;
|
||||
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
- marshall(arg, argc, args, i, *it);
|
||||
+ marshall(arg, args, i, *it);
|
||||
}
|
||||
- if ( (int) i != argc ) {
|
||||
+ if ( (uint) i != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -221,7 +221,11 @@
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
- findObject( app, objid, function, argc, args );
|
||||
+ QCStringList params;
|
||||
+ for( int i = 0; i < argc; i++ )
|
||||
+ params.append( args[ i ] );
|
||||
+
|
||||
+ findObject( app, objid, function, params );
|
||||
|
||||
return 0;
|
||||
}
|
924
kompare/tests/cvsdiff/unifiedm.diff
Normal file
|
@ -0,0 +1,924 @@
|
|||
Index: client/dcop.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcop.cpp,v
|
||||
retrieving revision 1.26
|
||||
diff -u -r1.26 dcop.cpp
|
||||
--- client/dcop.cpp 2001/10/31 01:17:39 1.26
|
||||
+++ client/dcop.cpp 2002/01/16 18:06:14
|
||||
@@ -20,19 +20,47 @@
|
||||
|
||||
******************************************************************/
|
||||
|
||||
-#include <qvariant.h>
|
||||
+#include <ctype.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
#include <qcolor.h>
|
||||
-#include "../kdatastream.h"
|
||||
+#include <qdir.h>
|
||||
+#include <qfile.h>
|
||||
+#include <qfileinfo.h>
|
||||
+#include <qmap.h>
|
||||
+#include <qstringlist.h>
|
||||
+#include <qtextstream.h>
|
||||
+#include <qvariant.h>
|
||||
+
|
||||
+// putenv() is not available on all platforms, so make sure the emulation
|
||||
+// wrapper is available in those cases by loading config.h!
|
||||
+#include <config.h>
|
||||
+
|
||||
#include "../dcopclient.h"
|
||||
#include "../dcopref.h"
|
||||
-#include <stdlib.h>
|
||||
-#include <stdio.h>
|
||||
-#include <ctype.h>
|
||||
+#include "../kdatastream.h"
|
||||
|
||||
#include "marshall.cpp"
|
||||
|
||||
+typedef QMap<QString, QString> UserList;
|
||||
+
|
||||
static DCOPClient* dcop = 0;
|
||||
|
||||
+static QTextStream cout( stdout, IO_WriteOnly );
|
||||
+static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
+
|
||||
+/**
|
||||
+ * Session to send call to
|
||||
+ * DefaultSession - current session. Current KDE session when called without
|
||||
+ * --user or --all-users option. Otherwise this value ignores
|
||||
+ * all users with more than one active session.
|
||||
+ * AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
+ * QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
+ * CustomSession - Use the specified session
|
||||
+ */
|
||||
+enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
+
|
||||
bool startsWith(const QCString &id, const char *str, int n)
|
||||
{
|
||||
return !n || (strncmp(id.data(), str, n) == 0);
|
||||
@@ -118,9 +146,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
-void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
+void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
{
|
||||
-
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
int right = f.find( ')' );
|
||||
@@ -136,7 +163,7 @@
|
||||
bool ok = false;
|
||||
QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
|
||||
QCString realfunc;
|
||||
- if ( !ok && argc == 0 )
|
||||
+ if ( !ok && args.isEmpty() )
|
||||
goto doit;
|
||||
if ( !ok )
|
||||
{
|
||||
@@ -153,15 +180,16 @@
|
||||
|
||||
if ( l > 0 && (*it).mid( s, l - s ) == func ) {
|
||||
realfunc = (*it).mid( s );
|
||||
- int a = (*it).contains(',');
|
||||
- if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
|
||||
+ uint a = (*it).contains(',');
|
||||
+ if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( realfunc.isEmpty() )
|
||||
{
|
||||
qWarning("no such function");
|
||||
- exit(1);
|
||||
+// exit(1);
|
||||
+ return;
|
||||
}
|
||||
f = realfunc;
|
||||
left = f.find( '(' );
|
||||
@@ -243,11 +271,12 @@
|
||||
QCString replyType;
|
||||
QDataStream arg(data, IO_WriteOnly);
|
||||
|
||||
- int i = 0;
|
||||
- for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
- marshall(arg, argc, args, i, *it);
|
||||
- }
|
||||
- if ( i != argc ) {
|
||||
+ uint i = 0;
|
||||
+ for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
+ marshall( arg, args, i, *it );
|
||||
+
|
||||
+ if ( i != args.count() )
|
||||
+ {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -265,79 +294,480 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
|
||||
+/**
|
||||
+ * Show command-line help and exit
|
||||
+ */
|
||||
+void showHelp( int exitCode = 0 )
|
||||
+{
|
||||
+ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
+ << "" << endl
|
||||
+ << "Console DCOP client" << endl
|
||||
+ << "" << endl
|
||||
+ << "Generic options:" << endl
|
||||
+ << " --help Show help about options" << endl
|
||||
+ << "" << endl
|
||||
+ << "Options:" << endl
|
||||
+ << " --pipe Call DCOP for each line read from stdin" << endl
|
||||
+ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
+ << " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
+ << " $ICEAUTHORITY, even if they are set." << endl
|
||||
+ << " If the user has more than one open session, you must also" << endl
|
||||
+ << " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
+ << " command-line options." << endl
|
||||
+ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
+ << " server. Only failed calls to existing DCOP servers will"
|
||||
+ << " generate an error message. If no DCOP server is available" << endl
|
||||
+ << " at all, no error will be generated." << endl;
|
||||
+
|
||||
+ exit( exitCode );
|
||||
+}
|
||||
|
||||
-int main( int argc, char** argv )
|
||||
+/**
|
||||
+ * Return a list of all users and their home directories.
|
||||
+ * Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
+ */
|
||||
+static UserList userList()
|
||||
{
|
||||
+ UserList result;
|
||||
+
|
||||
+ QFile f( "/etc/passwd" );
|
||||
+
|
||||
+ if( !f.open( IO_ReadOnly ) )
|
||||
+ {
|
||||
+ cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
+ return result;
|
||||
+ }
|
||||
|
||||
- if ( argc > 1 && argv[1][0] == '-' ) {
|
||||
- fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
|
||||
- exit(0);
|
||||
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
+
|
||||
+ for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
+ {
|
||||
+ QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
+ result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
}
|
||||
|
||||
- DCOPClient client;
|
||||
- client.attach();
|
||||
- dcop = &client;
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Return a list of available DCOP sessions for the specified user
|
||||
+ * An empty list means no sessions are available, or an error occurred.
|
||||
+ */
|
||||
+QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
+{
|
||||
+ if( home.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot determine home directory for user "
|
||||
+ << user << "!" << endl
|
||||
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ return QStringList();
|
||||
+ }
|
||||
+
|
||||
+ QStringList result;
|
||||
+ QFileInfo dirInfo( home );
|
||||
+ if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
+ return result;
|
||||
+
|
||||
+ QDir d( home );
|
||||
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
+ d.setNameFilter( ".DCOPserver*" );
|
||||
+
|
||||
+ const QFileInfoList *list = d.entryInfoList();
|
||||
+ if( !list )
|
||||
+ return result;
|
||||
+
|
||||
+ QFileInfoListIterator it( *list );
|
||||
+ QFileInfo *fi;
|
||||
+
|
||||
+ while ( ( fi = it.current() ) != 0 )
|
||||
+ {
|
||||
+ if( fi->isReadable() )
|
||||
+ result.append( fi->fileName() );
|
||||
+ ++it;
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
|
||||
+/**
|
||||
+ * Do the actual DCOP call
|
||||
+ */
|
||||
+void runDCOP( QCStringList args, UserList users, Session session,
|
||||
+ const QString sessionName, bool readStdin )
|
||||
+{
|
||||
QCString app;
|
||||
QCString objid;
|
||||
QCString function;
|
||||
- char **args = 0;
|
||||
- if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
|
||||
+ QCStringList params;
|
||||
+ DCOPClient *client = 0L;
|
||||
+ if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
{
|
||||
- char *delim = strchr(argv[1], ',');
|
||||
- if (!delim)
|
||||
- {
|
||||
- fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
|
||||
- return 1;
|
||||
- }
|
||||
- *delim = 0;
|
||||
- app = argv[1] + 8;
|
||||
- delim++;
|
||||
- delim[strlen(delim)-1] = 0;
|
||||
- objid = delim;
|
||||
- if (argc > 2)
|
||||
- function = argv[2];
|
||||
- if (argc > 3)
|
||||
- args = &argv[3];
|
||||
- argc++;
|
||||
+ // WARNING: This part (until the closing '}') could very
|
||||
+ // well be broken now. As I don't know how to trigger and test
|
||||
+ // dcoprefs this code is *not* tested. It compiles and it looks
|
||||
+ // ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
+ int delimPos = args[ 0 ].findRev( ',' );
|
||||
+ if( delimPos == -1 )
|
||||
+ {
|
||||
+ cerr << "Error: '" << args[ 0 ]
|
||||
+ << "' is not a valid DCOP reference." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ args[ 0 ][ delimPos ] = 0;
|
||||
+ app = args[ 0 ].mid( 8 );
|
||||
+ delimPos++;
|
||||
+ args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
+ objid = args[ 0 ].mid( delimPos );
|
||||
+ if( args.count() > 1 )
|
||||
+ function = args[ 1 ];
|
||||
+ if( args.count() > 2 )
|
||||
+ {
|
||||
+ params = args;
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (argc > 1)
|
||||
- app = argv[1];
|
||||
- if (argc > 2)
|
||||
- objid = argv[2];
|
||||
- if (argc > 3)
|
||||
- function = argv[3];
|
||||
- if (argc > 4)
|
||||
- args = &argv[4];
|
||||
- }
|
||||
-
|
||||
- switch ( argc ) {
|
||||
- case 0:
|
||||
- case 1:
|
||||
- queryApplications("");
|
||||
- break;
|
||||
- case 2:
|
||||
- if (endsWith(app, '*'))
|
||||
- queryApplications(app);
|
||||
- else
|
||||
- queryObjects( app, "" );
|
||||
- break;
|
||||
- case 3:
|
||||
- if (endsWith(objid, '*'))
|
||||
- queryObjects(app, objid);
|
||||
- else
|
||||
- queryFunctions( app, objid );
|
||||
- break;
|
||||
- case 4:
|
||||
- default:
|
||||
- callFunction( app, objid, function, argc - 4, args );
|
||||
- break;
|
||||
+ if( !args.isEmpty() )
|
||||
+ app = args[ 0 ];
|
||||
+ if( args.count() > 1 )
|
||||
+ objid = args[ 1 ];
|
||||
+ if( args.count() > 2 )
|
||||
+ function = args[ 2 ];
|
||||
+ if( args.count() > 3)
|
||||
+ {
|
||||
+ params = args;
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ bool firstRun = true;
|
||||
+ UserList::Iterator it;
|
||||
+ QStringList sessions;
|
||||
+ bool presetDCOPServer = false;
|
||||
+// char *dcopStr = 0L;
|
||||
+ QString dcopServer;
|
||||
+
|
||||
+ for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
+ {
|
||||
+ firstRun = false;
|
||||
+
|
||||
+ //cout << "Iterating '" << it.key() << "'" << endl;
|
||||
+
|
||||
+ if( session == QuerySessions )
|
||||
+ {
|
||||
+ QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
+ if( sessions.isEmpty() )
|
||||
+ {
|
||||
+ cout << "No active sessions";
|
||||
+ if( !( *it ).isEmpty() )
|
||||
+ cout << " for user " << *it;
|
||||
+ cout << endl;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cout << "Active sessions ";
|
||||
+ if( !( *it ).isEmpty() )
|
||||
+ cout << "for user " << *it << " ";
|
||||
+ cout << ":" << endl;
|
||||
+
|
||||
+ QStringList::Iterator sIt;
|
||||
+ for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
+ cout << " " << *sIt << endl;
|
||||
+
|
||||
+ cout << endl;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if( getenv( "DCOPSERVER" ) )
|
||||
+ {
|
||||
+ sessions.append( getenv( "DCOPSERVER" ) );
|
||||
+ presetDCOPServer = true;
|
||||
+ }
|
||||
+
|
||||
+ if( users.count() > 1 || ( users.count() == 1 &&
|
||||
+ ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
+ {
|
||||
+ sessions = dcopSessionList( it.key(), it.data() );
|
||||
+ if( sessions.isEmpty() )
|
||||
+ {
|
||||
+ if( users.count() > 1 )
|
||||
+ continue;
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "ERROR: No active KDE sessions!" << endl
|
||||
+ << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
+ << "before calling dcop." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+ else if( sessions.count() > 1 && session != AllSessions )
|
||||
+ {
|
||||
+ cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
+ << "Please specify the correct session to use with --session or use the" << endl
|
||||
+ << "--all-sessions option to broadcast to all sessions." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ if( users.count() > 1 || ( users.count() == 1 &&
|
||||
+ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
+ {
|
||||
+ // Check for ICE authority file and if the file can be read by us
|
||||
+ QString home = it.data();
|
||||
+ QString iceFile = it.data() + "/.ICEauthority";
|
||||
+ QFileInfo fi( iceFile );
|
||||
+ if( iceFile.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot determine home directory for user "
|
||||
+ << it.key() << "!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ else if( fi.exists() )
|
||||
+ {
|
||||
+ if( fi.isReadable() )
|
||||
+ {
|
||||
+ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
+ putenv( envStr );
|
||||
+ //cerr << "ice: " << envStr << endl;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "WARNING: ICE authority file " << iceFile
|
||||
+ << "is not readable by you!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if( users.count() > 1 )
|
||||
+ continue;
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot find ICE authority file "
|
||||
+ << iceFile << "!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY"
|
||||
+ << " variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Main loop
|
||||
+ // If users is an empty list we're calling for the currently logged
|
||||
+ // in user. In this case we don't have a session, but still want
|
||||
+ // to iterate the loop once.
|
||||
+ QStringList::Iterator sIt = sessions.begin();
|
||||
+ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
+ {
|
||||
+ if( !presetDCOPServer && !users.isEmpty() )
|
||||
+ {
|
||||
+ QString dcopFile = it.data() + "/" + *sIt;
|
||||
+ QFile f( dcopFile );
|
||||
+ if( !f.open( IO_ReadOnly ) )
|
||||
+ {
|
||||
+ cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+
|
||||
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
+ dcopServer = l.first();
|
||||
+
|
||||
+ if( dcopServer.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
+ << *sIt << "!" << endl
|
||||
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ delete client;
|
||||
+ client = new DCOPClient;
|
||||
+ if( !dcopServer.isEmpty() )
|
||||
+ client->setServerAddress( dcopServer.ascii() );
|
||||
+ bool success = client->attach();
|
||||
+ if( !success )
|
||||
+ {
|
||||
+ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
+ continue;
|
||||
+ }
|
||||
+ dcop = client;
|
||||
+
|
||||
+ switch ( args.count() )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ queryApplications("");
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ if (endsWith(app, '*'))
|
||||
+ queryApplications(app);
|
||||
+ else
|
||||
+ queryObjects( app, "" );
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (endsWith(objid, '*'))
|
||||
+ queryObjects(app, objid);
|
||||
+ else
|
||||
+ queryFunctions( app, objid );
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ default:
|
||||
+ if( readStdin )
|
||||
+ {
|
||||
+ QCStringList::Iterator replaceArg = args.end();
|
||||
+
|
||||
+ QCStringList::Iterator it;
|
||||
+ for( it = args.begin(); it != args.end(); it++ )
|
||||
+ if( *it == "%1" )
|
||||
+ replaceArg = it;
|
||||
+
|
||||
+ // Read from stdin until EOF and call function for each line read
|
||||
+ char *buf = new char[ 1000 ];
|
||||
+ while ( !feof( stdin ) )
|
||||
+ {
|
||||
+ fgets( buf, 1000, stdin );
|
||||
+
|
||||
+ if( replaceArg != args.end() )
|
||||
+ *replaceArg = buf;
|
||||
+
|
||||
+ callFunction( app, objid, function, params );
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // Just call function
|
||||
+// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
+ callFunction( app, objid, function, params );
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ // Another sIt++ would make the loop infinite...
|
||||
+ if( users.isEmpty() )
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ // Another it++ would make the loop infinite...
|
||||
+ if( it == users.end() )
|
||||
+ break;
|
||||
}
|
||||
+}
|
||||
+
|
||||
|
||||
+int main( int argc, char** argv )
|
||||
+{
|
||||
+ bool readStdin = false;
|
||||
+ int numOptions = 0;
|
||||
+ QString user;
|
||||
+ Session session = DefaultSession;
|
||||
+ QString sessionName;
|
||||
+
|
||||
+ // Scan for command-line options first
|
||||
+ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
+ {
|
||||
+ if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
+ showHelp( 0 );
|
||||
+ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
+ {
|
||||
+ readStdin = true;
|
||||
+ numOptions++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
+ {
|
||||
+ if( pos <= argc - 2 )
|
||||
+ {
|
||||
+ user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
+ numOptions +=2;
|
||||
+ pos++;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
+ {
|
||||
+ user = "*";
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
+ {
|
||||
+ session = QuerySessions;
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
+ {
|
||||
+ session = AllSessions;
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( argv[ pos ][ 0 ] == '-' )
|
||||
+ {
|
||||
+ cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
+ << "'." << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+ else
|
||||
+ break; // End of options
|
||||
+ }
|
||||
+
|
||||
+ argc -= numOptions;
|
||||
+
|
||||
+ QCStringList args;
|
||||
+ for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
+ args.append( argv[ i + 1 ] );
|
||||
+
|
||||
+ if( readStdin && args.count() < 3 )
|
||||
+ {
|
||||
+ cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session == QuerySessions && !args.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session == QuerySessions && user.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
+ << "--all-users options!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session != DefaultSession && session != QuerySessions &&
|
||||
+ args.count() < 3 )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
+ << "calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ UserList users;
|
||||
+ if( user == "*" )
|
||||
+ users = userList();
|
||||
+ else if( !user.isEmpty() )
|
||||
+ users[ user ] = userList()[ user ];
|
||||
+
|
||||
+ runDCOP( args, users, session, sessionName, readStdin );
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+// vim: set ts=8 sts=4 sw=4 noet:
|
||||
+
|
||||
Index: client/dcopfind.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/dcopfind.cpp,v
|
||||
retrieving revision 1.2
|
||||
diff -u -r1.2 dcopfind.cpp
|
||||
--- client/dcopfind.cpp 2001/10/31 01:17:39 1.2
|
||||
+++ client/dcopfind.cpp 2002/01/16 18:06:14
|
||||
@@ -36,7 +36,7 @@
|
||||
static bool bAppIdOnly = 0;
|
||||
static bool bLaunchApp = 0;
|
||||
|
||||
-bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
{
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
@@ -118,7 +118,7 @@
|
||||
f = fc;
|
||||
}
|
||||
|
||||
- if ( (int) types.count() != argc ) {
|
||||
+ if ( types.count() != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -128,9 +128,9 @@
|
||||
|
||||
int i = 0;
|
||||
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
- marshall(arg, argc, args, i, *it);
|
||||
+ marshall(arg, args, i, *it);
|
||||
}
|
||||
- if ( (int) i != argc ) {
|
||||
+ if ( (uint) i != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -221,7 +221,11 @@
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
- findObject( app, objid, function, argc, args );
|
||||
+ QCStringList params;
|
||||
+ for( int i = 0; i < argc; i++ )
|
||||
+ params.append( args[ i ] );
|
||||
+
|
||||
+ findObject( app, objid, function, params );
|
||||
|
||||
return 0;
|
||||
}
|
||||
Index: client/marshall.cpp
|
||||
===================================================================
|
||||
RCS file: /home/kde/kdelibs/dcop/client/marshall.cpp,v
|
||||
retrieving revision 1.3
|
||||
diff -u -r1.3 marshall.cpp
|
||||
--- client/marshall.cpp 2001/10/31 01:17:39 1.3
|
||||
+++ client/marshall.cpp 2002/01/16 18:06:14
|
||||
@@ -242,108 +242,110 @@
|
||||
|
||||
}
|
||||
|
||||
-void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
|
||||
+void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
{
|
||||
- if (type == "QStringList")
|
||||
- type = "QValueList<QString>";
|
||||
- if (type == "QCStringList")
|
||||
- type = "QValueList<QCString>";
|
||||
- if (i >= argc)
|
||||
- {
|
||||
- qWarning("Not enough arguments.");
|
||||
- exit(1);
|
||||
- }
|
||||
- QString s = QString::fromLocal8Bit(argv[i]);
|
||||
-
|
||||
- if ( type == "int" )
|
||||
- arg << s.toInt();
|
||||
- else if ( type == "uint" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "unsigned" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "unsigned int" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "long" )
|
||||
- arg << s.toLong();
|
||||
- else if ( type == "long int" )
|
||||
- arg << s.toLong();
|
||||
- else if ( type == "unsigned long" )
|
||||
- arg << s.toULong();
|
||||
- else if ( type == "unsigned long int" )
|
||||
- arg << s.toULong();
|
||||
- else if ( type == "float" )
|
||||
- arg << s.toFloat();
|
||||
- else if ( type == "double" )
|
||||
- arg << s.toDouble();
|
||||
- else if ( type == "bool" )
|
||||
- arg << mkBool( s );
|
||||
- else if ( type == "QString" )
|
||||
- arg << s;
|
||||
- else if ( type == "QCString" )
|
||||
- arg << QCString( argv[i] );
|
||||
- else if ( type == "QColor" )
|
||||
- arg << mkColor( s );
|
||||
- else if ( type == "QPoint" )
|
||||
- arg << mkPoint( s );
|
||||
- else if ( type == "QSize" )
|
||||
- arg << mkSize( s );
|
||||
- else if ( type == "QRect" )
|
||||
- arg << mkRect( s );
|
||||
- else if ( type == "QVariant" ) {
|
||||
- if ( s == "true" || s == "false" )
|
||||
- arg << QVariant( mkBool( s ), 42 );
|
||||
- else if ( s.left( 4 ) == "int(" )
|
||||
- arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
- else if ( s.left( 7 ) == "QPoint(" )
|
||||
- arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
- else if ( s.left( 6 ) == "QSize(" )
|
||||
- arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
- else if ( s.left( 6 ) == "QRect(" )
|
||||
- arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
- else if ( s.left( 7 ) == "QColor(" )
|
||||
- arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
- else
|
||||
- arg << QVariant( s );
|
||||
- } else if ( type.startsWith("QValueList<")) {
|
||||
- type = type.mid(11, type.length() - 12);
|
||||
- QStringList list;
|
||||
- QString delim = s;
|
||||
- if (delim == "[")
|
||||
- delim = "]";
|
||||
- if (delim == "(")
|
||||
- delim = ")";
|
||||
- i++;
|
||||
- QByteArray dummy_data;
|
||||
- QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
+ if (type == "QStringList")
|
||||
+ type = "QValueList<QString>";
|
||||
+ if (type == "QCStringList")
|
||||
+ type = "QValueList<QCString>";
|
||||
+ if( i > args.count() )
|
||||
+ {
|
||||
+ qWarning("Not enough arguments.");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
|
||||
- int j = i;
|
||||
- int count = 0;
|
||||
- // Parse list to get the count
|
||||
- while (true) {
|
||||
- if (j >= argc)
|
||||
- {
|
||||
- qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
- exit(1);
|
||||
- }
|
||||
- if (argv[j] == delim) break;
|
||||
- marshall(dummy_arg, argc, argv, j, type);
|
||||
- count++;
|
||||
- }
|
||||
- arg << (Q_UINT32) count;
|
||||
- // Parse the list for real
|
||||
- while (true) {
|
||||
- if (i >= argc)
|
||||
- {
|
||||
- qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
- exit(1);
|
||||
- }
|
||||
- if (argv[i] == delim) break;
|
||||
- marshall(arg, argc, argv, i, type);
|
||||
- }
|
||||
- } else {
|
||||
- qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
- exit(1);
|
||||
- }
|
||||
+ if ( type == "int" )
|
||||
+ arg << s.toInt();
|
||||
+ else if ( type == "uint" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "unsigned" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "unsigned int" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "long" )
|
||||
+ arg << s.toLong();
|
||||
+ else if ( type == "long int" )
|
||||
+ arg << s.toLong();
|
||||
+ else if ( type == "unsigned long" )
|
||||
+ arg << s.toULong();
|
||||
+ else if ( type == "unsigned long int" )
|
||||
+ arg << s.toULong();
|
||||
+ else if ( type == "float" )
|
||||
+ arg << s.toFloat();
|
||||
+ else if ( type == "double" )
|
||||
+ arg << s.toDouble();
|
||||
+ else if ( type == "bool" )
|
||||
+ arg << mkBool( s );
|
||||
+ else if ( type == "QString" )
|
||||
+ arg << s;
|
||||
+ else if ( type == "QCString" )
|
||||
+ arg << QCString( args[ i ] );
|
||||
+ else if ( type == "QColor" )
|
||||
+ arg << mkColor( s );
|
||||
+ else if ( type == "QPoint" )
|
||||
+ arg << mkPoint( s );
|
||||
+ else if ( type == "QSize" )
|
||||
+ arg << mkSize( s );
|
||||
+ else if ( type == "QRect" )
|
||||
+ arg << mkRect( s );
|
||||
+ else if ( type == "QVariant" ) {
|
||||
+ if ( s == "true" || s == "false" )
|
||||
+ arg << QVariant( mkBool( s ), 42 );
|
||||
+ else if ( s.left( 4 ) == "int(" )
|
||||
+ arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
+ else if ( s.left( 7 ) == "QPoint(" )
|
||||
+ arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
+ else if ( s.left( 6 ) == "QSize(" )
|
||||
+ arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
+ else if ( s.left( 6 ) == "QRect(" )
|
||||
+ arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
+ else if ( s.left( 7 ) == "QColor(" )
|
||||
+ arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
+ else
|
||||
+ arg << QVariant( s );
|
||||
+ } else if ( type.startsWith("QValueList<")) {
|
||||
+ type = type.mid(11, type.length() - 12);
|
||||
+ QStringList list;
|
||||
+ QString delim = s;
|
||||
+ if (delim == "[")
|
||||
+ delim = "]";
|
||||
+ if (delim == "(")
|
||||
+ delim = ")";
|
||||
i++;
|
||||
+ QByteArray dummy_data;
|
||||
+ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
+
|
||||
+ uint j = i;
|
||||
+ uint count = 0;
|
||||
+ // Parse list to get the count
|
||||
+ while (true) {
|
||||
+ if( j > args.count() )
|
||||
+ {
|
||||
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
+ break;
|
||||
+ marshall( dummy_arg, args, j, type );
|
||||
+ count++;
|
||||
+ }
|
||||
+ arg << (Q_UINT32) count;
|
||||
+ // Parse the list for real
|
||||
+ while (true) {
|
||||
+ if( i > args.count() )
|
||||
+ {
|
||||
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
+ break;
|
||||
+ marshall( arg, args, i, type );
|
||||
+ }
|
||||
+ } else {
|
||||
+ qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ i++;
|
||||
}
|
||||
|
27
kompare/tests/diff/context.diff
Normal file
|
@ -0,0 +1,27 @@
|
|||
*** /home/John/lao Thu Apr 12 11:09:30 2001
|
||||
--- /home/John/tzu Sat Jul 28 13:23:25 2001
|
||||
***************
|
||||
*** 1,7 ****
|
||||
- The Way that can be told of is not the eternal Way;
|
||||
- The name that can be named is not the eternal name.
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
! The Named is the mother of all things.
|
||||
Therefore let there always be non-being,
|
||||
so we may see their subtlety,
|
||||
And let there always be being,
|
||||
--- 1,6 ----
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
! The named is the mother of all things.
|
||||
!
|
||||
Therefore let there always be non-being,
|
||||
so we may see their subtlety,
|
||||
And let there always be being,
|
||||
***************
|
||||
*** 9,11 ****
|
||||
--- 8,13 ----
|
||||
The two are the same,
|
||||
But after they are produced,
|
||||
they have different names.
|
||||
+ They both may be called deep and profound.
|
||||
+ Deeper and more profound,
|
||||
+ The door of all subtleties!
|
1032
kompare/tests/diff/contextm.diff
Normal file
27
kompare/tests/diff/contextp.diff
Normal file
|
@ -0,0 +1,27 @@
|
|||
*** /home/John/lao Thu Apr 12 11:09:30 2001
|
||||
--- /home/John/tzu Sat Jul 28 13:23:25 2001
|
||||
***************
|
||||
*** 1,7 ****
|
||||
- The Way that can be told of is not the eternal Way;
|
||||
- The name that can be named is not the eternal name.
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
! The Named is the mother of all things.
|
||||
Therefore let there always be non-being,
|
||||
so we may see their subtlety,
|
||||
And let there always be being,
|
||||
--- 1,6 ----
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
! The named is the mother of all things.
|
||||
!
|
||||
Therefore let there always be non-being,
|
||||
so we may see their subtlety,
|
||||
And let there always be being,
|
||||
*************** And let there always be being,
|
||||
*** 9,11 ****
|
||||
--- 8,13 ----
|
||||
The two are the same,
|
||||
But after they are produced,
|
||||
they have different names.
|
||||
+ They both may be called deep and profound.
|
||||
+ Deeper and more profound,
|
||||
+ The door of all subtleties!
|
10
kompare/tests/diff/ed.diff
Normal file
|
@ -0,0 +1,10 @@
|
|||
11a
|
||||
They both may be called deep and profound.
|
||||
Deeper and more profound,
|
||||
The door of all subtleties!
|
||||
.
|
||||
4c
|
||||
The named is the mother of all things.
|
||||
|
||||
.
|
||||
1,2d
|
680
kompare/tests/diff/edm.diff
Normal file
|
@ -0,0 +1,680 @@
|
|||
diff -er dcop/client/dcop.cpp dcop2/client/dcop.cpp
|
||||
343a
|
||||
|
||||
// vim: set ts=8 sts=4 sw=4 noet:
|
||||
|
||||
.
|
||||
340a
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
bool readStdin = false;
|
||||
int numOptions = 0;
|
||||
QString user;
|
||||
Session session = DefaultSession;
|
||||
QString sessionName;
|
||||
|
||||
// Scan for command-line options first
|
||||
for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
{
|
||||
if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
showHelp( 0 );
|
||||
else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
{
|
||||
readStdin = true;
|
||||
numOptions++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
{
|
||||
if( pos <= argc - 2 )
|
||||
{
|
||||
user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
numOptions +=2;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
{
|
||||
user = "*";
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
{
|
||||
session = QuerySessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
{
|
||||
session = AllSessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( argv[ pos ][ 0 ] == '-' )
|
||||
{
|
||||
cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
<< "'." << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
else
|
||||
break; // End of options
|
||||
}
|
||||
|
||||
argc -= numOptions;
|
||||
|
||||
QCStringList args;
|
||||
for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
args.append( argv[ i + 1 ] );
|
||||
|
||||
if( readStdin && args.count() < 3 )
|
||||
{
|
||||
cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
{
|
||||
cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && !args.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && user.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
<< "--all-users options!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session != DefaultSession && session != QuerySessions &&
|
||||
args.count() < 3 )
|
||||
{
|
||||
cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
<< "calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
UserList users;
|
||||
if( user == "*" )
|
||||
users = userList();
|
||||
else if( !user.isEmpty() )
|
||||
users[ user ] = userList()[ user ];
|
||||
|
||||
runDCOP( args, users, session, sessionName, readStdin );
|
||||
.
|
||||
339a
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
{
|
||||
// Check for ICE authority file and if the file can be read by us
|
||||
QString home = it.data();
|
||||
QString iceFile = it.data() + "/.ICEauthority";
|
||||
QFileInfo fi( iceFile );
|
||||
if( iceFile.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< it.key() << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
else if( fi.exists() )
|
||||
{
|
||||
if( fi.isReadable() )
|
||||
{
|
||||
char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
putenv( envStr );
|
||||
//cerr << "ice: " << envStr << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: ICE authority file " << iceFile
|
||||
<< "is not readable by you!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: Cannot find ICE authority file "
|
||||
<< iceFile << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY"
|
||||
<< " variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main loop
|
||||
// If users is an empty list we're calling for the currently logged
|
||||
// in user. In this case we don't have a session, but still want
|
||||
// to iterate the loop once.
|
||||
QStringList::Iterator sIt = sessions.begin();
|
||||
for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
{
|
||||
if( !presetDCOPServer && !users.isEmpty() )
|
||||
{
|
||||
QString dcopFile = it.data() + "/" + *sIt;
|
||||
QFile f( dcopFile );
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
dcopServer = l.first();
|
||||
|
||||
if( dcopServer.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
<< *sIt << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
delete client;
|
||||
client = new DCOPClient;
|
||||
if( !dcopServer.isEmpty() )
|
||||
client->setServerAddress( dcopServer.ascii() );
|
||||
bool success = client->attach();
|
||||
if( !success )
|
||||
{
|
||||
cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
continue;
|
||||
}
|
||||
dcop = client;
|
||||
|
||||
switch ( args.count() )
|
||||
{
|
||||
case 0:
|
||||
queryApplications("");
|
||||
break;
|
||||
case 1:
|
||||
if (endsWith(app, '*'))
|
||||
queryApplications(app);
|
||||
else
|
||||
queryObjects( app, "" );
|
||||
break;
|
||||
case 2:
|
||||
if (endsWith(objid, '*'))
|
||||
queryObjects(app, objid);
|
||||
else
|
||||
queryFunctions( app, objid );
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if( readStdin )
|
||||
{
|
||||
QCStringList::Iterator replaceArg = args.end();
|
||||
|
||||
QCStringList::Iterator it;
|
||||
for( it = args.begin(); it != args.end(); it++ )
|
||||
if( *it == "%1" )
|
||||
replaceArg = it;
|
||||
|
||||
// Read from stdin until EOF and call function for each line read
|
||||
char *buf = new char[ 1000 ];
|
||||
while ( !feof( stdin ) )
|
||||
{
|
||||
fgets( buf, 1000, stdin );
|
||||
|
||||
if( replaceArg != args.end() )
|
||||
*replaceArg = buf;
|
||||
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just call function
|
||||
// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Another sIt++ would make the loop infinite...
|
||||
if( users.isEmpty() )
|
||||
break;
|
||||
}
|
||||
|
||||
// Another it++ would make the loop infinite...
|
||||
if( it == users.end() )
|
||||
break;
|
||||
.
|
||||
308,338c
|
||||
if( !args.isEmpty() )
|
||||
app = args[ 0 ];
|
||||
if( args.count() > 1 )
|
||||
objid = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
function = args[ 2 ];
|
||||
if( args.count() > 3)
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
bool firstRun = true;
|
||||
UserList::Iterator it;
|
||||
QStringList sessions;
|
||||
bool presetDCOPServer = false;
|
||||
// char *dcopStr = 0L;
|
||||
QString dcopServer;
|
||||
|
||||
for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
{
|
||||
firstRun = false;
|
||||
|
||||
//cout << "Iterating '" << it.key() << "'" << endl;
|
||||
|
||||
if( session == QuerySessions )
|
||||
{
|
||||
QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
cout << "No active sessions";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << " for user " << *it;
|
||||
cout << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Active sessions ";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << "for user " << *it << " ";
|
||||
cout << ":" << endl;
|
||||
|
||||
QStringList::Iterator sIt;
|
||||
for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
cout << " " << *sIt << endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( getenv( "DCOPSERVER" ) )
|
||||
{
|
||||
sessions.append( getenv( "DCOPSERVER" ) );
|
||||
presetDCOPServer = true;
|
||||
}
|
||||
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
{
|
||||
sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: No active KDE sessions!" << endl
|
||||
<< "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
<< "before calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
else if( sessions.count() > 1 && session != AllSessions )
|
||||
{
|
||||
cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
<< "Please specify the correct session to use with --session or use the" << endl
|
||||
<< "--all-sessions option to broadcast to all sessions." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
.
|
||||
289,304c
|
||||
// WARNING: This part (until the closing '}') could very
|
||||
// well be broken now. As I don't know how to trigger and test
|
||||
// dcoprefs this code is *not* tested. It compiles and it looks
|
||||
// ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
int delimPos = args[ 0 ].findRev( ',' );
|
||||
if( delimPos == -1 )
|
||||
{
|
||||
cerr << "Error: '" << args[ 0 ]
|
||||
<< "' is not a valid DCOP reference." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
args[ 0 ][ delimPos ] = 0;
|
||||
app = args[ 0 ].mid( 8 );
|
||||
delimPos++;
|
||||
args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
objid = args[ 0 ].mid( delimPos );
|
||||
if( args.count() > 1 )
|
||||
function = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
.
|
||||
286,287c
|
||||
QCStringList params;
|
||||
DCOPClient *client = 0L;
|
||||
if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
.
|
||||
282a
|
||||
/**
|
||||
* Do the actual DCOP call
|
||||
*/
|
||||
void runDCOP( QCStringList args, UserList users, Session session,
|
||||
const QString sessionName, bool readStdin )
|
||||
{
|
||||
.
|
||||
279,281c
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of available DCOP sessions for the specified user
|
||||
* An empty list means no sessions are available, or an error occurred.
|
||||
*/
|
||||
QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
{
|
||||
if( home.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< user << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList result;
|
||||
QFileInfo dirInfo( home );
|
||||
if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
return result;
|
||||
|
||||
QDir d( home );
|
||||
d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
d.setNameFilter( ".DCOPserver*" );
|
||||
|
||||
const QFileInfoList *list = d.entryInfoList();
|
||||
if( !list )
|
||||
return result;
|
||||
|
||||
QFileInfoListIterator it( *list );
|
||||
QFileInfo *fi;
|
||||
|
||||
while ( ( fi = it.current() ) != 0 )
|
||||
{
|
||||
if( fi->isReadable() )
|
||||
result.append( fi->fileName() );
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
.
|
||||
274,276c
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
|
||||
for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
{
|
||||
QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
.
|
||||
272a
|
||||
UserList result;
|
||||
|
||||
QFile f( "/etc/passwd" );
|
||||
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
return result;
|
||||
}
|
||||
.
|
||||
270,271c
|
||||
/**
|
||||
* Return a list of all users and their home directories.
|
||||
* Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
*/
|
||||
static UserList userList()
|
||||
.
|
||||
268a
|
||||
/**
|
||||
* Show command-line help and exit
|
||||
*/
|
||||
void showHelp( int exitCode = 0 )
|
||||
{
|
||||
cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
<< "" << endl
|
||||
<< "Console DCOP client" << endl
|
||||
<< "" << endl
|
||||
<< "Generic options:" << endl
|
||||
<< " --help Show help about options" << endl
|
||||
<< "" << endl
|
||||
<< "Options:" << endl
|
||||
<< " --pipe Call DCOP for each line read from stdin" << endl
|
||||
<< " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
<< " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
<< " $ICEAUTHORITY, even if they are set." << endl
|
||||
<< " If the user has more than one open session, you must also" << endl
|
||||
<< " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
<< " command-line options." << endl
|
||||
<< " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
<< " server. Only failed calls to existing DCOP servers will"
|
||||
<< " generate an error message. If no DCOP server is available" << endl
|
||||
<< " at all, no error will be generated." << endl;
|
||||
|
||||
exit( exitCode );
|
||||
}
|
||||
.
|
||||
246,250c
|
||||
uint i = 0;
|
||||
for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
marshall( arg, args, i, *it );
|
||||
|
||||
if ( i != args.count() )
|
||||
{
|
||||
.
|
||||
164c
|
||||
// exit(1);
|
||||
return;
|
||||
.
|
||||
156,157c
|
||||
uint a = (*it).contains(',');
|
||||
if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
.
|
||||
139c
|
||||
if ( !ok && args.isEmpty() )
|
||||
.
|
||||
123d
|
||||
121c
|
||||
void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
.
|
||||
35a
|
||||
static QTextStream cout( stdout, IO_WriteOnly );
|
||||
static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
|
||||
/**
|
||||
* Session to send call to
|
||||
* DefaultSession - current session. Current KDE session when called without
|
||||
* --user or --all-users option. Otherwise this value ignores
|
||||
* all users with more than one active session.
|
||||
* AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
* QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
* CustomSession - Use the specified session
|
||||
*/
|
||||
enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
|
||||
.
|
||||
33a
|
||||
typedef QMap<QString, QString> UserList;
|
||||
|
||||
.
|
||||
28,30c
|
||||
#include "../kdatastream.h"
|
||||
.
|
||||
25c
|
||||
#include <qdir.h>
|
||||
#include <qfile.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qmap.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
// putenv() is not available on all platforms, so make sure the emulation
|
||||
// wrapper is available in those cases by loading config.h!
|
||||
#include <config.h>
|
||||
|
||||
.
|
||||
23c
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
.
|
||||
diff -er dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
|
||||
224c
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
||||
.
|
||||
133c
|
||||
if ( (uint) i != args.count() ) {
|
||||
.
|
||||
131c
|
||||
marshall(arg, args, i, *it);
|
||||
.
|
||||
121c
|
||||
if ( types.count() != args.count() ) {
|
||||
.
|
||||
39c
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
.
|
||||
diff -er dcop/client/marshall.cpp dcop2/client/marshall.cpp
|
||||
347a
|
||||
QByteArray dummy_data;
|
||||
QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
|
||||
uint j = i;
|
||||
uint count = 0;
|
||||
// Parse list to get the count
|
||||
while (true) {
|
||||
if( j > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
break;
|
||||
marshall( dummy_arg, args, j, type );
|
||||
count++;
|
||||
}
|
||||
arg << (Q_UINT32) count;
|
||||
// Parse the list for real
|
||||
while (true) {
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
break;
|
||||
marshall( arg, args, i, type );
|
||||
}
|
||||
} else {
|
||||
qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
||||
.
|
||||
319,346c
|
||||
if ( type == "int" )
|
||||
arg << s.toInt();
|
||||
else if ( type == "uint" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned int" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "long" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "long int" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "unsigned long" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "unsigned long int" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "float" )
|
||||
arg << s.toFloat();
|
||||
else if ( type == "double" )
|
||||
arg << s.toDouble();
|
||||
else if ( type == "bool" )
|
||||
arg << mkBool( s );
|
||||
else if ( type == "QString" )
|
||||
arg << s;
|
||||
else if ( type == "QCString" )
|
||||
arg << QCString( args[ i ] );
|
||||
else if ( type == "QColor" )
|
||||
arg << mkColor( s );
|
||||
else if ( type == "QPoint" )
|
||||
arg << mkPoint( s );
|
||||
else if ( type == "QSize" )
|
||||
arg << mkSize( s );
|
||||
else if ( type == "QRect" )
|
||||
arg << mkRect( s );
|
||||
else if ( type == "QVariant" ) {
|
||||
if ( s == "true" || s == "false" )
|
||||
arg << QVariant( mkBool( s ), 42 );
|
||||
else if ( s.left( 4 ) == "int(" )
|
||||
arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
else if ( s.left( 7 ) == "QPoint(" )
|
||||
arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
else if ( s.left( 6 ) == "QSize(" )
|
||||
arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 6 ) == "QRect(" )
|
||||
arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 7 ) == "QColor(" )
|
||||
arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
else
|
||||
arg << QVariant( s );
|
||||
} else if ( type.startsWith("QValueList<")) {
|
||||
type = type.mid(11, type.length() - 12);
|
||||
QStringList list;
|
||||
QString delim = s;
|
||||
if (delim == "[")
|
||||
delim = "]";
|
||||
if (delim == "(")
|
||||
delim = ")";
|
||||
.
|
||||
247,317c
|
||||
if (type == "QStringList")
|
||||
type = "QValueList<QString>";
|
||||
if (type == "QCStringList")
|
||||
type = "QValueList<QCString>";
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("Not enough arguments.");
|
||||
exit(1);
|
||||
}
|
||||
QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
.
|
||||
245c
|
||||
void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
.
|
12
kompare/tests/diff/normal.diff
Normal file
|
@ -0,0 +1,12 @@
|
|||
1,2d0
|
||||
< The Way that can be told of is not the eternal Way;
|
||||
< The name that can be named is not the eternal name.
|
||||
4c2,3
|
||||
< The Named is the mother of all things.
|
||||
---
|
||||
> The named is the mother of all things.
|
||||
>
|
||||
11a11,13
|
||||
> They both may be called deep and profound.
|
||||
> Deeper and more profound,
|
||||
> The door of all subtleties!
|
849
kompare/tests/diff/normalm.diff
Normal file
|
@ -0,0 +1,849 @@
|
|||
diff -r dcop/client/dcop.cpp dcop2/client/dcop.cpp
|
||||
23c23,26
|
||||
< #include <qvariant.h>
|
||||
---
|
||||
> #include <ctype.h>
|
||||
> #include <stdio.h>
|
||||
> #include <stdlib.h>
|
||||
>
|
||||
25c28,39
|
||||
< #include "../kdatastream.h"
|
||||
---
|
||||
> #include <qdir.h>
|
||||
> #include <qfile.h>
|
||||
> #include <qfileinfo.h>
|
||||
> #include <qmap.h>
|
||||
> #include <qstringlist.h>
|
||||
> #include <qtextstream.h>
|
||||
> #include <qvariant.h>
|
||||
>
|
||||
> // putenv() is not available on all platforms, so make sure the emulation
|
||||
> // wrapper is available in those cases by loading config.h!
|
||||
> #include <config.h>
|
||||
>
|
||||
28,30c42
|
||||
< #include <stdlib.h>
|
||||
< #include <stdio.h>
|
||||
< #include <ctype.h>
|
||||
---
|
||||
> #include "../kdatastream.h"
|
||||
33a46,47
|
||||
> typedef QMap<QString, QString> UserList;
|
||||
>
|
||||
35a50,63
|
||||
> static QTextStream cout( stdout, IO_WriteOnly );
|
||||
> static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
>
|
||||
> /**
|
||||
> * Session to send call to
|
||||
> * DefaultSession - current session. Current KDE session when called without
|
||||
> * --user or --all-users option. Otherwise this value ignores
|
||||
> * all users with more than one active session.
|
||||
> * AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
> * QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
> * CustomSession - Use the specified session
|
||||
> */
|
||||
> enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
>
|
||||
121c149
|
||||
< void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
---
|
||||
> void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
123d150
|
||||
<
|
||||
139c166
|
||||
< if ( !ok && argc == 0 )
|
||||
---
|
||||
> if ( !ok && args.isEmpty() )
|
||||
156,157c183,184
|
||||
< int a = (*it).contains(',');
|
||||
< if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
|
||||
---
|
||||
> uint a = (*it).contains(',');
|
||||
> if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
164c191,192
|
||||
< exit(1);
|
||||
---
|
||||
> // exit(1);
|
||||
> return;
|
||||
246,250c274,279
|
||||
< int i = 0;
|
||||
< for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
< marshall(arg, argc, args, i, *it);
|
||||
< }
|
||||
< if ( i != argc ) {
|
||||
---
|
||||
> uint i = 0;
|
||||
> for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
> marshall( arg, args, i, *it );
|
||||
>
|
||||
> if ( i != args.count() )
|
||||
> {
|
||||
268a298,324
|
||||
> /**
|
||||
> * Show command-line help and exit
|
||||
> */
|
||||
> void showHelp( int exitCode = 0 )
|
||||
> {
|
||||
> cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
> << "" << endl
|
||||
> << "Console DCOP client" << endl
|
||||
> << "" << endl
|
||||
> << "Generic options:" << endl
|
||||
> << " --help Show help about options" << endl
|
||||
> << "" << endl
|
||||
> << "Options:" << endl
|
||||
> << " --pipe Call DCOP for each line read from stdin" << endl
|
||||
> << " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
> << " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
> << " $ICEAUTHORITY, even if they are set." << endl
|
||||
> << " If the user has more than one open session, you must also" << endl
|
||||
> << " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
> << " command-line options." << endl
|
||||
> << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
> << " server. Only failed calls to existing DCOP servers will"
|
||||
> << " generate an error message. If no DCOP server is available" << endl
|
||||
> << " at all, no error will be generated." << endl;
|
||||
>
|
||||
> exit( exitCode );
|
||||
> }
|
||||
270,271c326,330
|
||||
<
|
||||
< int main( int argc, char** argv )
|
||||
---
|
||||
> /**
|
||||
> * Return a list of all users and their home directories.
|
||||
> * Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
> */
|
||||
> static UserList userList()
|
||||
272a332,340
|
||||
> UserList result;
|
||||
>
|
||||
> QFile f( "/etc/passwd" );
|
||||
>
|
||||
> if( !f.open( IO_ReadOnly ) )
|
||||
> {
|
||||
> cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
> return result;
|
||||
> }
|
||||
274,276c342,347
|
||||
< if ( argc > 1 && argv[1][0] == '-' ) {
|
||||
< fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
|
||||
< exit(0);
|
||||
---
|
||||
> QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
>
|
||||
> for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
> {
|
||||
> QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
> result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
279,281c350,391
|
||||
< DCOPClient client;
|
||||
< client.attach();
|
||||
< dcop = &client;
|
||||
---
|
||||
> return result;
|
||||
> }
|
||||
>
|
||||
> /**
|
||||
> * Return a list of available DCOP sessions for the specified user
|
||||
> * An empty list means no sessions are available, or an error occurred.
|
||||
> */
|
||||
> QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
> {
|
||||
> if( home.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Cannot determine home directory for user "
|
||||
> << user << "!" << endl
|
||||
> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> return QStringList();
|
||||
> }
|
||||
>
|
||||
> QStringList result;
|
||||
> QFileInfo dirInfo( home );
|
||||
> if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
> return result;
|
||||
>
|
||||
> QDir d( home );
|
||||
> d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
> d.setNameFilter( ".DCOPserver*" );
|
||||
>
|
||||
> const QFileInfoList *list = d.entryInfoList();
|
||||
> if( !list )
|
||||
> return result;
|
||||
>
|
||||
> QFileInfoListIterator it( *list );
|
||||
> QFileInfo *fi;
|
||||
>
|
||||
> while ( ( fi = it.current() ) != 0 )
|
||||
> {
|
||||
> if( fi->isReadable() )
|
||||
> result.append( fi->fileName() );
|
||||
> ++it;
|
||||
> }
|
||||
> return result;
|
||||
> }
|
||||
282a393,398
|
||||
> /**
|
||||
> * Do the actual DCOP call
|
||||
> */
|
||||
> void runDCOP( QCStringList args, UserList users, Session session,
|
||||
> const QString sessionName, bool readStdin )
|
||||
> {
|
||||
286,287c402,404
|
||||
< char **args = 0;
|
||||
< if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
|
||||
---
|
||||
> QCStringList params;
|
||||
> DCOPClient *client = 0L;
|
||||
> if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
289,304c406,429
|
||||
< char *delim = strchr(argv[1], ',');
|
||||
< if (!delim)
|
||||
< {
|
||||
< fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
|
||||
< return 1;
|
||||
< }
|
||||
< *delim = 0;
|
||||
< app = argv[1] + 8;
|
||||
< delim++;
|
||||
< delim[strlen(delim)-1] = 0;
|
||||
< objid = delim;
|
||||
< if (argc > 2)
|
||||
< function = argv[2];
|
||||
< if (argc > 3)
|
||||
< args = &argv[3];
|
||||
< argc++;
|
||||
---
|
||||
> // WARNING: This part (until the closing '}') could very
|
||||
> // well be broken now. As I don't know how to trigger and test
|
||||
> // dcoprefs this code is *not* tested. It compiles and it looks
|
||||
> // ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
> int delimPos = args[ 0 ].findRev( ',' );
|
||||
> if( delimPos == -1 )
|
||||
> {
|
||||
> cerr << "Error: '" << args[ 0 ]
|
||||
> << "' is not a valid DCOP reference." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> args[ 0 ][ delimPos ] = 0;
|
||||
> app = args[ 0 ].mid( 8 );
|
||||
> delimPos++;
|
||||
> args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
> objid = args[ 0 ].mid( delimPos );
|
||||
> if( args.count() > 1 )
|
||||
> function = args[ 1 ];
|
||||
> if( args.count() > 2 )
|
||||
> {
|
||||
> params = args;
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> }
|
||||
308,338c433,516
|
||||
< if (argc > 1)
|
||||
< app = argv[1];
|
||||
< if (argc > 2)
|
||||
< objid = argv[2];
|
||||
< if (argc > 3)
|
||||
< function = argv[3];
|
||||
< if (argc > 4)
|
||||
< args = &argv[4];
|
||||
< }
|
||||
<
|
||||
< switch ( argc ) {
|
||||
< case 0:
|
||||
< case 1:
|
||||
< queryApplications("");
|
||||
< break;
|
||||
< case 2:
|
||||
< if (endsWith(app, '*'))
|
||||
< queryApplications(app);
|
||||
< else
|
||||
< queryObjects( app, "" );
|
||||
< break;
|
||||
< case 3:
|
||||
< if (endsWith(objid, '*'))
|
||||
< queryObjects(app, objid);
|
||||
< else
|
||||
< queryFunctions( app, objid );
|
||||
< break;
|
||||
< case 4:
|
||||
< default:
|
||||
< callFunction( app, objid, function, argc - 4, args );
|
||||
< break;
|
||||
---
|
||||
> if( !args.isEmpty() )
|
||||
> app = args[ 0 ];
|
||||
> if( args.count() > 1 )
|
||||
> objid = args[ 1 ];
|
||||
> if( args.count() > 2 )
|
||||
> function = args[ 2 ];
|
||||
> if( args.count() > 3)
|
||||
> {
|
||||
> params = args;
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> params.remove( params.begin() );
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> bool firstRun = true;
|
||||
> UserList::Iterator it;
|
||||
> QStringList sessions;
|
||||
> bool presetDCOPServer = false;
|
||||
> // char *dcopStr = 0L;
|
||||
> QString dcopServer;
|
||||
>
|
||||
> for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
> {
|
||||
> firstRun = false;
|
||||
>
|
||||
> //cout << "Iterating '" << it.key() << "'" << endl;
|
||||
>
|
||||
> if( session == QuerySessions )
|
||||
> {
|
||||
> QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
> if( sessions.isEmpty() )
|
||||
> {
|
||||
> cout << "No active sessions";
|
||||
> if( !( *it ).isEmpty() )
|
||||
> cout << " for user " << *it;
|
||||
> cout << endl;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cout << "Active sessions ";
|
||||
> if( !( *it ).isEmpty() )
|
||||
> cout << "for user " << *it << " ";
|
||||
> cout << ":" << endl;
|
||||
>
|
||||
> QStringList::Iterator sIt;
|
||||
> for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
> cout << " " << *sIt << endl;
|
||||
>
|
||||
> cout << endl;
|
||||
> }
|
||||
> continue;
|
||||
> }
|
||||
>
|
||||
> if( getenv( "DCOPSERVER" ) )
|
||||
> {
|
||||
> sessions.append( getenv( "DCOPSERVER" ) );
|
||||
> presetDCOPServer = true;
|
||||
> }
|
||||
>
|
||||
> if( users.count() > 1 || ( users.count() == 1 &&
|
||||
> ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
> {
|
||||
> sessions = dcopSessionList( it.key(), it.data() );
|
||||
> if( sessions.isEmpty() )
|
||||
> {
|
||||
> if( users.count() > 1 )
|
||||
> continue;
|
||||
> else
|
||||
> {
|
||||
> cerr << "ERROR: No active KDE sessions!" << endl
|
||||
> << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
> << "before calling dcop." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
> else if( sessions.count() > 1 && session != AllSessions )
|
||||
> {
|
||||
> cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
> << "Please specify the correct session to use with --session or use the" << endl
|
||||
> << "--all-sessions option to broadcast to all sessions." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
339a518,660
|
||||
> if( users.count() > 1 || ( users.count() == 1 &&
|
||||
> ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
> {
|
||||
> // Check for ICE authority file and if the file can be read by us
|
||||
> QString home = it.data();
|
||||
> QString iceFile = it.data() + "/.ICEauthority";
|
||||
> QFileInfo fi( iceFile );
|
||||
> if( iceFile.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Cannot determine home directory for user "
|
||||
> << it.key() << "!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> else if( fi.exists() )
|
||||
> {
|
||||
> if( fi.isReadable() )
|
||||
> {
|
||||
> char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
> putenv( envStr );
|
||||
> //cerr << "ice: " << envStr << endl;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cerr << "WARNING: ICE authority file " << iceFile
|
||||
> << "is not readable by you!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> if( users.count() > 1 )
|
||||
> continue;
|
||||
> else
|
||||
> {
|
||||
> cerr << "WARNING: Cannot find ICE authority file "
|
||||
> << iceFile << "!" << endl
|
||||
> << "Please check permissions or set the $ICEAUTHORITY"
|
||||
> << " variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> }
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> // Main loop
|
||||
> // If users is an empty list we're calling for the currently logged
|
||||
> // in user. In this case we don't have a session, but still want
|
||||
> // to iterate the loop once.
|
||||
> QStringList::Iterator sIt = sessions.begin();
|
||||
> for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
> {
|
||||
> if( !presetDCOPServer && !users.isEmpty() )
|
||||
> {
|
||||
> QString dcopFile = it.data() + "/" + *sIt;
|
||||
> QFile f( dcopFile );
|
||||
> if( !f.open( IO_ReadOnly ) )
|
||||
> {
|
||||
> cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
>
|
||||
> QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
> dcopServer = l.first();
|
||||
>
|
||||
> if( dcopServer.isEmpty() )
|
||||
> {
|
||||
> cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
> << *sIt << "!" << endl
|
||||
> << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
> << "calling dcop." << endl;
|
||||
> exit( -1 );
|
||||
> }
|
||||
> }
|
||||
>
|
||||
> delete client;
|
||||
> client = new DCOPClient;
|
||||
> if( !dcopServer.isEmpty() )
|
||||
> client->setServerAddress( dcopServer.ascii() );
|
||||
> bool success = client->attach();
|
||||
> if( !success )
|
||||
> {
|
||||
> cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
> continue;
|
||||
> }
|
||||
> dcop = client;
|
||||
>
|
||||
> switch ( args.count() )
|
||||
> {
|
||||
> case 0:
|
||||
> queryApplications("");
|
||||
> break;
|
||||
> case 1:
|
||||
> if (endsWith(app, '*'))
|
||||
> queryApplications(app);
|
||||
> else
|
||||
> queryObjects( app, "" );
|
||||
> break;
|
||||
> case 2:
|
||||
> if (endsWith(objid, '*'))
|
||||
> queryObjects(app, objid);
|
||||
> else
|
||||
> queryFunctions( app, objid );
|
||||
> break;
|
||||
> case 3:
|
||||
> default:
|
||||
> if( readStdin )
|
||||
> {
|
||||
> QCStringList::Iterator replaceArg = args.end();
|
||||
>
|
||||
> QCStringList::Iterator it;
|
||||
> for( it = args.begin(); it != args.end(); it++ )
|
||||
> if( *it == "%1" )
|
||||
> replaceArg = it;
|
||||
>
|
||||
> // Read from stdin until EOF and call function for each line read
|
||||
> char *buf = new char[ 1000 ];
|
||||
> while ( !feof( stdin ) )
|
||||
> {
|
||||
> fgets( buf, 1000, stdin );
|
||||
>
|
||||
> if( replaceArg != args.end() )
|
||||
> *replaceArg = buf;
|
||||
>
|
||||
> callFunction( app, objid, function, params );
|
||||
> }
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> // Just call function
|
||||
> // cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
> callFunction( app, objid, function, params );
|
||||
> }
|
||||
> break;
|
||||
> }
|
||||
> // Another sIt++ would make the loop infinite...
|
||||
> if( users.isEmpty() )
|
||||
> break;
|
||||
> }
|
||||
>
|
||||
> // Another it++ would make the loop infinite...
|
||||
> if( it == users.end() )
|
||||
> break;
|
||||
340a662,767
|
||||
> }
|
||||
>
|
||||
>
|
||||
> int main( int argc, char** argv )
|
||||
> {
|
||||
> bool readStdin = false;
|
||||
> int numOptions = 0;
|
||||
> QString user;
|
||||
> Session session = DefaultSession;
|
||||
> QString sessionName;
|
||||
>
|
||||
> // Scan for command-line options first
|
||||
> for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
> {
|
||||
> if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
> showHelp( 0 );
|
||||
> else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
> {
|
||||
> readStdin = true;
|
||||
> numOptions++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
> {
|
||||
> if( pos <= argc - 2 )
|
||||
> {
|
||||
> user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
> numOptions +=2;
|
||||
> pos++;
|
||||
> }
|
||||
> else
|
||||
> {
|
||||
> cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
> {
|
||||
> user = "*";
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
> {
|
||||
> session = QuerySessions;
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
> {
|
||||
> session = AllSessions;
|
||||
> numOptions ++;
|
||||
> }
|
||||
> else if( argv[ pos ][ 0 ] == '-' )
|
||||
> {
|
||||
> cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
> << "'." << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
> else
|
||||
> break; // End of options
|
||||
> }
|
||||
>
|
||||
> argc -= numOptions;
|
||||
>
|
||||
> QCStringList args;
|
||||
> for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
> args.append( argv[ i + 1 ] );
|
||||
>
|
||||
> if( readStdin && args.count() < 3 )
|
||||
> {
|
||||
> cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
> {
|
||||
> cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session == QuerySessions && !args.isEmpty() )
|
||||
> {
|
||||
> cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session == QuerySessions && user.isEmpty() )
|
||||
> {
|
||||
> cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
> << "--all-users options!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> if( session != DefaultSession && session != QuerySessions &&
|
||||
> args.count() < 3 )
|
||||
> {
|
||||
> cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
> << "calls!" << endl << endl;
|
||||
> showHelp( -1 );
|
||||
> }
|
||||
>
|
||||
> UserList users;
|
||||
> if( user == "*" )
|
||||
> users = userList();
|
||||
> else if( !user.isEmpty() )
|
||||
> users[ user ] = userList()[ user ];
|
||||
>
|
||||
> runDCOP( args, users, session, sessionName, readStdin );
|
||||
343a771,773
|
||||
>
|
||||
> // vim: set ts=8 sts=4 sw=4 noet:
|
||||
>
|
||||
diff -r dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
|
||||
39c39
|
||||
< bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
---
|
||||
> bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
121c121
|
||||
< if ( (int) types.count() != argc ) {
|
||||
---
|
||||
> if ( types.count() != args.count() ) {
|
||||
131c131
|
||||
< marshall(arg, argc, args, i, *it);
|
||||
---
|
||||
> marshall(arg, args, i, *it);
|
||||
133c133
|
||||
< if ( (int) i != argc ) {
|
||||
---
|
||||
> if ( (uint) i != args.count() ) {
|
||||
224c224,228
|
||||
< findObject( app, objid, function, argc, args );
|
||||
---
|
||||
> QCStringList params;
|
||||
> for( int i = 0; i < argc; i++ )
|
||||
> params.append( args[ i ] );
|
||||
>
|
||||
> findObject( app, objid, function, params );
|
||||
diff -r dcop/client/marshall.cpp dcop2/client/marshall.cpp
|
||||
245c245
|
||||
< void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
|
||||
---
|
||||
> void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
247,317c247,256
|
||||
< if (type == "QStringList")
|
||||
< type = "QValueList<QString>";
|
||||
< if (type == "QCStringList")
|
||||
< type = "QValueList<QCString>";
|
||||
< if (i >= argc)
|
||||
< {
|
||||
< qWarning("Not enough arguments.");
|
||||
< exit(1);
|
||||
< }
|
||||
< QString s = QString::fromLocal8Bit(argv[i]);
|
||||
<
|
||||
< if ( type == "int" )
|
||||
< arg << s.toInt();
|
||||
< else if ( type == "uint" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "unsigned" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "unsigned int" )
|
||||
< arg << s.toUInt();
|
||||
< else if ( type == "long" )
|
||||
< arg << s.toLong();
|
||||
< else if ( type == "long int" )
|
||||
< arg << s.toLong();
|
||||
< else if ( type == "unsigned long" )
|
||||
< arg << s.toULong();
|
||||
< else if ( type == "unsigned long int" )
|
||||
< arg << s.toULong();
|
||||
< else if ( type == "float" )
|
||||
< arg << s.toFloat();
|
||||
< else if ( type == "double" )
|
||||
< arg << s.toDouble();
|
||||
< else if ( type == "bool" )
|
||||
< arg << mkBool( s );
|
||||
< else if ( type == "QString" )
|
||||
< arg << s;
|
||||
< else if ( type == "QCString" )
|
||||
< arg << QCString( argv[i] );
|
||||
< else if ( type == "QColor" )
|
||||
< arg << mkColor( s );
|
||||
< else if ( type == "QPoint" )
|
||||
< arg << mkPoint( s );
|
||||
< else if ( type == "QSize" )
|
||||
< arg << mkSize( s );
|
||||
< else if ( type == "QRect" )
|
||||
< arg << mkRect( s );
|
||||
< else if ( type == "QVariant" ) {
|
||||
< if ( s == "true" || s == "false" )
|
||||
< arg << QVariant( mkBool( s ), 42 );
|
||||
< else if ( s.left( 4 ) == "int(" )
|
||||
< arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
< else if ( s.left( 7 ) == "QPoint(" )
|
||||
< arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
< else if ( s.left( 6 ) == "QSize(" )
|
||||
< arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
< else if ( s.left( 6 ) == "QRect(" )
|
||||
< arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
< else if ( s.left( 7 ) == "QColor(" )
|
||||
< arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
< else
|
||||
< arg << QVariant( s );
|
||||
< } else if ( type.startsWith("QValueList<")) {
|
||||
< type = type.mid(11, type.length() - 12);
|
||||
< QStringList list;
|
||||
< QString delim = s;
|
||||
< if (delim == "[")
|
||||
< delim = "]";
|
||||
< if (delim == "(")
|
||||
< delim = ")";
|
||||
< i++;
|
||||
< QByteArray dummy_data;
|
||||
< QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
---
|
||||
> if (type == "QStringList")
|
||||
> type = "QValueList<QString>";
|
||||
> if (type == "QCStringList")
|
||||
> type = "QValueList<QCString>";
|
||||
> if( i > args.count() )
|
||||
> {
|
||||
> qWarning("Not enough arguments.");
|
||||
> exit(1);
|
||||
> }
|
||||
> QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
319,346c258,314
|
||||
< int j = i;
|
||||
< int count = 0;
|
||||
< // Parse list to get the count
|
||||
< while (true) {
|
||||
< if (j >= argc)
|
||||
< {
|
||||
< qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
< exit(1);
|
||||
< }
|
||||
< if (argv[j] == delim) break;
|
||||
< marshall(dummy_arg, argc, argv, j, type);
|
||||
< count++;
|
||||
< }
|
||||
< arg << (Q_UINT32) count;
|
||||
< // Parse the list for real
|
||||
< while (true) {
|
||||
< if (i >= argc)
|
||||
< {
|
||||
< qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
< exit(1);
|
||||
< }
|
||||
< if (argv[i] == delim) break;
|
||||
< marshall(arg, argc, argv, i, type);
|
||||
< }
|
||||
< } else {
|
||||
< qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
< exit(1);
|
||||
< }
|
||||
---
|
||||
> if ( type == "int" )
|
||||
> arg << s.toInt();
|
||||
> else if ( type == "uint" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "unsigned" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "unsigned int" )
|
||||
> arg << s.toUInt();
|
||||
> else if ( type == "long" )
|
||||
> arg << s.toLong();
|
||||
> else if ( type == "long int" )
|
||||
> arg << s.toLong();
|
||||
> else if ( type == "unsigned long" )
|
||||
> arg << s.toULong();
|
||||
> else if ( type == "unsigned long int" )
|
||||
> arg << s.toULong();
|
||||
> else if ( type == "float" )
|
||||
> arg << s.toFloat();
|
||||
> else if ( type == "double" )
|
||||
> arg << s.toDouble();
|
||||
> else if ( type == "bool" )
|
||||
> arg << mkBool( s );
|
||||
> else if ( type == "QString" )
|
||||
> arg << s;
|
||||
> else if ( type == "QCString" )
|
||||
> arg << QCString( args[ i ] );
|
||||
> else if ( type == "QColor" )
|
||||
> arg << mkColor( s );
|
||||
> else if ( type == "QPoint" )
|
||||
> arg << mkPoint( s );
|
||||
> else if ( type == "QSize" )
|
||||
> arg << mkSize( s );
|
||||
> else if ( type == "QRect" )
|
||||
> arg << mkRect( s );
|
||||
> else if ( type == "QVariant" ) {
|
||||
> if ( s == "true" || s == "false" )
|
||||
> arg << QVariant( mkBool( s ), 42 );
|
||||
> else if ( s.left( 4 ) == "int(" )
|
||||
> arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
> else if ( s.left( 7 ) == "QPoint(" )
|
||||
> arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
> else if ( s.left( 6 ) == "QSize(" )
|
||||
> arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
> else if ( s.left( 6 ) == "QRect(" )
|
||||
> arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
> else if ( s.left( 7 ) == "QColor(" )
|
||||
> arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
> else
|
||||
> arg << QVariant( s );
|
||||
> } else if ( type.startsWith("QValueList<")) {
|
||||
> type = type.mid(11, type.length() - 12);
|
||||
> QStringList list;
|
||||
> QString delim = s;
|
||||
> if (delim == "[")
|
||||
> delim = "]";
|
||||
> if (delim == "(")
|
||||
> delim = ")";
|
||||
347a316,349
|
||||
> QByteArray dummy_data;
|
||||
> QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
>
|
||||
> uint j = i;
|
||||
> uint count = 0;
|
||||
> // Parse list to get the count
|
||||
> while (true) {
|
||||
> if( j > args.count() )
|
||||
> {
|
||||
> qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
> exit(1);
|
||||
> }
|
||||
> if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
> break;
|
||||
> marshall( dummy_arg, args, j, type );
|
||||
> count++;
|
||||
> }
|
||||
> arg << (Q_UINT32) count;
|
||||
> // Parse the list for real
|
||||
> while (true) {
|
||||
> if( i > args.count() )
|
||||
> {
|
||||
> qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
> exit(1);
|
||||
> }
|
||||
> if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
> break;
|
||||
> marshall( arg, args, i, type );
|
||||
> }
|
||||
> } else {
|
||||
> qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
> exit(1);
|
||||
> }
|
||||
> i++;
|
9
kompare/tests/diff/rcs.diff
Normal file
|
@ -0,0 +1,9 @@
|
|||
d1 2
|
||||
d4 1
|
||||
a4 2
|
||||
The named is the mother of all things.
|
||||
|
||||
a11 3
|
||||
They both may be called deep and profound.
|
||||
Deeper and more profound,
|
||||
The door of all subtleties!
|
671
kompare/tests/diff/rcsm.diff
Normal file
|
@ -0,0 +1,671 @@
|
|||
diff -nr dcop/client/dcop.cpp dcop2/client/dcop.cpp
|
||||
d23 1
|
||||
a23 4
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
d25 1
|
||||
a25 12
|
||||
#include <qdir.h>
|
||||
#include <qfile.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qmap.h>
|
||||
#include <qstringlist.h>
|
||||
#include <qtextstream.h>
|
||||
#include <qvariant.h>
|
||||
|
||||
// putenv() is not available on all platforms, so make sure the emulation
|
||||
// wrapper is available in those cases by loading config.h!
|
||||
#include <config.h>
|
||||
|
||||
d28 3
|
||||
a30 1
|
||||
#include "../kdatastream.h"
|
||||
a33 2
|
||||
typedef QMap<QString, QString> UserList;
|
||||
|
||||
a35 14
|
||||
static QTextStream cout( stdout, IO_WriteOnly );
|
||||
static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
|
||||
/**
|
||||
* Session to send call to
|
||||
* DefaultSession - current session. Current KDE session when called without
|
||||
* --user or --all-users option. Otherwise this value ignores
|
||||
* all users with more than one active session.
|
||||
* AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
* QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
* CustomSession - Use the specified session
|
||||
*/
|
||||
enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
|
||||
d121 1
|
||||
a121 1
|
||||
void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
d123 1
|
||||
d139 1
|
||||
a139 1
|
||||
if ( !ok && args.isEmpty() )
|
||||
d156 2
|
||||
a157 2
|
||||
uint a = (*it).contains(',');
|
||||
if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
d164 1
|
||||
a164 2
|
||||
// exit(1);
|
||||
return;
|
||||
d246 5
|
||||
a250 6
|
||||
uint i = 0;
|
||||
for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
marshall( arg, args, i, *it );
|
||||
|
||||
if ( i != args.count() )
|
||||
{
|
||||
a268 27
|
||||
/**
|
||||
* Show command-line help and exit
|
||||
*/
|
||||
void showHelp( int exitCode = 0 )
|
||||
{
|
||||
cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
<< "" << endl
|
||||
<< "Console DCOP client" << endl
|
||||
<< "" << endl
|
||||
<< "Generic options:" << endl
|
||||
<< " --help Show help about options" << endl
|
||||
<< "" << endl
|
||||
<< "Options:" << endl
|
||||
<< " --pipe Call DCOP for each line read from stdin" << endl
|
||||
<< " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
<< " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
<< " $ICEAUTHORITY, even if they are set." << endl
|
||||
<< " If the user has more than one open session, you must also" << endl
|
||||
<< " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
<< " command-line options." << endl
|
||||
<< " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
<< " server. Only failed calls to existing DCOP servers will"
|
||||
<< " generate an error message. If no DCOP server is available" << endl
|
||||
<< " at all, no error will be generated." << endl;
|
||||
|
||||
exit( exitCode );
|
||||
}
|
||||
d270 2
|
||||
a271 5
|
||||
/**
|
||||
* Return a list of all users and their home directories.
|
||||
* Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
*/
|
||||
static UserList userList()
|
||||
a272 9
|
||||
UserList result;
|
||||
|
||||
QFile f( "/etc/passwd" );
|
||||
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
return result;
|
||||
}
|
||||
d274 3
|
||||
a276 6
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
|
||||
for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
{
|
||||
QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
d279 3
|
||||
a281 42
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a list of available DCOP sessions for the specified user
|
||||
* An empty list means no sessions are available, or an error occurred.
|
||||
*/
|
||||
QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
{
|
||||
if( home.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< user << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList result;
|
||||
QFileInfo dirInfo( home );
|
||||
if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
return result;
|
||||
|
||||
QDir d( home );
|
||||
d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
d.setNameFilter( ".DCOPserver*" );
|
||||
|
||||
const QFileInfoList *list = d.entryInfoList();
|
||||
if( !list )
|
||||
return result;
|
||||
|
||||
QFileInfoListIterator it( *list );
|
||||
QFileInfo *fi;
|
||||
|
||||
while ( ( fi = it.current() ) != 0 )
|
||||
{
|
||||
if( fi->isReadable() )
|
||||
result.append( fi->fileName() );
|
||||
++it;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
a282 6
|
||||
/**
|
||||
* Do the actual DCOP call
|
||||
*/
|
||||
void runDCOP( QCStringList args, UserList users, Session session,
|
||||
const QString sessionName, bool readStdin )
|
||||
{
|
||||
d286 2
|
||||
a287 3
|
||||
QCStringList params;
|
||||
DCOPClient *client = 0L;
|
||||
if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
d289 16
|
||||
a304 24
|
||||
// WARNING: This part (until the closing '}') could very
|
||||
// well be broken now. As I don't know how to trigger and test
|
||||
// dcoprefs this code is *not* tested. It compiles and it looks
|
||||
// ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
int delimPos = args[ 0 ].findRev( ',' );
|
||||
if( delimPos == -1 )
|
||||
{
|
||||
cerr << "Error: '" << args[ 0 ]
|
||||
<< "' is not a valid DCOP reference." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
args[ 0 ][ delimPos ] = 0;
|
||||
app = args[ 0 ].mid( 8 );
|
||||
delimPos++;
|
||||
args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
objid = args[ 0 ].mid( delimPos );
|
||||
if( args.count() > 1 )
|
||||
function = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
d308 31
|
||||
a338 84
|
||||
if( !args.isEmpty() )
|
||||
app = args[ 0 ];
|
||||
if( args.count() > 1 )
|
||||
objid = args[ 1 ];
|
||||
if( args.count() > 2 )
|
||||
function = args[ 2 ];
|
||||
if( args.count() > 3)
|
||||
{
|
||||
params = args;
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
params.remove( params.begin() );
|
||||
}
|
||||
}
|
||||
|
||||
bool firstRun = true;
|
||||
UserList::Iterator it;
|
||||
QStringList sessions;
|
||||
bool presetDCOPServer = false;
|
||||
// char *dcopStr = 0L;
|
||||
QString dcopServer;
|
||||
|
||||
for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
{
|
||||
firstRun = false;
|
||||
|
||||
//cout << "Iterating '" << it.key() << "'" << endl;
|
||||
|
||||
if( session == QuerySessions )
|
||||
{
|
||||
QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
cout << "No active sessions";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << " for user " << *it;
|
||||
cout << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << "Active sessions ";
|
||||
if( !( *it ).isEmpty() )
|
||||
cout << "for user " << *it << " ";
|
||||
cout << ":" << endl;
|
||||
|
||||
QStringList::Iterator sIt;
|
||||
for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
cout << " " << *sIt << endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if( getenv( "DCOPSERVER" ) )
|
||||
{
|
||||
sessions.append( getenv( "DCOPSERVER" ) );
|
||||
presetDCOPServer = true;
|
||||
}
|
||||
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
{
|
||||
sessions = dcopSessionList( it.key(), it.data() );
|
||||
if( sessions.isEmpty() )
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "ERROR: No active KDE sessions!" << endl
|
||||
<< "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
<< "before calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
else if( sessions.count() > 1 && session != AllSessions )
|
||||
{
|
||||
cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
<< "Please specify the correct session to use with --session or use the" << endl
|
||||
<< "--all-sessions option to broadcast to all sessions." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
a339 143
|
||||
if( users.count() > 1 || ( users.count() == 1 &&
|
||||
( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
{
|
||||
// Check for ICE authority file and if the file can be read by us
|
||||
QString home = it.data();
|
||||
QString iceFile = it.data() + "/.ICEauthority";
|
||||
QFileInfo fi( iceFile );
|
||||
if( iceFile.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Cannot determine home directory for user "
|
||||
<< it.key() << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
else if( fi.exists() )
|
||||
{
|
||||
if( fi.isReadable() )
|
||||
{
|
||||
char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
putenv( envStr );
|
||||
//cerr << "ice: " << envStr << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: ICE authority file " << iceFile
|
||||
<< "is not readable by you!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( users.count() > 1 )
|
||||
continue;
|
||||
else
|
||||
{
|
||||
cerr << "WARNING: Cannot find ICE authority file "
|
||||
<< iceFile << "!" << endl
|
||||
<< "Please check permissions or set the $ICEAUTHORITY"
|
||||
<< " variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Main loop
|
||||
// If users is an empty list we're calling for the currently logged
|
||||
// in user. In this case we don't have a session, but still want
|
||||
// to iterate the loop once.
|
||||
QStringList::Iterator sIt = sessions.begin();
|
||||
for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
{
|
||||
if( !presetDCOPServer && !users.isEmpty() )
|
||||
{
|
||||
QString dcopFile = it.data() + "/" + *sIt;
|
||||
QFile f( dcopFile );
|
||||
if( !f.open( IO_ReadOnly ) )
|
||||
{
|
||||
cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
dcopServer = l.first();
|
||||
|
||||
if( dcopServer.isEmpty() )
|
||||
{
|
||||
cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
<< *sIt << "!" << endl
|
||||
<< "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
<< "calling dcop." << endl;
|
||||
exit( -1 );
|
||||
}
|
||||
}
|
||||
|
||||
delete client;
|
||||
client = new DCOPClient;
|
||||
if( !dcopServer.isEmpty() )
|
||||
client->setServerAddress( dcopServer.ascii() );
|
||||
bool success = client->attach();
|
||||
if( !success )
|
||||
{
|
||||
cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
continue;
|
||||
}
|
||||
dcop = client;
|
||||
|
||||
switch ( args.count() )
|
||||
{
|
||||
case 0:
|
||||
queryApplications("");
|
||||
break;
|
||||
case 1:
|
||||
if (endsWith(app, '*'))
|
||||
queryApplications(app);
|
||||
else
|
||||
queryObjects( app, "" );
|
||||
break;
|
||||
case 2:
|
||||
if (endsWith(objid, '*'))
|
||||
queryObjects(app, objid);
|
||||
else
|
||||
queryFunctions( app, objid );
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
if( readStdin )
|
||||
{
|
||||
QCStringList::Iterator replaceArg = args.end();
|
||||
|
||||
QCStringList::Iterator it;
|
||||
for( it = args.begin(); it != args.end(); it++ )
|
||||
if( *it == "%1" )
|
||||
replaceArg = it;
|
||||
|
||||
// Read from stdin until EOF and call function for each line read
|
||||
char *buf = new char[ 1000 ];
|
||||
while ( !feof( stdin ) )
|
||||
{
|
||||
fgets( buf, 1000, stdin );
|
||||
|
||||
if( replaceArg != args.end() )
|
||||
*replaceArg = buf;
|
||||
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just call function
|
||||
// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
callFunction( app, objid, function, params );
|
||||
}
|
||||
break;
|
||||
}
|
||||
// Another sIt++ would make the loop infinite...
|
||||
if( users.isEmpty() )
|
||||
break;
|
||||
}
|
||||
|
||||
// Another it++ would make the loop infinite...
|
||||
if( it == users.end() )
|
||||
break;
|
||||
a340 106
|
||||
}
|
||||
|
||||
|
||||
int main( int argc, char** argv )
|
||||
{
|
||||
bool readStdin = false;
|
||||
int numOptions = 0;
|
||||
QString user;
|
||||
Session session = DefaultSession;
|
||||
QString sessionName;
|
||||
|
||||
// Scan for command-line options first
|
||||
for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
{
|
||||
if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
showHelp( 0 );
|
||||
else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
{
|
||||
readStdin = true;
|
||||
numOptions++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
{
|
||||
if( pos <= argc - 2 )
|
||||
{
|
||||
user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
numOptions +=2;
|
||||
pos++;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
{
|
||||
user = "*";
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
{
|
||||
session = QuerySessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
{
|
||||
session = AllSessions;
|
||||
numOptions ++;
|
||||
}
|
||||
else if( argv[ pos ][ 0 ] == '-' )
|
||||
{
|
||||
cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
<< "'." << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
else
|
||||
break; // End of options
|
||||
}
|
||||
|
||||
argc -= numOptions;
|
||||
|
||||
QCStringList args;
|
||||
for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
args.append( argv[ i + 1 ] );
|
||||
|
||||
if( readStdin && args.count() < 3 )
|
||||
{
|
||||
cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
{
|
||||
cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && !args.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session == QuerySessions && user.isEmpty() )
|
||||
{
|
||||
cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
<< "--all-users options!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
if( session != DefaultSession && session != QuerySessions &&
|
||||
args.count() < 3 )
|
||||
{
|
||||
cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
<< "calls!" << endl << endl;
|
||||
showHelp( -1 );
|
||||
}
|
||||
|
||||
UserList users;
|
||||
if( user == "*" )
|
||||
users = userList();
|
||||
else if( !user.isEmpty() )
|
||||
users[ user ] = userList()[ user ];
|
||||
|
||||
runDCOP( args, users, session, sessionName, readStdin );
|
||||
a343 3
|
||||
|
||||
// vim: set ts=8 sts=4 sw=4 noet:
|
||||
|
||||
diff -nr dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
|
||||
d39 1
|
||||
a39 1
|
||||
bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
d121 1
|
||||
a121 1
|
||||
if ( types.count() != args.count() ) {
|
||||
d131 1
|
||||
a131 1
|
||||
marshall(arg, args, i, *it);
|
||||
d133 1
|
||||
a133 1
|
||||
if ( (uint) i != args.count() ) {
|
||||
d224 1
|
||||
a224 5
|
||||
QCStringList params;
|
||||
for( int i = 0; i < argc; i++ )
|
||||
params.append( args[ i ] );
|
||||
|
||||
findObject( app, objid, function, params );
|
||||
diff -nr dcop/client/marshall.cpp dcop2/client/marshall.cpp
|
||||
d245 1
|
||||
a245 1
|
||||
void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
d247 71
|
||||
a317 10
|
||||
if (type == "QStringList")
|
||||
type = "QValueList<QString>";
|
||||
if (type == "QCStringList")
|
||||
type = "QValueList<QCString>";
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("Not enough arguments.");
|
||||
exit(1);
|
||||
}
|
||||
QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
d319 28
|
||||
a346 57
|
||||
if ( type == "int" )
|
||||
arg << s.toInt();
|
||||
else if ( type == "uint" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "unsigned int" )
|
||||
arg << s.toUInt();
|
||||
else if ( type == "long" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "long int" )
|
||||
arg << s.toLong();
|
||||
else if ( type == "unsigned long" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "unsigned long int" )
|
||||
arg << s.toULong();
|
||||
else if ( type == "float" )
|
||||
arg << s.toFloat();
|
||||
else if ( type == "double" )
|
||||
arg << s.toDouble();
|
||||
else if ( type == "bool" )
|
||||
arg << mkBool( s );
|
||||
else if ( type == "QString" )
|
||||
arg << s;
|
||||
else if ( type == "QCString" )
|
||||
arg << QCString( args[ i ] );
|
||||
else if ( type == "QColor" )
|
||||
arg << mkColor( s );
|
||||
else if ( type == "QPoint" )
|
||||
arg << mkPoint( s );
|
||||
else if ( type == "QSize" )
|
||||
arg << mkSize( s );
|
||||
else if ( type == "QRect" )
|
||||
arg << mkRect( s );
|
||||
else if ( type == "QVariant" ) {
|
||||
if ( s == "true" || s == "false" )
|
||||
arg << QVariant( mkBool( s ), 42 );
|
||||
else if ( s.left( 4 ) == "int(" )
|
||||
arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
else if ( s.left( 7 ) == "QPoint(" )
|
||||
arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
else if ( s.left( 6 ) == "QSize(" )
|
||||
arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 6 ) == "QRect(" )
|
||||
arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
else if ( s.left( 7 ) == "QColor(" )
|
||||
arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
else
|
||||
arg << QVariant( s );
|
||||
} else if ( type.startsWith("QValueList<")) {
|
||||
type = type.mid(11, type.length() - 12);
|
||||
QStringList list;
|
||||
QString delim = s;
|
||||
if (delim == "[")
|
||||
delim = "]";
|
||||
if (delim == "(")
|
||||
delim = ")";
|
||||
a347 34
|
||||
QByteArray dummy_data;
|
||||
QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
|
||||
uint j = i;
|
||||
uint count = 0;
|
||||
// Parse list to get the count
|
||||
while (true) {
|
||||
if( j > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
break;
|
||||
marshall( dummy_arg, args, j, type );
|
||||
count++;
|
||||
}
|
||||
arg << (Q_UINT32) count;
|
||||
// Parse the list for real
|
||||
while (true) {
|
||||
if( i > args.count() )
|
||||
{
|
||||
qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
exit(1);
|
||||
}
|
||||
if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
break;
|
||||
marshall( arg, args, i, type );
|
||||
}
|
||||
} else {
|
||||
qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
exit(1);
|
||||
}
|
||||
i++;
|
19
kompare/tests/diff/unified.diff
Normal file
|
@ -0,0 +1,19 @@
|
|||
--- /home/John/lao Thu Apr 12 11:09:30 2001
|
||||
+++ /home/John/tzu Sat Jul 28 13:23:25 2001
|
||||
@@ -1,7 +1,6 @@
|
||||
-The Way that can be told of is not the eternal Way;
|
||||
-The name that can be named is not the eternal name.
|
||||
The Nameless is the origin of Heaven and Earth;
|
||||
-The Named is the mother of all things.
|
||||
+The named is the mother of all things.
|
||||
+
|
||||
Therefore let there always be non-being,
|
||||
so we may see their subtlety,
|
||||
And let there always be being,
|
||||
@@ -9,3 +8,6 @@
|
||||
The two are the same,
|
||||
But after they are produced,
|
||||
they have different names.
|
||||
+They both may be called deep and profound.
|
||||
+Deeper and more profound,
|
||||
+The door of all subtleties!
|
911
kompare/tests/diff/unifiedm.diff
Normal file
|
@ -0,0 +1,911 @@
|
|||
diff -aur dcop/client/dcop.cpp dcop2/client/dcop.cpp
|
||||
--- dcop/client/dcop.cpp Wed Jan 30 22:38:07 2002
|
||||
+++ dcop2/client/dcop.cpp Wed Jan 30 22:37:04 2002
|
||||
@@ -20,19 +20,47 @@
|
||||
|
||||
******************************************************************/
|
||||
|
||||
-#include <qvariant.h>
|
||||
+#include <ctype.h>
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
#include <qcolor.h>
|
||||
-#include "../kdatastream.h"
|
||||
+#include <qdir.h>
|
||||
+#include <qfile.h>
|
||||
+#include <qfileinfo.h>
|
||||
+#include <qmap.h>
|
||||
+#include <qstringlist.h>
|
||||
+#include <qtextstream.h>
|
||||
+#include <qvariant.h>
|
||||
+
|
||||
+// putenv() is not available on all platforms, so make sure the emulation
|
||||
+// wrapper is available in those cases by loading config.h!
|
||||
+#include <config.h>
|
||||
+
|
||||
#include "../dcopclient.h"
|
||||
#include "../dcopref.h"
|
||||
-#include <stdlib.h>
|
||||
-#include <stdio.h>
|
||||
-#include <ctype.h>
|
||||
+#include "../kdatastream.h"
|
||||
|
||||
#include "marshall.cpp"
|
||||
|
||||
+typedef QMap<QString, QString> UserList;
|
||||
+
|
||||
static DCOPClient* dcop = 0;
|
||||
|
||||
+static QTextStream cout( stdout, IO_WriteOnly );
|
||||
+static QTextStream cerr( stderr, IO_WriteOnly );
|
||||
+
|
||||
+/**
|
||||
+ * Session to send call to
|
||||
+ * DefaultSession - current session. Current KDE session when called without
|
||||
+ * --user or --all-users option. Otherwise this value ignores
|
||||
+ * all users with more than one active session.
|
||||
+ * AllSessions - Send to all sessions found. requires --user or --all-users.
|
||||
+ * QuerySessions - Don't call DCOP, return a list of available sessions.
|
||||
+ * CustomSession - Use the specified session
|
||||
+ */
|
||||
+enum Session { DefaultSession = 0, AllSessions, QuerySessions, CustomSession };
|
||||
+
|
||||
bool startsWith(const QCString &id, const char *str, int n)
|
||||
{
|
||||
return !n || (strncmp(id.data(), str, n) == 0);
|
||||
@@ -118,9 +146,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
-void callFunction( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
+void callFunction( const char* app, const char* obj, const char* func, const QCStringList args )
|
||||
{
|
||||
-
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
int right = f.find( ')' );
|
||||
@@ -136,7 +163,7 @@
|
||||
bool ok = false;
|
||||
QCStringList funcs = dcop->remoteFunctions( app, obj, &ok );
|
||||
QCString realfunc;
|
||||
- if ( !ok && argc == 0 )
|
||||
+ if ( !ok && args.isEmpty() )
|
||||
goto doit;
|
||||
if ( !ok )
|
||||
{
|
||||
@@ -153,15 +180,16 @@
|
||||
|
||||
if ( l > 0 && (*it).mid( s, l - s ) == func ) {
|
||||
realfunc = (*it).mid( s );
|
||||
- int a = (*it).contains(',');
|
||||
- if ( ( a == 0 && argc == 0) || ( a > 0 && a + 1 == argc ) )
|
||||
+ uint a = (*it).contains(',');
|
||||
+ if ( ( a == 0 && args.isEmpty() ) || ( a > 0 && a + 1 == args.count() ) )
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( realfunc.isEmpty() )
|
||||
{
|
||||
qWarning("no such function");
|
||||
- exit(1);
|
||||
+// exit(1);
|
||||
+ return;
|
||||
}
|
||||
f = realfunc;
|
||||
left = f.find( '(' );
|
||||
@@ -243,11 +271,12 @@
|
||||
QCString replyType;
|
||||
QDataStream arg(data, IO_WriteOnly);
|
||||
|
||||
- int i = 0;
|
||||
- for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
- marshall(arg, argc, args, i, *it);
|
||||
- }
|
||||
- if ( i != argc ) {
|
||||
+ uint i = 0;
|
||||
+ for( QStringList::Iterator it = types.begin(); it != types.end(); ++it )
|
||||
+ marshall( arg, args, i, *it );
|
||||
+
|
||||
+ if ( i != args.count() )
|
||||
+ {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -266,78 +295,479 @@
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * Show command-line help and exit
|
||||
+ */
|
||||
+void showHelp( int exitCode = 0 )
|
||||
+{
|
||||
+ cout << "Usage: dcop [options] [application [object [function [arg1] [arg2] ... ] ] ]" << endl
|
||||
+ << "" << endl
|
||||
+ << "Console DCOP client" << endl
|
||||
+ << "" << endl
|
||||
+ << "Generic options:" << endl
|
||||
+ << " --help Show help about options" << endl
|
||||
+ << "" << endl
|
||||
+ << "Options:" << endl
|
||||
+ << " --pipe Call DCOP for each line read from stdin" << endl
|
||||
+ << " --user <user> Connect to the given user's DCOP server. This option will" << endl
|
||||
+ << " ignore the values of the environment vars $DCOPSERVER and" << endl
|
||||
+ << " $ICEAUTHORITY, even if they are set." << endl
|
||||
+ << " If the user has more than one open session, you must also" << endl
|
||||
+ << " use one of the --list-sessions, --session or --als-sessions" << endl
|
||||
+ << " command-line options." << endl
|
||||
+ << " --all-users Send the same DCOP call to all users with a running DCOP" << endl
|
||||
+ << " server. Only failed calls to existing DCOP servers will"
|
||||
+ << " generate an error message. If no DCOP server is available" << endl
|
||||
+ << " at all, no error will be generated." << endl;
|
||||
+
|
||||
+ exit( exitCode );
|
||||
+}
|
||||
|
||||
-
|
||||
-int main( int argc, char** argv )
|
||||
+/**
|
||||
+ * Return a list of all users and their home directories.
|
||||
+ * Returns an empty list if /etc/passwd cannot be read for some reason.
|
||||
+ */
|
||||
+static UserList userList()
|
||||
{
|
||||
+ UserList result;
|
||||
+
|
||||
+ QFile f( "/etc/passwd" );
|
||||
+
|
||||
+ if( !f.open( IO_ReadOnly ) )
|
||||
+ {
|
||||
+ cerr << "Can't open /etc/passwd for reading!" << endl;
|
||||
+ return result;
|
||||
+ }
|
||||
|
||||
- if ( argc > 1 && argv[1][0] == '-' ) {
|
||||
- fprintf( stderr, "Usage: dcop [ application [object [function [arg1] [arg2] [arg3] ... ] ] ] \n" );
|
||||
- exit(0);
|
||||
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
+
|
||||
+ for( QStringList::ConstIterator it( l.begin() ); it != l.end(); ++it )
|
||||
+ {
|
||||
+ QStringList userInfo( QStringList::split( ':', *it, true ) );
|
||||
+ result[ userInfo[ 0 ] ] = userInfo[ 5 ];
|
||||
}
|
||||
|
||||
- DCOPClient client;
|
||||
- client.attach();
|
||||
- dcop = &client;
|
||||
+ return result;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * Return a list of available DCOP sessions for the specified user
|
||||
+ * An empty list means no sessions are available, or an error occurred.
|
||||
+ */
|
||||
+QStringList dcopSessionList( const QString &user, const QString &home )
|
||||
+{
|
||||
+ if( home.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot determine home directory for user "
|
||||
+ << user << "!" << endl
|
||||
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ return QStringList();
|
||||
+ }
|
||||
+
|
||||
+ QStringList result;
|
||||
+ QFileInfo dirInfo( home );
|
||||
+ if( !dirInfo.exists() || !dirInfo.isReadable() )
|
||||
+ return result;
|
||||
+
|
||||
+ QDir d( home );
|
||||
+ d.setFilter( QDir::Files | QDir::Hidden | QDir::NoSymLinks );
|
||||
+ d.setNameFilter( ".DCOPserver*" );
|
||||
+
|
||||
+ const QFileInfoList *list = d.entryInfoList();
|
||||
+ if( !list )
|
||||
+ return result;
|
||||
+
|
||||
+ QFileInfoListIterator it( *list );
|
||||
+ QFileInfo *fi;
|
||||
+
|
||||
+ while ( ( fi = it.current() ) != 0 )
|
||||
+ {
|
||||
+ if( fi->isReadable() )
|
||||
+ result.append( fi->fileName() );
|
||||
+ ++it;
|
||||
+ }
|
||||
+ return result;
|
||||
+}
|
||||
|
||||
+/**
|
||||
+ * Do the actual DCOP call
|
||||
+ */
|
||||
+void runDCOP( QCStringList args, UserList users, Session session,
|
||||
+ const QString sessionName, bool readStdin )
|
||||
+{
|
||||
QCString app;
|
||||
QCString objid;
|
||||
QCString function;
|
||||
- char **args = 0;
|
||||
- if ((argc > 1) && (strncmp(argv[1], "DCOPRef(", 8)) == 0)
|
||||
+ QCStringList params;
|
||||
+ DCOPClient *client = 0L;
|
||||
+ if ( !args.isEmpty() && args[ 0 ].find( "DCOPRef(" ) == 0 )
|
||||
{
|
||||
- char *delim = strchr(argv[1], ',');
|
||||
- if (!delim)
|
||||
- {
|
||||
- fprintf(stderr, "Error: '%s' is not a valid DCOP reference.\n", argv[1]);
|
||||
- return 1;
|
||||
- }
|
||||
- *delim = 0;
|
||||
- app = argv[1] + 8;
|
||||
- delim++;
|
||||
- delim[strlen(delim)-1] = 0;
|
||||
- objid = delim;
|
||||
- if (argc > 2)
|
||||
- function = argv[2];
|
||||
- if (argc > 3)
|
||||
- args = &argv[3];
|
||||
- argc++;
|
||||
+ // WARNING: This part (until the closing '}') could very
|
||||
+ // well be broken now. As I don't know how to trigger and test
|
||||
+ // dcoprefs this code is *not* tested. It compiles and it looks
|
||||
+ // ok to me, but that's all I can say - Martijn (2001/12/24)
|
||||
+ int delimPos = args[ 0 ].findRev( ',' );
|
||||
+ if( delimPos == -1 )
|
||||
+ {
|
||||
+ cerr << "Error: '" << args[ 0 ]
|
||||
+ << "' is not a valid DCOP reference." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ args[ 0 ][ delimPos ] = 0;
|
||||
+ app = args[ 0 ].mid( 8 );
|
||||
+ delimPos++;
|
||||
+ args[ 0 ][ args[ 0 ].length() - 1 ] = 0;
|
||||
+ objid = args[ 0 ].mid( delimPos );
|
||||
+ if( args.count() > 1 )
|
||||
+ function = args[ 1 ];
|
||||
+ if( args.count() > 2 )
|
||||
+ {
|
||||
+ params = args;
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ }
|
||||
}
|
||||
else
|
||||
{
|
||||
- if (argc > 1)
|
||||
- app = argv[1];
|
||||
- if (argc > 2)
|
||||
- objid = argv[2];
|
||||
- if (argc > 3)
|
||||
- function = argv[3];
|
||||
- if (argc > 4)
|
||||
- args = &argv[4];
|
||||
- }
|
||||
-
|
||||
- switch ( argc ) {
|
||||
- case 0:
|
||||
- case 1:
|
||||
- queryApplications("");
|
||||
- break;
|
||||
- case 2:
|
||||
- if (endsWith(app, '*'))
|
||||
- queryApplications(app);
|
||||
- else
|
||||
- queryObjects( app, "" );
|
||||
- break;
|
||||
- case 3:
|
||||
- if (endsWith(objid, '*'))
|
||||
- queryObjects(app, objid);
|
||||
- else
|
||||
- queryFunctions( app, objid );
|
||||
- break;
|
||||
- case 4:
|
||||
- default:
|
||||
- callFunction( app, objid, function, argc - 4, args );
|
||||
- break;
|
||||
+ if( !args.isEmpty() )
|
||||
+ app = args[ 0 ];
|
||||
+ if( args.count() > 1 )
|
||||
+ objid = args[ 1 ];
|
||||
+ if( args.count() > 2 )
|
||||
+ function = args[ 2 ];
|
||||
+ if( args.count() > 3)
|
||||
+ {
|
||||
+ params = args;
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ params.remove( params.begin() );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ bool firstRun = true;
|
||||
+ UserList::Iterator it;
|
||||
+ QStringList sessions;
|
||||
+ bool presetDCOPServer = false;
|
||||
+// char *dcopStr = 0L;
|
||||
+ QString dcopServer;
|
||||
+
|
||||
+ for( it = users.begin(); it != users.end() || firstRun; it++ )
|
||||
+ {
|
||||
+ firstRun = false;
|
||||
+
|
||||
+ //cout << "Iterating '" << it.key() << "'" << endl;
|
||||
+
|
||||
+ if( session == QuerySessions )
|
||||
+ {
|
||||
+ QStringList sessions = dcopSessionList( it.key(), it.data() );
|
||||
+ if( sessions.isEmpty() )
|
||||
+ {
|
||||
+ cout << "No active sessions";
|
||||
+ if( !( *it ).isEmpty() )
|
||||
+ cout << " for user " << *it;
|
||||
+ cout << endl;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cout << "Active sessions ";
|
||||
+ if( !( *it ).isEmpty() )
|
||||
+ cout << "for user " << *it << " ";
|
||||
+ cout << ":" << endl;
|
||||
+
|
||||
+ QStringList::Iterator sIt;
|
||||
+ for( sIt = sessions.begin(); sIt != sessions.end(); sIt++ )
|
||||
+ cout << " " << *sIt << endl;
|
||||
+
|
||||
+ cout << endl;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if( getenv( "DCOPSERVER" ) )
|
||||
+ {
|
||||
+ sessions.append( getenv( "DCOPSERVER" ) );
|
||||
+ presetDCOPServer = true;
|
||||
+ }
|
||||
+
|
||||
+ if( users.count() > 1 || ( users.count() == 1 &&
|
||||
+ ( getenv( "DCOPSERVER" ) == 0 /*&& getenv( "DISPLAY" ) == 0*/ ) ) )
|
||||
+ {
|
||||
+ sessions = dcopSessionList( it.key(), it.data() );
|
||||
+ if( sessions.isEmpty() )
|
||||
+ {
|
||||
+ if( users.count() > 1 )
|
||||
+ continue;
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "ERROR: No active KDE sessions!" << endl
|
||||
+ << "If you are sure there is one, please set the $DCOPSERVER variable manually" << endl
|
||||
+ << "before calling dcop." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+ else if( sessions.count() > 1 && session != AllSessions )
|
||||
+ {
|
||||
+ cerr << "ERROR: Multiple available KDE sessions!" << endl
|
||||
+ << "Please specify the correct session to use with --session or use the" << endl
|
||||
+ << "--all-sessions option to broadcast to all sessions." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ if( users.count() > 1 || ( users.count() == 1 &&
|
||||
+ ( getenv( "ICEAUTHORITY" ) == 0 || getenv( "DISPLAY" ) == 0 ) ) )
|
||||
+ {
|
||||
+ // Check for ICE authority file and if the file can be read by us
|
||||
+ QString home = it.data();
|
||||
+ QString iceFile = it.data() + "/.ICEauthority";
|
||||
+ QFileInfo fi( iceFile );
|
||||
+ if( iceFile.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot determine home directory for user "
|
||||
+ << it.key() << "!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ else if( fi.exists() )
|
||||
+ {
|
||||
+ if( fi.isReadable() )
|
||||
+ {
|
||||
+ char *envStr = strdup( ( "ICEAUTHORITY=" + iceFile ).ascii() );
|
||||
+ putenv( envStr );
|
||||
+ //cerr << "ice: " << envStr << endl;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "WARNING: ICE authority file " << iceFile
|
||||
+ << "is not readable by you!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if( users.count() > 1 )
|
||||
+ continue;
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "WARNING: Cannot find ICE authority file "
|
||||
+ << iceFile << "!" << endl
|
||||
+ << "Please check permissions or set the $ICEAUTHORITY"
|
||||
+ << " variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Main loop
|
||||
+ // If users is an empty list we're calling for the currently logged
|
||||
+ // in user. In this case we don't have a session, but still want
|
||||
+ // to iterate the loop once.
|
||||
+ QStringList::Iterator sIt = sessions.begin();
|
||||
+ for( ; sIt != sessions.end() || users.isEmpty(); sIt++ )
|
||||
+ {
|
||||
+ if( !presetDCOPServer && !users.isEmpty() )
|
||||
+ {
|
||||
+ QString dcopFile = it.data() + "/" + *sIt;
|
||||
+ QFile f( dcopFile );
|
||||
+ if( !f.open( IO_ReadOnly ) )
|
||||
+ {
|
||||
+ cerr << "Can't open " << dcopFile << " for reading!" << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+
|
||||
+ QStringList l( QStringList::split( '\n', f.readAll() ) );
|
||||
+ dcopServer = l.first();
|
||||
+
|
||||
+ if( dcopServer.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "WARNING: Unable to determine DCOP server for session "
|
||||
+ << *sIt << "!" << endl
|
||||
+ << "Please check permissions or set the $DCOPSERVER variable manually before" << endl
|
||||
+ << "calling dcop." << endl;
|
||||
+ exit( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ delete client;
|
||||
+ client = new DCOPClient;
|
||||
+ if( !dcopServer.isEmpty() )
|
||||
+ client->setServerAddress( dcopServer.ascii() );
|
||||
+ bool success = client->attach();
|
||||
+ if( !success )
|
||||
+ {
|
||||
+ cerr << "ERROR: Couldn't attach to DCOP server!" << endl;
|
||||
+ continue;
|
||||
+ }
|
||||
+ dcop = client;
|
||||
+
|
||||
+ switch ( args.count() )
|
||||
+ {
|
||||
+ case 0:
|
||||
+ queryApplications("");
|
||||
+ break;
|
||||
+ case 1:
|
||||
+ if (endsWith(app, '*'))
|
||||
+ queryApplications(app);
|
||||
+ else
|
||||
+ queryObjects( app, "" );
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ if (endsWith(objid, '*'))
|
||||
+ queryObjects(app, objid);
|
||||
+ else
|
||||
+ queryFunctions( app, objid );
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ default:
|
||||
+ if( readStdin )
|
||||
+ {
|
||||
+ QCStringList::Iterator replaceArg = args.end();
|
||||
+
|
||||
+ QCStringList::Iterator it;
|
||||
+ for( it = args.begin(); it != args.end(); it++ )
|
||||
+ if( *it == "%1" )
|
||||
+ replaceArg = it;
|
||||
+
|
||||
+ // Read from stdin until EOF and call function for each line read
|
||||
+ char *buf = new char[ 1000 ];
|
||||
+ while ( !feof( stdin ) )
|
||||
+ {
|
||||
+ fgets( buf, 1000, stdin );
|
||||
+
|
||||
+ if( replaceArg != args.end() )
|
||||
+ *replaceArg = buf;
|
||||
+
|
||||
+ callFunction( app, objid, function, params );
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ // Just call function
|
||||
+// cout << "call " << app << ", " << objid << ", " << function << ", (params)" << endl;
|
||||
+ callFunction( app, objid, function, params );
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ // Another sIt++ would make the loop infinite...
|
||||
+ if( users.isEmpty() )
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ // Another it++ would make the loop infinite...
|
||||
+ if( it == users.end() )
|
||||
+ break;
|
||||
}
|
||||
+}
|
||||
+
|
||||
+
|
||||
+int main( int argc, char** argv )
|
||||
+{
|
||||
+ bool readStdin = false;
|
||||
+ int numOptions = 0;
|
||||
+ QString user;
|
||||
+ Session session = DefaultSession;
|
||||
+ QString sessionName;
|
||||
+
|
||||
+ // Scan for command-line options first
|
||||
+ for( int pos = 1 ; pos <= argc - 1 ; pos++ )
|
||||
+ {
|
||||
+ if( strcmp( argv[ pos ], "--help" ) == 0 )
|
||||
+ showHelp( 0 );
|
||||
+ else if( strcmp( argv[ pos ], "--pipe" ) == 0 )
|
||||
+ {
|
||||
+ readStdin = true;
|
||||
+ numOptions++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--user" ) == 0 )
|
||||
+ {
|
||||
+ if( pos <= argc - 2 )
|
||||
+ {
|
||||
+ user = QString::fromLocal8Bit( argv[ pos + 1] );
|
||||
+ numOptions +=2;
|
||||
+ pos++;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ cerr << "Missing username for '--user' option!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--all-users" ) == 0 )
|
||||
+ {
|
||||
+ user = "*";
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--list-sessions" ) == 0 )
|
||||
+ {
|
||||
+ session = QuerySessions;
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( strcmp( argv[ pos ], "--all-sessions" ) == 0 )
|
||||
+ {
|
||||
+ session = AllSessions;
|
||||
+ numOptions ++;
|
||||
+ }
|
||||
+ else if( argv[ pos ][ 0 ] == '-' )
|
||||
+ {
|
||||
+ cerr << "Unknown command-line option '" << argv[ pos ]
|
||||
+ << "'." << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+ else
|
||||
+ break; // End of options
|
||||
+ }
|
||||
+
|
||||
+ argc -= numOptions;
|
||||
+
|
||||
+ QCStringList args;
|
||||
+ for( int i = numOptions; i < argc + numOptions - 1; i++ )
|
||||
+ args.append( argv[ i + 1 ] );
|
||||
+
|
||||
+ if( readStdin && args.count() < 3 )
|
||||
+ {
|
||||
+ cerr << "--pipe option only supported for function calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( user == "*" && args.count() < 3 && session != QuerySessions )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --all-users option is only supported for function calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session == QuerySessions && !args.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --list-sessions option cannot be used for actual DCOP calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session == QuerySessions && user.isEmpty() )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --list-sessions option can only be used with the --user or" << endl
|
||||
+ << "--all-users options!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ if( session != DefaultSession && session != QuerySessions &&
|
||||
+ args.count() < 3 )
|
||||
+ {
|
||||
+ cerr << "ERROR: The --session and --all-sessions options are only supported for function" << endl
|
||||
+ << "calls!" << endl << endl;
|
||||
+ showHelp( -1 );
|
||||
+ }
|
||||
+
|
||||
+ UserList users;
|
||||
+ if( user == "*" )
|
||||
+ users = userList();
|
||||
+ else if( !user.isEmpty() )
|
||||
+ users[ user ] = userList()[ user ];
|
||||
+
|
||||
+ runDCOP( args, users, session, sessionName, readStdin );
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+// vim: set ts=8 sts=4 sw=4 noet:
|
||||
+
|
||||
diff -aur dcop/client/dcopfind.cpp dcop2/client/dcopfind.cpp
|
||||
--- dcop/client/dcopfind.cpp Wed Jan 30 22:38:07 2002
|
||||
+++ dcop2/client/dcopfind.cpp Wed Jan 30 22:37:04 2002
|
||||
@@ -36,7 +36,7 @@
|
||||
static bool bAppIdOnly = 0;
|
||||
static bool bLaunchApp = 0;
|
||||
|
||||
-bool findObject( const char* app, const char* obj, const char* func, int argc, char** args )
|
||||
+bool findObject( const char* app, const char* obj, const char* func, QCStringList args )
|
||||
{
|
||||
QString f = func; // Qt is better with unicode strings, so use one.
|
||||
int left = f.find( '(' );
|
||||
@@ -118,7 +118,7 @@
|
||||
f = fc;
|
||||
}
|
||||
|
||||
- if ( (int) types.count() != argc ) {
|
||||
+ if ( types.count() != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -128,9 +128,9 @@
|
||||
|
||||
int i = 0;
|
||||
for ( QStringList::Iterator it = types.begin(); it != types.end(); ++it ) {
|
||||
- marshall(arg, argc, args, i, *it);
|
||||
+ marshall(arg, args, i, *it);
|
||||
}
|
||||
- if ( (int) i != argc ) {
|
||||
+ if ( (uint) i != args.count() ) {
|
||||
qWarning( "arguments do not match" );
|
||||
exit(1);
|
||||
}
|
||||
@@ -221,7 +221,11 @@
|
||||
argc = 0;
|
||||
}
|
||||
|
||||
- findObject( app, objid, function, argc, args );
|
||||
+ QCStringList params;
|
||||
+ for( int i = 0; i < argc; i++ )
|
||||
+ params.append( args[ i ] );
|
||||
+
|
||||
+ findObject( app, objid, function, params );
|
||||
|
||||
return 0;
|
||||
}
|
||||
diff -aur dcop/client/marshall.cpp dcop2/client/marshall.cpp
|
||||
--- dcop/client/marshall.cpp Wed Jan 30 22:38:07 2002
|
||||
+++ dcop2/client/marshall.cpp Wed Jan 30 22:37:04 2002
|
||||
@@ -242,108 +242,110 @@
|
||||
|
||||
}
|
||||
|
||||
-void marshall(QDataStream &arg, int argc, char **argv, int &i, QString type)
|
||||
+void marshall( QDataStream &arg, QCStringList args, uint &i, QString type )
|
||||
{
|
||||
- if (type == "QStringList")
|
||||
- type = "QValueList<QString>";
|
||||
- if (type == "QCStringList")
|
||||
- type = "QValueList<QCString>";
|
||||
- if (i >= argc)
|
||||
- {
|
||||
- qWarning("Not enough arguments.");
|
||||
- exit(1);
|
||||
- }
|
||||
- QString s = QString::fromLocal8Bit(argv[i]);
|
||||
-
|
||||
- if ( type == "int" )
|
||||
- arg << s.toInt();
|
||||
- else if ( type == "uint" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "unsigned" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "unsigned int" )
|
||||
- arg << s.toUInt();
|
||||
- else if ( type == "long" )
|
||||
- arg << s.toLong();
|
||||
- else if ( type == "long int" )
|
||||
- arg << s.toLong();
|
||||
- else if ( type == "unsigned long" )
|
||||
- arg << s.toULong();
|
||||
- else if ( type == "unsigned long int" )
|
||||
- arg << s.toULong();
|
||||
- else if ( type == "float" )
|
||||
- arg << s.toFloat();
|
||||
- else if ( type == "double" )
|
||||
- arg << s.toDouble();
|
||||
- else if ( type == "bool" )
|
||||
- arg << mkBool( s );
|
||||
- else if ( type == "QString" )
|
||||
- arg << s;
|
||||
- else if ( type == "QCString" )
|
||||
- arg << QCString( argv[i] );
|
||||
- else if ( type == "QColor" )
|
||||
- arg << mkColor( s );
|
||||
- else if ( type == "QPoint" )
|
||||
- arg << mkPoint( s );
|
||||
- else if ( type == "QSize" )
|
||||
- arg << mkSize( s );
|
||||
- else if ( type == "QRect" )
|
||||
- arg << mkRect( s );
|
||||
- else if ( type == "QVariant" ) {
|
||||
- if ( s == "true" || s == "false" )
|
||||
- arg << QVariant( mkBool( s ), 42 );
|
||||
- else if ( s.left( 4 ) == "int(" )
|
||||
- arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
- else if ( s.left( 7 ) == "QPoint(" )
|
||||
- arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
- else if ( s.left( 6 ) == "QSize(" )
|
||||
- arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
- else if ( s.left( 6 ) == "QRect(" )
|
||||
- arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
- else if ( s.left( 7 ) == "QColor(" )
|
||||
- arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
- else
|
||||
- arg << QVariant( s );
|
||||
- } else if ( type.startsWith("QValueList<")) {
|
||||
- type = type.mid(11, type.length() - 12);
|
||||
- QStringList list;
|
||||
- QString delim = s;
|
||||
- if (delim == "[")
|
||||
- delim = "]";
|
||||
- if (delim == "(")
|
||||
- delim = ")";
|
||||
- i++;
|
||||
- QByteArray dummy_data;
|
||||
- QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
+ if (type == "QStringList")
|
||||
+ type = "QValueList<QString>";
|
||||
+ if (type == "QCStringList")
|
||||
+ type = "QValueList<QCString>";
|
||||
+ if( i > args.count() )
|
||||
+ {
|
||||
+ qWarning("Not enough arguments.");
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ QString s = QString::fromLocal8Bit( args[ i ] );
|
||||
|
||||
- int j = i;
|
||||
- int count = 0;
|
||||
- // Parse list to get the count
|
||||
- while (true) {
|
||||
- if (j >= argc)
|
||||
- {
|
||||
- qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
- exit(1);
|
||||
- }
|
||||
- if (argv[j] == delim) break;
|
||||
- marshall(dummy_arg, argc, argv, j, type);
|
||||
- count++;
|
||||
- }
|
||||
- arg << (Q_UINT32) count;
|
||||
- // Parse the list for real
|
||||
- while (true) {
|
||||
- if (i >= argc)
|
||||
- {
|
||||
- qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
- exit(1);
|
||||
- }
|
||||
- if (argv[i] == delim) break;
|
||||
- marshall(arg, argc, argv, i, type);
|
||||
- }
|
||||
- } else {
|
||||
- qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
- exit(1);
|
||||
- }
|
||||
+ if ( type == "int" )
|
||||
+ arg << s.toInt();
|
||||
+ else if ( type == "uint" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "unsigned" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "unsigned int" )
|
||||
+ arg << s.toUInt();
|
||||
+ else if ( type == "long" )
|
||||
+ arg << s.toLong();
|
||||
+ else if ( type == "long int" )
|
||||
+ arg << s.toLong();
|
||||
+ else if ( type == "unsigned long" )
|
||||
+ arg << s.toULong();
|
||||
+ else if ( type == "unsigned long int" )
|
||||
+ arg << s.toULong();
|
||||
+ else if ( type == "float" )
|
||||
+ arg << s.toFloat();
|
||||
+ else if ( type == "double" )
|
||||
+ arg << s.toDouble();
|
||||
+ else if ( type == "bool" )
|
||||
+ arg << mkBool( s );
|
||||
+ else if ( type == "QString" )
|
||||
+ arg << s;
|
||||
+ else if ( type == "QCString" )
|
||||
+ arg << QCString( args[ i ] );
|
||||
+ else if ( type == "QColor" )
|
||||
+ arg << mkColor( s );
|
||||
+ else if ( type == "QPoint" )
|
||||
+ arg << mkPoint( s );
|
||||
+ else if ( type == "QSize" )
|
||||
+ arg << mkSize( s );
|
||||
+ else if ( type == "QRect" )
|
||||
+ arg << mkRect( s );
|
||||
+ else if ( type == "QVariant" ) {
|
||||
+ if ( s == "true" || s == "false" )
|
||||
+ arg << QVariant( mkBool( s ), 42 );
|
||||
+ else if ( s.left( 4 ) == "int(" )
|
||||
+ arg << QVariant( s.mid(4, s.length()-5).toInt() );
|
||||
+ else if ( s.left( 7 ) == "QPoint(" )
|
||||
+ arg << QVariant( mkPoint( s.mid(7, s.length()-8) ) );
|
||||
+ else if ( s.left( 6 ) == "QSize(" )
|
||||
+ arg << QVariant( mkSize( s.mid(6, s.length()-7) ) );
|
||||
+ else if ( s.left( 6 ) == "QRect(" )
|
||||
+ arg << QVariant( mkRect( s.mid(6, s.length()-7) ) );
|
||||
+ else if ( s.left( 7 ) == "QColor(" )
|
||||
+ arg << QVariant( mkColor( s.mid(7, s.length()-8) ) );
|
||||
+ else
|
||||
+ arg << QVariant( s );
|
||||
+ } else if ( type.startsWith("QValueList<")) {
|
||||
+ type = type.mid(11, type.length() - 12);
|
||||
+ QStringList list;
|
||||
+ QString delim = s;
|
||||
+ if (delim == "[")
|
||||
+ delim = "]";
|
||||
+ if (delim == "(")
|
||||
+ delim = ")";
|
||||
i++;
|
||||
+ QByteArray dummy_data;
|
||||
+ QDataStream dummy_arg(dummy_data, IO_WriteOnly);
|
||||
+
|
||||
+ uint j = i;
|
||||
+ uint count = 0;
|
||||
+ // Parse list to get the count
|
||||
+ while (true) {
|
||||
+ if( j > args.count() )
|
||||
+ {
|
||||
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if( QString::fromLocal8Bit( args[ j ] ) == delim )
|
||||
+ break;
|
||||
+ marshall( dummy_arg, args, j, type );
|
||||
+ count++;
|
||||
+ }
|
||||
+ arg << (Q_UINT32) count;
|
||||
+ // Parse the list for real
|
||||
+ while (true) {
|
||||
+ if( i > args.count() )
|
||||
+ {
|
||||
+ qWarning("List end-delimiter '%s' not found.", delim.latin1());
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ if( QString::fromLocal8Bit( args[ i ] ) == delim )
|
||||
+ break;
|
||||
+ marshall( arg, args, i, type );
|
||||
+ }
|
||||
+ } else {
|
||||
+ qWarning( "cannot handle datatype '%s'", type.latin1() );
|
||||
+ exit(1);
|
||||
+ }
|
||||
+ i++;
|
||||
}
|
||||
|