# HG changeset patch
# User joachim99
# Date 1071001783 0
# Node ID c59d5a3a8ff3f567a527e7e37b2c85be738f844d
# Parent 8c9752066f099d25711f6e6a9dfc2064437c30db
0.9.80
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/ChangeLog
--- a/kdiff3/ChangeLog Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/ChangeLog Tue Dec 09 20:29:43 2003 +0000
@@ -1,3 +1,33 @@
+Version 0.9.80 - 2003/12/08
+===========================
+New Text Diff/Merge Features:
+- Now using GNU-diff algorithms internally. (Option "External Diff" removed.)
+- Option for treating C/C++ comments as whitespace during diff.
+- Bugfix for locale character encoding (+ new option "Use string encoding")
+- Option for suppressing highlighting in white-space changes.
+ (Also suppresses highlighting in comments and numbers when the
+ respective options are active.)
+- Merge-menu: Choose A/B/C for all unsolved conflicts.
+ Choose A/B/C for all unsolved whitespace conflicts.
+- Options to automatically choose a certain source for whitespace conflicts.
+- Shorcut F5 now used to reload the current file.
+
+New Directory-Comparison/Merge Features:
+- Option to trust filesize. (Some directory services don't copy the date/time correctly.)
+- Shortcut F7 now starts complete directory merge (previously F5).
+- Do the selected merge operation for the selected file/dir only
+ "Run Operation For Current Item" (F6).
+- Shortcuts for selecting the merge operation for the selected item.
+ Ctrl-1/2/3/4/Del select A/B/C/Merge/Delete respectively.
+
+Other Improvements:
+- Several i18n-corrections (by Stephan Binner)
+- Bugfix for option CVS-ignore: Didn't work correctly in subdirectories.
+- Bugfix for remote operations: Operation can now be aborted, when KIO-slaves doesn't respond.
+- Cancel-Button in progress bar.
+- Default diff-view now again side by side instead of one above the other.
+
+
Version 0.9.71 - 2003/10/14
===========================
- Windows-Installer by Sebastien Fricker.
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/README
--- a/kdiff3/README Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/README Tue Dec 09 20:29:43 2003 +0000
@@ -3,7 +3,7 @@
Author: Joachim Eibl (joachim.eibl@gmx.de)
Copyright: (C) 2002-2003 by Joachim Eibl
-KDiff3-Version: 0.9.70
+KDiff3-Version: 0.9.80
KDiff3 is a program that
@@ -42,12 +42,12 @@
Requirements & Installation:
- Version 0.9.70 provides special support for KDE3, but it can also be
+ Version 0.9.80 provides special support for KDE3, but it can also be
built without KDE3 if the Qt-libraries are available.
(I also tested the program under Windows.)
You always need
- - kdiff3-0.9.70.tar.gz
+ - kdiff3-0.9.80.tar.gz
For building the KDE3-version
- KDE>=3.1 and QT>=3.1-libraries.
@@ -64,7 +64,7 @@
- Make sure your shell-variable QTDIR is correct. (echo $QTDIR).
If it doesn't contain the correct path, type
export QTDIR=your_path_to_qt (e.g. /usr/lib/qt3)
- - cd into the directory kdiff3-0.9.70 and type
+ - cd into the directory kdiff3-0.9.80 and type
- ./configure --prefix=/opt/kde3 (your KDE3 directory here)
- (make clean) (Required if you already compiled once.)
- make (Run compilation)
@@ -93,7 +93,7 @@
- Make sure your shell-variable QTDIR is correct. (echo $QTDIR).
If it doesn't contain the correct path, type
export QTDIR=your_path_to_qt (e.g. /usr/lib/qt)
- - cd into the directory kdiff3-0.9.70/src and type
+ - cd into the directory kdiff3-0.9.80/src and type
- make -f Makefile.qt
- make -f Makefile.qt install (You must have root-rights for this step.)
(copies the files into /usr/local/bin and /usr/local/share/doc/kdiff3)
@@ -110,7 +110,7 @@
set QTDIR=your_path_to_qt (e.g. c:\qt)
- Make sure your VC6 environment variables are set. Run VCVARS32.BAT.
(Typically located in "c:\programs\Microsoft Visual Studio\VC98\bin")
- - cd into the directory kdiff3-0.9.70\src and type
+ - cd into the directory kdiff3-0.9.80\src and type
- nmake /f Makefile.win_qt230
- For execution the Qt-DLL must be in the path or in the same directory.
For newer versions of Qt, use qmake and kdiff3.pro to generate
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/README_WIN.txt
--- a/kdiff3/README_WIN.txt Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/README_WIN.txt Tue Dec 09 20:29:43 2003 +0000
@@ -3,7 +3,7 @@
Author: Joachim Eibl (joachim.eibl@gmx.de)
Copyright: (C) 2002-2003 by Joachim Eibl
-KDiff3-Version: 0.9.71
+KDiff3-Version: 0.9.80
Homepage: http://kdiff3.sourceforge.net
KDiff3 is a program that
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/TODO
--- a/kdiff3/TODO Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/TODO Tue Dec 09 20:29:43 2003 +0000
@@ -6,6 +6,4 @@
- Automatic line wrap in the difference windows
- Printing of the diff-windows (requires automatic line wrap)
- Undo function in the merge-editor.
-- Diff should allow to treat C/C++-comments as white space.
-- A inserted or removed linefeed should be detected and treated like white space.
-
+- More viewing options for directory widget.
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/doc/en/index.docbook
--- a/kdiff3/doc/en/index.docbook Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/doc/en/index.docbook Tue Dec 09 20:29:43 2003 +0000
@@ -45,8 +45,8 @@
(V.MM.LL), it could be used by automation scripts.
Do NOT change these in the translation. -->
-2003-09-15
-0.9.70
+2003-12-07
+0.9.80
@@ -59,10 +59,10 @@
provides an automatic merge-facility,
has an editor for comfortable solving of merge-conflicts,
provides networktransparency via KIO,
-and is very colorful (by default) :-)
+has options to highlight or hide changes in white-space or comments.
- This document describes KDiff3-version 0.9.70.
+ This document describes KDiff3-version 0.9.80.
@@ -89,6 +89,8 @@
kio
networktransparent
editor
+white space
+comments
@@ -217,6 +219,7 @@
Show the line numbers for each line.
Paste clipboard or drag text into a diff input window.
Networktransparency via KIO.
+ Can be used as diff-viewer in KDevelop 3.
...
@@ -445,12 +448,20 @@
copy and paste some text containing such a line. But still be careful to
do so.
- The "Merge" menu contains some actions that let you select "A", "B" or
- "C" everywhere. When you select "Automatically solve simple conflicts" then
- KDiff3 restarts the merge and solves as many conflicts as it can. "Set deltas
- to conflicts" does the opposite: Even simple conflicts have to be solved
- manually then. For all these actions the manual selections that happened
- before are lost. (KDiff3 will tell you so, before proceeding.)
+ The normal merge will start by solving simple conflicts automatically.
+ But the "Merge"-menu provides some actions for other common needs.
+ If you have to select the same source for most conflicts, then you can
+ choose "A", "B" or "C" everywhere, or only for the remaining unsolved
+ conflicts, or for unsolved whitespace conflicts. If you want to decide every
+ single delta yourself, you can "Set deltas to conflicts". Or if you want to
+ return to the automatic choices of KDiff3 then select
+ "Automatically solve simple conflicts". KDiff3 then restarts the merge.
+ For actions that change your previous modifications KDiff3 will ask for your
+ confirmation before proceeding.
+
+ Note: When choosing either source for unsolved whitespace conflicts and
+ the options "Ignore Numbers" or "Ignore C/C++ Comments" are used then changes in
+ numbers or comments will be treated like whitespace too.
@@ -592,6 +603,8 @@
of the previous line is used for the new line.
Auto copy selection: Every selection is immediately copied
to the clipboard when active and you needn't explicitely copy it.
+ Use locale encoding: For displaying foreign characters.
+ Try changing this if some characters of your language aren't displayed correctly.
@@ -604,10 +617,6 @@
- Ignore white space: Default is on. White space will be
- ignored in the first part of the analysis in which the line matching is
- done. In the result the white space differences will be shown nevertheless.
-
Preserve Carriage Return: Some editors (on some systems) save
carriage return '\r' and linefeed '\n'-characters at the end of line, while
others will only save the linefeed '\n'. Usually KDiff3 ignores the carriage
@@ -620,6 +629,9 @@
done. In the result the differences will be shown nevertheless, but they are treated
as white space.
+ Ignore C/C++ comments: Default is off.
+ Changes in comments will be treated like changes in white space.
+
Convert to Upper Case: Default is off. Converts the input to upper case
while reading. Hence the comparison is not case sensitive. Take care during merging
because the case information will be lost in the merge-result too.
@@ -639,28 +651,21 @@
You can write your own preprocessor that fulfills your specific needs.
Each input line must have a corresponding output line.
- Use external diff: If you have an external diff-tool (e.g. GNU-diff)
- you can use it for the line matching phase. For some complicated files this
- might be better than the internal algorithm of KDiff3.
-
- Try Hard: Passes the "--minimal"-option to the external diff
- tool, which then will try hard to find an even smaller delta. This will probably
+ Try Hard:
+ Try hard to find an even smaller delta. (Default is on.) This will probably
be effective for complicated and big files. And slow for very big files.
- Ignore trivial matches: Default is on. When trivial lines
- match after an difference, this will be ignored and the search for a nontrivial
- matching line continues. This improves the results for inputs with empty
- lines and lines containing only a open or close-brace character, which is
- often the case for C/C++-programs.
-
- Max search length: Searching for a match is aborted after this
- number of lines. The diff might fail for small values but take too long
- for big values. Default is 1000.
-
Auto Advance Delay (ms): When in auto-advance-mode this setting specifies
how long to show the result of the selection before jumping to the next unsolved
conflict.
+ White space 2/3-file merge default:
+ Automatically solve all white-space conflict by choosing the specified file.
+ (Default is manual choice.) Useful if white-space really isn't important in many files.
+ If you need this only occasionally better use "Choose A/B/C For All Unsolved Whitespace Conflicts"
+ in the merge menu. Note that if you enable either "Ignore numbers" or "Ignore C/C++ comments"
+ then this auto-choice also applies for conflicts in numbers or comments.
+
@@ -689,6 +694,10 @@
shown for the input files.
Show space and tabulator characters for differences: Sometimes
the visible spaces and tabs are disturbing. You can turn this off.
+ Show white space: Turn this off to suppress
+ any highlighting of white-space-only changes in the text or overview-columns.
+ (Note that this also applies to changes in numbers or comments if the options "Ignore numbers"
+ or "Ignore C/C++ comments" are active.)
Show Window A/B/C: Sometimes you want to use the space on
the screen better for long lines. Hide the windows that are not important.
(In the Windows-menu.)
@@ -696,8 +705,9 @@
Switch between diff windows shown next to each other (A left of B left of C) or above
each other (A above B above C). This should also help for long lines. (In the Windows-menu.)
- Start a merge quickly: Sometimes you are viewing the deltas
- and decide to merge.
+ Start a merge quickly:
+ Sometimes you are viewing the deltas and decide to merge.
+
"Merge current file" in the Directory-menu also works if you only compare
two files. A single click starts the merge and uses the filename of the last
input-file as the default output filename. (When this is used to restart
@@ -750,7 +760,8 @@
take place, without actually doing them,
... lets you really do the merge, and lets you interact whenever
manual interaction is needed,
- ... lets you continue the merge after manual interaction with key F5,
+ ... lets you run the selected operation for all items (key F7) or the selected item (key F6),
+ ... lets you continue the merge after manual interaction with key F7,
... optionally creates backups, with the ".orig" extension,
...
@@ -786,7 +797,7 @@
Note that only the comparison starts automatically, not the merge. For this you first must
- select a menu entry or the key F5. (More details later.)
+ select a menu entry or the key F7. (More details later.)
@@ -874,12 +885,14 @@
After comparing the directories KDiff3 also evaluates a proposal for a
merge operation. This is shown in the "Operation" column. You can modify
the operation by clicking on the operation you want to change. A small menu
- will popup and allows you to select an operation for that item. This operation
- will be executed during the merge. It depends on the item and on the merge-mode
- you are in, what operations are available. The merge-mode is one of
+ will popup and allows you to select an operation for that item. (You can also
+ select the most needed operations via keyboard.
+ Ctrl+1/2/3/4/Del will select A/B/C/Merge/Delete respectively if available.)
+ This operation will be executed during the merge. It depends on the item and
+ on the merge-mode you are in, what operations are available. The merge-mode is one of
- Three directory-merge (A is treated as older base of both).
+ Three directory-merge ("A" is treated as older base of both).
Two directory-merge.
Two directory-sync-mode (activate via option "Synchronize Directories").
@@ -954,6 +967,7 @@
Doing A Merge
+ You can either merge the currently selected item (file or directory), or all items.
When you have made all your operation choices (in all subdirectories too)
then you can start the merge.
@@ -975,19 +989,21 @@
in the tree, and hence also not in the destination.
- (In the current version, you must do a rescan yourself, after changing
- options affecting the directory scan.)
+ (In the current version, you must do a rescan via menu "Directory"->"Rescan"
+ yourself, after changing options affecting the directory scan.)
If you are satisfied so far, the rest is easy.
- In the "Directory"-menu select "Start/Continue directory merge" or press
- F5 (which is the shortcut).
+ To merge all items: Select "Start/Continue directory merge" in the "Directory"-menu
+ or press F7 (which is the shortcut).
+ To merge only the current item: Select "Run Operation For Current Item"
+ or press F6.
If due to conflicting filetypes still some items with invalid operations
exist, then a messagebox will appear and these items will be pointed out,
so you can select a valid operation for the item.
- Otherwise a dialog will appear giving you the options "Do it", "Simulate
+ If you merge all items a dialog will appear giving you the options "Do it", "Simulate
it" and "Cancel".
@@ -1001,18 +1017,24 @@
(see the big screenshot).
When you have finished with a file, again select "Start/Continue directory
- merge" or the key F5. If you haven't saved yet, a dialog will ask you to
+ merge" or the key F7. If you haven't saved yet, a dialog will ask you to
do so. Then KDiff3 will continue with the next item.
When KDiff3 encounters an error, it will tell you so and will show the
- verbose-status-information. At the bottom of this list, there will be some
- error messages which should help you to understand the cause of the problem.
- When you continue merging (F5 key) KDiff3 will give you the choice to retry
- or skip the item that caused the problem. This means that before continuing
- you can choose another operation or solve the problem by other means.
+ verbose-status-information. At the bottom of this list, there will be some
+ error messages which should help you to understand the cause of the problem.
+ When you continue merging (F7 key) KDiff3 will give you the choice to retry
+ or skip the item that caused the problem. This means that before continuing
+ you can choose another operation or solve the problem by other means.
When the merge is complete, then KDiff3 will inform you via a message
box.
+
+ If some items were merged individually then KDiff3 remembers this (while this
+ merge-session goes on), and doesn't merge them again when later the merge for
+ all items is run. Even when the merge was skipped or nothing was saved these
+ items count as completed. Only when you change the merge operation the item
+ will be merged again.
@@ -1062,6 +1084,11 @@
over a slow network, it might be faster to compare the modification dates
and file length alone. But this speed improvement comes with the price of
a little uncertainty. Use this option with care. Default is off.
+ Trust the size:
+ Similar to trusting the modification date. No real comparison happens. Two
+ files are considered equal if their file-sizes are equal. This is useful
+ when the file-copy operation didn't preserve the modification date.
+ Use this option with care. Default is off.
Synchronize Directories: Activates "Sync-Mode" when two directories
are compared and no explicit destination directory was specified. In this
mode the proposed operations will be chosen so that both source directories
@@ -1152,7 +1179,8 @@
- A path can be relative and can contain "." or "..". This is not possible for URLs which are always absolute.
+ A path can be relative and can contain "." or "..". This is not possible for URLs
+ which are always absolute.
Special characters must be written with "escaping". ("#"->"%23", space->"%20", etc.)
E.g. A file with the name "/#foo#" would have the URL "file:/%23foo%23".
@@ -1174,13 +1202,15 @@
Sometimes there is no support for links.
- Or there is no way to distinguish if a link points to a file or a directory; always assuming a file. (ftp:, sftp:).
+ Or there is no way to distinguish if a link points to a file or a directory; always
+ assuming a file. (ftp:, sftp:).
Can't always determine the filesize.
Limited support for permissions.
- No possibility to modify permissions or modification time, so permissions or time of a copy will differ from the original.
+ No possibility to modify permissions or modification time, so permissions or time
+ of a copy will differ from the original. (See the option "Trust the size".)
(Only possible for local files.)
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/Makefile.am
--- a/kdiff3/src/Makefile.am Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/Makefile.am Tue Dec 09 20:29:43 2003 +0000
@@ -5,7 +5,7 @@
# these are the headers for your project
noinst_HEADERS = kdiff3_part.h kdiff3_shell.h \
kdiff3.h common.h diff.h directorymergewindow.h \
- merger.h optiondialog.h fileaccess.h
+ merger.h optiondialog.h fileaccess.h version.h
# let automoc handle all of the meta source files (moc)
METASOURCES = AUTO
@@ -44,7 +44,8 @@
# the Part's source, library search path, and link libraries
libkdiff3part_la_SOURCES = kdiff3_part.cpp kdiff3.cpp directorymergewindow.cpp \
merger.cpp pdiff.cpp difftextwindow.cpp diff.cpp \
- optiondialog.cpp mergeresultwindow.cpp fileaccess.cpp
+ optiondialog.cpp mergeresultwindow.cpp fileaccess.cpp \
+ gnudiff_analyze.cpp gnudiff_io.cpp gnudiff_xmalloc.cpp
libkdiff3part_la_LDFLAGS = -module $(KDE_PLUGIN) $(all_libraries)
libkdiff3part_la_LIBADD = $(LIB_KPARTS) $(LIB_KFILE)
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/Makefile.qt
--- a/kdiff3/src/Makefile.qt Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/Makefile.qt Tue Dec 09 20:29:43 2003 +0000
@@ -1,6 +1,6 @@
#############################################################################
# Makefile for building: kdiff3
-# Generated by qmake (1.05a) (Qt 3.1.2-snapshot-20030618) on: Thu Oct 2 22:13:20 2003
+# Generated by qmake (1.06c) (Qt 3.2.1) on: Mon Dec 8 20:06:47 2003
# Project: kdiff3.pro
# Template: app
# Command: $(QMAKE) -o Makefile kdiff3.pro
@@ -12,8 +12,8 @@
CXX = g++
LEX = flex
YACC = yacc
-CFLAGS = -pipe -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -DNO_DEBUG -Wall -W -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -DNO_DEBUG -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
-CXXFLAGS = -pipe -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -DNO_DEBUG -Wall -W -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -DNO_DEBUG -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT
+CFLAGS = -pipe -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -Wall -W -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT
+CXXFLAGS = -pipe -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -Wall -W -O2 -march=i586 -mcpu=i686 -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT
LEXFLAGS =
YACCFLAGS= -d
INCPATH = -I$(QTDIR)/mkspecs/default -I. -Ikreplacements -I/usr/include -I$(QTDIR)/include
@@ -28,8 +28,8 @@
TAR = tar -cf
GZIP = gzip -9f
COPY = cp -f
-COPY_FILE= $(COPY) -p
-COPY_DIR = $(COPY) -pR
+COPY_FILE= $(COPY)
+COPY_DIR = $(COPY) -r
DEL_FILE = rm -f
SYMLINK = ln -sf
DEL_DIR = rmdir
@@ -43,7 +43,8 @@
####### Files
-HEADERS = diff.h \
+HEADERS = version.h \
+ diff.h \
kdiff3.h \
merger.h \
optiondialog.h \
@@ -64,7 +65,10 @@
fileaccess.cpp \
kdiff3_shell.cpp \
kdiff3_part.cpp \
- kreplacements/kreplacements.cpp
+ kreplacements/kreplacements.cpp \
+ gnudiff_analyze.cpp \
+ gnudiff_io.cpp \
+ gnudiff_xmalloc.cpp
OBJECTS = diff.o \
difftextwindow.o \
kdiff3.o \
@@ -77,7 +81,10 @@
fileaccess.o \
kdiff3_shell.o \
kdiff3_part.o \
- kreplacements.o
+ kreplacements.o \
+ gnudiff_analyze.o \
+ gnudiff_io.o \
+ gnudiff_xmalloc.o
FORMS =
UICDECLS =
UICIMPLS =
@@ -105,7 +112,7 @@
first: all
####### Implicit rules
-.SUFFIXES: .c .cpp .cc .cxx .C
+.SUFFIXES: .c .o .cpp .cc .cxx .C
.cpp.o:
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
@@ -126,10 +133,11 @@
all: $(TARGET)
-$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC)
- $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC)
+ $(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)
mocables: $(SRCMOC)
+uicables: $(UICDECLS) $(UICIMPLS)
$(MOC):
( cd $(QTDIR)/src/moc ; $(MAKE) )
@@ -146,7 +154,7 @@
yaccclean:
lexclean:
clean: mocclean
- -$(DEL_FILE) $(OBJECTS)
+ -$(DEL_FILE) $(OBJECTS)
-$(DEL_FILE) *~ core *.core
@@ -191,10 +199,10 @@
xpm/autoadvance.xpm \
xpm/showwhitespace.xpm \
xpm/showlinenumbers.xpm \
- xpm/startmerge.xpm \
common.h
-main.o: main.cpp kdiff3_shell.h
+main.o: main.cpp kdiff3_shell.h \
+ version.h
merger.o: merger.cpp merger.h \
diff.h \
@@ -216,10 +224,13 @@
kdiff3.h \
optiondialog.h \
fileaccess.h \
- common.h
+ gnudiff_diff.h \
+ common.h \
+ gnudiff_system.h
directorymergewindow.o: directorymergewindow.cpp directorymergewindow.h \
optiondialog.h \
+ xpm/startmerge.xpm \
common.h \
fileaccess.h
@@ -243,6 +254,16 @@
kreplacements/kreplacements.moc
$(CXX) -c $(CXXFLAGS) $(INCPATH) -o kreplacements.o kreplacements/kreplacements.cpp
+gnudiff_analyze.o: gnudiff_analyze.cpp gnudiff_diff.h \
+ gnudiff_xalloc.h \
+ gnudiff_system.h
+
+gnudiff_io.o: gnudiff_io.cpp gnudiff_diff.h \
+ gnudiff_xalloc.h \
+ gnudiff_system.h
+
+gnudiff_xmalloc.o: gnudiff_xmalloc.cpp gnudiff_xalloc.h
+
moc_diff.o: moc_diff.cpp diff.h common.h \
fileaccess.h
@@ -302,7 +323,6 @@
install_target:
@$(CHK_DIR_EXISTS) "$(INSTALL_ROOT)/usr/local/bin/" || $(MKDIR) "$(INSTALL_ROOT)/usr/local/bin/"
-$(COPY) "$(QMAKE_TARGET)" "$(INSTALL_ROOT)/usr/local/bin/$(QMAKE_TARGET)"
- -strip "$(INSTALL_ROOT)/usr/local/bin/$(QMAKE_TARGET)"
uninstall_target:
-$(DEL_FILE) "$(INSTALL_ROOT)/usr/local/bin/$(QMAKE_TARGET)"
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/Makefile.win_qt230
--- a/kdiff3/src/Makefile.win_qt230 Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/Makefile.win_qt230 Tue Dec 09 20:29:43 2003 +0000
@@ -1,6 +1,6 @@
#############################################################################
# Makefile for building kdiff3
-# Generated by tmake at 22:40, 2003/10/01
+# Generated by tmake at 12:39, 2003/12/06
# Project: kdiff3_tmake
# Template: app
#############################################################################
@@ -43,7 +43,10 @@
fileaccess.cpp \
kdiff3_shell.cpp \
kdiff3_part.cpp \
- kreplacements\kreplacements.cpp
+ kreplacements\kreplacements.cpp \
+ gnudiff_analyze.cpp \
+ gnudiff_io.cpp \
+ gnudiff_xmalloc.cpp
OBJECTS = diff.obj \
difftextwindow.obj \
kdiff3.obj \
@@ -56,7 +59,10 @@
fileaccess.obj \
kdiff3_shell.obj \
kdiff3_part.obj \
- kreplacements\kreplacements.obj
+ kreplacements\kreplacements.obj \
+ gnudiff_analyze.obj \
+ gnudiff_io.obj \
+ gnudiff_xmalloc.obj
INTERFACES =
UICDECLS =
UICIMPLS =
@@ -128,6 +134,9 @@
-del kdiff3_shell.obj
-del kdiff3_part.obj
-del kreplacements\kreplacements.obj
+ -del gnudiff_analyze.obj
+ -del gnudiff_io.obj
+ -del gnudiff_xmalloc.obj
-del moc_diff.cpp
-del moc_kdiff3.cpp
-del moc_optiondialog.cpp
@@ -182,11 +191,11 @@
xpm\iconC.xpm \
xpm\autoadvance.xpm \
xpm\showwhitespace.xpm \
- xpm\showlinenumbers.xpm \
- xpm\startmerge.xpm
+ xpm\showlinenumbers.xpm
main.obj: main.cpp \
- kdiff3_shell.h
+ kdiff3_shell.h \
+ version.h
merger.obj: merger.cpp \
merger.h \
@@ -212,7 +221,9 @@
fileaccess.h \
directorymergewindow.h \
kdiff3.h \
- optiondialog.h
+ optiondialog.h \
+ gnudiff_diff.h \
+ gnudiff_system.h
directorymergewindow.obj: directorymergewindow.cpp \
directorymergewindow.h \
@@ -225,7 +236,8 @@
xpm\not_there.xpm \
xpm\link_arrow.xpm \
xpm\file.xpm \
- xpm\folder.xpm
+ xpm\folder.xpm \
+ xpm\startmerge.xpm
fileaccess.obj: fileaccess.cpp \
fileaccess.h \
@@ -251,6 +263,19 @@
kreplacements\..\xpm\fileopen.xpm \
kreplacements\..\xpm\filesave.xpm
+gnudiff_analyze.obj: gnudiff_analyze.cpp \
+ gnudiff_diff.h \
+ gnudiff_system.h \
+ gnudiff_xalloc.h
+
+gnudiff_io.obj: gnudiff_io.cpp \
+ gnudiff_diff.h \
+ gnudiff_system.h \
+ gnudiff_xalloc.h
+
+gnudiff_xmalloc.obj: gnudiff_xmalloc.cpp \
+ gnudiff_xalloc.h
+
moc_diff.obj: moc_diff.cpp \
diff.h \
common.h \
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/common.h
--- a/kdiff3/src/common.h Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/common.h Tue Dec 09 20:29:43 2003 +0000
@@ -15,13 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- * *
- ***************************************************************************/
-
#ifndef _COMMON_H
#define _COMMON_H
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/diff.cpp
--- a/kdiff3/src/diff.cpp Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/diff.cpp Tue Dec 09 20:29:43 2003 +0000
@@ -15,19 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.3 2003/10/15 19:54:41 joachim99
- * Handling of pFirstNonWhiteChar corrected.
- *
- * Revision 1.2 2003/10/14 20:49:56 joachim99
- * SourceData::preprocess(): Fix for several subsequent CR-characters.
- *
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- * *
- ***************************************************************************/
-
#include
#include
@@ -226,16 +213,160 @@
m_vSize = lines;
}
-// read and prepocess file for line matching input data
-void SourceData::readLMPPFile( SourceData* pOrigSource, const QString& ppCmd, bool bUpCase )
+
+// Must not be entered, when within a comment.
+// Returns either at a newline-character p[i]=='\n' or when i==size.
+// A line that contains only comments is still "white".
+// Comments in white lines must remain, while comments in
+// non-white lines are overwritten with spaces.
+static void checkLineForComments(
+ char* p, // pointer to start of buffer
+ int& i, // index of current position (in, out)
+ int size, // size of buffer
+ bool& bWhite, // false if this line contains nonwhite characters (in, out)
+ bool& bCommentInLine, // true if any comment is within this line (in, out)
+ bool& bStartsOpenComment // true if the line ends within an comment (out)
+ )
{
- if ( ppCmd.isEmpty() || pOrigSource->m_bPreserve )
+ bStartsOpenComment = false;
+ for(; i=size )
+ {
+ return;
+ }
+ else if ( !isspace(p[i]) )
+ {
+ bWhite = false;
+ }
+ }
+}
+
+// Modifies the input data, and replaces C/C++ comments with whitespace
+// when the line contains other data too. If the line contains only
+// a comment or white data, remember this in the flag bContainsPureComment.
+void SourceData::removeComments( LineData* pLD )
+{
+ int line=0;
+ char* p = (char*)m_pBuf;
+ bool bWithinComment=false;
+ int size = m_size;
+ for(int i=0; i=size || p[i]=='\n');
+ pLD[line].bContainsPureComment = bCommentInLine && bWhite;
+/* std::cout << line << " : " <<
+ ( bCommentInLine ? "c" : " " ) <<
+ ( bWhite ? "w " : " ") <<
+ std::string(pLD[line].pLine, pLD[line].size) << std::endl;*/
+
+ ++line;
+ }
+}
+
+// read and preprocess file for line matching input data
+void SourceData::readLMPPFile( SourceData* pOrigSource, const QString& ppCmd, bool bUpCase, bool bRemoveComments )
+{
+ if ( ( ppCmd.isEmpty() && !bRemoveComments ) || pOrigSource->m_bPreserve )
{
reset();
}
else
{
- m_fileName = pOrigSource->m_fileAccess.absFilePath();
+ setFilename( pOrigSource->m_fileAccess.absFilePath() );
readPPFile( false, ppCmd, bUpCase );
if ( m_vSize < pOrigSource->m_vSize )
{
@@ -243,6 +374,8 @@
m_vSize = pOrigSource->m_vSize;
}
}
+ if ( bRemoveComments && m_vSize==pOrigSource->m_vSize )
+ removeComments( &pOrigSource->m_v[0] );
}
@@ -304,37 +437,6 @@
return;
}
- /*
-
- FILE* f = fopen( filename, "rb" );
- if ( f==0 )
- {
- std::cerr << "File open error for file: '"<< filename <<"': ";
- perror("");
- return;
- }
-
- fseek( f, 0, SEEK_END );
-
- m_size = ftell(f);
-
- fseek( f, 0, SEEK_SET );
-
- m_pBuf = pBuf = new char[m_size+100];
- int bytesRead = fread( pBuf, 1, m_size, f );
- if( bytesRead != m_size )
- {
- std::cerr << "File read error for file: '"<< filename <<"': ";
-
- perror("");
- fclose(f);
- m_size = 0;
- delete pBuf;
- m_pBuf = 0;
- return;
- }
- fclose( f );
- */
if ( bUpCase )
{
@@ -958,7 +1060,7 @@
*/
}
-void calcWhiteDiff3Lines(
+void calcWhiteDiff3Lines(
Diff3LineList& d3ll, LineData* pldA, LineData* pldB, LineData* pldC
)
{
@@ -966,9 +1068,9 @@
for( ; i3!=d3ll.end(); ++i3 )
{
- i3->bWhiteLineA = ( (*i3).lineA == -1 || pldA[(*i3).lineA].whiteLine() );
- i3->bWhiteLineB = ( (*i3).lineB == -1 || pldB[(*i3).lineB].whiteLine() );
- i3->bWhiteLineC = ( (*i3).lineC == -1 || pldC[(*i3).lineC].whiteLine() );
+ i3->bWhiteLineA = ( (*i3).lineA == -1 || pldA[(*i3).lineA].whiteLine() || pldA[(*i3).lineA].bContainsPureComment );
+ i3->bWhiteLineB = ( (*i3).lineB == -1 || pldB[(*i3).lineB].whiteLine() || pldB[(*i3).lineB].bContainsPureComment );
+ i3->bWhiteLineC = ( (*i3).lineC == -1 || pldC[(*i3).lineC].whiteLine() || pldC[(*i3).lineC].bContainsPureComment );
}
}
@@ -995,7 +1097,7 @@
KMessageBox::error(0, i18n(
"Data loss error:\n"
"If it is reproducable please contact the author.\n"
- ), "Severe internal Error" );
+ ), i18n("Severe Internal Error") );
assert(false);
std::cerr << "Severe Internal Error.\n";
::exit(-1);
@@ -1009,24 +1111,198 @@
KMessageBox::error(0, i18n(
"Data loss error:\n"
"If it is reproducable please contact the author.\n"
- ), "Severe internal Error" );
+ ), i18n("Severe Internal Error") );
assert(false);
std::cerr << "Severe Internal Error.\n";
::exit(-1);
}
}
+inline bool equal( char c1, char c2, bool /*bStrict*/ )
+{
+ // If bStrict then white space doesn't match
+
+ //if ( bStrict && ( c1==' ' || c1=='\t' ) )
+ // return false;
+
+ return c1==c2;
+}
+
+
+// My own diff-invention:
+template
+void calcDiff( const T* p1, int size1, const T* p2, int size2, DiffList& diffList, int match, int maxSearchRange )
+{
+ diffList.clear();
+
+ const T* p1start = p1;
+ const T* p2start = p2;
+ const T* p1end=p1+size1;
+ const T* p2end=p2+size2;
+ for(;;)
+ {
+ int nofEquals = 0;
+ while( p1!=p1end && p2!=p2end && equal(*p1, *p2, false) )
+ {
+ ++p1;
+ ++p2;
+ ++nofEquals;
+ }
+
+ bool bBestValid=false;
+ int bestI1=0;
+ int bestI2=0;
+ int i1=0;
+ int i2=0;
+ for( i1=0; ; ++i1 )
+ {
+ if ( &p1[i1]==p1end || ( bBestValid && i1>= bestI1+bestI2))
+ {
+ break;
+ }
+ for(i2=0;i2=bestI1+bestI2) )
+ {
+ break;
+ }
+ else if( equal( p2[i2], p1[i1], true ) &&
+ ( match==1 || abs(i1-i2)<3 || ( &p2[i2+1]==p2end && &p1[i1+1]==p1end ) ||
+ ( &p2[i2+1]!=p2end && &p1[i1+1]!=p1end && equal( p2[i2+1], p1[i1+1], false ))
+ )
+ )
+ {
+ if ( i1+i2 < bestI1+bestI2 || bBestValid==false )
+ {
+ bestI1 = i1;
+ bestI2 = i2;
+ bBestValid = true;
+ break;
+ }
+ }
+ }
+ }
+
+ // The match was found using the strict search. Go back if there are non-strict
+ // matches.
+ while( bestI1>=1 && bestI2>=1 && equal( p1[bestI1-1], p2[bestI2-1], false ) )
+ {
+ --bestI1;
+ --bestI2;
+ }
+
+
+ bool bEndReached = false;
+ if (bBestValid)
+ {
+ // continue somehow
+ Diff d(nofEquals, bestI1, bestI2);
+ diffList.push_back( d );
+
+ p1 += bestI1;
+ p2 += bestI2;
+ }
+ else
+ {
+ // Nothing else to match.
+ Diff d(nofEquals, p1end-p1, p2end-p2);
+ diffList.push_back( d );
+
+ bEndReached = true; //break;
+ }
+
+ // Sometimes the algorithm that chooses the first match unfortunately chooses
+ // a match where later actually equal parts don't match anymore.
+ // A different match could be achieved, if we start at the end.
+ // Do it, if it would be a better match.
+ int nofUnmatched = 0;
+ const T* pu1 = p1-1;
+ const T* pu2 = p2-1;
+ while ( pu1>=p1start && pu2>=p2start && equal( *pu1, *pu2, false ) )
+ {
+ ++nofUnmatched;
+ --pu1;
+ --pu2;
+ }
+
+ Diff d = diffList.back();
+ if ( nofUnmatched > 0 )
+ {
+ // We want to go backwards the nofUnmatched elements and redo
+ // the matching
+ d = diffList.back();
+ Diff origBack = d;
+ diffList.pop_back();
+
+ while ( nofUnmatched > 0 )
+ {
+ if ( d.diff1 > 0 && d.diff2 > 0 )
+ {
+ --d.diff1;
+ --d.diff2;
+ --nofUnmatched;
+ }
+ else if ( d.nofEquals > 0 )
+ {
+ --d.nofEquals;
+ --nofUnmatched;
+ }
+
+ if ( d.nofEquals==0 && (d.diff1==0 || d.diff2==0) && nofUnmatched>0 )
+ {
+ if ( diffList.empty() )
+ break;
+ d.nofEquals += diffList.back().nofEquals;
+ d.diff1 += diffList.back().diff1;
+ d.diff2 += diffList.back().diff2;
+ diffList.pop_back();
+ bEndReached = false;
+ }
+ }
+
+ if ( bEndReached )
+ diffList.push_back( origBack );
+ else
+ {
+
+ p1 = pu1 + 1 + nofUnmatched;
+ p2 = pu2 + 1 + nofUnmatched;
+ diffList.push_back( d );
+ }
+ }
+ if ( bEndReached )
+ break;
+ }
+
+#ifndef NDEBUG
+ // Verify difflist
+ {
+ int l1=0;
+ int l2=0;
+ DiffList::iterator i;
+ for( i = diffList.begin(); i!=diffList.end(); ++i )
+ {
+ l1+= i->nofEquals + i->diff1;
+ l2+= i->nofEquals + i->diff2;
+ }
+
+ //if( l1!=p1-p1start || l2!=p2-p2start )
+ if( l1!=size1 || l2!=size2 )
+ assert( false );
+ }
+#endif
+}
void fineDiff(
Diff3LineList& diff3LineList,
int selector,
LineData* v1,
LineData* v2,
- int maxSearchLength,
bool& bTextsTotalEqual
)
{
// Finetuning: Diff each line with deltas
+ int maxSearchLength=500;
Diff3LineList::iterator i;
int k1=0;
int k2=0;
@@ -1066,6 +1342,14 @@
else if (selector==3){ delete (*i).pFineCA; (*i).pFineCA = pDiffList; }
else assert(false);
}
+
+ if ( (v1[k1].bContainsPureComment || v1[k1].whiteLine()) && (v2[k2].bContainsPureComment || v2[k2].whiteLine()))
+ {
+ if (selector==1){ i->bAEqB = true; }
+ else if (selector==2){ i->bBEqC = true; }
+ else if (selector==3){ i->bAEqC = true; }
+ else assert(false);
+ }
}
++listIdx;
g_pProgressDialog->setSubCurrent(double(listIdx)/listSize);
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/diff.h
--- a/kdiff3/src/diff.h Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/diff.h Tue Dec 09 20:29:43 2003 +0000
@@ -15,13 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- * *
- ***************************************************************************/
-
#ifndef DIFF_H
#define DIFF_H
@@ -108,7 +101,7 @@
bool bTextAEqB;
};
-void calcDiff3LineListUsingAB(
+void calcDiff3LineListUsingAB(
const DiffList* pDiffListAB,
Diff3LineList& d3ll
);
@@ -129,10 +122,11 @@
const char* pFirstNonWhiteChar;
int size;
- LineData(){ pLine=0; size=0; occurances=0; }
+ LineData(){ pLine=0; size=0; occurances=0; bContainsPureComment=false; }
int width(); // Calcs width considering tabs.
int occurances;
bool whiteLine(){ return pFirstNonWhiteChar-pLine == size; }
+ bool bContainsPureComment;
};
void prepareOccurances( LineData* p, int size );
@@ -150,9 +144,10 @@
bool m_bPreserve;
void reset();
void readPPFile( bool bPreserveCR, const QString& ppCmd, bool bUpCase );
- void readLMPPFile( SourceData* pOrigSource, const QString& ppCmd, bool bUpCase );
+ void readLMPPFile( SourceData* pOrigSource, const QString& ppCmd, bool bUpCase, bool bRemoveComments );
void readFile(const QString& filename, bool bFollowLinks, bool bUpCase );
void preprocess(bool bPreserveCR );
+ void removeComments( LineData* pLD );
void setData( const QString& data, bool bUpCase );
void setFilename(const QString& filename);
void setFileAccess( const FileAccess& fa );
@@ -218,6 +213,8 @@
class OptionDialog;
+QString decodeString( const char*s , OptionDialog* );
+
class DiffTextWindow : public QWidget
{
Q_OBJECT
@@ -337,6 +334,7 @@
public slots:
void setFirstLine(int firstLine);
+ void slotRedraw();
signals:
void setLine(int);
private:
@@ -376,6 +374,12 @@
void mergeOneLine( const Diff3Line& d, e_MergeDetails& mergeDetails, bool& bConflict, bool& bLineRemoved, int& src, bool bTwoInputs );
+enum e_MergeSrcSelector
+{
+ A=1,
+ B=2,
+ C=3
+};
class MergeResultWindow : public QWidget
{
@@ -398,6 +402,7 @@
bool saveDocument( const QString& fileName );
int getNrOfUnsolvedConflicts();
void choose(int selector);
+ void chooseGlobal(int selector, bool bConflictsOnly, bool bWhiteSpaceOnly );
int getNofColumns();
int getNofLines();
@@ -430,12 +435,6 @@
void slotGoNextUnsolvedConflict();
void slotGoPrevConflict();
void slotGoNextConflict();
- void slotChooseA();
- void slotChooseB();
- void slotChooseC();
- void slotChooseAEverywhere();
- void slotChooseBEverywhere();
- void slotChooseCEverywhere();
void slotAutoSolve();
void slotUnsolve();
void slotSetFastSelectorLine(int);
@@ -452,7 +451,7 @@
void showPopupMenu( const QPoint& point );
private:
- void merge(bool bAutoSolve, int defaultSelector);
+ void merge(bool bAutoSolve, int defaultSelector, bool bConflictsOnly=false, bool bWhiteSpaceOnly=false );
QCString getString( int lineIdx );
OptionDialog* m_pOptionDialog;
@@ -517,12 +516,16 @@
struct MergeLine
{
MergeLine()
- { srcSelect=0; mergeDetails=eDefault; d3lLineIdx = -1; srcRangeLength=0; bConflict=false; bDelta=false;}
+ {
+ srcSelect=0; mergeDetails=eDefault; d3lLineIdx = -1; srcRangeLength=0;
+ bConflict=false; bDelta=false; bWhiteSpaceConflict=false;
+ }
Diff3LineList::const_iterator id3l;
e_MergeDetails mergeDetails;
int d3lLineIdx; // Needed to show the correct window pos.
int srcRangeLength; // how many src-lines have this properties
bool bConflict;
+ bool bWhiteSpaceConflict;
bool bDelta;
int srcSelect;
MergeEditLineList mergeEditLineList;
@@ -596,189 +599,12 @@
int selector,
LineData* v1,
LineData* v2,
- int maxSearchLength,
bool& bTextsTotalEqual
);
bool equal( const LineData& l1, const LineData& l2, bool bStrict );
-inline bool equal( char c1, char c2, bool /*bStrict*/ )
-{
- // If bStrict then white space doesn't match
-
- //if ( bStrict && ( c1==' ' || c1=='\t' ) )
- // return false;
-
- return c1==c2;
-}
-
-
-// My own diff-invention:
-template
-void calcDiff( const T* p1, int size1, const T* p2, int size2, DiffList& diffList, int match, int maxSearchRange )
-{
- diffList.clear();
-
- const T* p1start = p1;
- const T* p2start = p2;
- const T* p1end=p1+size1;
- const T* p2end=p2+size2;
- for(;;)
- {
- int nofEquals = 0;
- while( p1!=p1end && p2!=p2end && equal(*p1, *p2, false) )
- {
-
-
- ++p1;
- ++p2;
- ++nofEquals;
- }
-
- bool bBestValid=false;
- int bestI1=0;
- int bestI2=0;
- int i1=0;
- int i2=0;
- for( i1=0; ; ++i1 )
- {
- if ( &p1[i1]==p1end || ( bBestValid && i1>= bestI1+bestI2))
- {
- break;
- }
- for(i2=0;i2=bestI1+bestI2) )
- {
- break;
- }
- else if( equal( p2[i2], p1[i1], true ) &&
- ( match==1 || abs(i1-i2)<3 || ( &p2[i2+1]==p2end && &p1[i1+1]==p1end ) ||
- ( &p2[i2+1]!=p2end && &p1[i1+1]!=p1end && equal( p2[i2+1], p1[i1+1], false ))
- )
- )
- {
- if ( i1+i2 < bestI1+bestI2 || bBestValid==false )
- {
- bestI1 = i1;
- bestI2 = i2;
- bBestValid = true;
- break;
- }
- }
- }
- }
-
- // The match was found using the strict search. Go back if there are non-strict
- // matches.
- while( bestI1>=1 && bestI2>=1 && equal( p1[bestI1-1], p2[bestI2-1], false ) )
- {
- --bestI1;
- --bestI2;
- }
-
-
- bool bEndReached = false;
- if (bBestValid)
- {
- // continue somehow
- Diff d(nofEquals, bestI1, bestI2);
- diffList.push_back( d );
-
- p1 += bestI1;
- p2 += bestI2;
- }
- else
- {
- // Nothing else to match.
- Diff d(nofEquals, p1end-p1, p2end-p2);
- diffList.push_back( d );
-
- bEndReached = true; //break;
- }
-
- // Sometimes the algorithm that chooses the first match unfortunately chooses
- // a match where later actually equal parts don't match anymore.
- // A different match could be achieved, if we start at the end.
- // Do it, if it would be a better match.
- int nofUnmatched = 0;
- const T* pu1 = p1-1;
- const T* pu2 = p2-1;
- while ( pu1>=p1start && pu2>=p2start && equal( *pu1, *pu2, false ) )
- {
- ++nofUnmatched;
- --pu1;
- --pu2;
- }
-
- Diff d = diffList.back();
- if ( nofUnmatched > 0 )
- {
- // We want to go backwards the nofUnmatched elements and redo
- // the matching
- d = diffList.back();
- Diff origBack = d;
- diffList.pop_back();
-
- while ( nofUnmatched > 0 )
- {
- if ( d.diff1 > 0 && d.diff2 > 0 )
- {
- --d.diff1;
- --d.diff2;
- --nofUnmatched;
- }
- else if ( d.nofEquals > 0 )
- {
- --d.nofEquals;
- --nofUnmatched;
- }
-
- if ( d.nofEquals==0 && (d.diff1==0 || d.diff2==0) && nofUnmatched>0 )
- {
- if ( diffList.empty() )
- break;
- d.nofEquals += diffList.back().nofEquals;
- d.diff1 += diffList.back().diff1;
- d.diff2 += diffList.back().diff2;
- diffList.pop_back();
- bEndReached = false;
- }
- }
-
- if ( bEndReached )
- diffList.push_back( origBack );
- else
- {
-
- p1 = pu1 + 1 + nofUnmatched;
- p2 = pu2 + 1 + nofUnmatched;
- diffList.push_back( d );
- }
- }
- if ( bEndReached )
- break;
- }
-
-#ifndef NDEBUG
- // Verify difflist
- {
- int l1=0;
- int l2=0;
- DiffList::iterator i;
- for( i = diffList.begin(); i!=diffList.end(); ++i )
- {
- l1+= i->nofEquals + i->diff1;
- l2+= i->nofEquals + i->diff2;
- }
-
- //if( l1!=p1-p1start || l2!=p2-p2start )
- if( l1!=size1 || l2!=size2 )
- assert( false );
- }
-#endif
-}
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/difftextwindow.cpp
--- a/kdiff3/src/difftextwindow.cpp Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/difftextwindow.cpp Tue Dec 09 20:29:43 2003 +0000
@@ -15,15 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.2 2003/10/11 12:47:09 joachim99
- * Avoid QWidget::setFont() in paintEvent()
- *
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- ***************************************************************************/
-
#include
#include "diff.h"
#include "merger.h"
@@ -37,6 +28,7 @@
#include
#include
#include
+#include
#define leftInfoWidth (4+m_lineNumberWidth) // Nr of information columns on left side
@@ -500,7 +492,7 @@
}
p.fillRect( leftInfoWidth*fontWidth, yOffset, width(), fontHeight, bgColor );
-
+
if (pld!=0)
{
// First calculate the "changed" information for each character.
@@ -548,11 +540,18 @@
c = m_cDiffBoth;
}
+ if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 && !m_pOptionDialog->m_bShowWhiteSpace )
+ {
+ // The user doesn't want to see highlighted white space.
+ c = m_pOptionDialog->m_fgColor;
+ }
+
QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight );
if ( m_invalidRect.intersects( outRect ) )
{
if( !selection.within( line, outPos ) )
{
+
if( c!=m_pOptionDialog->m_fgColor )
{
QColor lightc = diffBgColor;
@@ -564,7 +563,7 @@
p.setPen( c );
if ( s[0]==' ' && c!=m_pOptionDialog->m_fgColor && charChanged[i]!=0 )
{
- if ( m_pOptionDialog->m_bShowWhiteSpace )
+ if ( m_pOptionDialog->m_bShowWhiteSpaceCharacters && m_pOptionDialog->m_bShowWhiteSpace)
{
p.fillRect( xOffset + fontWidth*outPos, yOffset+fontAscent,
fontWidth*spaces-1, fontDescent+1, c );
@@ -572,7 +571,7 @@
}
else
{
- p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, QString::fromUtf8(s) );
+ p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
}
p.setFont(normalFont);
}
@@ -583,7 +582,7 @@
fontWidth*(spaces), fontHeight, colorGroup().highlight() );
p.setPen( colorGroup().highlightedText() );
- p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, QString::fromUtf8(s) );
+ p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) );
selection.bSelectionContainsData = true;
}
@@ -617,8 +616,11 @@
}
if ( c!=m_pOptionDialog->m_fgColor && whatChanged2==0 )//&& whatChanged==0 )
{
- p.setBrushOrigin(0,0);
- p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, QBrush(c,Dense5Pattern) );
+ if ( m_pOptionDialog->m_bShowWhiteSpace )
+ {
+ p.setBrushOrigin(0,0);
+ p.fillRect( xLeft, yOffset, fontWidth*2-1, fontHeight, QBrush(c,Dense5Pattern) );
+ }
}
else
{
@@ -782,11 +784,11 @@
const char* winId = ( m_winIdx==1 ? (m_bTriple?"A (Base)":"A") :
( m_winIdx==2 ? "B" : "C" ) );
- QString s;
+ QString s = QString(" ")+ winId + " : " + m_filename + " : ";
if ( l!=-1 )
- s.sprintf(" %s : %s : Topline %d", winId, m_filename.ascii(), l+1 );
+ s += i18n("Topline %1").arg( l+1 );
else
- s.sprintf(" %s : %s: End", winId, m_filename.ascii() );
+ s += i18n("End");
if (hasFocus())
{
@@ -1021,3 +1023,20 @@
selection.end( lastLine, convertToPosOnScreen( getString(lastLine), endPos ) );
update();
}
+
+
+#include
+
+QString decodeString( const char*s , OptionDialog* pOptions )
+{
+ if ( pOptions->m_bStringEncoding )
+ {
+ QTextCodec* c = QTextCodec::codecForLocale();
+ if (c!=0)
+ return c->toUnicode( s );
+ else
+ return QString(s);
+ }
+ else
+ return QString(s);
+}
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/directorymergewindow.cpp
--- a/kdiff3/src/directorymergewindow.cpp Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/directorymergewindow.cpp Tue Dec 09 20:29:43 2003 +0000
@@ -15,18 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.3 2003/10/15 20:14:03 joachim99
- * Fix for MergeOperation DeleteAB.
- *
- * Revision 1.2 2003/10/11 12:41:57 joachim99
- * Fix for gcc 2.95
- *
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- ***************************************************************************/
-
#include "directorymergewindow.h"
#include "optiondialog.h"
#include
@@ -37,6 +25,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -50,6 +39,7 @@
#include
#include
+static bool conflictingFileTypes(MergeFileInfos& mfi);
class StatusInfo : public QListView
{
@@ -120,14 +110,14 @@
{
if ( fi1.isSymLink() != fi2.isSymLink() )
{
- status = "Mix of links and normal files.";
+ status = i18n("Mix of links and normal files.");
return;
}
else if ( fi1.isSymLink() && fi2.isSymLink() )
{
bError = false;
bEqual = fi1.readLink() == fi2.readLink();
- status = "Link: ";
+ status = i18n("Link: ");
return;
}
}
@@ -135,7 +125,12 @@
if ( fi1.size()!=fi2.size() )
{
bEqual = false;
- status = "Size. ";
+ status = i18n("Size. ");
+ return;
+ }
+ else if ( m_pOptions->m_bDmTrustSize )
+ {
+ bEqual = true;
return;
}
@@ -143,7 +138,7 @@
{
bEqual = ( fi1.lastModified() == fi2.lastModified() && fi1.size()==fi2.size() );
bError = false;
- status = "Date&Size: ";
+ status = i18n("Date & Size: ");
return;
}
@@ -152,13 +147,13 @@
TempRemover tr1( fileName1, fi1 );
if ( !tr1.success() )
{
- status = "Creating temp copy of " + fileName1 + " failed.";
+ status = i18n("Creating temp copy of %1 failed.").arg(fileName1);
return;
}
TempRemover tr2( fileName2, fi2 );
if ( !tr2.success() )
{
- status = "Creating temp copy of " + fileName2 + " failed.";
+ status = i18n("Creating temp copy of %1 failed.").arg(fileName2);
return;
}
@@ -169,7 +164,7 @@
if ( ! file1.open(IO_ReadOnly) )
{
- status = "Opening " + fileName1 + " failed.";
+ status = i18n("Opening %1 failed.").arg(fileName1);
return;
}
@@ -177,7 +172,7 @@
if ( ! file2.open(IO_ReadOnly) )
{
- status = "Opening " + fileName2 + " failed.";
+ status = i18n("Opening %1 failed.").arg(fileName2);
return;
}
@@ -193,13 +188,13 @@
int len = min2( size, (t_FileSize)buf1.size() );
if( len != file1.readBlock( &buf1[0], len ) )
{
- status = "Error reading from " + fileName1;
+ status = i18n("Error reading from %1").arg(fileName1);
return;
}
if( len != file2.readBlock( &buf2[0], len ) )
{
- status = "Error reading from " + fileName2;
+ status = i18n("Error reading from %1").arg(fileName2);
return;
}
@@ -240,18 +235,17 @@
m_bAllowResizeEvents = true;
m_bSimulatedMergeStarted=false;
m_bRealMergeStarted=false;
- m_bSingleFileOperationStarted=false;
m_bError = false;
m_bSyncMode = false;
m_pStatusInfo = new StatusInfo(0);
m_pStatusInfo->hide();
- addColumn("Name");
+ addColumn(i18n("Name"));
addColumn("A");
addColumn("B");
addColumn("C");
- addColumn("Operation");
- addColumn("Status");
+ addColumn(i18n("Operation"));
+ addColumn(i18n("Status"));
}
DirectoryMergeWindow::~DirectoryMergeWindow()
@@ -275,7 +269,7 @@
{
int result = KMessageBox::warningYesNo(this,
i18n("You are currently doing a directory merge. Are you sure, you want to abort the merge and rescan the directory?"),
- i18n("Warning"), i18n("Yes - Rescan"), i18n("No - Continue merging") );
+ i18n("Warning"), i18n("Rescan"), i18n("Continue Merging") );
if ( result!=KMessageBox::Yes )
return;
}
@@ -371,7 +365,7 @@
clear();
- m_pCurrentItemForOperation = 0;
+ m_currentItemForOperation = m_mergeItemList.end();
m_dirA = dirA;
m_dirB = dirB;
@@ -386,15 +380,15 @@
QString text( i18n("Opening of directories failed:") );
text += "\n\n";
if ( !dirA.isDir() )
- { text += "Dir A \"" + m_dirA.prettyAbsPath() + "\" does not exist or is not a directory.\n"; }
+ { text += i18n("Dir A \"%1\" does not exist or is not a directory.\n").arg(m_dirA.prettyAbsPath()); }
if ( !dirB.isDir() )
- { text += "Dir B \"" + m_dirB.prettyAbsPath() + "\" does not exist or is not a directory.\n"; }
+ { text += i18n("Dir B \"%1\" does not exist or is not a directory.\n").arg(m_dirB.prettyAbsPath()); }
if ( m_dirC.isValid() && !m_dirC.isDir() )
- { text += "Dir C \"" + m_dirC.prettyAbsPath() + "\" does not exist or is not a directory.\n"; }
+ { text += i18n("Dir C \"%1\" does not exist or is not a directory.\n").arg(m_dirC.prettyAbsPath()); }
- KMessageBox::sorry( this, text, i18n("Directory open error") );
+ KMessageBox::sorry( this, text, i18n("Directory Open Error") );
return false;
}
@@ -404,7 +398,7 @@
KMessageBox::error(this,
i18n( "The destination directory must not be the same as A or B when"
"three directories are merged.\nCheck again before continuing."),
- "KDiff3: Parameter warning");
+ i18n("Parameter Warning"));
return false;
}
@@ -431,7 +425,7 @@
bool bListDirSuccessC = true;
if ( m_dirA.isValid() )
{
- g_pProgressDialog->setInformation("Reading Directory A");
+ g_pProgressDialog->setInformation(i18n("Reading Directory A"));
g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
++currentScan;
@@ -453,7 +447,7 @@
if ( m_dirB.isValid() )
{
- g_pProgressDialog->setInformation("Reading Directory B");
+ g_pProgressDialog->setInformation(i18n("Reading Directory B"));
g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
++currentScan;
@@ -475,7 +469,7 @@
e_MergeOperation eDefaultMergeOp;
if ( m_dirC.isValid() )
{
- g_pProgressDialog->setInformation("Reading Directory C");
+ g_pProgressDialog->setInformation(i18n("Reading Directory C"));
g_pProgressDialog->setSubRangeTransformation(currentScan/nofScans, (currentScan+1)/nofScans);
++currentScan;
@@ -553,7 +547,7 @@
nofFiles, nofDirs, nofEqualFiles, nofManualMerges );
QString s;
- s = i18n("Directory Comparison Status:") + "\n\n" +
+ s = i18n("Directory Comparison Status") + "\n\n" +
i18n("Number of subdirectories:") +" "+ QString::number(nofDirs) + "\n"+
i18n("Number of equal files:") +" "+ QString::number(nofEqualFiles) + "\n"+
i18n("Number of different files:") +" "+ QString::number(nofFiles-nofEqualFiles);
@@ -604,11 +598,91 @@
setListViewItemOpen( p, true );
}
+static void setMergeOperation( QListViewItem* pLVI, e_MergeOperation eMergeOp )
+{
+ if ( pLVI==0 ) return;
+
+ DirMergeItem* pDMI = static_cast(pLVI);
+ MergeFileInfos& mfi = *pDMI->m_pMFI;
+
+ mfi.setMergeOperation(eMergeOp );
+}
+
+// Merge current item (merge mode)
+void DirectoryMergeWindow::slotCurrentDoNothing() { setMergeOperation(currentItem(), eNoOperation ); }
+void DirectoryMergeWindow::slotCurrentChooseA() { setMergeOperation(currentItem(), eCopyAToDest ); }
+void DirectoryMergeWindow::slotCurrentChooseB() { setMergeOperation(currentItem(), eCopyBToDest ); }
+void DirectoryMergeWindow::slotCurrentChooseC() { setMergeOperation(currentItem(), eCopyCToDest ); }
+void DirectoryMergeWindow::slotCurrentMerge()
+{
+ bool bThreeDirs = m_dirC.isValid();
+ setMergeOperation(currentItem(), bThreeDirs ? eMergeABCToDest : eMergeABToDest );
+}
+void DirectoryMergeWindow::slotCurrentDelete() { setMergeOperation(currentItem(), eDeleteFromDest ); }
+// Sync current item
+void DirectoryMergeWindow::slotCurrentCopyAToB() { setMergeOperation(currentItem(), eCopyAToB ); }
+void DirectoryMergeWindow::slotCurrentCopyBToA() { setMergeOperation(currentItem(), eCopyBToA ); }
+void DirectoryMergeWindow::slotCurrentDeleteA() { setMergeOperation(currentItem(), eDeleteA ); }
+void DirectoryMergeWindow::slotCurrentDeleteB() { setMergeOperation(currentItem(), eDeleteB ); }
+void DirectoryMergeWindow::slotCurrentDeleteAAndB() { setMergeOperation(currentItem(), eDeleteAB ); }
+void DirectoryMergeWindow::slotCurrentMergeToA() { setMergeOperation(currentItem(), eMergeToA ); }
+void DirectoryMergeWindow::slotCurrentMergeToB() { setMergeOperation(currentItem(), eMergeToB ); }
+void DirectoryMergeWindow::slotCurrentMergeToAAndB() { setMergeOperation(currentItem(), eMergeToAB ); }
+
+
+void DirectoryMergeWindow::keyPressEvent( QKeyEvent* e )
+{
+ if ( (e->state() & Qt::ControlButton)!=0 )
+ {
+ bool bThreeDirs = m_dirC.isValid();
+
+ QListViewItem* lvi = currentItem();
+ DirMergeItem* pDMI = lvi==0 ? 0 : static_cast(lvi);
+ MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
+
+ if ( pMFI==0 ) return;
+ bool bMergeMode = bThreeDirs || !m_bSyncMode;
+ bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
+
+ if ( bMergeMode )
+ {
+ switch(e->key())
+ {
+ case Key_1: if(pMFI->m_bExistsInA){ slotCurrentChooseA(); } return;
+ case Key_2: if(pMFI->m_bExistsInB){ slotCurrentChooseB(); } return;
+ case Key_3: if(pMFI->m_bExistsInC){ slotCurrentChooseC(); } return;
+ case Key_Space: slotCurrentDoNothing(); return;
+ case Key_4: if ( !bFTConflict ) { slotCurrentMerge(); } return;
+ case Key_Delete: slotCurrentDelete(); return;
+ default: break;
+ }
+ }
+ else
+ {
+ switch(e->key())
+ {
+ case Key_1: if(pMFI->m_bExistsInA){ slotCurrentCopyAToB(); } return;
+ case Key_2: if(pMFI->m_bExistsInB){ slotCurrentCopyBToA(); } return;
+ case Key_Space: slotCurrentDoNothing(); return;
+ case Key_4: if ( !bFTConflict ) { slotCurrentMergeToAAndB(); } return;
+ case Key_Delete: if( pMFI->m_bExistsInA && pMFI->m_bExistsInB ) slotCurrentDeleteAAndB();
+ else if( pMFI->m_bExistsInA ) slotCurrentDeleteA();
+ else if( pMFI->m_bExistsInB ) slotCurrentDeleteB();
+ return;
+ default: break;
+ }
+ }
+ }
+
+ QListView::keyPressEvent(e);
+}
+
+
void DirectoryMergeWindow::setAllMergeOperations( e_MergeOperation eDefaultOperation )
{
if ( KMessageBox::Yes == KMessageBox::warningYesNo(this,
i18n("This affects all merge operations."),
- i18n("KDiff3: Changing all merge operations"),i18n("Continue"), i18n("Cancel") ) )
+ i18n("Changing All Merge Operations"),i18n("C&ontinue"), i18n("&Cancel") ) )
{
for( QListViewItem* p = firstChild(); p!=0; p = p->nextSibling() )
{
@@ -875,7 +949,7 @@
QString("");
g_pProgressDialog->setInformation(
- "Processing " + QString::number(currentIdx) +" / "+ QString::number(nrOfFiles)
+ i18n("Processing ") + QString::number(currentIdx) +" / "+ QString::number(nrOfFiles)
+"\n" + fileName, double(currentIdx) / nrOfFiles, false );
if ( g_pProgressDialog->wasCancelled() ) break;
++currentIdx;
@@ -1004,10 +1078,10 @@
if ( eDefaultMergeOp == eMergeABCToDest && !bCheckC ) { eDefaultMergeOp = eMergeABToDest; }
if ( eDefaultMergeOp == eMergeToAB && bCheckC ) { assert(false); }
-
+
if ( eDefaultMergeOp == eMergeToA || eDefaultMergeOp == eMergeToB ||
eDefaultMergeOp == eMergeABCToDest || eDefaultMergeOp == eMergeABToDest || eDefaultMergeOp == eMergeToAB )
- {
+ {
if ( !bCheckC )
{
if ( mfi.m_bEqualAB )
@@ -1174,53 +1248,45 @@
bool bThreeDirs = m_dirC.isValid();
- //bool bImmediate = (button==Qt::LeftButton);
-
KPopupMenu m(this);
- //if (bImmediate ) m.insertItem("Immediate Mode", eTitleId );
- //else m.insertItem("Postponed Mode", eTitleId );
- //m.setItemEnabled ( eTitleId, false );
if ( bThreeDirs )
{
- m.insertItem("Do nothing", eNoOperation );
+ dirCurrentDoNothing->plug(&m);
int count=0;
- if ( mfi.m_bExistsInA ) { m.insertItem("A", eCopyAToDest ); ++count; }
- if ( mfi.m_bExistsInB ) { m.insertItem("B", eCopyBToDest ); ++count; }
- if ( mfi.m_bExistsInC ) { m.insertItem("C", eCopyCToDest ); ++count; }
- if ( !conflictingFileTypes(mfi) && count>1 ) m.insertItem("Merge", eMergeABCToDest );
- m.insertItem("Delete (if exists)", eDeleteFromDest );
+ if ( mfi.m_bExistsInA ) { dirCurrentChooseA->plug(&m); ++count; }
+ if ( mfi.m_bExistsInB ) { dirCurrentChooseB->plug(&m); ++count; }
+ if ( mfi.m_bExistsInC ) { dirCurrentChooseC->plug(&m); ++count; }
+ if ( !conflictingFileTypes(mfi) && count>1 ) dirCurrentMerge->plug(&m);
+ dirCurrentDelete->plug(&m);
}
else if ( m_bSyncMode )
{
- m.insertItem("Do nothing", eNoOperation );
- if ( mfi.m_bExistsInA ) m.insertItem("Copy A to B", eCopyAToB );
- if ( mfi.m_bExistsInB ) m.insertItem("Copy B to A", eCopyBToA );
- if ( mfi.m_bExistsInA ) m.insertItem("Delete A", eDeleteA );
- if ( mfi.m_bExistsInB ) m.insertItem("Delete B", eDeleteB );
+ dirCurrentSyncDoNothing->plug(&m);
+ if ( mfi.m_bExistsInA ) dirCurrentSyncCopyAToB->plug(&m);
+ if ( mfi.m_bExistsInB ) dirCurrentSyncCopyBToA->plug(&m);
+ if ( mfi.m_bExistsInA ) dirCurrentSyncDeleteA->plug(&m);
+ if ( mfi.m_bExistsInB ) dirCurrentSyncDeleteB->plug(&m);
if ( mfi.m_bExistsInA && mfi.m_bExistsInB )
{
- m.insertItem("Delete A and B", eDeleteAB );
+ dirCurrentSyncDeleteAAndB->plug(&m);
if ( !conflictingFileTypes(mfi))
{
- m.insertItem("Merge to A", eMergeToA );
- m.insertItem("Merge to B", eMergeToB );
- m.insertItem("Merge to A and B", eMergeToAB );
+ dirCurrentSyncMergeToA->plug(&m);
+ dirCurrentSyncMergeToB->plug(&m);
+ dirCurrentSyncMergeToAAndB->plug(&m);
}
}
}
else
{
- m.insertItem("Do nothing", eNoOperation );
- if ( mfi.m_bExistsInA ) m.insertItem("A", eCopyAToDest );
- if ( mfi.m_bExistsInB ) m.insertItem("B", eCopyBToDest );
- if ( mfi.m_bExistsInA && mfi.m_bExistsInB && !conflictingFileTypes(mfi) )
- m.insertItem("Merge", eMergeABToDest );
- m.insertItem("Delete (if exists)", eDeleteFromDest );
+ dirCurrentDoNothing->plug(&m);
+ if ( mfi.m_bExistsInA ) { dirCurrentChooseA->plug(&m); }
+ if ( mfi.m_bExistsInB ) { dirCurrentChooseB->plug(&m); }
+ if ( !conflictingFileTypes(mfi) && mfi.m_bExistsInA && mfi.m_bExistsInB ) dirCurrentMerge->plug(&m);
+ dirCurrentDelete->plug(&m);
}
- int result = m.exec( p );
- if (result>=0 )
- mfi.setMergeOperation( (e_MergeOperation)result );
+ m.exec( p );
}
// Since Qt 2.3.0 doesn't allow the specification of a compare operator, this trick emulates it.
@@ -1231,14 +1297,14 @@
#endif
DirMergeItem::DirMergeItem( QListView* pParent, const QString& fileName, MergeFileInfos* pMFI )
-: QListViewItem( pParent, DIRSORT( fileName ), "","","", "To do." )
+: QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do.") )
{
pMFI->m_pDMI = this;
m_pMFI = pMFI;
}
DirMergeItem::DirMergeItem( DirMergeItem* pParent, const QString& fileName, MergeFileInfos* pMFI )
-: QListViewItem( pParent, DIRSORT( fileName ), "","","", "To do." )
+: QListViewItem( pParent, DIRSORT( fileName ), "","","", i18n("To do.") )
{
pMFI->m_pDMI = this;
m_pMFI = pMFI;
@@ -1251,30 +1317,36 @@
void MergeFileInfos::setMergeOperation( e_MergeOperation eMOp )
{
+ if ( eMOp != m_eMergeOperation )
+ {
+ m_bOperationComplete = false;
+ m_pDMI->setText( s_OpStatusCol, "" );
+ }
+
m_eMergeOperation = eMOp;
- const char* s=0;
+ QString s;
bool bDir = m_bDirA || m_bDirB || m_bDirC;
if( m_pDMI!=0 )
{
switch( m_eMergeOperation )
{
case eNoOperation: s=""; m_pDMI->setText(s_OpCol,""); break;
- case eCopyAToB: s="Copy A to B"; break;
- case eCopyBToA: s="Copy B to A"; break;
- case eDeleteA: s="Delete A"; break;
- case eDeleteB: s="Delete B"; break;
- case eDeleteAB: s="Delete A and B"; break;
- case eMergeToA: s="Merge to A"; break;
- case eMergeToB: s="Merge to B"; break;
- case eMergeToAB: s="Merge to A and B"; break;
+ case eCopyAToB: s=i18n("Copy A to B"); break;
+ case eCopyBToA: s=i18n("Copy B to A"); break;
+ case eDeleteA: s=i18n("Delete A"); break;
+ case eDeleteB: s=i18n("Delete B"); break;
+ case eDeleteAB: s=i18n("Delete A & B"); break;
+ case eMergeToA: s=i18n("Merge to A"); break;
+ case eMergeToB: s=i18n("Merge to B"); break;
+ case eMergeToAB: s=i18n("Merge to A & B"); break;
case eCopyAToDest: s="A"; break;
case eCopyBToDest: s="B"; break;
case eCopyCToDest: s="C"; break;
- case eDeleteFromDest: s="Delete (if exists)"; break;
- case eMergeABCToDest: s= bDir ? "Merge" : "Merge (manual)"; break;
- case eMergeABToDest: s= bDir ? "Merge" : "Merge (manual)"; break;
- case eConflictingFileTypes: s="Error: Conflicting File Types"; break;
- case eConflictingAges: s="Error: Dates are equal but files are not."; break;
+ case eDeleteFromDest: s=i18n("Delete (if exists)"); break;
+ case eMergeABCToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
+ case eMergeABToDest: s= bDir ? i18n("Merge") : i18n("Merge (manual)"); break;
+ case eConflictingFileTypes: s=i18n("Error: Conflicting File Types"); break;
+ case eConflictingAges: s=i18n("Error: Dates are equal but files are not."); break;
default: assert(false); break;
}
m_pDMI->setText(s_OpCol,s);
@@ -1298,7 +1370,7 @@
if ( m_bRealMergeStarted )
{
- KMessageBox::sorry(this,"This operation is currently not possible.","KDiff3");
+ KMessageBox::sorry(this,i18n("This operation is currently not possible."),i18n("Operation Not Possible"));
return;
}
@@ -1320,36 +1392,6 @@
emit updateAvailabilities();
}
-void DirectoryMergeWindow::mergeCurrentFile()
-{
- if (!canContinue()) return;
-
- if ( m_bRealMergeStarted )
- {
- KMessageBox::sorry(this,"This operation is currently not possible because diff merge currently runs.","KDiff3");
- return;
- }
-
- if ( isFileSelected() )
- {
- DirMergeItem* pDMI = static_cast( selectedItem() );
- if ( pDMI != 0 )
- {
- MergeFileInfos& mfi = *pDMI->m_pMFI;
- m_bSingleFileOperationStarted = true;
- emit startDiffMerge(
- mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
- mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
- mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
- fullNameDest(mfi),
- "","",""
- );
- m_pCurrentItemForOperation = pDMI;
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "In progress ..." );
- }
- }
- emit updateAvailabilities();
-}
bool DirectoryMergeWindow::isFileSelected()
@@ -1365,33 +1407,41 @@
void DirectoryMergeWindow::mergeResultSaved(const QString& fileName)
{
- m_bSingleFileOperationStarted = false;
- if ( m_pCurrentItemForOperation!=0 && m_pCurrentItemForOperation->m_pMFI==0 )
+ DirMergeItem* pCurrentItemForOperation = (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() )
+ ? 0
+ : *m_currentItemForOperation;
+
+ if ( pCurrentItemForOperation!=0 && pCurrentItemForOperation->m_pMFI==0 )
{
- KMessageBox::error( this, "This should never happen: \n\nmergeResultSaved: m_pMFI=0\n\nIf you know how to reproduce this, please contact the program author.","Program Error" );
+ KMessageBox::error( this, i18n("This should never happen: \n\nmergeResultSaved: m_pMFI=0\n\nIf you know how to reproduce this, please contact the program author."),i18n("Program Error") );
return;
}
- if ( m_pCurrentItemForOperation!=0 && fileName == fullNameDest(*m_pCurrentItemForOperation->m_pMFI) )
+ if ( pCurrentItemForOperation!=0 && fileName == fullNameDest(*pCurrentItemForOperation->m_pMFI) )
{
- if ( m_pCurrentItemForOperation->m_pMFI->m_eMergeOperation==eMergeToAB )
+ if ( pCurrentItemForOperation->m_pMFI->m_eMergeOperation==eMergeToAB )
{
- MergeFileInfos& mfi = *m_pCurrentItemForOperation->m_pMFI;
+ MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
bool bSuccess = copyFLD( fullNameB(mfi), fullNameA(mfi) );
if (!bSuccess)
{
- KMessageBox::error(this, i18n("An error occurred while copying.\n"), "KDiff3: Error" );
- m_pStatusInfo->setCaption("KDiff3: Merge-Error");
+ KMessageBox::error(this, i18n("An error occurred while copying.\n"), i18n("Error") );
+ m_pStatusInfo->setCaption(i18n("Merge Error"));
m_pStatusInfo->show();
if ( m_pStatusInfo->firstChild()!=0 )
m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
m_bError = true;
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "Error." );
+ pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
mfi.m_eMergeOperation = eCopyBToA;
return;
}
}
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "Done." );
- m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
+ pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Done.") );
+ pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
+ if ( m_mergeItemList.size()==1 )
+ {
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
+ }
}
emit updateAvailabilities();
@@ -1403,76 +1453,246 @@
checkIfCanContinue( &bCanContinue );
if ( bCanContinue && !m_bError )
{
- if ( m_bRealMergeStarted && m_pCurrentItemForOperation!=0 && ! m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
+ DirMergeItem* pCurrentItemForOperation =
+ (m_mergeItemList.empty() || m_currentItemForOperation==m_mergeItemList.end() ) ? 0 : *m_currentItemForOperation;
+
+ if ( pCurrentItemForOperation!=0 && ! pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
{
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "Not saved." );
- m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
+ pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Not saved.") );
+ pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
+ if ( m_mergeItemList.size()==1 )
+ {
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
+ }
}
}
return bCanContinue;
}
-void DirectoryMergeWindow::mergeContinue()
+bool DirectoryMergeWindow::executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge )
{
- if ( ! canContinue() ) return;
+ bool bCreateBackups = m_pOptions->m_bDmCreateBakFiles;
+ // First decide destname
+ QString destName;
+ switch( mfi.m_eMergeOperation )
+ {
+ case eNoOperation: break;
+ case eDeleteAB: break;
+ case eMergeToAB: // let the user save in B. In mergeResultSaved() the file will be copied to A.
+ case eMergeToB:
+ case eDeleteB:
+ case eCopyAToB: destName = fullNameB(mfi); break;
+ case eMergeToA:
+ case eDeleteA:
+ case eCopyBToA: destName = fullNameA(mfi); break;
+ case eMergeABToDest:
+ case eMergeABCToDest:
+ case eCopyAToDest:
+ case eCopyBToDest:
+ case eCopyCToDest:
+ case eDeleteFromDest: destName = fullNameDest(mfi); break;
+ default:
+ KMessageBox::error( this, i18n("Unknown merge operation. (This must never happen!)"), i18n("Error") );
+ assert(false);
+ }
- m_bSingleFileOperationStarted = false;
+ bool bSuccess = false;
+ bSingleFileMerge = false;
+ switch( mfi.m_eMergeOperation )
+ {
+ case eNoOperation: bSuccess = true; break;
+ case eCopyAToDest:
+ case eCopyAToB: bSuccess = copyFLD( fullNameA(mfi), destName ); break;
+ case eCopyBToDest:
+ case eCopyBToA: bSuccess = copyFLD( fullNameB(mfi), destName ); break;
+ case eCopyCToDest: bSuccess = copyFLD( fullNameC(mfi), destName ); break;
+ case eDeleteFromDest:
+ case eDeleteA:
+ case eDeleteB: bSuccess = deleteFLD( destName, bCreateBackups ); break;
+ case eDeleteAB: bSuccess = deleteFLD( fullNameA(mfi), bCreateBackups ) &&
+ deleteFLD( fullNameB(mfi), bCreateBackups ); break;
+ case eMergeABToDest:
+ case eMergeToA:
+ case eMergeToAB:
+ case eMergeToB: bSuccess = mergeFLD( fullNameA(mfi), fullNameB(mfi), "",
+ destName, bSingleFileMerge );
+ break;
+ case eMergeABCToDest:bSuccess = mergeFLD(
+ mfi.m_bExistsInA ? fullNameA(mfi) : QString(""),
+ mfi.m_bExistsInB ? fullNameB(mfi) : QString(""),
+ mfi.m_bExistsInC ? fullNameC(mfi) : QString(""),
+ destName, bSingleFileMerge );
+ break;
+ default:
+ KMessageBox::error( this, i18n("Unknown merge operation."), i18n("Error") );
+ assert(false);
+ }
- int nrOfItems = 0;
- int nrOfCompletedItems = 0;
- int nrOfCompletedSimItems = 0;
+ return bSuccess;
+}
- if ( !m_bSimulatedMergeStarted && !m_bRealMergeStarted )
+
+// Check if the merge can start, and prepare the m_mergeItemList which then contains all
+// items that must be merged.
+void DirectoryMergeWindow::prepareMergeStart( QListViewItem* pBegin, QListViewItem* pEnd, bool bVerbose )
+{
+ if ( bVerbose )
{
- // First check if an invalid merge operations exist.
- for( QListViewItem* p=firstChild(); p!=0; p = treeIterator( p ) )
+ int status = KMessageBox::warningYesNoCancel(this,
+ i18n("The merge is about to begin.\n\n"
+ "Choose \"Do it\" if you have read the instructions and know what you are doing.\n"
+ "Choosing \"Simulate it\" will tell you what would happen.\n\n"
+ "Be aware that this program still has beta status "
+ "and there is NO WARRANTY whatsoever! Make backups of your vital data!"),
+ i18n("Starting Merge"), i18n("Do It"), i18n("Simulate It") );
+ if (status==KMessageBox::Yes) m_bRealMergeStarted = true;
+ else if (status==KMessageBox::No ) m_bSimulatedMergeStarted = true;
+ else return;
+ }
+ else
+ {
+ m_bRealMergeStarted = true;
+ }
+
+ m_mergeItemList.clear();
+ if (pBegin == 0)
+ return;
+
+ for( QListViewItem* p = pBegin; p!= pEnd; p = treeIterator( p ) )
+ {
+ DirMergeItem* pDMI = static_cast(p);
+
+ if ( ! pDMI->m_pMFI->m_bOperationComplete )
{
- DirMergeItem* pDMI = static_cast(p);
+ m_mergeItemList.push_back(pDMI);
+
if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingFileTypes )
{
ensureItemVisible( pDMI );
setSelected( pDMI, true );
- KMessageBox::error(this, i18n("The highlighted item has a different type in the different directories. Select what to do."), "Error");
+ KMessageBox::error(this, i18n("The highlighted item has a different type in the different directories. Select what to do."), i18n("Error"));
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
return;
}
if (pDMI!=0 && pDMI->m_pMFI->m_eMergeOperation == eConflictingAges )
{
ensureItemVisible( pDMI );
setSelected( pDMI, true );
- KMessageBox::error(this, i18n("The modification dates of the file are equal but the files are not. Select what to do."), "Error");
+ KMessageBox::error(this, i18n("The modification dates of the file are equal but the files are not. Select what to do."), i18n("Error"));
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
return;
}
- ++nrOfItems;
- if ( pDMI->m_pMFI->m_bSimOpComplete )
- ++nrOfCompletedSimItems;
- if ( pDMI->m_pMFI->m_bOperationComplete )
- ++nrOfCompletedItems;
}
-
- int status = KMessageBox::warningYesNoCancel(this,
- i18n("The merge is about to begin.\n\n"
- "Choose \"Do it\" if you have read the instructions and know what you are doing.\n"
- "Choosing \"Simulate it\" will tell you what would happen.\n\n"
- "Be aware that this program still has beta status "
- "and there is NO WARRANTY whatsoever! Make backups of your vital data!"),
- i18n("KDiff3: Starting the Merge"), i18n("Do it"), i18n("Simulate it") );
- if (status==KMessageBox::Yes) m_bRealMergeStarted = true;
- else if (status==KMessageBox::No ) m_bSimulatedMergeStarted = true;
- else return;
-
- m_pStatusInfo->hide();
- m_pStatusInfo->clear();
}
- bool bContinueWithCurrentItem = false;
+ m_currentItemForOperation = m_mergeItemList.begin();
+ return;
+}
+
+void DirectoryMergeWindow::slotRunOperationForCurrentItem()
+{
+ if ( ! canContinue() ) return;
+
+ bool bVerbose = false;
+ if ( m_mergeItemList.empty() )
+ {
+ QListViewItem* pBegin = currentItem();
+
+ prepareMergeStart( pBegin, pBegin->nextSibling(), bVerbose );
+ mergeContinue(true, bVerbose);
+ }
+ else
+ mergeContinue(false, bVerbose);
+}
+
+void DirectoryMergeWindow::slotRunOperationForAllItems()
+{
+ if ( ! canContinue() ) return;
+
+ bool bVerbose = true;
+ if ( m_mergeItemList.empty() )
+ {
+ QListViewItem* pBegin = firstChild();
+
+ prepareMergeStart( pBegin, 0, bVerbose );
+ mergeContinue(true, bVerbose);
+ }
+ else
+ mergeContinue(false, bVerbose);
+}
+
+void DirectoryMergeWindow::mergeCurrentFile()
+{
+ if (!canContinue()) return;
+
+ if ( m_bRealMergeStarted )
+ {
+ KMessageBox::sorry(this,i18n("This operation is currently not possible because dir merge currently runs."),i18n("Operation Not Possible"));
+ return;
+ }
+
+ if ( isFileSelected() )
+ {
+ DirMergeItem* pDMI = static_cast( selectedItem() );
+ if ( pDMI != 0 )
+ {
+ MergeFileInfos& mfi = *pDMI->m_pMFI;
+ m_mergeItemList.clear();
+ m_mergeItemList.push_back( pDMI );
+ m_currentItemForOperation=m_mergeItemList.begin();
+ bool bDummy=false;
+ mergeFLD(
+ mfi.m_bExistsInA ? mfi.m_fileInfoA.absFilePath() : QString(""),
+ mfi.m_bExistsInB ? mfi.m_fileInfoB.absFilePath() : QString(""),
+ mfi.m_bExistsInC ? mfi.m_fileInfoC.absFilePath() : QString(""),
+ fullNameDest(mfi),
+ bDummy
+ );
+ }
+ }
+ emit updateAvailabilities();
+}
+
+
+// When bStart is true then m_currentItemForOperation must still be processed.
+// When bVerbose is true then a messagebox will tell when the merge is complete.
+void DirectoryMergeWindow::mergeContinue(bool bStart, bool bVerbose)
+{
+ if ( m_mergeItemList.empty() )
+ return;
+
+ int nrOfItems = 0;
+ int nrOfCompletedItems = 0;
+ int nrOfCompletedSimItems = 0;
+
+ // Count the number of completed items (for the progress bar).
+ for( MergeItemList::iterator i = m_mergeItemList.begin(); i!=m_mergeItemList.end(); ++i )
+ {
+ DirMergeItem* pDMI = static_cast(*i);
+ ++nrOfItems;
+ if ( pDMI->m_pMFI->m_bOperationComplete )
+ ++nrOfCompletedItems;
+ if ( pDMI->m_pMFI->m_bSimOpComplete )
+ ++nrOfCompletedSimItems;
+ }
+
+ m_pStatusInfo->hide();
+ m_pStatusInfo->clear();
+
+ DirMergeItem* pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
+
+ bool bContinueWithCurrentItem = bStart; // true for first item, else false
bool bSkipItem = false;
- if ( m_bError && m_pCurrentItemForOperation!=0 )
+ if ( !bStart && m_bError && pCurrentItemForOperation!=0 )
{
int status = KMessageBox::warningYesNoCancel(this,
i18n("There was an error in the last step.\n"
"Do you want to continue with the item that caused the error or do you want to skip this item?"),
- i18n("KDiff3: Continue merge after an error"), i18n("Continue with last item"), i18n("Skip item") );
- if (status==KMessageBox::Yes) bContinueWithCurrentItem = true;
+ i18n("Continue merge after an error"), i18n("Continue With Last Item"), i18n("Skip Item") );
+ if (status==KMessageBox::Yes) bContinueWithCurrentItem = true;
else if (status==KMessageBox::No ) bSkipItem = true;
else return;
m_bError = false;
@@ -1485,89 +1705,87 @@
bool bSim = m_bSimulatedMergeStarted;
while( bSuccess )
{
- if ( m_pCurrentItemForOperation!=0 && !bContinueWithCurrentItem )
+ if ( pCurrentItemForOperation==0 )
+ {
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
+ break;
+ }
+
+ if ( pCurrentItemForOperation!=0 && !bContinueWithCurrentItem )
{
if ( bSim )
{
- if( m_pCurrentItemForOperation->firstChild()==0 )
+ if( pCurrentItemForOperation->firstChild()==0 )
{
- m_pCurrentItemForOperation->m_pMFI->m_bSimOpComplete = true;
+ pCurrentItemForOperation->m_pMFI->m_bSimOpComplete = true;
}
}
else
{
- if( m_pCurrentItemForOperation->firstChild()==0 )
+ if( pCurrentItemForOperation->firstChild()==0 )
{
- if( !m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
+ if( !pCurrentItemForOperation->m_pMFI->m_bOperationComplete )
{
- m_pCurrentItemForOperation->setText( s_OpStatusCol, bSkipItem ? "Skipped." : "Done." );
- m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
+ pCurrentItemForOperation->setText( s_OpStatusCol, bSkipItem ? i18n("Skipped.") : i18n("Done.") );
+ pCurrentItemForOperation->m_pMFI->m_bOperationComplete = true;
bSkipItem = false;
}
}
else
{
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "In progress ..." );
+ pCurrentItemForOperation->setText( s_OpStatusCol, i18n("In progress...") );
}
}
}
- if ( m_pCurrentItemForOperation==0 )
+ if ( ! bContinueWithCurrentItem )
{
- m_pCurrentItemForOperation = static_cast( firstChild() );
- }
- else
- {
- if ( ! bContinueWithCurrentItem )
+ // Depth first
+ QListViewItem* pPrevItem = pCurrentItemForOperation;
+ ++m_currentItemForOperation;
+ pCurrentItemForOperation = m_currentItemForOperation==m_mergeItemList.end() ? 0 : *m_currentItemForOperation;
+ if ( (pCurrentItemForOperation==0 || pCurrentItemForOperation->parent()!=pPrevItem->parent()) && pPrevItem->parent()!=0 )
{
- // Depth first
- QListViewItem* pNextItem = m_pCurrentItemForOperation->firstChild();
- QListViewItem* pCurrentItem = m_pCurrentItemForOperation;
- while( pCurrentItem!=0 && pNextItem==0 )
+ // Check if the parent may be set to "Done"
+ QListViewItem* pParent = pPrevItem->parent();
+ bool bDone = true;
+ while ( bDone && pParent!=0 )
{
- // Find an item on this level that hasn't been operated yet. (Always start at beginning.)
- if ( pCurrentItem->parent()==0 )
- pNextItem = firstChild();
- else
- pNextItem = pCurrentItem->parent()->firstChild();
-
- while( pNextItem!=0 && ( static_cast(pNextItem)->m_pMFI->m_bOperationComplete ||
- ( bSim && static_cast(pNextItem)->m_pMFI->m_bSimOpComplete ) ) )
+ for( QListViewItem* p = pParent->firstChild(); p!=0; p=p->nextSibling() )
{
- pNextItem = pNextItem->nextSibling();
- }
-
- if ( pNextItem == 0 )
- {
- pCurrentItem = pCurrentItem->parent();
- if ( pCurrentItem!=0 )
+ DirMergeItem* pDMI = static_cast(p);
+ if ( !bSim && ! pDMI->m_pMFI->m_bOperationComplete || bSim && pDMI->m_pMFI->m_bSimOpComplete )
{
- if (bSim)
- static_cast(pCurrentItem)->m_pMFI->m_bSimOpComplete = true;
- else
- {
- pCurrentItem->setText( s_OpStatusCol, "Done." );
- static_cast(pCurrentItem)->m_pMFI->m_bOperationComplete = true;
- }
+ bDone=false;
+ break;
}
}
+ if ( bDone )
+ {
+ if (bSim)
+ static_cast(pParent)->m_pMFI->m_bSimOpComplete = bDone;
+ else
+ {
+ pParent->setText( s_OpStatusCol, i18n("Done.") );
+ static_cast(pParent)->m_pMFI->m_bOperationComplete = bDone;
+ }
+ }
+ pParent = pParent->parent();
}
- m_pCurrentItemForOperation = static_cast(pNextItem);
}
}
- if( m_pCurrentItemForOperation !=0 &&
- (bSim ? m_pCurrentItemForOperation->m_pMFI->m_bSimOpComplete :
- m_pCurrentItemForOperation->m_pMFI->m_bOperationComplete ))
- m_pCurrentItemForOperation = 0;
-
- if ( m_pCurrentItemForOperation==0 )
+ if ( pCurrentItemForOperation == 0 ) // end?
{
if ( m_bRealMergeStarted )
{
- KMessageBox::information( this, "Merge operation complete.", "The merge is complete." );
+ if (bVerbose)
+ {
+ KMessageBox::information( this, i18n("Merge operation complete."), i18n("Merge Complete") );
+ }
m_bRealMergeStarted = false;
- m_pStatusInfo->setCaption("KDiff3: Merge complete.");
+ m_pStatusInfo->setCaption(i18n("Merge Complete"));
}
if ( m_bSimulatedMergeStarted )
{
@@ -1576,104 +1794,61 @@
{
static_cast(p)->m_pMFI->m_bSimOpComplete = false;
}
- m_pStatusInfo->setCaption("KDiff3: Simulated merge complete: Check if you agree with the proposed operations.");
+ m_pStatusInfo->setCaption(i18n("Simulated merge complete: Check if you agree with the proposed operations."));
m_pStatusInfo->show();
}
g_pProgressDialog->hide();
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
return;
}
- MergeFileInfos& mfi = *m_pCurrentItemForOperation->m_pMFI;
- bool bCreateBackups = m_pOptions->m_bDmCreateBakFiles;
+ MergeFileInfos& mfi = *pCurrentItemForOperation->m_pMFI;
g_pProgressDialog->setInformation( mfi.m_subPath,
bSim ? double(nrOfCompletedSimItems)/nrOfItems : double(nrOfCompletedItems)/nrOfItems,
- true
+ false // bRedrawUpdate
);
g_pProgressDialog->show();
- // First decide destname
- QString destName;
- switch( mfi.m_eMergeOperation )
- {
- case eNoOperation: break;
- case eDeleteAB: break;
- case eMergeToAB: // let the user save in B. In mergeResultSaved() the file will be copied to A.
- case eMergeToB:
- case eDeleteB:
- case eCopyAToB: destName = fullNameB(mfi); break;
- case eMergeToA:
- case eDeleteA:
- case eCopyBToA: destName = fullNameA(mfi); break;
- case eMergeABToDest:
- case eMergeABCToDest:
- case eCopyAToDest:
- case eCopyBToDest:
- case eCopyCToDest:
- case eDeleteFromDest: destName = fullNameDest(mfi); break;
- default:
- KMessageBox::error( this, "Unknown merge operation.(This must never happen!)", "Error" );
- assert(false);
- }
+ bSuccess = executeMergeOperation( mfi, bSingleFileMerge ); // Here the real operation happens.
- bSuccess = false;
- bSingleFileMerge = false;
- switch( mfi.m_eMergeOperation )
- {
- case eNoOperation: bSuccess = true; break;
- case eCopyAToDest:
- case eCopyAToB: bSuccess = copyFLD( fullNameA(mfi), destName ); break;
- case eCopyBToDest:
- case eCopyBToA: bSuccess = copyFLD( fullNameB(mfi), destName ); break;
- case eCopyCToDest: bSuccess = copyFLD( fullNameC(mfi), destName ); break;
- case eDeleteFromDest:
- case eDeleteA:
- case eDeleteB: bSuccess = deleteFLD( destName, bCreateBackups ); break;
- case eDeleteAB: bSuccess = deleteFLD( fullNameA(mfi), bCreateBackups ) &&
- deleteFLD( fullNameB(mfi), bCreateBackups ); break;
- case eMergeABToDest:
- case eMergeToA:
- case eMergeToAB:
- case eMergeToB: bSuccess = mergeFLD( fullNameA(mfi), fullNameB(mfi), "",
- destName, bSingleFileMerge );
- break;
- case eMergeABCToDest:bSuccess = mergeFLD(
- mfi.m_bExistsInA ? fullNameA(mfi) : QString(""),
- mfi.m_bExistsInB ? fullNameB(mfi) : QString(""),
- mfi.m_bExistsInC ? fullNameC(mfi) : QString(""),
- destName, bSingleFileMerge );
- break;
- default:
- KMessageBox::error( this, "Unknown merge operation.", "Error" );
- assert(false);
- }
if ( bSuccess )
{
if(bSim) ++nrOfCompletedSimItems;
else ++nrOfCompletedItems;
bContinueWithCurrentItem = false;
}
+
+ if( g_pProgressDialog->wasCancelled() )
+ break;
} // end while
g_pProgressDialog->hide();
- setCurrentItem( m_pCurrentItemForOperation );
- ensureItemVisible( m_pCurrentItemForOperation );
+ setCurrentItem( pCurrentItemForOperation );
+ ensureItemVisible( pCurrentItemForOperation );
if ( !bSuccess && !bSingleFileMerge )
{
- KMessageBox::error(this, i18n("An error occurred. Press OK to see detailed information.\n"), "KDiff3: Error" );
- m_pStatusInfo->setCaption("KDiff3: Merge-Error");
+ KMessageBox::error(this, i18n("An error occurred. Press OK to see detailed information.\n"), i18n("Error") );
+ m_pStatusInfo->setCaption(i18n("Merge Error"));
m_pStatusInfo->show();
if ( m_pStatusInfo->firstChild()!=0 )
m_pStatusInfo->ensureItemVisible( m_pStatusInfo->last() );
m_bError = true;
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "Error." );
+ pCurrentItemForOperation->setText( s_OpStatusCol, i18n("Error.") );
}
else
{
m_bError = false;
}
emit updateAvailabilities();
+
+ if ( m_currentItemForOperation==m_mergeItemList.end() )
+ {
+ m_mergeItemList.clear();
+ m_bRealMergeStarted=false;
+ }
}
void DirectoryMergeWindow::allowResizeEvents(bool bAllowResizeEvents )
@@ -1698,16 +1873,16 @@
bool bSuccess = renameFLD( name, name+".orig" );
if (!bSuccess)
{
- m_pStatusInfo->addText( "Error: While deleting "+name+": Creating backup failed." );
+ m_pStatusInfo->addText( i18n("Error: While deleting %1: Creating backup failed.").arg(name) );
return false;
}
}
else
{
if ( fi.isDir() && !fi.isSymLink() )
- m_pStatusInfo->addText("delete directory recursively( "+name+" )");
+ m_pStatusInfo->addText(i18n("delete directory recursively( %1 )").arg(name));
else
- m_pStatusInfo->addText("delete( "+name+" )");
+ m_pStatusInfo->addText(i18n("delete( %1 )").arg(name));
if ( m_bSimulatedMergeStarted )
{
@@ -1722,7 +1897,7 @@
if ( !bSuccess )
{
// No Permission to read directory or other error.
- m_pStatusInfo->addText( "Error: delete dir operation failed while trying to read the directory." );
+ m_pStatusInfo->addText( i18n("Error: delete dir operation failed while trying to read the directory.") );
return false;
}
@@ -1741,7 +1916,7 @@
bSuccess = FileAccess::removeDir( name );
if ( !bSuccess )
{
- m_pStatusInfo->addText( "Error: rmdir( "+name+" ) operation failed." );
+ m_pStatusInfo->addText( i18n("Error: rmdir( %1 ) operation failed.").arg(name));
return false;
}
}
@@ -1751,7 +1926,7 @@
bool bSuccess = FileAccess::removeFile( name );
if ( !bSuccess )
{
- m_pStatusInfo->addText( "Error: delete operation failed." );
+ m_pStatusInfo->addText( i18n("Error: delete operation failed.") );
return false;
}
}
@@ -1777,16 +1952,16 @@
return false;
}
- m_pStatusInfo->addText("manual merge( "+nameA+ ", "+nameB+","+nameC+" -> " + nameDest +" )" );
+ m_pStatusInfo->addText(i18n("manual merge( %1, %2, %3 -> %4)").arg(nameA).arg(nameB).arg(nameC).arg(nameDest));
if ( m_bSimulatedMergeStarted )
{
- m_pStatusInfo->addText(" Note: After a manual merge the user should continue via F5." );
+ m_pStatusInfo->addText(i18n(" Note: After a manual merge the user should continue via F7.") );
return true;
}
bSingleFileMerge = true;
- m_pCurrentItemForOperation->setText( s_OpStatusCol, "In progress ..." );
- ensureItemVisible( m_pCurrentItemForOperation );
+ (*m_currentItemForOperation)->setText( s_OpStatusCol, i18n("In progress...") );
+ ensureItemVisible( *m_currentItemForOperation );
emit startDiffMerge( nameA, nameB, nameC, nameDest, "","","" );
@@ -1803,8 +1978,8 @@
bool bSuccess = deleteFLD( destName, m_pOptions->m_bDmCreateBakFiles );
if ( !bSuccess )
{
- m_pStatusInfo->addText("Error: copy( "+srcName+ " -> " + destName +" ) failed."
- "Deleting existing destination failed.");
+ m_pStatusInfo->addText(i18n("Error: copy( %1 -> %2 ) failed."
+ "Deleting existing destination failed.").arg(srcName).arg(destName));
return false;
}
}
@@ -1813,7 +1988,7 @@
if ( fi.isSymLink() && (fi.isDir() && !m_bFollowDirLinks || !fi.isDir() && !m_bFollowDirLinks) )
{
- m_pStatusInfo->addText("copyLink( "+srcName+ " -> " + destName +" )");
+ m_pStatusInfo->addText(i18n("copyLink( %1 -> %2 )").arg(srcName).arg(destName));
#ifdef _WIN32
// What are links?
#else
@@ -1824,13 +1999,13 @@
FileAccess destFi(destName);
if ( !destFi.isLocal() || !fi.isLocal() )
{
- m_pStatusInfo->addText("Error: copyLink failed: Remote links are not yet supported.");
+ m_pStatusInfo->addText(i18n("Error: copyLink failed: Remote links are not yet supported."));
return false;
}
QString linkTarget = fi.readLink();
bool bSuccess = FileAccess::symLink( linkTarget, destName );
if (!bSuccess)
- m_pStatusInfo->addText("Error: copyLink failed.");
+ m_pStatusInfo->addText(i18n("Error: copyLink failed."));
return bSuccess;
#endif
}
@@ -1850,7 +2025,7 @@
return false;
}
- m_pStatusInfo->addText("copy( "+srcName+ " -> " + destName +" )");
+ m_pStatusInfo->addText(i18n("copy( %1 -> %2 )").arg(srcName).arg(destName));
if ( m_bSimulatedMergeStarted )
{
@@ -1876,13 +2051,13 @@
bool bSuccess = deleteFLD( destName, false /*no backup*/ );
if (!bSuccess)
{
- m_pStatusInfo->addText( "Error during rename( "+srcName+" -> " + destName + " ): "
- "Cannot delete existing destination." );
+ m_pStatusInfo->addText( i18n("Error during rename( %1 -> %2 ): "
+ "Cannot delete existing destination." ).arg(srcName).arg(destName));
return false;
}
}
- m_pStatusInfo->addText("rename( "+srcName+ " -> " + destName +" )");
+ m_pStatusInfo->addText(i18n("rename( %1 -> %2 )").arg(srcName).arg(destName)) ;
if ( m_bSimulatedMergeStarted )
{
return true;
@@ -1891,7 +2066,7 @@
bool bSuccess = FileAccess( srcName ).rename( destName );
if (!bSuccess)
{
- m_pStatusInfo->addText( "Error: Rename failed." );
+ m_pStatusInfo->addText( i18n("Error: Rename failed.") );
return false;
}
@@ -1909,8 +2084,8 @@
bool bSuccess = deleteFLD( name, true );
if (!bSuccess)
{
- m_pStatusInfo->addText( "Error during makeDir of "+name+
- "Cannot delete existing file." );
+ m_pStatusInfo->addText( i18n("Error during makeDir of %1. "
+ "Cannot delete existing file." ).arg(name));
return false;
}
}
@@ -1925,7 +2100,7 @@
}
if ( ! bQuiet )
- m_pStatusInfo->addText("makeDir( " + name + " )");
+ m_pStatusInfo->addText(i18n("makeDir( %1 )").arg(name));
if ( m_bSimulatedMergeStarted )
{
@@ -1935,7 +2110,7 @@
bool bSuccess = FileAccess::makeDir( name );
if ( bSuccess == false )
{
- m_pStatusInfo->addText( "Error while creating directory." );
+ m_pStatusInfo->addText( i18n("Error while creating directory.") );
return false;
}
return true;
@@ -1962,16 +2137,16 @@
m_pInfoB = new QLabel(this); grid->addWidget( m_pInfoB,line,1 ); ++line;
m_pC = new QLabel("C",this); grid->addWidget( m_pC,line, 0 );
m_pInfoC = new QLabel(this); grid->addWidget( m_pInfoC,line,1 ); ++line;
- m_pDest = new QLabel("Dest",this); grid->addWidget( m_pDest,line, 0 );
+ m_pDest = new QLabel(i18n("Dest"),this); grid->addWidget( m_pDest,line, 0 );
m_pInfoDest = new QLabel(this); grid->addWidget( m_pInfoDest,line,1 ); ++line;
m_pInfoList = new QListView(this); topLayout->addWidget( m_pInfoList );
- m_pInfoList->addColumn("Dir");
- m_pInfoList->addColumn("Type");
- m_pInfoList->addColumn("Size");
- m_pInfoList->addColumn("Attr");
- m_pInfoList->addColumn("Last Modification");
- m_pInfoList->addColumn("Link-Destination");
+ m_pInfoList->addColumn(i18n("Dir"));
+ m_pInfoList->addColumn(i18n("Type"));
+ m_pInfoList->addColumn(i18n("Size"));
+ m_pInfoList->addColumn(i18n("Attr"));
+ m_pInfoList->addColumn(i18n("Last Modification"));
+ m_pInfoList->addColumn(i18n("Link-Destination"));
setMinimumSize( 100,100 );
}
@@ -1995,7 +2170,7 @@
new QListViewItem(
pListView,
dir,
- QString( fi.isDir() ? "Dir" : "File" ) + (fi.isSymLink() ? "-Link" : ""),
+ QString( fi.isDir() ? i18n("Dir") : i18n("File") ) + (fi.isSymLink() ? "-Link" : ""),
QString::number(fi.size()),
QString(fi.isReadable() ? "r" : " ") + (fi.isWritable()?"w" : " ")
#ifdef _WIN32
@@ -2012,7 +2187,7 @@
new QListViewItem(
pListView,
dir,
- "not available",
+ i18n("not available"),
"",
"",
"",
@@ -2032,16 +2207,16 @@
bool bHideDest = false;
if ( dirA.absFilePath()==dirDest.absFilePath() )
{
- m_pA->setText( "A (Dest): " ); bHideDest=true;
+ m_pA->setText( i18n("A (Dest): ") ); bHideDest=true;
}
else
- m_pA->setText( !dirC.isValid() ? "A: " : "A (Base): ");
+ m_pA->setText( !dirC.isValid() ? QString("A: ") : i18n("A (Base): "));
m_pInfoA->setText( dirA.prettyAbsPath() );
if ( dirB.absFilePath()==dirDest.absFilePath() )
{
- m_pB->setText( "B (Dest): " ); bHideDest=true;
+ m_pB->setText( i18n("B (Dest): ") ); bHideDest=true;
}
else
m_pB->setText( "B: " );
@@ -2049,13 +2224,13 @@
if ( dirC.absFilePath()==dirDest.absFilePath() )
{
- m_pC->setText( "C (Dest): " ); bHideDest=true;
+ m_pC->setText( i18n("C (Dest): ") ); bHideDest=true;
}
else
m_pC->setText( "C: " );
m_pInfoC->setText( dirC.prettyAbsPath() );
- m_pDest->setText( "Dest: " ); m_pInfoDest->setText( dirDest.prettyAbsPath() );
+ m_pDest->setText( i18n("Dest: ") ); m_pInfoDest->setText( dirDest.prettyAbsPath() );
if (!dirC.isValid()) { m_pC->hide(); m_pInfoC->hide(); }
else { m_pC->show(); m_pInfoC->show(); }
@@ -2070,8 +2245,95 @@
if (!bHideDest)
{
FileAccess fiDest( dirDest.prettyAbsPath() + "/" + mfi.m_subPath, true );
- addListViewItem( m_pInfoList, "Dest", dirDest.prettyAbsPath(), fiDest );
+ addListViewItem( m_pInfoList, i18n("Dest"), dirDest.prettyAbsPath(), fiDest );
}
}
+
+void DirectoryMergeWindow::initDirectoryMergeActions( QObject* pKDiff3App, KActionCollection* ac )
+{
+#include "xpm/startmerge.xpm"
+ DirectoryMergeWindow* p = this;
+
+ dirStartOperation = new KAction(i18n("Start/Continue Directory Merge"), Key_F7, p, SLOT(slotRunOperationForAllItems()), ac, "dir_start_operation");
+ dirRunOperationForCurrentItem = new KAction(i18n("Run Operation for Current Item"), Key_F6, p, SLOT(slotRunOperationForCurrentItem()), ac, "dir_run_operation_for_current_item");
+ dirCompareCurrent = new KAction(i18n("Compare Selected File"), 0, p, SLOT(compareCurrentFile()), ac, "dir_compare_current");
+ dirMergeCurrent = new KAction(i18n("Merge Current File"), QIconSet(QPixmap(startmerge)), 0, pKDiff3App, SLOT(slotMergeCurrentFile()), ac, "merge_current");
+ dirFoldAll = new KAction(i18n("Fold All Subdirs"), 0, p, SLOT(slotFoldAllSubdirs()), ac, "dir_fold_all");
+ dirUnfoldAll = new KAction(i18n("Unfold All Subdirs"), 0, p, SLOT(slotUnfoldAllSubdirs()), ac, "dir_unfold_all");
+ dirRescan = new KAction(i18n("Rescan"), 0, p, SLOT(reload()), ac, "dir_rescan");
+ dirChooseAEverywhere = new KAction(i18n("Choose A for All Items"), 0, p, SLOT(slotChooseAEverywhere()), ac, "dir_choose_a_everywhere");
+ dirChooseBEverywhere = new KAction(i18n("Choose B for All Items"), 0, p, SLOT(slotChooseBEverywhere()), ac, "dir_choose_b_everywhere");
+ dirChooseCEverywhere = new KAction(i18n("Choose C for All Items"), 0, p, SLOT(slotChooseCEverywhere()), ac, "dir_choose_c_everywhere");
+ dirAutoChoiceEverywhere = new KAction(i18n("Auto-Choose Operation for All Items"), 0, p, SLOT(slotAutoChooseEverywhere()), ac, "dir_autochoose_everywhere");
+ dirDoNothingEverywhere = new KAction(i18n("No Operation for All Items"), 0, p, SLOT(slotNoOpEverywhere()), ac, "dir_nothing_everywhere");
+
+ dirCurrentDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_do_nothing");
+ dirCurrentChooseA = new KAction(i18n("A"), 0, p, SLOT(slotCurrentChooseA()), ac, "dir_current_choose_a");
+ dirCurrentChooseB = new KAction(i18n("B"), 0, p, SLOT(slotCurrentChooseB()), ac, "dir_current_choose_b");
+ dirCurrentChooseC = new KAction(i18n("C"), 0, p, SLOT(slotCurrentChooseC()), ac, "dir_current_choose_c");
+ dirCurrentMerge = new KAction(i18n("Merge"), 0, p, SLOT(slotCurrentMerge()), ac, "dir_current_merge");
+ dirCurrentDelete = new KAction(i18n("Delete (If Exists)"), 0, p, SLOT(slotCurrentDelete()), ac, "dir_current_delete");
+
+ dirCurrentSyncDoNothing = new KAction(i18n("Do Nothing"), 0, p, SLOT(slotCurrentDoNothing()), ac, "dir_current_sync_do_nothing");
+ dirCurrentSyncCopyAToB = new KAction(i18n("Copy A to B"), 0, p, SLOT(slotCurrentCopyAToB()), ac, "dir_current_sync_copy_a_to_b" );
+ dirCurrentSyncCopyBToA = new KAction(i18n("Copy B to A"), 0, p, SLOT(slotCurrentCopyBToA()), ac, "dir_current_sync_copy_b_to_a" );
+ dirCurrentSyncDeleteA = new KAction(i18n("Delete A"), 0, p, SLOT(slotCurrentDeleteA()), ac,"dir_current_sync_delete_a");
+ dirCurrentSyncDeleteB = new KAction(i18n("Delete B"), 0, p, SLOT(slotCurrentDeleteB()), ac,"dir_current_sync_delete_b");
+ dirCurrentSyncDeleteAAndB = new KAction(i18n("Delete A and B"), 0, p, SLOT(slotCurrentDeleteAAndB()), ac,"dir_current_sync_delete_a_and_b");
+ dirCurrentSyncMergeToA = new KAction(i18n("Merge to A"), 0, p, SLOT(slotCurrentMergeToA()), ac,"dir_current_sync_merge_to_a");
+ dirCurrentSyncMergeToB = new KAction(i18n("Merge to B"), 0, p, SLOT(slotCurrentMergeToB()), ac,"dir_current_sync_merge_to_b");
+ dirCurrentSyncMergeToAAndB = new KAction(i18n("Merge to A and B"), 0, p, SLOT(slotCurrentMergeToAAndB()), ac,"dir_current_sync_merge_to_a_and_b");
+}
+
+
+void DirectoryMergeWindow::updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible )
+{
+ dirStartOperation->setEnabled( bDirCompare );
+ dirRunOperationForCurrentItem->setEnabled( bDirCompare );
+ dirFoldAll->setEnabled( bDirCompare );
+ dirUnfoldAll->setEnabled( bDirCompare );
+
+ dirCompareCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected() );
+
+ dirMergeCurrent->setEnabled( bDirCompare && isVisible() && isFileSelected()
+ || bDiffWindowVisible );
+
+ dirRescan->setEnabled( bDirCompare );
+
+ dirAutoChoiceEverywhere->setEnabled( bDirCompare && isVisible() );
+ dirDoNothingEverywhere->setEnabled( bDirCompare && isVisible() );
+ dirChooseAEverywhere->setEnabled( bDirCompare && isVisible() );
+ dirChooseBEverywhere->setEnabled( bDirCompare && isVisible() );
+ dirChooseCEverywhere->setEnabled( bDirCompare && isVisible() );
+
+ bool bThreeDirs = m_dirC.isValid();
+
+ QListViewItem* lvi = currentItem();
+ DirMergeItem* pDMI = lvi==0 ? 0 : static_cast(lvi);
+ MergeFileInfos* pMFI = pDMI==0 ? 0 : pDMI->m_pMFI;
+
+ bool bItemActive = bDirCompare && isVisible() && pMFI!=0;// && hasFocus();
+ bool bMergeMode = bThreeDirs || !m_bSyncMode;
+ bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI);
+
+ dirCurrentDoNothing->setEnabled( bItemActive && bMergeMode );
+ dirCurrentChooseA->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInA );
+ dirCurrentChooseB->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInB );
+ dirCurrentChooseC->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInC );
+ dirCurrentMerge->setEnabled( bItemActive && bMergeMode && !bFTConflict );
+ dirCurrentDelete->setEnabled( bItemActive && bMergeMode );
+
+ dirCurrentSyncDoNothing->setEnabled( bItemActive && !bMergeMode );
+ dirCurrentSyncCopyAToB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
+ dirCurrentSyncCopyBToA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
+ dirCurrentSyncDeleteA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA );
+ dirCurrentSyncDeleteB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
+ dirCurrentSyncDeleteAAndB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB && pMFI->m_bExistsInB );
+ dirCurrentSyncMergeToA->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
+ dirCurrentSyncMergeToB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
+ dirCurrentSyncMergeToAAndB->setEnabled( bItemActive && !bMergeMode && !bFTConflict );
+}
+
+
#include "directorymergewindow.moc"
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/directorymergewindow.h
--- a/kdiff3/src/directorymergewindow.h Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/directorymergewindow.h Tue Dec 09 20:29:43 2003 +0000
@@ -15,16 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.2 2003/10/14 20:51:45 joachim99
- * Bugfix for Syncmode.
- *
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- * *
- ***************************************************************************/
-
#ifndef DIRECTORY_MERGE_WINDOW_H
#define DIRECTORY_MERGE_WINDOW_H
@@ -44,6 +34,9 @@
class DirectoryMergeInfo;
class OneDirectoryInfo;
class QLabel;
+class KAction;
+class KToggleAction;
+class KActionCollection;
enum e_MergeOperation
{
@@ -146,12 +139,17 @@
bool isDirectoryMergeInProgress() { return m_bRealMergeStarted; }
int totalColumnWidth();
bool isSyncMode() { return m_bSyncMode; }
+ void initDirectoryMergeActions( QObject* pKDiff3App, KActionCollection* ac );
+ void updateAvailabilities( bool bDirCompare, bool bDiffWindowVisible );
+
+ virtual void keyPressEvent( QKeyEvent* e );
public slots:
- void mergeContinue();
void reload();
void mergeCurrentFile();
void compareCurrentFile();
+ void slotRunOperationForAllItems();
+ void slotRunOperationForCurrentItem();
void mergeResultSaved(const QString& fileName);
void slotChooseAEverywhere();
void slotChooseBEverywhere();
@@ -160,8 +158,25 @@
void slotNoOpEverywhere();
void slotFoldAllSubdirs();
void slotUnfoldAllSubdirs();
+ // Merge current item (merge mode)
+ void slotCurrentDoNothing();
+ void slotCurrentChooseA();
+ void slotCurrentChooseB();
+ void slotCurrentChooseC();
+ void slotCurrentMerge();
+ void slotCurrentDelete();
+ // Sync current item
+ void slotCurrentCopyAToB();
+ void slotCurrentCopyBToA();
+ void slotCurrentDeleteA();
+ void slotCurrentDeleteB();
+ void slotCurrentDeleteAAndB();
+ void slotCurrentMergeToA();
+ void slotCurrentMergeToB();
+ void slotCurrentMergeToAAndB();
protected:
+ void mergeContinue( bool bStart, bool bVerbose );
void resizeEvent(QResizeEvent* e);
bool m_bAllowResizeEvents;
@@ -171,6 +186,8 @@
friend class MergeFileInfos;
bool canContinue();
+ void prepareMergeStart( QListViewItem* pBegin, QListViewItem* pEnd, bool bVerbose );
+ bool executeMergeOperation( MergeFileInfos& mfi, bool& bSingleFileMerge );
void scanDirectory( const QString& dirName, t_DirectoryList& dirList );
void scanLocalDirectory( const QString& dirName, t_DirectoryList& dirList );
@@ -206,17 +223,49 @@
bool m_bFollowFileLinks;
bool m_bSimulatedMergeStarted;
bool m_bRealMergeStarted;
- bool m_bSingleFileOperationStarted;
bool m_bError;
bool m_bSyncMode;
bool m_bDirectoryMerge; // if true, then merge is the default operation, otherwise it's diff.
OptionDialog* m_pOptions;
KIconLoader* m_pIconLoader;
- DirMergeItem* m_pCurrentItemForOperation;
StatusMessageBox* m_pStatusMessageBox;
DirectoryMergeInfo* m_pDirectoryMergeInfo;
StatusInfo* m_pStatusInfo;
+
+ typedef std::list MergeItemList;
+ MergeItemList m_mergeItemList;
+ MergeItemList::iterator m_currentItemForOperation;
+
+ KAction* dirStartOperation;
+ KAction* dirRunOperationForCurrentItem;
+ KAction* dirCompareCurrent;
+ KAction* dirMergeCurrent;
+ KAction* dirRescan;
+ KAction* dirChooseAEverywhere;
+ KAction* dirChooseBEverywhere;
+ KAction* dirChooseCEverywhere;
+ KAction* dirAutoChoiceEverywhere;
+ KAction* dirDoNothingEverywhere;
+ KAction* dirFoldAll;
+ KAction* dirUnfoldAll;
+
+ KAction* dirCurrentDoNothing;
+ KAction* dirCurrentChooseA;
+ KAction* dirCurrentChooseB;
+ KAction* dirCurrentChooseC;
+ KAction* dirCurrentMerge;
+ KAction* dirCurrentDelete;
+
+ KAction* dirCurrentSyncDoNothing;
+ KAction* dirCurrentSyncCopyAToB;
+ KAction* dirCurrentSyncCopyBToA;
+ KAction* dirCurrentSyncDeleteA;
+ KAction* dirCurrentSyncDeleteB;
+ KAction* dirCurrentSyncDeleteAAndB;
+ KAction* dirCurrentSyncMergeToA;
+ KAction* dirCurrentSyncMergeToB;
+ KAction* dirCurrentSyncMergeToAAndB;
signals:
void startDiffMerge(QString fn1,QString fn2, QString fn3, QString ofn, QString,QString,QString);
void checkIfCanContinue( bool* pbContinue );
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/fileaccess.cpp
--- a/kdiff3/src/fileaccess.cpp Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/fileaccess.cpp Tue Dec 09 20:29:43 2003 +0000
@@ -16,6 +16,7 @@
#include
#include
#include
+#include
#if QT_VERSION==230
#else
#include
@@ -99,10 +100,19 @@
// (This is a Win95-bug which has been corrected only in WinNT/2000/XP.)
if ( !name.isEmpty() )
{
- if ( m_url.isLocalFile() || !m_url.isValid() ) // assuming that malformed means relative
+ // FileAccess tries to detect if the given name is an URL or a local file.
+ // This is a problem if the filename looks like an URL (i.e. contains a colon ':').
+ // e.g. "file:f.txt" is a valid filename.
+ // Most of the time it is sufficient to check if the file exists locally.
+ // 2 Problems remain:
+ // 1. When the local file exists and the remote location is wanted nevertheless. (unlikely)
+ // 2. When the local file doesn't exist and should be written to.
+
+ bool bExistsLocal = QDir().exists(name);
+ if ( m_url.isLocalFile() || !m_url.isValid() || bExistsLocal ) // assuming that invalid means relative
{
QString localName = name;
- if ( m_url.isLocalFile() && name.left(5).lower()=="file:" )
+ if ( !bExistsLocal && m_url.isLocalFile() && name.left(5).lower()=="file:" )
{
localName = m_url.path(); // I want the path without preceding "file:"
}
@@ -145,14 +155,25 @@
jh.stat(2/*all details*/, bWantToWrite); // returns bSuccess, ignored
m_path = name;
+ m_bValidData = true; // After running stat() the variables are initialised
+ // and valid even if the file doesn't exist and the stat
+ // query failed.
}
}
}
void FileAccess::addPath( const QString& txt )
{
- m_url.addPath( txt );
- setFile( m_url.url() ); // reinitialise
+ if ( m_url.isValid() )
+ {
+ m_url.addPath( txt );
+ setFile( m_url.url() ); // reinitialise
+ }
+ else
+ {
+ QString slash = (txt.isEmpty() || txt[0]=='/') ? "" : "/";
+ setFile( absFilePath() + slash + txt );
+ }
}
/* Filetype:
@@ -540,7 +561,7 @@
connect( pStatJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotStatResult(KIO::Job*)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pStatJob, i18n("Getting file status: %1").arg(m_pFileAccess->prettyAbsPath()) );
return m_bSuccess;
}
@@ -582,7 +603,7 @@
connect( pJob, SIGNAL(data(KIO::Job*,const QByteArray &)), this, SLOT(slotGetData(KIO::Job*, const QByteArray&)));
connect( pJob, SIGNAL(percent(KIO::Job*,unsigned long)), this, SLOT(slotPercent(KIO::Job*, unsigned long)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob, i18n("Reading file: %1").arg(m_pFileAccess->prettyAbsPath()) );
return m_bSuccess;
}
else
@@ -618,7 +639,7 @@
connect( pJob, SIGNAL(dataReq(KIO::Job*, QByteArray&)), this, SLOT(slotPutData(KIO::Job*, QByteArray&)));
connect( pJob, SIGNAL(percent(KIO::Job*,unsigned long)), this, SLOT(slotPercent(KIO::Job*, unsigned long)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob, i18n("Writing file: %1").arg(m_pFileAccess->prettyAbsPath()) );
return m_bSuccess;
}
else
@@ -681,7 +702,7 @@
KIO::SimpleJob* pJob = KIO::mkdir( dirURL );
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob, i18n("Making directory: %1").arg(dirName) );
return m_bSuccess;
}
}
@@ -701,7 +722,7 @@
KIO::SimpleJob* pJob = KIO::rmdir( dirURL );
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop(pJob, i18n("Removing directory: %1").arg(dirName));
return m_bSuccess;
}
}
@@ -716,7 +737,7 @@
KIO::SimpleJob* pJob = KIO::file_delete( fileName, false );
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob, i18n("Removing file: %1").arg(fileName) );
return m_bSuccess;
}
}
@@ -731,7 +752,8 @@
KIO::CopyJob* pJob = KIO::link( linkTarget, linkLocation, false );
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob,
+ i18n("Creating symbolic link: %1 -> %2").arg(linkLocation).arg(linkTarget) );
return m_bSuccess;
}
}
@@ -756,7 +778,8 @@
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
connect( pJob, SIGNAL(percent(KIO::Job*,unsigned long)), this, SLOT(slotPercent(KIO::Job*, unsigned long)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob,
+ i18n("Renaming file: %1 -> %2").arg(m_pFileAccess->prettyAbsPath()).arg(dest) );
return m_bSuccess;
}
}
@@ -790,7 +813,8 @@
KIO::FileCopyJob* pJob = KIO::file_copy ( m_pFileAccess->m_url, destUrl.url(), permissions, bOverwrite, bResume, bShowProgress );
connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*)));
connect( pJob, SIGNAL(percent(KIO::Job*,unsigned long)), this, SLOT(slotPercent(KIO::Job*, unsigned long)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pJob,
+ i18n("Copying file: %1 -> %2").arg(m_pFileAccess->prettyAbsPath()).arg(dest) );
return m_bSuccess;
// Note that the KIO-slave preserves the original date, if this is supported.
@@ -804,13 +828,13 @@
bool bReadSuccess = srcFile.open( IO_ReadOnly );
if ( bReadSuccess == false )
{
- m_pFileAccess->m_statusText = "Error during file copy operation: Opening file for reading failed. Filename: " + srcName;
+ m_pFileAccess->m_statusText = i18n("Error during file copy operation: Opening file for reading failed. Filename: %1").arg(srcName);
return false;
}
bool bWriteSuccess = destFile.open( IO_WriteOnly );
if ( bWriteSuccess == false )
{
- m_pFileAccess->m_statusText = "Error during file copy operation: Opening file for writing failed. Filename: " + destName;
+ m_pFileAccess->m_statusText = i18n("Error during file copy operation: Opening file for writing failed. Filename: %1").arg(destName);
return false;
}
@@ -825,7 +849,7 @@
Q_LONG readSize = srcFile.readBlock( &buffer[0], min2( srcSize, bufSize ) );
if ( readSize==-1 )
{
- m_pFileAccess->m_statusText = "Error during file copy operation: Reading failed. Filename: "+srcName;
+ m_pFileAccess->m_statusText = i18n("Error during file copy operation: Reading failed. Filename: %1").arg(srcName);
return false;
}
srcSize -= readSize;
@@ -834,7 +858,7 @@
Q_LONG writeSize = destFile.writeBlock( &buffer[0], readSize );
if ( writeSize==-1 )
{
- m_pFileAccess->m_statusText = "Error during file copy operation: Writing failed. Filename: "+destName;
+ m_pFileAccess->m_statusText = i18n("Error during file copy operation: Writing failed. Filename: %1").arg(destName);
return false;
}
readSize -= writeSize;
@@ -1190,7 +1214,8 @@
// This line makes the transfer via fish unreliable.:-(
//connect( pListJob, SIGNAL(percent(KIO::Job*,unsigned long)), this, SLOT(slotPercent(KIO::Job*, unsigned long)));
- g_pProgressDialog->enterEventLoop();
+ g_pProgressDialog->enterEventLoop( pListJob,
+ i18n("Listing directory: %1").arg(m_pFileAccess->prettyAbsPath()) );
}
}
@@ -1259,75 +1284,6 @@
}
-// Return value false means that the directory or some subdirectories
-// were not readable. Probably because of missing permissions.
-bool FileAccessJobHandler::scanLocalDirectory( const QString& dirName, t_DirectoryList* pDirList )
-{
- bool bSuccess = true;
- QDir dir( dirName );
- g_pProgressDialog->setInformation( "Scanning directory: " + dirName, 0, false );
-
- // First search subdirectorys
- bool bHidden = m_bFindHidden;
- dir.setSorting( QDir::Name | QDir::DirsFirst );
- dir.setFilter( QDir::Dirs | (bHidden ? QDir::Hidden : 0) );
- dir.setMatchAllDirs( true );
-
- const QFileInfoList *fiList = dir.entryInfoList();
- if ( fiList == 0 )
- {
- // No Permission to read directory or other error.
- return false;
- }
-
- QFileInfoListIterator it( *fiList ); // create list iterator
-
- for ( ; it.current() != 0; ++it ) // for each file...
- {
- if ( g_pProgressDialog->wasCancelled() )
- return true;
-
- QFileInfo *fi = it.current();
- if ( fi->isDir() )
- {
- if ( fi->fileName() == "." || fi->fileName()==".." ||
- wildcardMultiMatch( m_dirAntiPattern, fi->fileName(), true/*case sensitive*/ ) )
- continue;
- else
- {
- if ( m_bRecursive )
- if ( ! fi->isSymLink() || m_bFollowDirLinks )
- {
- bool bLocalSuccess = scanLocalDirectory( fi->filePath(), pDirList );
- if ( ! bLocalSuccess )
- bSuccess = false;
- }
- }
- }
- }
-
- dir.setFilter( QDir::Files | QDir::Dirs | (bHidden ? QDir::Hidden : 0) );
- dir.setMatchAllDirs( true );
- dir.setNameFilter( m_filePattern );
-
- fiList = dir.entryInfoList();
- it = *fiList;
-
- QString sizeString;
-
- for ( ; it.current() != 0; ++it ) // for each file...
- {
- QFileInfo* fi = it.current();
-
- if ( fi->fileName() == "." || fi->fileName()==".." ||
- wildcardMultiMatch( fi->isDir() ? m_dirAntiPattern : m_fileAntiPattern, fi->fileName(), true/*case sensitive*/ ) )
- continue;
-
- pDirList->push_back( FileAccess( nicePath(*fi) ) );
- }
- return bSuccess;
-}
-
void FileAccessJobHandler::slotListDirProcessNewEntries( KIO::Job *, const KIO::UDSEntryList& l )
{
KURL parentUrl( m_pFileAccess->m_absFilePath );
@@ -1377,6 +1333,14 @@
m_pSubProgressBar = new KProgress(1000, this);
layout->addWidget( m_pSubProgressBar );
+ QHBoxLayout* hlayout = new QHBoxLayout( layout );
+ m_pSlowJobInfo = new QLabel( " ", this);
+ hlayout->addWidget( m_pSlowJobInfo );
+
+ m_pAbortButton = new QPushButton( i18n("Cancel"), this);
+ hlayout->addWidget( m_pAbortButton );
+ connect( m_pAbortButton, SIGNAL(clicked()), this, SLOT(slotAbort()) );
+
m_dCurrent = 0.0;
m_dSubMax = 1.0;
m_dSubMin = 0.0;
@@ -1385,6 +1349,7 @@
m_t1.start();
m_t2.start();
m_bWasCancelled = false;
+ m_pJob = 0;
}
@@ -1439,8 +1404,12 @@
void qt_enter_modal(QWidget*);
void qt_leave_modal(QWidget*);
-void ProgressDialog::enterEventLoop()
+void ProgressDialog::enterEventLoop( KIO::Job* pJob, const QString& jobInfo )
{
+ m_pJob = pJob;
+ m_currentJobInfo = jobInfo;
+ startTimer( 3000 ); /* 3 s delay */
+
// instead of using exec() the eventloop is entered and exited often without hiding/showing the window.
#if QT_VERSION==230
//qApp->enter_loop();
@@ -1453,6 +1422,8 @@
void ProgressDialog::exitEventLoop()
{
+ killTimers();
+ m_pJob = 0;
#if QT_VERSION==230
//qApp->exit_loop();
#else
@@ -1467,6 +1438,7 @@
m_pProgressBar->setProgress( int( 1000.0 * m_dCurrent ) );
m_pSubProgressBar->setProgress( int( 1000.0 * ( m_dSubCurrent * (m_dSubMax - m_dSubMin) + m_dSubMin ) ) );
if ( !isVisible() ) show();
+ m_pSlowJobInfo->setText("");
qApp->processEvents();
m_t1.restart();
}
@@ -1485,6 +1457,7 @@
#include
void ProgressDialog::show()
{
+ killTimers();
if ( !isVisible() )
{
#if QT_VERSION==230
@@ -1497,13 +1470,28 @@
void ProgressDialog::hide()
{
+ killTimers();
// Calling QDialog::hide() directly doesn't always work. (?)
QTimer::singleShot( 100, this, SLOT(delayedHide()) );
}
void ProgressDialog::delayedHide()
{
+ if (m_pJob!=0)
+ {
+ m_pJob->kill(false);
+ m_pJob = 0;
+ }
QDialog::hide();
+ m_pInformation->setText( "" );
+ m_dSubCurrent = 0;
+ m_dSubMin = 0;
+ m_dSubMax = 1;
+ m_dCurrent = 0;
+ m_pProgressBar->setProgress( 0 );
+ m_pSubProgressBar->setProgress( 0 );
+ m_pSubInformation->setText("");
+ m_pSlowJobInfo->setText("");
}
void ProgressDialog::reject()
@@ -1512,6 +1500,11 @@
QDialog::reject();
}
+void ProgressDialog::slotAbort()
+{
+ reject();
+}
+
bool ProgressDialog::wasCancelled()
{
if( m_t2.elapsed()>100 )
@@ -1533,5 +1526,14 @@
m_dSubCurrent = 0;
}
+void ProgressDialog::timerEvent(QTimerEvent*)
+{
+ if( !isVisible() )
+ {
+ show();
+ }
+ m_pSlowJobInfo->setText( m_currentJobInfo );
+}
+
#include "fileaccess.moc"
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/fileaccess.h
--- a/kdiff3/src/fileaccess.h Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/fileaccess.h Tue Dec 09 20:29:43 2003 +0000
@@ -187,18 +187,22 @@
void setSubRangeTransformation( double dMin, double dMax );
void exitEventLoop();
- void enterEventLoop();
+ void enterEventLoop( KIO::Job* pJob, const QString& jobInfo );
void start();
bool wasCancelled();
void show();
void hide();
+
+ virtual void timerEvent(QTimerEvent*);
private:
KProgress* m_pProgressBar;
KProgress* m_pSubProgressBar;
QLabel* m_pInformation;
QLabel* m_pSubInformation;
+ QLabel* m_pSlowJobInfo;
+ QPushButton* m_pAbortButton;
int m_maximum;
double m_dCurrent;
double m_dSubCurrent;
@@ -208,11 +212,13 @@
QTime m_t1;
QTime m_t2;
bool m_bWasCancelled;
-
+ KIO::Job* m_pJob;
+ QString m_currentJobInfo; // Needed if the job doesn't stop after a reasonable time.
protected:
virtual void reject();
private slots:
void delayedHide();
+ void slotAbort();
};
extern ProgressDialog* g_pProgressDialog;
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/kdiff3.cpp
--- a/kdiff3/src/kdiff3.cpp Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/kdiff3.cpp Tue Dec 09 20:29:43 2003 +0000
@@ -15,15 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.2 2003/10/11 12:45:25 joachim99
- * Allow CTRL-Tab for Windows
- *
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- ***************************************************************************/
-
#include "diff.h"
#include
@@ -114,6 +105,9 @@
m_bOutputModified = false;
m_bTimerBlock = false;
+ // Needed before any file operations via FileAccess happen.
+ g_pProgressDialog = new ProgressDialog(this);
+
// Option handling: Only when pParent==0 (no parent)
KCmdLineArgs *args = isPart() ? 0 : KCmdLineArgs::parsedArgs();
@@ -147,14 +141,14 @@
m_sd1.setFilename( args->getOption("base") );
if ( m_sd1.isEmpty() )
{
- if ( args->count() > 0 ) m_sd1.setFilename( args->arg(0) );
- if ( args->count() > 1 ) m_sd2.setFilename( args->arg(1) );
- if ( args->count() > 2 ) m_sd3.setFilename( args->arg(2) );
+ if ( args->count() > 0 ) m_sd1.setFilename( args->url(0).url() ); // args->arg(0)
+ if ( args->count() > 1 ) m_sd2.setFilename( args->url(1).url() );
+ if ( args->count() > 2 ) m_sd3.setFilename( args->url(2).url() );
}
else
{
- if ( args->count() > 0 ) m_sd2.setFilename( args->arg(0) );
- if ( args->count() > 1 ) m_sd3.setFilename( args->arg(1) );
+ if ( args->count() > 0 ) m_sd2.setFilename( args->url(0).url() );
+ if ( args->count() > 1 ) m_sd3.setFilename( args->url(1).url() );
}
QCStringList aliasList = args->getOptionList("fname");
@@ -163,7 +157,6 @@
if ( ali != aliasList.end() ) { m_sd2.setAliasName(*ali); ++ali; }
if ( ali != aliasList.end() ) { m_sd3.setAliasName(*ali); ++ali; }
}
- g_pProgressDialog = new ProgressDialog(this);
///////////////////////////////////////////////////////////////////
// call inits to invoke all other construction parts
initActions(actionCollection());
@@ -178,6 +171,12 @@
readOptions( isPart() ? m_pKDiff3Part->instance()->config() : kapp->config() );
+ autoAdvance->setChecked( m_pOptionDialog->m_bAutoAdvance );
+ showWhiteSpaceCharacters->setChecked( m_pOptionDialog->m_bShowWhiteSpaceCharacters );
+ showWhiteSpace->setChecked( m_pOptionDialog->m_bShowWhiteSpace );
+ showWhiteSpaceCharacters->setEnabled( m_pOptionDialog->m_bShowWhiteSpace );
+ showLineNumbers->setChecked( m_pOptionDialog->m_bShowLineNumbers );
+
m_pMainSplitter = this; //new QSplitter(this);
m_pMainSplitter->setOrientation( Vertical );
// setCentralWidget( m_pMainSplitter );
@@ -194,7 +193,7 @@
connect( m_pDirectoryMergeWindow, SIGNAL(checkIfCanContinue(bool*)), this, SLOT(slotCheckIfCanContinue(bool*)));
connect( m_pDirectoryMergeWindow, SIGNAL(updateAvailabilities()), this, SLOT(slotUpdateAvailabilities()));
- initDirectoryMergeActions();
+ m_pDirectoryMergeWindow->initDirectoryMergeActions( this, actionCollection() );
if ( args!=0 ) args->clear(); // Free up some memory.
@@ -294,7 +293,7 @@
if ( ! m_sd3.isEmpty() && m_sd3.m_pBuf==0 )
text += " - " + m_sd3.getAliasName() + "\n";
- KMessageBox::sorry( this, text, i18n("File open error") );
+ KMessageBox::sorry( this, text, i18n("File Open Error") );
bFileOpenError = true;
}
@@ -313,7 +312,7 @@
if (ac==0) KMessageBox::error(0, "actionCollection==0");
fileOpen = KStdAction::open(this, SLOT(slotFileOpen()), ac);
- fileOpen->setStatusText(i18n("Opens documents for comparison ..."));
+ fileOpen->setStatusText(i18n("Opens documents for comparison..."));
fileSave = KStdAction::save(this, SLOT(slotFileSave()), ac);
fileSave->setStatusText(i18n("Saves the merge result. All conflicts must be solved!"));
fileSaveAs = KStdAction::saveAs(this, SLOT(slotFileSaveAs()), ac);
@@ -337,7 +336,7 @@
KStdAction::keyBindings(this, SLOT(slotConfigureKeys()), ac);
KAction* pAction = KStdAction::preferences(this, SLOT(slotConfigure()), ac );
if ( isPart() )
- pAction->setText("Configure KDiff3 ...");
+ pAction->setText(i18n("Configure KDiff3..."));
#include "xpm/downend.xpm"
@@ -360,24 +359,33 @@
goCurrent = new KAction(i18n("Go to Current Delta"), QIconSet(QPixmap(currentpos)), CTRL+Key_Space, this, SLOT(slotGoCurrent()), ac, "go_current");
goTop = new KAction(i18n("Go to First Delta"), QIconSet(QPixmap(upend)), 0, this, SLOT(slotGoTop()), ac, "go_top");
goBottom = new KAction(i18n("Go to Last Delta"), QIconSet(QPixmap(downend)), 0, this, SLOT(slotGoBottom()), ac, "go_bottom");
- goPrevDelta = new KAction(i18n("Go to PrevDelta"), QIconSet(QPixmap(up1arrow)), CTRL+Key_Up, this, SLOT(slotGoPrevDelta()), ac, "go_prev_delta");
- goNextDelta = new KAction(i18n("Go to NextDelta"), QIconSet(QPixmap(down1arrow)), CTRL+Key_Down, this, SLOT(slotGoNextDelta()), ac, "go_next_delta");
+ goPrevDelta = new KAction(i18n("Go to Previous Delta"), QIconSet(QPixmap(up1arrow)), CTRL+Key_Up, this, SLOT(slotGoPrevDelta()), ac, "go_prev_delta");
+ goNextDelta = new KAction(i18n("Go to Next Delta"), QIconSet(QPixmap(down1arrow)), CTRL+Key_Down, this, SLOT(slotGoNextDelta()), ac, "go_next_delta");
goPrevConflict = new KAction(i18n("Go to Previous Conflict"), QIconSet(QPixmap(up2arrow)), CTRL+Key_PageUp, this, SLOT(slotGoPrevConflict()), ac, "go_prev_conflict");
goNextConflict = new KAction(i18n("Go to Next Conflict"), QIconSet(QPixmap(down2arrow)), CTRL+Key_PageDown, this, SLOT(slotGoNextConflict()), ac, "go_next_conflict");
goPrevUnsolvedConflict = new KAction(i18n("Go to Previous Unsolved Conflict"), QIconSet(QPixmap(prevunsolved)), 0, this, SLOT(slotGoPrevUnsolvedConflict()), ac, "go_prev_unsolved_conflict");
goNextUnsolvedConflict = new KAction(i18n("Go to Next Unsolved Conflict"), QIconSet(QPixmap(nextunsolved)), 0, this, SLOT(slotGoNextUnsolvedConflict()), ac, "go_next_unsolved_conflict");
- chooseA = new KToggleAction(i18n("Select line(s) from A"), QIconSet(QPixmap(iconA)), CTRL+Key_1, this, SLOT(slotChooseA()), ac, "merge_choose_a");
- chooseB = new KToggleAction(i18n("Select line(s) from B"), QIconSet(QPixmap(iconB)), CTRL+Key_2, this, SLOT(slotChooseB()), ac, "merge_choose_b");
- chooseC = new KToggleAction(i18n("Select line(s) from C"), QIconSet(QPixmap(iconC)), CTRL+Key_3, this, SLOT(slotChooseC()), ac, "merge_choose_c");
- autoAdvance = new KToggleAction(i18n("Automatically go to next unsolved conflict after source selection"), QIconSet(QPixmap(autoadvance)), 0, this, SLOT(slotAutoAdvanceToggled()), ac, "merge_autoadvance");
- showWhiteSpace = new KToggleAction(i18n("Show space and tabulator characters for differences"), QIconSet(QPixmap(showwhitespace)), 0, this, SLOT(slotShowWhiteSpaceToggled()), ac, "merge_showwhitespace");
- showLineNumbers = new KToggleAction(i18n("Show line numbers"), QIconSet(QPixmap(showlinenumbers)), 0, this, SLOT(slotShowLineNumbersToggled()), ac, "merge_showlinenumbers");
+ chooseA = new KToggleAction(i18n("Select Line(s) From A"), QIconSet(QPixmap(iconA)), CTRL+Key_1, this, SLOT(slotChooseA()), ac, "merge_choose_a");
+ chooseB = new KToggleAction(i18n("Select Line(s) From B"), QIconSet(QPixmap(iconB)), CTRL+Key_2, this, SLOT(slotChooseB()), ac, "merge_choose_b");
+ chooseC = new KToggleAction(i18n("Select Line(s) From C"), QIconSet(QPixmap(iconC)), CTRL+Key_3, this, SLOT(slotChooseC()), ac, "merge_choose_c");
+ autoAdvance = new KToggleAction(i18n("Automatically Go to Next Unsolved Conflict After Source Selection"), QIconSet(QPixmap(autoadvance)), 0, this, SLOT(slotAutoAdvanceToggled()), ac, "merge_autoadvance");
+
+ showWhiteSpaceCharacters = new KToggleAction(i18n("Show Space && Tabulator Characters for Differences"), QIconSet(QPixmap(showwhitespace)), 0, this, SLOT(slotShowWhiteSpaceToggled()), ac, "merge_show_whitespace_characters");
+ showWhiteSpace = new KToggleAction(i18n("Show White Space"), 0, this, SLOT(slotShowWhiteSpaceToggled()), ac, "merge_show_whitespace");
+
+ showLineNumbers = new KToggleAction(i18n("Show Line Numbers"), QIconSet(QPixmap(showlinenumbers)), 0, this, SLOT(slotShowLineNumbersToggled()), ac, "merge_showlinenumbers");
chooseAEverywhere = new KAction(i18n("Choose A Everywhere"), CTRL+SHIFT+Key_1, this, SLOT(slotChooseAEverywhere()), ac, "merge_choose_a_everywhere");
chooseBEverywhere = new KAction(i18n("Choose B Everywhere"), CTRL+SHIFT+Key_2, this, SLOT(slotChooseBEverywhere()), ac, "merge_choose_b_everywhere");
chooseCEverywhere = new KAction(i18n("Choose C Everywhere"), CTRL+SHIFT+Key_3, this, SLOT(slotChooseCEverywhere()), ac, "merge_choose_c_everywhere");
- autoSolve = new KAction(i18n("Automatically solve simple conflicts"), 0, this, SLOT(slotAutoSolve()), ac, "merge_autosolve");
- unsolve = new KAction(i18n("Set deltas to conflicts"), 0, this, SLOT(slotUnsolve()), actionCollection(), "merge_autounsolve");
- fileReload = new KAction(i18n("Reload"), /*QIconSet(QPixmap(reloadIcon)),*/ 0, this, SLOT(slotReload()), ac, "file_reload");
+ chooseAForUnsolvedConflicts = new KAction(i18n("Choose A For All Unsolved Conflicts"), 0, this, SLOT(slotChooseAForUnsolvedConflicts()), ac, "merge_choose_a_for_unsolved_conflicts");
+ chooseBForUnsolvedConflicts = new KAction(i18n("Choose B For All Unsolved Conflicts"), 0, this, SLOT(slotChooseBForUnsolvedConflicts()), ac, "merge_choose_b_for_unsolved_conflicts");
+ chooseCForUnsolvedConflicts = new KAction(i18n("Choose C For All Unsolved Conflicts"), 0, this, SLOT(slotChooseCForUnsolvedConflicts()), ac, "merge_choose_c_for_unsolved_conflicts");
+ chooseAForUnsolvedWhiteSpaceConflicts = new KAction(i18n("Choose A For All Unsolved Whitespace Conflicts"), 0, this, SLOT(slotChooseAForUnsolvedWhiteSpaceConflicts()), ac, "merge_choose_a_for_unsolved_whitespace_conflicts");
+ chooseBForUnsolvedWhiteSpaceConflicts = new KAction(i18n("Choose B For All Unsolved Whitespace Conflicts"), 0, this, SLOT(slotChooseBForUnsolvedWhiteSpaceConflicts()), ac, "merge_choose_b_for_unsolved_whitespace_conflicts");
+ chooseCForUnsolvedWhiteSpaceConflicts = new KAction(i18n("Choose C For All Unsolved Whitespace Conflicts"), 0, this, SLOT(slotChooseCForUnsolvedWhiteSpaceConflicts()), ac, "merge_choose_c_for_unsolved_whitespace_conflicts");
+ autoSolve = new KAction(i18n("Automatically Solve Simple Conflicts"), 0, this, SLOT(slotAutoSolve()), ac, "merge_autosolve");
+ unsolve = new KAction(i18n("Set Deltas to Conflicts"), 0, this, SLOT(slotUnsolve()), actionCollection(), "merge_autounsolve");
+ fileReload = new KAction(i18n("Reload"), /*QIconSet(QPixmap(reloadIcon)),*/ Key_F5, this, SLOT(slotReload()), ac, "file_reload");
showWindowA = new KToggleAction(i18n("Show Window A"), 0, this, SLOT(slotShowWindowAToggled()), ac, "win_show_a");
showWindowB = new KToggleAction(i18n("Show Window B"), 0, this, SLOT(slotShowWindowBToggled()), ac, "win_show_b");
showWindowC = new KToggleAction(i18n("Show Window C"), 0, this, SLOT(slotShowWindowCToggled()), ac, "win_show_c");
@@ -387,28 +395,10 @@
#endif
winFocusPrev = new KAction(i18n("Focus Prev Window"), ALT+Key_Left, this, SLOT(slotWinFocusPrev()), ac, "win_focus_prev");
winToggleSplitOrientation = new KAction(i18n("Toggle Split Orientation"), 0, this, SLOT(slotWinToggleSplitterOrientation()), ac, "win_toggle_split_orientation");
-}
-void KDiff3App::initDirectoryMergeActions()
-{
-#include "xpm/startmerge.xpm"
- //dirOpen = new KAction(i18n("Open directories ..."), 0, this, SLOT(slotDirOpen()), actionCollection(), "dir_open");
- dirStartOperation = new KAction(i18n("Start/Continue directory merge"), Key_F5, m_pDirectoryMergeWindow, SLOT(mergeContinue()), actionCollection(), "dir_start_operation");
- dirCompareCurrent = new KAction(i18n("Compare selected file"), 0, m_pDirectoryMergeWindow, SLOT(compareCurrentFile()), actionCollection(), "dir_compare_current");
- dirMergeCurrent = new KAction(i18n("Merge current file"), QIconSet(QPixmap(startmerge)), 0, this, SLOT(slotMergeCurrentFile()), actionCollection(), "merge_current");
- dirShowBoth = new KToggleAction(i18n("Dir and Text Split Screen View"), 0, this, SLOT(slotDirShowBoth()), actionCollection(), "win_dir_show_both");
+ dirShowBoth = new KToggleAction(i18n("Dir && Text Split Screen View"), 0, this, SLOT(slotDirShowBoth()), ac, "win_dir_show_both");
dirShowBoth->setChecked( true );
- dirViewToggle = new KAction(i18n("Toggle between Dir and Text View"), 0, this, SLOT(slotDirViewToggle()), actionCollection(), "win_dir_view_toggle");
- dirFoldAll = new KAction(i18n("Fold all subdirs"), 0, m_pDirectoryMergeWindow, SLOT(slotFoldAllSubdirs()), actionCollection(), "dir_fold_all");
- dirUnfoldAll = new KAction(i18n("Unfold all subdirs"), 0, m_pDirectoryMergeWindow, SLOT(slotUnfoldAllSubdirs()), actionCollection(), "dir_unfold_all");
- dirRescan = new KAction(i18n("Rescan"), 0, m_pDirectoryMergeWindow, SLOT(reload()), actionCollection(), "dir_rescan");
- dirChooseAEverywhere = new KAction(i18n("Choose A for all items"), 0, m_pDirectoryMergeWindow, SLOT(slotChooseAEverywhere()), actionCollection(), "dir_choose_a_everywhere");
- dirChooseBEverywhere = new KAction(i18n("Choose B for all items"), 0, m_pDirectoryMergeWindow, SLOT(slotChooseBEverywhere()), actionCollection(), "dir_choose_b_everywhere");
- dirChooseCEverywhere = new KAction(i18n("Choose C for all items"), 0, m_pDirectoryMergeWindow, SLOT(slotChooseCEverywhere()), actionCollection(), "dir_choose_c_everywhere");
- dirAutoChoiceEverywhere = new KAction(i18n("Auto-choose operation for all items"), 0, m_pDirectoryMergeWindow, SLOT(slotAutoChooseEverywhere()), actionCollection(), "dir_autochoose_everywhere");
- dirDoNothingEverywhere = new KAction(i18n("No operation for all items"), 0, m_pDirectoryMergeWindow, SLOT(slotNoOpEverywhere()), actionCollection(), "dir_nothing_everywhere");
- // choose A/B/C/Suggestion/NoOp everywhere
-
+ dirViewToggle = new KAction(i18n("Toggle Between Dir && Text View"), 0, this, SLOT(slotDirViewToggle()), actionCollection(), "win_dir_view_toggle");
m_pMergeEditorPopupMenu = new QPopupMenu( this );
chooseA->plug( m_pMergeEditorPopupMenu );
@@ -416,6 +406,7 @@
chooseC->plug( m_pMergeEditorPopupMenu );
}
+
void KDiff3App::showPopupMenu( const QPoint& point )
{
m_pMergeEditorPopupMenu->popup( point );
@@ -441,14 +432,6 @@
if(toolBar("mainToolBar")!=0)
config->writeEntry("ToolBarPos", (int) toolBar("mainToolBar")->barPos());
}
- m_pOptionDialog->m_bAutoAdvance = autoAdvance->isChecked();
- m_pOptionDialog->m_bShowWhiteSpace = showWhiteSpace->isChecked();
- m_pOptionDialog->m_bShowLineNumbers = showLineNumbers->isChecked();
-
- if ( m_pDiffWindowSplitter!=0 )
- {
- m_pOptionDialog->m_bHorizDiffWindowSplitting = m_pDiffWindowSplitter->orientation()==Horizontal;
- }
m_pOptionDialog->saveOptions( config );
}
@@ -498,7 +481,7 @@
{
int result = KMessageBox::warningYesNoCancel(this,
i18n("The merge result hasn't been saved."),
- i18n("Warning"), i18n("Save and quit"), i18n("Quit without saving") );
+ i18n("Warning"), i18n("Save && Quit"), i18n("Quit Without Saving") );
if ( result==KMessageBox::Cancel )
return false;
else if ( result==KMessageBox::Yes )
@@ -518,7 +501,7 @@
{
int result = KMessageBox::warningYesNo(this,
i18n("You are currently doing a directory merge. Are you sure, you want to abort?"),
- i18n("Warning"), i18n("Yes - Quit"), i18n("No - Continue merging") );
+ i18n("Warning"), i18n("Quit"), i18n("Continue Merging") );
if ( result!=KMessageBox::Yes )
return false;
}
@@ -558,7 +541,7 @@
{
slotStatusMsg(i18n("Saving file with a new filename..."));
- QString s = KFileDialog::getSaveURL( QDir::currentDirPath(), 0, this, i18n("Save as...") ).url();
+ QString s = KFileDialog::getSaveURL( QDir::currentDirPath(), 0, this, i18n("Save As...") ).url();
if(!s.isEmpty())
{
m_outputFilename = s;
@@ -659,7 +642,7 @@
layout->addMultiCellWidget( m_pSearchString, line,line,0,1 );
++line;
- m_pCaseSensitive = new QCheckBox(i18n("Case Sensitive"),this);
+ m_pCaseSensitive = new QCheckBox(i18n("Case sensitive"),this);
layout->addWidget( m_pCaseSensitive, line, 1 );
m_pSearchInA = new QCheckBox(i18n("Search A"),this);
@@ -677,16 +660,16 @@
m_pSearchInC->setChecked( true );
++line;
- m_pSearchInOutput = new QCheckBox(i18n("Search Output"),this);
+ m_pSearchInOutput = new QCheckBox(i18n("Search output"),this);
layout->addWidget( m_pSearchInOutput, line, 0 );
m_pSearchInOutput->setChecked( true );
++line;
-
- QPushButton* pButton = new QPushButton( i18n("Search"), this );
+
+ QPushButton* pButton = new QPushButton( i18n("&Search"), this );
layout->addWidget( pButton, line, 0 );
connect( pButton, SIGNAL(clicked()), this, SLOT(accept()));
- pButton = new QPushButton( i18n("Cancel"), this );
+ pButton = new QPushButton( i18n("&Cancel"), this );
layout->addWidget( pButton, line, 1 );
connect( pButton, SIGNAL(clicked()), this, SLOT(reject()));
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/kdiff3.desktop
--- a/kdiff3/src/kdiff3.desktop Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/kdiff3.desktop Tue Dec 09 20:29:43 2003 +0000
@@ -2,14 +2,9 @@
[Desktop Entry]
Encoding=UTF-8
Name=KDiff3
-Name[xx]=xxkdiff3xx
Exec=kdiff3 %i %m -caption "%c"
Icon=kdiff3
Type=Application
DocPath=kdiff3/kdiff3.html
-Comment=A KDE KPart Application
-Comment[hu]=KPart-alapú KDE-alkalmazás
-Comment[pt_BR]=Um Aplicativo KPart do KDE
-Comment[sv]=Ett KDE Kpart-program
-Comment[xx]=xxA KDE KPart Applicationxx
+Comment=A File And Directory Comparison And Merge Tool
Terminal=0
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/kdiff3.h
--- a/kdiff3/src/kdiff3.h Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/kdiff3.h Tue Dec 09 20:29:43 2003 +0000
@@ -15,13 +15,6 @@
* *
***************************************************************************/
-/***************************************************************************
- * $Log$
- * Revision 1.1 2003/10/06 18:38:48 joachim99
- * KDiff3 version 0.9.70
- * *
- ***************************************************************************/
-
#ifndef KDIFF3_H
#define KDIFF3_H
@@ -158,20 +151,6 @@
// Special KDiff3 specific stuff starts here
KAction *editFind;
KAction *editFindNext;
- KAction *dirOpen;
- KAction *dirStartOperation;
- KAction *dirCompareCurrent;
- KAction *dirMergeCurrent;
- KToggleAction *dirShowBoth;
- KAction *dirViewToggle;
- KAction *dirRescan;
- KAction* dirChooseAEverywhere;
- KAction* dirChooseBEverywhere;
- KAction* dirChooseCEverywhere;
- KAction* dirAutoChoiceEverywhere;
- KAction* dirDoNothingEverywhere;
- KAction* dirFoldAll;
- KAction* dirUnfoldAll;
KAction *goCurrent;
KAction *goTop;
@@ -186,11 +165,18 @@
KToggleAction *chooseB;
KToggleAction *chooseC;
KToggleAction *autoAdvance;
+ KToggleAction *showWhiteSpaceCharacters;
KToggleAction *showWhiteSpace;
KToggleAction *showLineNumbers;
- KAction *chooseAEverywhere;
- KAction *chooseBEverywhere;
- KAction *chooseCEverywhere;
+ KAction* chooseAEverywhere;
+ KAction* chooseBEverywhere;
+ KAction* chooseCEverywhere;
+ KAction* chooseAForUnsolvedConflicts;
+ KAction* chooseBForUnsolvedConflicts;
+ KAction* chooseCForUnsolvedConflicts;
+ KAction* chooseAForUnsolvedWhiteSpaceConflicts;
+ KAction* chooseBForUnsolvedWhiteSpaceConflicts;
+ KAction* chooseCForUnsolvedWhiteSpaceConflicts;
KAction *autoSolve;
KAction *unsolve;
KToggleAction *showWindowA;
@@ -199,6 +185,8 @@
KAction *winFocusNext;
KAction *winFocusPrev;
KAction* winToggleSplitOrientation;
+ KToggleAction *dirShowBoth;
+ KAction *dirViewToggle;
QPopupMenu* m_pMergeEditorPopupMenu;
@@ -225,7 +213,7 @@
Overview* m_pOverview;
QWidget* m_pCornerWidget;
-
+
TotalDiffStatus m_totalDiffStatus;
SourceData m_sd1;
@@ -273,7 +261,7 @@
KParts::MainWindow* m_pKDiff3Shell;
bool m_bAuto;
-private slots:
+public slots:
void resizeDiffTextWindow(int newWidth, int newHeight);
void resizeMergeResultWindow();
@@ -307,6 +295,12 @@
void slotChooseAEverywhere();
void slotChooseBEverywhere();
void slotChooseCEverywhere();
+ void slotChooseAForUnsolvedConflicts();
+ void slotChooseBForUnsolvedConflicts();
+ void slotChooseCForUnsolvedConflicts();
+ void slotChooseAForUnsolvedWhiteSpaceConflicts();
+ void slotChooseBForUnsolvedWhiteSpaceConflicts();
+ void slotChooseCForUnsolvedWhiteSpaceConflicts();
void slotConfigure();
void slotConfigureKeys();
void slotRefresh();
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/kdiff3.pro
--- a/kdiff3/src/kdiff3.pro Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/kdiff3.pro Tue Dec 09 20:29:43 2003 +0000
@@ -4,7 +4,8 @@
directorymergewindow.h fileaccess.h kdiff3_shell.h kdiff3_part.h
SOURCES = diff.cpp difftextwindow.cpp kdiff3.cpp main.cpp merger.cpp mergeresultwindow.cpp \
optiondialog.cpp pdiff.cpp directorymergewindow.cpp fileaccess.cpp \
- kdiff3_shell.cpp kdiff3_part.cpp kreplacements/kreplacements.cpp
+ kdiff3_shell.cpp kdiff3_part.cpp kreplacements/kreplacements.cpp \
+ gnudiff_analyze.cpp gnudiff_io.cpp gnudiff_xmalloc.cpp
TARGET = kdiff3
INCLUDEPATH += . ./kreplacements
diff -r 8c9752066f09 -r c59d5a3a8ff3 kdiff3/src/kdiff3_part.rc
--- a/kdiff3/src/kdiff3_part.rc Fri Oct 17 16:54:25 2003 +0000
+++ b/kdiff3/src/kdiff3_part.rc Tue Dec 09 20:29:43 2003 +0000
@@ -1,5 +1,5 @@
-
+