Mercurial > hg > easyhg-kdiff3
changeset 68:d7cafcda8c99
KDiff3 0.9.87
line wrap: on
line diff
--- a/kdiff3/ChangeLog Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/ChangeLog Mon Jan 31 22:30:47 2005 +0000 @@ -1,3 +1,12 @@ +Version 0.9.87 - 2005/30/01 +=========================== +- Unicode16 and UTF8 support (Internal data format is now QString (Unicode16). Conversion during save and load.) +- Directory "Full Analysis": Equality-Coloring for files with only whitespace differences. (Michael Denio) +- Support for right to left languages. +- In MergeResultWindow show "<Merge Conflict (Whitespace only)>" for whitespace-only conflicts +- Statusbar shows the number of remaining conflicts and whitespace conflicts. +- Go Next/Prev Difference/Conflict now have improved tooltips informing about "Show White Space"-disabled-behaviour. + Version 0.9.86 - 2004/06/14 =========================== - Double click on any file in directory merge would close the directory merge window. (Regression in 0.9.85)
--- a/kdiff3/Makefile.am Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/Makefile.am Mon Jan 31 22:30:47 2005 +0000 @@ -12,7 +12,7 @@ MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files package-messages: - $(MAKE) -f admin/Makefile.common package-messages + cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common package-messages $(MAKE) -C po merge EXTRA_DIST = admin COPYING configure.in.in
--- a/kdiff3/README Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/README Mon Jan 31 22:30:47 2005 +0000 @@ -2,8 +2,8 @@ ============= Author: Joachim Eibl (joachim.eibl@gmx.de) -Copyright: (C) 2002-2004 by Joachim Eibl -KDiff3-Version: 0.9.86 +Copyright: (C) 2002-2005 by Joachim Eibl +KDiff3-Version: 0.9.87 KDiff3 is a program that @@ -45,12 +45,12 @@ Requirements & Installation: - Version 0.9.86 provides special support for KDE3, but it can also be + Version 0.9.87 provides special support for KDE3, but it can also be built without KDE3 if the Qt-libraries are available. (I also test and use the program under Windows.) You always need - - kdiff3-0.9.86.tar.gz + - kdiff3-0.9.87.tar.gz For building the KDE3-version - KDE>=3.1 and QT>=3.1-libraries. (QT>=3.2 is recommended) @@ -67,7 +67,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.86 and type + - cd into the directory kdiff3-0.9.87 and type - ./configure --prefix=/opt/kde3 (your KDE3 directory here) - (make clean) (Required if you already compiled once.) - make (Run compilation) @@ -108,7 +108,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.86/src and type + - cd into the directory kdiff3-0.9.87/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)
--- a/kdiff3/TODO Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/TODO Mon Jan 31 22:30:47 2005 +0000 @@ -3,6 +3,41 @@ TODO ==== +- ftp: Abbruch beim Einlesen von Verzeichnis stoppt nicht vollständig + +- Projekt-Verwaltung: Die ganze Config-Datei (=Projektdatei) an einen benutzerdefinierten Ort zu legen. (Keine Angabe->Default) +- Bei Combobox-History alle Elemente von (A/B/C/Out) anzeigen. + +- Test on empty floppy drive. + +-I suppose this has been asked before, but are there any plans to use + colors for change/insert/delete (i.e. blue = change, green = insert, red + = delete)? + +> I want to compare two revisions of a file (eventually I wanna do this on +> two directory hierarchies of files) and have an output of how many lines +> of code were added, modified, and deleted for each file and overall. + +> Also, for "Send To" from Windows, it would be nice if I could pick one +> file via Send To, find the second file (if it's in a different +> directory), and click "Send To" again to compare. I.e., when user does +> "Send To", if one instance is already open and waiting for a second +> file, the first instance is used. + + +- kdiff3 does not preserve the permissions of files it overwrites during a 'save' operation. + +- Insbesondere Ausführbarkeit "x" und Schreibschutz "w" sollten erhalten bleiben. +- Edit Select All, Ctrl-A + +- Under Windows: Shortcut Ctrl-Shift-2 (for select B everywhere doesn't work.) +- Paste from Clipboard doesn't work. + +- Improve message about WinCVS in the Installer. + +- Bug: Comment section isn't recognized as nonwhite difference if several lines are between /* and */ on one side. + + - Overview-option to show only remaining conflicts. - Colors for disabled and enabled arrow are very similar - ??? The gutters (kdiff3 have 2 "gutters") fonts and background-foreground colors sholud be configured other
--- a/kdiff3/doc/en/index.docbook Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/doc/en/index.docbook Mon Jan 31 22:30:47 2005 +0000 @@ -30,7 +30,7 @@ <!-- TRANS:ROLES_OF_TRANSLATORS --> <copyright> -<year>2002-2004</year> +<year>2002-2005</year> <holder>Joachim Eibl</holder> </copyright> <!-- Translators: put here the copyright notice of the translation --> @@ -45,8 +45,8 @@ (V.MM.LL), it could be used by automation scripts. Do NOT change these in the translation. --> -<date>2004-05-29</date> -<releaseinfo>0.9.84</releaseinfo> +<date>2005-01-30</date> +<releaseinfo>0.9.87</releaseinfo> <abstract> @@ -59,10 +59,11 @@ <listitem><para>provides an automatic merge-facility,</para></listitem> <listitem><para>has an editor for comfortable solving of merge-conflicts,</para></listitem> <listitem><para>provides networktransparency via KIO,</para></listitem> -<listitem><para>has options to highlight or hide changes in white-space or comments.</para></listitem> +<listitem><para>has options to highlight or hide changes in white-space or comments,</para></listitem> +<listitem><para>supports Unicode, UTF-8 and other file encodings.</para></listitem> </itemizedlist> </para><para> - This document describes KDiff3-version 0.9.84. + This document describes KDiff3-version 0.9.87. </para> </abstract> @@ -221,6 +222,8 @@ <listitem><para>Networktransparency via KIO.</para></listitem> <listitem><para>Can be used as diff-viewer in KDevelop 3.</para></listitem> <listitem><para>Word-wrap for long lines.</para></listitem> + <listitem><para>Support for Unicode, UTF-8 and other codecs.</para></listitem> + <listitem><para>Support for right to left languages.</para></listitem> <listitem><para>...</para></listitem> </itemizedlist> </sect2> @@ -693,6 +696,26 @@ </variablelist> </sect2> +<sect2><title>Regional and Language Options</title> + <variablelist> + <varlistentry><term><emphasis>Language:</emphasis></term><listitem><para>Adjust the language of the user interface. Changing this option doesn't affect the running program. You have to exit and restart KDiff3 so that the language is changed. (This option is not available in the KDE version of KDiff3 because the language is adjustable in the global KDE settings.) + </para></listitem></varlistentry> + <varlistentry><term><emphasis>Use the same encoding for everything:</emphasis></term><listitem><para> The following encoding options can be adjusted separately for each item or if this option is true, all values will take the first value. + </para></listitem></varlistentry> + <varlistentry><term><emphasis>Local Encoding:</emphasis></term><listitem><para>Above the codec-selectors appears a note that tells you what the local encoding is. (This is not adjustable but for your information just in case you don't know your local encoding, but need to select it.) + </para></listitem></varlistentry> + <varlistentry><term><emphasis>File Encoding for A/B/C:</emphasis></term><listitem><para> Adjust the file encoding for input files. This has an effect on how the special characters are interpreted. Since you can adjust each codec separately you can even compare and merge files that were saved using different codecs. + </para></listitem></varlistentry> + <varlistentry><term><emphasis>File Encoding for Merge Output and Saving:</emphasis></term><listitem><para> When you have edited a file, then you can adjust which encoding will be used when saving to disk. + </para></listitem></varlistentry> + <varlistentry><term><emphasis>File Encoding for Preprocessor Files:</emphasis></term><listitem><para>When you define preprocessors then they might not be able to operate on your codec. (e.g.: Your files are 16-bit-unicode and your preprocessor can only take 8-bit-ascii.) With this option you can define the encoding of preprocessor output. + </para></listitem></varlistentry> + <varlistentry><term><emphasis>Right To Left Language:</emphasis></term><listitem><para>Some languages are written right to left. When this option is enabled, KDiff3 draws the text from right to left in the diff input windows and in the merge output window. Note that if you start KDiff3 with the command line option "--reverse" then all layouting will be done right to left too. (This is a feature provided by Qt.) This documentation was written assuming that "Right To Left Language" or reverse layout are disabled. So some references to "left" or "right" must be replaced by their respective counterpart if you use these options. + </para></listitem></varlistentry> + + </variablelist> +</sect2> + <sect2><title>Miscellaneous</title> <para>(These options and actions are available in menus or the buttonbar.)</para> <variablelist> @@ -1511,7 +1534,7 @@ </para></listitem><listitem><para> 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".) - (Modifying permissions or modification time is only possible for local files.) + (To modify permissions or modification time is only possible for local files.) </para></listitem> </itemizedlist> </sect2> @@ -1642,14 +1665,14 @@ &kdiff3; - File and Directory Comparison and Merge Tool </para> <para> -Program copyright 2002-2004 Joachim Eibl <email>joachim.eibl at gmx.de</email> +Program copyright 2002-2005 Joachim Eibl <email>joachim.eibl at gmx.de</email> </para> <para> Several cool ideas and bugreports came from colleagues and many people out in the Wild Wild Web. Thank you! </para> <para> -Documentation Copyright © 2002-2004 Joachim Eibl <email>joachim.eibl at gmx.de</email> +Documentation Copyright © 2002-2005 Joachim Eibl <email>joachim.eibl at gmx.de</email> </para> <!-- TRANS:CREDIT_FOR_TRANSLATORS -->
--- a/kdiff3/kdiff3.kdevelop Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/kdiff3.kdevelop Mon Jan 31 22:30:47 2005 +0000 @@ -3,7 +3,7 @@ <general> <author>Joachim Eibl</author> <email>joachim@gmx.de</email> - <version>0.9.85</version> + <version>0.9.87</version> <projectmanagement>KDevKDEAutoProject</projectmanagement> <primarylanguage>C++</primarylanguage> <keywords> @@ -106,7 +106,7 @@ <kdevdebugger> <general> <dbgshell>libtool</dbgshell> - <programargs/> + <programargs>/windows/C/qt/kdiff3-0.9.87/src/ /home/joachim/kdiff3-0.9.87/src</programargs> <gdbpath/> <configGdbScript/> <runShellScript/> @@ -153,7 +153,10 @@ <automaticHeaderCompletion>true</automaticHeaderCompletion> <headerCompletionDelay>250</headerCompletionDelay> </codecompletion> - <references/> + <references> + <pcs>KDElibs</pcs> + <pcs>Qt</pcs> + </references> </kdevcppsupport> <cppsupportpart> <filetemplates>
--- a/kdiff3/src/Makefile.qt Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/Makefile.qt Mon Jan 31 22:30:47 2005 +0000 @@ -12,8 +12,8 @@ CXX = g++ LEX = flex YACC = yacc -CFLAGS = -pipe -O2 -march=i586 -Wall -W -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -D__USE_STD_IOSTREAM -CXXFLAGS = -pipe -O2 -march=i586 -Wall -W -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -D__USE_STD_IOSTREAM +CFLAGS = -pipe -O2 -Wall -W -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -D__USE_STD_IOSTREAM +CXXFLAGS = -pipe -O2 -Wall -W -fmessage-length=0 -fPIC -D_REENTRANT -DQT_NO_DEBUG -DQT_THREAD_SUPPORT -DQT_SHARED -DQT_TABLET_SUPPORT -D__USE_STD_IOSTREAM LEXFLAGS = YACCFLAGS= -d INCPATH = -I$(QTDIR)/mkspecs/default -I. -Ikreplacements -I/usr/include -I$(QTDIR)/include
--- a/kdiff3/src/diff.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/diff.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -26,6 +26,7 @@ #include <klocale.h> #include <qfileinfo.h> #include <qdir.h> +#include <qtextcodec.h> #include <map> #include <assert.h> @@ -67,11 +68,11 @@ return false; // Ignore white space diff - const char* p1 = l1.pLine; - const char* p1End = p1 + l1.size; + const QChar* p1 = l1.pLine; + const QChar* p1End = p1 + l1.size; - const char* p2 = l2.pLine; - const char* p2End = p2 + l2.size; + const QChar* p2 = l2.pLine; + const QChar* p2End = p2 + l2.size; if ( g_bIgnoreWhiteSpace ) { @@ -111,9 +112,7 @@ } - - -static bool isLineOrBufEnd( const char* p, int i, int size ) +static bool isLineOrBufEnd( const QChar* p, int i, int size ) { return i>=size // End of file @@ -131,7 +130,7 @@ - Allocate and free buffers as necessary. - Run a preprocessor, when specified. - Run the line-matching preprocessor, when specified. -- Run other preprocessing steps: Uppercase, ignore comments, +- Run other preprocessing steps: Uppercase, ignore comments, remove carriage return, ignore numbers. Order of operation: @@ -150,7 +149,7 @@ */ SourceData::SourceData() -{ +{ m_pOptionDialog = 0; reset(); } @@ -238,20 +237,20 @@ { m_tempInputFileName = FileAccess::tempFileName(); } - + FileAccess f( m_tempInputFileName ); - bool bSuccess = f.writeFile( encodeString(data, m_pOptionDialog), data.length() ); + bool bSuccess = f.writeFile( QTextCodec::codecForName("UTF-8")->fromUnicode(data), data.length() ); if ( !bSuccess ) { KMessageBox::error( m_pOptionDialog, i18n("Writing clipboard data to temp file failed.") ); return; } - + m_aliasName = i18n("From Clipboard"); m_fileAccess = FileAccess(""); // Effect: m_fileAccess.isValid() is false } -const LineData* SourceData::getLineDataForDiff() const +const LineData* SourceData::getLineDataForDiff() const { return m_lmppData.m_pBuf==0 ? &m_normalData.m_v[0] : &m_lmppData.m_v[0]; } @@ -312,6 +311,8 @@ m_size = fa.sizeForReading(); char* pBuf; m_pBuf = pBuf = new char[m_size+100]; // Alloc 100 byte extra: Savety hack, not nice but does no harm. + // Some extra bytes at the end of the buffer are needed by + // the diff algorithm. See also GnuDiff::diff_2_files(). bool bSuccess = fa.readFile( pBuf, m_size ); if ( !bSuccess ) { @@ -339,21 +340,46 @@ void SourceData::FileData::copyBufFrom( const FileData& src ) { reset(); - char* pBuf; + char* pBuf; m_size = src.m_size; m_pBuf = pBuf = new char[m_size+100]; memcpy( pBuf, src.m_pBuf, m_size ); } -void SourceData::readAndPreprocess() +// Convert the input file from input encoding to output encoding and write it to the output file. +static bool convertFileEncoding( const QString& fileNameIn, QTextCodec* pCodecIn, + const QString& fileNameOut, QTextCodec* pCodecOut ) { + QFile in( fileNameIn ); + if ( ! in.open(IO_ReadOnly ) ) + return false; + QTextStream inStream( &in ); + inStream.setCodec( pCodecIn ); + + QFile out( fileNameOut ); + if ( ! out.open( IO_WriteOnly ) ) + return false; + QTextStream outStream( &out ); + outStream.setCodec( pCodecOut ); + + QString data = inStream.read(); + outStream << data; + + return true; +} + +void SourceData::readAndPreprocess(QTextCodec* pEncoding) +{ + m_pEncoding = pEncoding; QString fileNameIn1; QString fileNameOut1; QString fileNameIn2; QString fileNameOut2; - + QTextCodec* pEncoding1 = pEncoding; + QTextCodec* pEncoding2 = pEncoding; + bool bTempFileFromClipboard = !m_fileAccess.isValid(); - + // Detect the input for the preprocessing operations if ( !bTempFileFromClipboard ) { @@ -364,7 +390,7 @@ else // File is not local: create a temporary local copy: { if ( m_tempInputFileName.isEmpty() ) { m_tempInputFileName = FileAccess::tempFileName(); } - + m_fileAccess.copyFile(m_tempInputFileName); fileNameIn1 = m_tempInputFileName; } @@ -372,16 +398,19 @@ else // The input was set via setData(), probably from clipboard. { fileNameIn1 = m_tempInputFileName; + m_pEncoding = QTextCodec::codecForName("UTF-8"); + pEncoding1 = m_pEncoding; + pEncoding2 = m_pEncoding; } - + m_normalData.reset(); m_lmppData.reset(); - + FileAccess faIn(fileNameIn1); int fileInSize = faIn.size(); - + if ( faIn.exists() ) // fileInSize > 0 ) - { + { #ifdef _WIN32 QString catCmd = "type"; @@ -389,7 +418,7 @@ #else QString catCmd = "cat"; #endif - + // Run the first preprocessor if ( m_pOptionDialog->m_PreProcessorCmd.isEmpty() ) { @@ -398,10 +427,20 @@ } else { + QString fileNameInPP = fileNameIn1; + + if ( pEncoding1 != m_pOptionDialog->m_pEncodingPP ) + { + // Before running the preprocessor convert to the format that the preprocessor expects. + fileNameInPP = FileAccess::tempFileName(); + pEncoding1 = m_pOptionDialog->m_pEncodingPP; + convertFileEncoding( fileNameIn1, pEncoding, fileNameInPP, pEncoding1 ); + } + QString ppCmd = m_pOptionDialog->m_PreProcessorCmd; fileNameOut1 = FileAccess::tempFileName(); - QString cmd = catCmd + " \"" + fileNameIn1 + "\" | " + ppCmd + " >\"" + fileNameOut1+"\""; - ::system( encodeString(cmd, m_pOptionDialog) ); + QString cmd = catCmd + " \"" + fileNameInPP + "\" | " + ppCmd + " >\"" + fileNameOut1+"\""; + ::system( encodeString(cmd) ); bool bSuccess = m_normalData.readFile( fileNameOut1 ); if ( fileInSize >0 && ( !bSuccess || m_normalData.m_size==0 ) ) { @@ -411,18 +450,32 @@ ).arg(cmd) ); m_pOptionDialog->m_PreProcessorCmd = ""; m_normalData.readFile( fileNameIn1 ); + pEncoding1 = m_pEncoding; + } + if (fileNameInPP != fileNameIn1) + { + FileAccess::removeFile( fileNameInPP ); } } - + // LineMatching Preprocessor if ( ! m_pOptionDialog->m_LineMatchingPreProcessorCmd.isEmpty() ) { fileNameIn2 = fileNameOut1.isEmpty() ? fileNameIn1 : fileNameOut1; - + QString fileNameInPP = fileNameIn2; + pEncoding2 = pEncoding1; + if ( pEncoding2 != m_pOptionDialog->m_pEncodingPP ) + { + // Before running the preprocessor convert to the format that the preprocesor expects. + fileNameInPP = FileAccess::tempFileName(); + pEncoding2 = m_pOptionDialog->m_pEncodingPP; + convertFileEncoding( fileNameIn2, pEncoding1, fileNameInPP, pEncoding2 ); + } + QString ppCmd = m_pOptionDialog->m_LineMatchingPreProcessorCmd; fileNameOut2 = FileAccess::tempFileName(); - QString cmd = catCmd + " \"" + fileNameIn2 + "\" | " + ppCmd + " >\"" + fileNameOut2 + "\""; - ::system( encodeString(cmd, m_pOptionDialog) ); + QString cmd = catCmd + " \"" + fileNameInPP + "\" | " + ppCmd + " >\"" + fileNameOut2 + "\""; + ::system( encodeString(cmd) ); bool bSuccess = m_lmppData.readFile( fileNameOut2 ); if ( FileAccess(fileNameIn2).size()>0 && ( !bSuccess || m_lmppData.m_size==0 ) ) { @@ -434,6 +487,10 @@ m_lmppData.readFile( fileNameIn2 ); } FileAccess::removeFile( fileNameOut2 ); + if (fileNameInPP != fileNameIn2) + { + FileAccess::removeFile( fileNameInPP ); + } } else if ( m_pOptionDialog->m_bIgnoreComments || m_pOptionDialog->m_bIgnoreCase ) { @@ -444,20 +501,20 @@ { // We don't need any lmpp data at all. m_lmppData.reset(); } - } - - m_normalData.preprocess( m_pOptionDialog->m_bPreserveCarriageReturn ); - m_lmppData.preprocess( false ); - + } + + m_normalData.preprocess( m_pOptionDialog->m_bPreserveCarriageReturn, pEncoding1 ); + m_lmppData.preprocess( false, pEncoding2 ); + if ( m_lmppData.m_vSize < m_normalData.m_vSize ) { // This probably is the fault of the LMPP-Command, but not worth reporting. m_lmppData.m_v.resize( m_normalData.m_vSize ); for(int i=m_lmppData.m_vSize; i<m_normalData.m_vSize; ++i ) { // Set all empty lines to point to the end of the buffer. - m_lmppData.m_v[i].pLine = m_lmppData.m_pBuf+m_lmppData.m_size; + m_lmppData.m_v[i].pLine = m_lmppData.m_unicodeBuf.unicode()+m_lmppData.m_unicodeBuf.length(); } - + m_lmppData.m_vSize = m_normalData.m_vSize; } @@ -465,13 +522,14 @@ if ( m_pOptionDialog->m_bIgnoreCase ) { int i; - char* pBuf = const_cast<char*>(m_lmppData.m_pBuf); - for(i=0; i<m_lmppData.m_size; ++i) + QChar* pBuf = const_cast<QChar*>(m_lmppData.m_unicodeBuf.unicode()); + int ucSize = m_lmppData.m_unicodeBuf.length(); + for(i=0; i<ucSize; ++i) { - pBuf[i] = toupper(pBuf[i]); + pBuf[i] = pBuf[i].upper(); } - } - + } + // Ignore comments if ( m_pOptionDialog->m_bIgnoreComments ) { @@ -482,14 +540,14 @@ m_normalData.m_v[i].bContainsPureComment = m_lmppData.m_v[i].bContainsPureComment; } } - + // Remove unneeded temporary files. (A temp file from clipboard must not be deleted.) if ( !bTempFileFromClipboard && !m_tempInputFileName.isEmpty() ) { FileAccess::removeFile( m_tempInputFileName ); m_tempInputFileName = ""; } - + if ( !fileNameOut1.isEmpty() ) { FileAccess::removeFile( fileNameOut1 ); @@ -499,15 +557,28 @@ /** Prepare the linedata vector for every input line.*/ -void SourceData::FileData::preprocess( bool bPreserveCR ) +void SourceData::FileData::preprocess( bool bPreserveCR, QTextCodec* pEncoding ) { - const char* p = m_pBuf; + //m_unicodeBuf = decodeString( m_pBuf, m_size, eEncoding ); + + QByteArray ba; + ba.setRawData( m_pBuf, m_size ); + QTextStream ts( ba, IO_ReadOnly ); + ts.setCodec( pEncoding); + m_unicodeBuf = ts.read(); + ba.resetRawData( m_pBuf, m_size ); + + int ucSize = m_unicodeBuf.length(); + m_unicodeBuf += " "; // Some extra bytes at the end of the buffer are needed by + // the diff algorithm. See also GnuDiff::diff_2_files(). + const QChar* p = m_unicodeBuf.unicode(); + m_bIsText = true; int lines = 1; int i; - for( i=0; i<m_size; ++i ) + for( i=0; i<ucSize; ++i ) { - if ( isLineOrBufEnd(p,i,m_size) ) + if ( isLineOrBufEnd(p,i,ucSize) ) { ++lines; } @@ -522,9 +593,9 @@ int lineLength=0; bool bNonWhiteFound = false; int whiteLength = 0; - for( i=0; i<=m_size; ++i ) + for( i=0; i<=ucSize; ++i ) { - if ( isLineOrBufEnd( p, i, m_size ) ) + if ( isLineOrBufEnd( p, i, ucSize ) ) { m_v[lineIdx].pLine = &p[ i-lineLength ]; while ( !bPreserveCR && lineLength>0 && m_v[lineIdx].pLine[lineLength-1]=='\r' ) @@ -560,7 +631,7 @@ // 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 + QChar* 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) @@ -650,9 +721,9 @@ void SourceData::FileData::removeComments() { int line=0; - char* p = (char*)m_pBuf; + QChar* p = const_cast<QChar*>(m_unicodeBuf.unicode()); bool bWithinComment=false; - int size = m_size; + int size = m_unicodeBuf.length(); for(int i=0; i<size; ++i ) { // std::cout << "2 " << std::string(&p[i], m_v[line].size) << std::endl; @@ -1293,7 +1364,7 @@ } } -inline bool equal( char c1, char c2, bool /*bStrict*/ ) +inline bool equal( QChar c1, QChar c2, bool /*bStrict*/ ) { // If bStrict then white space doesn't match @@ -1494,11 +1565,10 @@ if( k1==-1 && k2!=-1 || k1!=-1 && k2==-1 ) bTextsTotalEqual=false; if( k1!=-1 && k2!=-1 ) { - if ( v1[k1].size != v2[k2].size || memcmp( v1[k1].pLine, v2[k2].pLine, v1[k1].size)!=0 ) + if ( v1[k1].size != v2[k2].size || memcmp( v1[k1].pLine, v2[k2].pLine, v1[k1].size<<1)!=0 ) { bTextsTotalEqual = false; DiffList* pDiffList = new DiffList; -// std::cout << std::string( v1[k1].pLine, v1[k1].size ) << "\n"; calcDiff( v1[k1].pLine, v1[k1].size, v2[k2].pLine, v2[k2].size, *pDiffList, 2, maxSearchLength ); // Optimize the diff list.
--- a/kdiff3/src/diff.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/diff.h Mon Jan 31 22:30:47 2005 +0000 @@ -22,13 +22,15 @@ #include <qpixmap.h> #include <qtimer.h> #include <qframe.h> +#include <qtextstream.h> +#include <qpainter.h> #include <list> #include <vector> #include <assert.h> #include "common.h" #include "fileaccess.h" +#include "optiondialog.h" -class OptionDialog; // Each range with matching elements is followed by a range with differences on either side. // Then again range of matching elements should follow. @@ -136,15 +138,15 @@ Diff3LineList& d3ll ); -void calcDiff3LineListUsingBC( +void calcDiff3LineListUsingBC( const DiffList* pDiffListBC, Diff3LineList& d3ll ); struct LineData { - const char* pLine; - const char* pFirstNonWhiteChar; + const QChar* pLine; + const QChar* pFirstNonWhiteChar; int size; LineData(){ pLine=0; size=0; occurances=0; bContainsPureComment=false; } @@ -160,9 +162,9 @@ public: SourceData(); ~SourceData(); - + void setOptionDialog( OptionDialog* pOptionDialog ); - + int getSizeLines() const; int getSizeBytes() const; const char* getBuf() const; @@ -181,38 +183,40 @@ bool isFromBuffer(); // was it set via setData() (vs. setFileAccess() or setFilename()) void setData( const QString& data ); bool isValid(); // Either no file is specified or reading was successful - - void readAndPreprocess(); + + void readAndPreprocess(QTextCodec* pEncoding); bool saveNormalDataAs( const QString& fileName ); - + bool isBinaryEqualWith( const SourceData& other ) const; - + void reset(); -private: +private: QString m_aliasName; FileAccess m_fileAccess; OptionDialog* m_pOptionDialog; QString m_tempInputFileName; struct FileData - { + { FileData(){ m_pBuf=0; m_size=0; } ~FileData(){ reset(); } const char* m_pBuf; int m_size; int m_vSize; // Nr of lines in m_pBuf1 and size of m_v1, m_dv12 and m_dv13 + QString m_unicodeBuf; std::vector<LineData> m_v; bool m_bIsText; bool readFile( const QString& filename ); bool writeFile( const QString& filename ); - void preprocess(bool bPreserveCR ); + void preprocess(bool bPreserveCR, QTextCodec* pEncoding ); void reset(); void removeComments(); void copyBufFrom( const FileData& src ); }; FileData m_normalData; - FileData m_lmppData; + FileData m_lmppData; + QTextCodec* m_pEncoding; }; void calcDiff3LineListTrim( Diff3LineList& d3ll, const LineData* pldA, const LineData* pldB, const LineData* pldC ); @@ -225,7 +229,6 @@ class QStatusBar; - class Selection { public: @@ -266,8 +269,49 @@ class OptionDialog; -QString decodeString( const char*s , OptionDialog* ); -QCString encodeString( const QString& s , OptionDialog* ); +QCString encodeString( const QString& s ); + + +// Helper class that swaps left and right for some commands. +class MyPainter : public QPainter +{ + int m_factor; + int m_xOffset; + int m_fontWidth; +public: + MyPainter(const QPaintDevice* pd, bool bRTL, int width, int fontWidth) + : QPainter(pd) + { + if (bRTL) + { + m_fontWidth = fontWidth; + m_factor = -1; + m_xOffset = width-1; + } + else + { + m_fontWidth = 0; + m_factor = 1; + m_xOffset = 0; + } + } + + void fillRect( int x, int y, int w, int h, const QBrush& b ) + { + QPainter::fillRect( m_xOffset + m_factor*x, y, m_factor*w, h, b ); + } + + void drawText( int x, int y, const QString& s, bool bAdapt=false ) + { + TextDirection td = (m_factor==1 || bAdapt == false) ? LTR : RTL; + QPainter::drawText( m_xOffset-m_fontWidth*s.length() + m_factor*x, y, s, -1, td ); + } + + void drawLine( int x1, int y1, int x2, int y2 ) + { + QPainter::drawLine( m_xOffset + m_factor*x1, y1, m_xOffset + m_factor*x2, y2 ); + } +}; class DiffTextWindow : public QWidget { @@ -315,7 +359,7 @@ void convertSelectionToD3LCoords(); - bool findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ); + bool findString( const QString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ); void setSelection( int firstLine, int startPos, int lastLine, int endPos, int& l, int& p ); void setPaintingAllowed( bool bAllowPainting ); @@ -367,11 +411,11 @@ DiffList*& pFineDiff1, DiffList*& pFineDiff2, // return values int& changed, int& changed2 ); - QCString getString( int d3lIdx ); - QCString getLineString( int line ); + QString getString( int d3lIdx ); + QString getLineString( int line ); void writeLine( - QPainter& p, const LineData* pld, + MyPainter& p, const LineData* pld, const DiffList* pLineDiff1, const DiffList* pLineDiff2, int line, int whatChanged, int whatChanged2, int srcLineNr, int wrapLineOffset, int wrapLineLength, bool bWrapLine ); @@ -385,9 +429,9 @@ virtual void timerEvent(QTimerEvent*); bool m_bMyUpdate; void myUpdate(int afterMilliSecs ); - + void showStatusLine( int line ); - + QRect m_invalidRect; }; @@ -479,7 +523,7 @@ ); bool saveDocument( const QString& fileName ); - int getNrOfUnsolvedConflicts(); + int getNrOfUnsolvedConflicts(int* pNrOfWhiteSpaceConflicts=0); void choose(int selector); void chooseGlobal(int selector, bool bConflictsOnly, bool bWhiteSpaceOnly ); @@ -496,7 +540,7 @@ bool isConflictBelowCurrent(); bool isUnsolvedConflictAboveCurrent(); bool isUnsolvedConflictBelowCurrent(); - bool findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ); + bool findString( const QString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ); void setSelection( int firstLine, int startPos, int lastLine, int endPos ); public slots: void setFirstLine(int firstLine); @@ -530,7 +574,7 @@ private: void merge(bool bAutoSolve, int defaultSelector, bool bConflictsOnly=false, bool bWhiteSpaceOnly=false ); - QCString getString( int lineIdx ); + QString getString( int lineIdx ); OptionDialog* m_pOptionDialog; @@ -548,13 +592,13 @@ { public: MergeEditLine(){ m_src=0; m_bLineRemoved=false; } - void setConflict() { m_src=0; m_bLineRemoved=false; m_str=QCString(); } + void setConflict() { m_src=0; m_bLineRemoved=false; m_str=QString(); } bool isConflict() { return m_src==0 && !m_bLineRemoved && m_str.isNull(); } - void setRemoved(int src=0) { m_src=src; m_bLineRemoved=true; m_str=QCString(); } + void setRemoved(int src=0) { m_src=src; m_bLineRemoved=true; m_str=QString(); } bool isRemoved() { return m_bLineRemoved; } bool isEditableText() { return !isConflict() && !isRemoved(); } - void setString( const QCString& s ){ m_str=s; m_bLineRemoved=false; m_src=0; } - const char* getString( const MergeResultWindow*, int& size ); + void setString( const QString& s ){ m_str=s; m_bLineRemoved=false; m_src=0; } + QString getString( const MergeResultWindow* ); bool isModified() { return ! m_str.isNull() || (m_bLineRemoved && m_src==0); } void setSource( int src, Diff3LineList::const_iterator i, bool bLineRemoved ) @@ -567,7 +611,7 @@ private: Diff3LineList::const_iterator m_id3l; int m_src; // 1, 2 or 3 for A, B or C respectively, or 0 when line is from neither source. - QCString m_str; // String when modified by user or null-string when orig data is used. + QString m_str; // String when modified by user or null-string when orig data is used. bool m_bLineRemoved; }; @@ -590,16 +634,16 @@ iterator begin(){return BASE::begin();} iterator end(){return BASE::end();} bool empty() { return m_size==0; } - + void setTotalSizePtr(int* pTotalSize) { m_pTotalSize = pTotalSize; *m_pTotalSize += m_size; } - + private: void ds(int deltaSize) - { + { m_size+=deltaSize; if (m_pTotalSize!=0) *m_pTotalSize+=deltaSize; } @@ -648,8 +692,8 @@ void myUpdate(int afterMilliSecs); virtual void timerEvent(QTimerEvent*); void writeLine( - QPainter& p, int line, const char* pStr, int size, - int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved + MyPainter& p, int line, const QString& str, + int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved, bool bWhiteSpaceConflict ); void setFastSelector(MergeLineList::iterator i); void convertToLinePos( int x, int y, int& line, int& pos ); @@ -682,10 +726,10 @@ bool m_bCursorOn; // blinking on and off each second QTimer m_cursorTimer; QStatusBar* m_pStatusBar; - + Selection m_selection; - bool deleteSelection2( const char*& ps, int& stringLength, int& x, int& y, + bool deleteSelection2( QString& str, int& x, int& y, MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt ); public slots: void deleteSelection(); @@ -708,7 +752,7 @@ -inline bool isWhite( char c ) +inline bool isWhite( QChar c ) { return c==' ' || c=='\t' || c=='\r'; } @@ -732,8 +776,8 @@ extern int g_bAutoSolve; // Cursor conversions that consider g_tabSize. -int convertToPosInText( const char* p, int size, int posOnScreen ); -int convertToPosOnScreen( const QString& p, int posInText ); -void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 ); +int convertToPosInText( const QString& s, int posOnScreen ); +int convertToPosOnScreen( const QString& s, int posInText ); +void calcTokenPos( const QString&, int posOnScreen, int& pos1, int& pos2 ); #endif
--- a/kdiff3/src/difftextwindow.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/difftextwindow.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -152,8 +152,14 @@ m_firstColumn = newFirstColumn; - QRect r( xOffset, topLineYOffset, width()-xOffset, height()-topLineYOffset ); - + QRect r( xOffset, topLineYOffset, width()-xOffset, height()-topLineYOffset ); + + if ( m_pOptionDialog->m_bRightToLeftLanguage ) + { + deltaX = -deltaX; + r = QRect( width()-1-xOffset, topLineYOffset, -(width()-xOffset), height()-topLineYOffset ).normalize(); + } + QWidget::scroll( deltaX, 0, r ); } @@ -289,7 +295,7 @@ } } -bool isCTokenChar( char c ) +bool isCTokenChar( QChar c ) { return (c=='_') || ( c>='A' && c<='Z' ) || ( c>='a' && c<='z' ) || @@ -297,27 +303,27 @@ } /// Calculate where a token starts and ends, given the x-position on screen. -void calcTokenPos( const char* p, int size, int posOnScreen, int& pos1, int& pos2 ) +void calcTokenPos( const QString& s, int posOnScreen, int& pos1, int& pos2 ) { // Cursor conversions that consider g_tabSize - int pos = convertToPosInText( p, size, max2( 0, posOnScreen ) ); - if ( pos>=size ) + int pos = convertToPosInText( s, max2( 0, posOnScreen ) ); + if ( pos>=(int)s.length() ) { - pos1=size; - pos2=size; + pos1=s.length(); + pos2=s.length(); return; } pos1 = pos; pos2 = pos+1; - if( isCTokenChar( p[pos1] ) ) + if( isCTokenChar( s[pos1] ) ) { - while( pos1>=0 && isCTokenChar( p[pos1] ) ) + while( pos1>=0 && isCTokenChar( s[pos1] ) ) --pos1; ++pos1; - while( pos2<size && isCTokenChar( p[pos2] ) ) + while( pos2<(int)s.length() && isCTokenChar( s[pos2] ) ) ++pos2; } } @@ -331,7 +337,7 @@ convertToLinePos( e->x(), e->y(), line, pos ); // Get the string data of the current line - QCString s; + QString s; if ( m_bWordWrap ) { const Diff3WrapLine& d = m_diff3WrapLineVector[line]; @@ -345,7 +351,7 @@ if ( ! s.isEmpty() ) { int pos1, pos2; - calcTokenPos( s, s.length(), pos, pos1, pos2 ); + calcTokenPos( s, pos, pos1, pos2 ); resetSelection(); selection.start( line, convertToPosOnScreen( s, pos1 ) ); @@ -389,8 +395,16 @@ int topLineYOffset = fontHeight + 3; int deltaX=0; int deltaY=0; - if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; - if ( e->x() > width() ) deltaX=+1; + if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) + { + if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; + if ( e->x() > width() ) deltaX=+1; + } + else + { + if ( e->x() > width()-1-leftInfoWidth*fontWidth ) deltaX=-1; + if ( e->x() < fontWidth ) deltaX=+1; + } if ( e->y() < topLineYOffset ) deltaY=-1; if ( e->y() > height() ) deltaY=+1; if ( deltaX != 0 && m_scrollDeltaX!=deltaX || deltaY!= 0 && m_scrollDeltaY!=deltaY ) @@ -454,7 +468,10 @@ int yOffset = topLineYOffset - m_firstLine * fontHeight; line = ( y - yOffset ) / fontHeight; - pos = ( x - xOffset ) / fontWidth; + if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) + pos = ( x - xOffset ) / fontWidth; + else + pos = ( (width() - 1 - x) - xOffset ) / fontWidth; } int Selection::firstPosInLine(int l) @@ -523,8 +540,9 @@ return ( l1 <= l && l <= l2 ); } + void DiffTextWindow::writeLine( - QPainter& p, + MyPainter& p, const LineData* pld, const DiffList* pLineDiff1, const DiffList* pLineDiff2, @@ -605,23 +623,25 @@ } } - QCString s=" "; + QString s=" "; // Convert tabs int outPos = 0; + + QString lineString( pld->pLine, pld->size ); + int lineLength = m_bWordWrap ? wrapLineOffset+wrapLineLength : lineString.length(); - int lineLength = m_bWordWrap ? wrapLineOffset+wrapLineLength : pld->size; for( i=wrapLineOffset; i<lineLength; ++i ) { int spaces = 1; - if ( pld->pLine[i]=='\t' ) + if ( lineString[i]=='\t' ) { spaces = tabber( outPos, g_tabSize ); s[0] = ' '; } else { - s[0] = pld->pLine[i]; + s[0] = lineString[i]; } QColor c = m_pOptionDialog->m_fgColor; @@ -642,6 +662,8 @@ } QRect outRect( xOffset + fontWidth*outPos, yOffset, fontWidth*spaces, fontHeight ); + if ( m_pOptionDialog->m_bRightToLeftLanguage ) + outRect = QRect( width()-1-(xOffset + fontWidth*outPos), yOffset, -fontWidth*spaces, fontHeight ).normalize(); if ( m_invalidRect.intersects( outRect ) ) { if( !selection.within( line, outPos ) ) @@ -666,7 +688,7 @@ } else { - p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) ); + p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s ); } p.setFont(normalFont); } @@ -676,7 +698,7 @@ fontWidth*(spaces), fontHeight, colorGroup().highlight() ); p.setPen( colorGroup().highlightedText() ); - p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, decodeString(s,m_pOptionDialog) ); + p.drawText( xOffset + fontWidth*outPos, yOffset + fontAscent, s ); selection.bSelectionContainsData = true; } @@ -804,10 +826,11 @@ QPainter painter(this); //QPainter& p=painter; QPixmap pixmap( m_invalidRect.size() ); - QPainter p( &pixmap ); + MyPainter p( &pixmap, m_pOptionDialog->m_bRightToLeftLanguage, width(), fontMetrics().width('W') ); + p.translate( -m_invalidRect.x(), -m_invalidRect.y() ); - p.fillRect( m_invalidRect, m_pOptionDialog->m_bgColor ); + p.QPainter::fillRect( m_invalidRect, m_pOptionDialog->m_bgColor ); p.setFont( font() ); @@ -912,7 +935,7 @@ } -QCString DiffTextWindow::getString( int d3lIdx ) +QString DiffTextWindow::getString( int d3lIdx ) { const Diff3Line* d3l = (*m_pDiff3LineVector)[d3lIdx]; DiffList* pFineDiff1; @@ -922,16 +945,16 @@ int lineIdx; getLineInfo( *d3l, lineIdx, pFineDiff1, pFineDiff2, changed, changed2 ); - if (lineIdx==-1) return QCString(); + if (lineIdx==-1) return QString(); else { const LineData* ld = &m_pLineData[lineIdx]; - return QCString( ld->pLine, ld->size + 1 ); + return QString( ld->pLine, ld->size ); } - return QCString(); + return QString(); } -QCString DiffTextWindow::getLineString( int line ) +QString DiffTextWindow::getLineString( int line ) { if ( m_bWordWrap ) { @@ -1027,14 +1050,15 @@ else assert(false); if( lineIdx != -1 ) - { - const char* pLine = m_pLineData[lineIdx].pLine; + { + const QChar* pLine = m_pLineData[lineIdx].pLine; int size = m_pLineData[lineIdx].size; + QString lineString = QString( pLine, size ); if ( m_bWordWrap ) { - pLine += m_diff3WrapLineVector[it].wrapLineOffset; size = m_diff3WrapLineVector[it].wrapLineLength; + lineString = lineString.mid( m_diff3WrapLineVector[it].wrapLineOffset, size ); } // Consider tabs @@ -1042,23 +1066,18 @@ for( int i=0; i<size; ++i ) { int spaces = 1; - if ( pLine[i]=='\t' ) + if ( lineString[i]=='\t' ) { spaces = tabber( outPos, g_tabSize ); } if( selection.within( line, outPos ) ) { - char buf[2]; - buf[0] = pLine[i]; - buf[1] = '\0'; - selectionString += decodeString( buf, m_pOptionDialog ); + selectionString += lineString[i]; } outPos += spaces; - } - - + } if( selection.within( line, outPos ) && !( m_bWordWrap && it+1<vectorSize && d == m_diff3WrapLineVector[it+1].pD3L ) @@ -1077,7 +1096,7 @@ return selectionString; } -bool DiffTextWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ) +bool DiffTextWindow::findString( const QString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ) { int it = d3vLine; int endIt = bDirDown ? (int)m_pDiff3LineVector->size() : -1; @@ -1086,7 +1105,7 @@ for( ; it!=endIt; it+=step ) { - QCString line = getString( it ); + QString line = getString( it ); if ( !line.isEmpty() ) { int pos = line.find( s, startPos, bCaseSensitive ); @@ -1252,13 +1271,13 @@ // convert the selection to unwrapped coordinates: Later restore to new coords int firstD3LIdx, firstD3LPos; - QCString s = getLineString( selection.beginLine() ); - int firstPosInText = convertToPosInText( s, s.length(), selection.beginPos() ); + QString s = getLineString( selection.beginLine() ); + int firstPosInText = convertToPosInText( s, selection.beginPos() ); convertLineCoordsToD3LCoords( selection.beginLine(), firstPosInText, firstD3LIdx, firstD3LPos ); int lastD3LIdx, lastD3LPos; s = getLineString( selection.endLine() ); - int lastPosInText = convertToPosInText( s, s.length(), selection.endPos() ); + int lastPosInText = convertToPosInText( s, selection.endPos() ); convertLineCoordsToD3LCoords( selection.endLine(), lastPosInText, lastD3LIdx, lastD3LPos ); //selection.reset(); @@ -1349,30 +1368,12 @@ #include <qtextcodec.h> -QString decodeString( const char*s , OptionDialog* pOptions ) + +QCString encodeString( const QString& s ) { - if ( pOptions->m_bStringEncoding ) - { - QTextCodec* c = QTextCodec::codecForLocale(); - if (c!=0) - return c->toUnicode( s ); - else - return QString(s); - } + QTextCodec* c = QTextCodec::codecForLocale(); + if (c!=0) + return c->fromUnicode( s ); else - return QString(s); + return QCString( s.latin1() ); } - -QCString encodeString( const QString& s , OptionDialog* pOptions ) -{ - if ( pOptions->m_bStringEncoding ) - { - QTextCodec* c = QTextCodec::codecForLocale(); - if (c!=0) - return c->fromUnicode( s ); - else - return QCString( s.ascii() ); - } - else - return QCString( s.ascii() ); -}
--- a/kdiff3/src/directorymergewindow.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/directorymergewindow.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -56,7 +56,7 @@ if (firstChild()==0) return 0; else return m_pLast; } - + void addText(const QString& s ) { if (firstChild()==0) m_pLast = new QListViewItem( this, s ); @@ -177,7 +177,7 @@ return; } - pp.setInformation( i18n("Comparing file ..."), 0, false ); + pp.setInformation( i18n("Comparing file..."), 0, false ); #if QT_VERSION==230 typedef int t_FileSize; #else @@ -248,7 +248,7 @@ m_pStatusInfo = new StatusInfo(0); m_pStatusInfo->hide(); m_bScanning = false; - + addColumn(i18n("Name")); addColumn("A"); addColumn("B"); @@ -259,7 +259,7 @@ addColumn(i18n("Solved")); addColumn(i18n("Nonwhite")); addColumn(i18n("White")); - + setColumnAlignment( s_UnsolvedCol, Qt::AlignRight ); setColumnAlignment( s_SolvedCol, Qt::AlignRight ); setColumnAlignment( s_NonWhiteCol, Qt::AlignRight ); @@ -291,6 +291,7 @@ if ( result!=KMessageBox::Yes ) return; } + init( m_dirA, m_dirB, m_dirC, m_dirDest, m_bDirectoryMerge ); } @@ -385,14 +386,15 @@ { if ( m_pOptions->m_bDmFullAnalysis ) { - // A full analysis uses the same ressources that a normal text-diff/merge uses. + // A full analysis uses the same ressources that a normal text-diff/merge uses. // So make sure that the user saves his data first. bool bCanContinue=false; checkIfCanContinue( &bCanContinue ); if ( !bCanContinue ) return false; + startDiffMerge("","","","","","","",0); // hide main window } - + show(); ProgressProxy pp; @@ -442,9 +444,9 @@ i18n("Parameter Warning")); return false; } - + m_bScanning = true; - statusBarMessage(i18n("Scanning directories ...")); + statusBarMessage(i18n("Scanning directories...")); m_bSyncMode = m_pOptions->m_bDmSyncMode && !m_dirC.isValid() && !m_dirDest.isValid(); @@ -472,7 +474,7 @@ setColumnWidth( s_NonWhiteCol, 0 ); setColumnWidth( s_UnsolvedCol, 0 ); setColumnWidth( s_SolvedCol, 0 ); - } + } else if ( m_dirC.isValid() ) { setColumnWidth(s_WhiteCol, 50 ); @@ -487,7 +489,7 @@ setColumnWidth(s_UnsolvedCol, 50 ); setColumnWidth(s_SolvedCol, 0 ); } - + bool bListDirSuccessA = true; bool bListDirSuccessB = true; bool bListDirSuccessC = true; @@ -600,7 +602,7 @@ sizes[1]=total - sizes[0]; pSplitter->setSizes( sizes ); } - + m_bScanning = false; statusBarMessage(i18n("Ready.")); @@ -626,7 +628,7 @@ KMessageBox::information( this, s ); setSelected( firstChild(), true ); } - + return true; } @@ -811,13 +813,23 @@ "", "","","",&mfi.m_totalDiffStatus ); - mfi.m_bEqualAB = mfi.m_totalDiffStatus.bBinaryAEqB; - mfi.m_bEqualBC = mfi.m_totalDiffStatus.bBinaryBEqC; - mfi.m_bEqualAC = mfi.m_totalDiffStatus.bBinaryAEqC; + int nofNonwhiteConflicts = mfi.m_totalDiffStatus.nofUnsolvedConflicts + + mfi.m_totalDiffStatus.nofSolvedConflicts - mfi.m_totalDiffStatus.nofWhitespaceConflicts; + + if (m_pOptions->m_bDmWhiteSpaceEqual && nofNonwhiteConflicts == 0) + { + mfi.m_bEqualAB = mfi.m_bEqualBC = mfi.m_bEqualAC = true; + } + else + { + mfi.m_bEqualAB = mfi.m_totalDiffStatus.bBinaryAEqB; + mfi.m_bEqualBC = mfi.m_totalDiffStatus.bBinaryBEqC; + mfi.m_bEqualAC = mfi.m_totalDiffStatus.bBinaryAEqC; + } } } else - { + { bool bError; QString eqStatus; if( mfi.m_bExistsInA && mfi.m_bExistsInB ) @@ -1743,7 +1755,7 @@ { pEnd = pEnd->parent(); } - if ( pEnd!=0 ) + if ( pEnd!=0 ) pEnd=pEnd->nextSibling(); prepareMergeStart( pBegin, pEnd, bVerbose ); @@ -2201,7 +2213,7 @@ } } - m_pStatusInfo->addText(i18n("rename( %1 -> %2 )").arg(srcName).arg(destName)) ; + m_pStatusInfo->addText(i18n("rename( %1 -> %2 )").arg(srcName).arg(destName)); if ( m_bSimulatedMergeStarted ) { return true; @@ -2288,7 +2300,7 @@ m_pInfoList->addColumn(i18n("Last Modification")); m_pInfoList->addColumn(i18n("Link-Destination")); setMinimumSize( 100,100 ); - + m_pInfoList->installEventFilter(this); } @@ -2422,17 +2434,17 @@ 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"); + 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"); + dirCurrentSyncDeleteAAndB = new KAction(i18n("Delete A && 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"); + dirCurrentSyncMergeToAAndB = new KAction(i18n("Merge to A && B"), 0, p, SLOT(slotCurrentMergeToAAndB()), ac,"dir_current_sync_merge_to_a_and_b"); } @@ -2468,7 +2480,7 @@ bool bFTConflict = pMFI==0 ? false : conflictingFileTypes(*pMFI); bool bDirWindowHasFocus = isVisible() && hasFocus(); - + dirCurrentDoNothing->setEnabled( bItemActive && bMergeMode ); dirCurrentChooseA->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInA ); dirCurrentChooseB->setEnabled( bItemActive && bMergeMode && pMFI->m_bExistsInB ); @@ -2484,7 +2496,7 @@ chooseB->setChecked( false ); chooseC->setChecked( false ); } - + dirCurrentSyncDoNothing->setEnabled( bItemActive && !bMergeMode ); dirCurrentSyncCopyAToB->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInA ); dirCurrentSyncCopyBToA->setEnabled( bItemActive && !bMergeMode && pMFI->m_bExistsInB );
--- a/kdiff3/src/fileaccess.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/fileaccess.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -740,7 +740,7 @@ else { m_bSuccess = false; - KIO::SimpleJob* pJob = KIO::file_delete( fileName, false ); + KIO::SimpleJob* pJob = KIO::file_delete( KURL::fromPathOrURL(fileName), false ); connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*))); g_pProgressDialog->enterEventLoop( pJob, i18n("Removing file: %1").arg(fileName) ); @@ -755,7 +755,7 @@ else { m_bSuccess = false; - KIO::CopyJob* pJob = KIO::link( linkTarget, linkLocation, false ); + KIO::CopyJob* pJob = KIO::link( KURL::fromPathOrURL(linkTarget), KURL::fromPathOrURL(linkLocation), false ); connect( pJob, SIGNAL(result(KIO::Job*)), this, SLOT(slotSimpleJobResult(KIO::Job*))); g_pProgressDialog->enterEventLoop( pJob, @@ -780,7 +780,7 @@ bool bShowProgress = false; int permissions=-1; m_bSuccess = false; - KIO::FileCopyJob* pJob = KIO::file_move( m_pFileAccess->m_url, kurl.url(), permissions, bOverwrite, bResume, bShowProgress ); + KIO::FileCopyJob* pJob = KIO::file_move( m_pFileAccess->m_url, kurl, 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))); @@ -817,7 +817,7 @@ bool bShowProgress = false; int permissions = (m_pFileAccess->isExecutable()?0111:0)+(m_pFileAccess->isWritable()?0222:0)+(m_pFileAccess->isReadable()?0444:0); m_bSuccess = false; - KIO::FileCopyJob* pJob = KIO::file_copy ( m_pFileAccess->m_url, destUrl.url(), permissions, bOverwrite, bResume, bShowProgress ); + KIO::FileCopyJob* pJob = KIO::file_copy ( m_pFileAccess->m_url, destUrl, 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( pJob, @@ -1207,7 +1207,7 @@ WIN32_FIND_DATA findData; WIN32_FIND_DATAA& findDataA=*(WIN32_FIND_DATAA*)&findData; // Needed for Win95 - HANDLE searchHandle = QT_WA_INLINE( + HANDLE searchHandle = QT_WA_INLINE( FindFirstFile( (TCHAR*)pattern.ucs2(), &findData ), FindFirstFileA( pattern.local8Bit(), &findDataA ) ); @@ -1240,7 +1240,7 @@ fa.m_creationTime = QDateTime( QDate(t.wYear, t.wMonth, t.wDay), QTime(t.wHour, t.wMinute, t.wSecond) ); int a = findData.dwFileAttributes; - fa.m_bWritable = ( a & FILE_ATTRIBUTE_READONLY) == 0; + fa.m_bWritable = ( a & FILE_ATTRIBUTE_READONLY) == 0; fa.m_bDir = ( a & FILE_ATTRIBUTE_DIRECTORY ) != 0; fa.m_bFile = !fa.m_bDir; fa.m_bHidden = ( a & FILE_ATTRIBUTE_HIDDEN) != 0; @@ -1253,9 +1253,9 @@ fa.m_bSymLink = false; fa.m_fileType = 0; - fa.m_name = QT_WA_INLINE( + fa.m_name = QT_WA_INLINE( QString::fromUcs2(findData.cFileName), - QString::fromLocal8Bit(findDataA.cFileName) + QString::fromLocal8Bit(findDataA.cFileName) ); fa.m_path = fa.m_name; @@ -1424,7 +1424,7 @@ m_pSlowJobInfo = new QLabel( " ", this); hlayout->addWidget( m_pSlowJobInfo ); - m_pAbortButton = new QPushButton( i18n("Cancel"), this); + m_pAbortButton = new QPushButton( i18n("&Cancel"), this); hlayout->addWidget( m_pAbortButton ); connect( m_pAbortButton, SIGNAL(clicked()), this, SLOT(slotAbort()) ); @@ -1457,18 +1457,18 @@ void ProgressDialog::pop( bool bRedrawUpdate ) { if ( !m_progressStack.empty() ) - { + { m_progressStack.pop_back(); if ( m_progressStack.empty() ) hide(); - else + else recalc(bRedrawUpdate); } } void ProgressDialog::setInformation(const QString& info, double dCurrent, bool bRedrawUpdate ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_dCurrent = dCurrent; @@ -1487,7 +1487,7 @@ void ProgressDialog::setInformation(const QString& info, bool bRedrawUpdate ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; //ProgressLevelData& pld = m_progressStack.back(); int level = m_progressStack.size(); @@ -1505,7 +1505,7 @@ void ProgressDialog::setMaxNofSteps( int maxNofSteps ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_maxNofSteps = maxNofSteps; @@ -1514,7 +1514,7 @@ void ProgressDialog::step( bool bRedrawUpdate ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_dCurrent += 1.0/pld.m_maxNofSteps; @@ -1523,7 +1523,7 @@ void ProgressDialog::setCurrent( double dSubCurrent, bool bRedrawUpdate ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_dCurrent = dSubCurrent; @@ -1536,7 +1536,7 @@ // Requirement: 0 < dMin < dMax < 1 void ProgressDialog::setRangeTransformation( double dMin, double dMax ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_dRangeMin = dMin; @@ -1546,7 +1546,7 @@ void ProgressDialog::setSubRangeTransformation( double dMin, double dMax ) { - if ( m_progressStack.empty() ) + if ( m_progressStack.empty() ) return; ProgressLevelData& pld = m_progressStack.back(); pld.m_dSubRangeMin = dMin; @@ -1603,7 +1603,7 @@ else m_pSubProgressBar->setProgress( int( 1000.0 * m_progressStack.front().m_dSubRangeMin ) ); } - + if ( !isVisible() ) show(); m_pSlowJobInfo->setText(""); qApp->processEvents(); @@ -1644,7 +1644,7 @@ m_pInformation->setText( "" ); m_progressStack.clear(); - + m_pProgressBar->setProgress( 0 ); m_pSubProgressBar->setProgress( 0 ); m_pSubInformation->setText("");
--- a/kdiff3/src/gnudiff_analyze.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/gnudiff_analyze.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -792,6 +792,13 @@ /* Report the differences of two files. */ +// WARNING: +// This algorithm has one big problem: It must have a line end character +// at the end of the last line, even if there is none in the file. +// Because of this the algorithm first places a line end character there +// which means that the input data can't be const and some extra bytes of memory +// must be allocated in advance for this purpose. This is very dangerous, because +// easy to forget. GnuDiff::change* GnuDiff::diff_2_files (struct comparison *cmp) { lin diags; @@ -882,131 +889,33 @@ Return nonzero if the lines differ. */ bool -GnuDiff::lines_differ (char const *s1, char const *s2) +GnuDiff::lines_differ (const QChar *s1, const QChar *s2) { - register unsigned char const *t1 = (unsigned char const *) s1; - register unsigned char const *t2 = (unsigned char const *) s2; - size_t column = 0; + const QChar *t1 = s1; + const QChar *t2 = s2; while (1) { - register unsigned char c1 = *t1++; - register unsigned char c2 = *t2++; + QChar c1 = *t1++; + QChar c2 = *t2++; /* Test for exact char equality first, since it's a common case. */ if (c1 != c2) { while ( bIgnoreWhiteSpace && isWhite( c1 ) || - bIgnoreNumbers && (isdigit( c1 ) || c1=='-' || c1=='.' )) + bIgnoreNumbers && (c1.isDigit() || c1=='-' || c1=='.' )) c1 = *t1++; while ( bIgnoreWhiteSpace && isWhite( c2 ) || - bIgnoreNumbers && (isdigit( c2 ) || c2=='-' || c2=='.' )) + bIgnoreNumbers && (c2.isDigit() || c2=='-' || c2=='.' )) c2 = *t2++; -#if 0 - switch (ignore_white_space) - { - case IGNORE_ALL_SPACE: - /* For -w, just skip past any white space. */ - while (ISSPACE (c1) && c1 != '\n') c1 = *t1++; - while (ISSPACE (c2) && c2 != '\n') c2 = *t2++; - break; - - case IGNORE_SPACE_CHANGE: - /* For -b, advance past any sequence of white space in - line 1 and consider it just one space, or nothing at - all if it is at the end of the line. */ - if (ISSPACE (c1)) - { - while (c1 != '\n') - { - c1 = *t1++; - if (! ISSPACE (c1)) - { - --t1; - c1 = ' '; - break; - } - } - } - - /* Likewise for line 2. */ - if (ISSPACE (c2)) - { - while (c2 != '\n') - { - c2 = *t2++; - if (! ISSPACE (c2)) - { - --t2; - c2 = ' '; - break; - } - } - } - - if (c1 != c2) - { - /* If we went too far when doing the simple test - for equality, go back to the first non-white-space - character in both sides and try again. */ - if (c2 == ' ' && c1 != '\n' - && (unsigned char const *) s1 + 1 < t1 - && ISSPACE (t1[-2])) - { - --t1; - continue; - } - if (c1 == ' ' && c2 != '\n' - && (unsigned char const *) s2 + 1 < t2 - && ISSPACE (t2[-2])) - { - --t2; - continue; - } - } - - break; - - case IGNORE_TAB_EXPANSION: - if ((c1 == ' ' && c2 == '\t') - || (c1 == '\t' && c2 == ' ')) - { - size_t column2 = column; - for (;; c1 = *t1++) - { - if (c1 == ' ') - column++; - else if (c1 == '\t') - column += TAB_WIDTH - column % TAB_WIDTH; - else - break; - } - for (;; c2 = *t2++) - { - if (c2 == ' ') - column2++; - else if (c2 == '\t') - column2 += TAB_WIDTH - column2 % TAB_WIDTH; - else - break; - } - if (column != column2) - return 1; - } - break; - - case IGNORE_NO_WHITE_SPACE: - break; - } -#endif /* Lowercase all letters if -i is specified. */ if (ignore_case) { - c1 = TOLOWER (c1); - c2 = TOLOWER (c2); + c1 = c1.lower(); + c2 = c2.lower(); } if (c1 != c2) @@ -1014,8 +923,6 @@ } if (c1 == '\n') return 0; - - column += c1 == '\t' ? TAB_WIDTH - column % TAB_WIDTH : 1; } return 1;
--- a/kdiff3/src/gnudiff_diff.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/gnudiff_diff.h Mon Jan 31 22:30:47 2005 +0000 @@ -1,6 +1,6 @@ /* Shared definitions for GNU DIFF - Modified for KDiff3 by Joachim Eibl 2003. + Modified for KDiff3 by Joachim Eibl 2003, 2004, 2005. The original file was part of GNU DIFF. Copyright (C) 1988, 1989, 1991, 1992, 1993, 1994, 1995, 1998, 2001, @@ -27,6 +27,7 @@ #include "gnudiff_system.h" #include <stdio.h> +#include <qstring.h> #define TAB_WIDTH 8 @@ -134,9 +135,6 @@ /* Ignore differences in case of letters in file names. */ bool ignore_file_name_case; -/* File labels for `-c' output headers (--label). */ -char *file_label[2]; - /* Regexp to identify function-header lines (-F). */ //struct re_pattern_buffer function_regexp; @@ -155,22 +153,19 @@ without changing the characters in it (-T). */ bool initial_tab; -/* Remove trailing carriage returns from input. */ -bool strip_trailing_cr; - /* In directory comparison, specify file to start with (-S). This is used for resuming an aborted comparison. All file names less than this name are ignored. */ -char const *starting_file; +const QChar *starting_file; /* Pipe each file's output through pr (-l). */ bool paginate; /* Line group formats for unchanged, old, new, and changed groups. */ -char const *group_format[CHANGED + 1]; +const QChar *group_format[CHANGED + 1]; /* Line formats for unchanged, old, and new lines. */ -char const *line_format[NEW + 1]; +const QChar *line_format[NEW + 1]; /* If using OUTPUT_SDIFF print extra information to help the sdiff filter. */ bool sdiff_merge_assist; @@ -185,11 +180,6 @@ unsigned int sdiff_half_width; unsigned int sdiff_column2_offset; -/* String containing all the command options diff received, - with spaces between and at the beginning but none at the end. - If there were no options given, this string is empty. */ -char *switch_string; - /* Use heuristics for better speed with large files with a small density of changes. */ bool speed_large_files; @@ -201,11 +191,6 @@ slower) but will find a guaranteed minimal set of changes. */ bool minimal; -/* Name of program the user invoked (for error messages). */ -char *program_name; - -/* The strftime format to use for time strings. */ -char const *time_format; /* The result of comparison is an "edit script": a chain of `struct change'. Each `struct change' represents one place where some lines are deleted @@ -235,13 +220,13 @@ struct file_data { #if 0 int desc; /* File descriptor */ - char const *name; /* File name */ + const QChar *name; /* File name */ struct stat stat; /* File status */ #endif /* Buffer in which text of file is read. */ word *buffer; - /* Allocated size of buffer, in bytes. Always a multiple of + /* Allocated size of buffer, in QChars. Always a multiple of sizeof *buffer. */ size_t bufsize; @@ -249,7 +234,7 @@ size_t buffered; /* Array of pointers to lines in the file. */ - char const **linbuf; + const QChar **linbuf; /* linbuf_base <= buffered_lines <= valid_lines <= alloc_lines. linebuf[linbuf_base ... buffered_lines - 1] are possibly differing. @@ -258,14 +243,14 @@ lin linbuf_base, buffered_lines, valid_lines, alloc_lines; /* Pointer to end of prefix of this file to ignore when hashing. */ - char const *prefix_end; + const QChar *prefix_end; /* Count of lines in the prefix. There are this many lines in the file before linbuf[0]. */ lin prefix_lines; /* Pointer to start of suffix of this file to ignore when hashing. */ - char const *suffix_begin; + const QChar *suffix_begin; /* Vector, indexed by line number, containing an equivalence code for each line. It is this vector that is actually compared with that @@ -301,7 +286,7 @@ /* The file buffer, considered as an array of bytes rather than as an array of words. */ -#define FILE_BUFFER(f) ((char *) (f)->buffer) +#define FILE_BUFFER(f) ((QChar *) (f)->buffer) /* Data on two input files being compared. */ @@ -329,7 +314,7 @@ void print_context_script (struct change *, bool); /* dir.c */ -int diff_dirs (struct comparison const *, int (*) (struct comparison const *, char const *, char const *)); +int diff_dirs (struct comparison const *, int (*) (struct comparison const *, const QChar *, const QChar *)); /* ed.c */ void print_ed_script (struct change *); @@ -352,11 +337,8 @@ void print_sdiff_script (struct change *); /* util.c */ -//extern char const change_letter[4]; -//extern char const pr_program[]; -char *concat (char const *, char const *, char const *); -char *dir_file_pathname (char const *, char const *); -bool lines_differ (char const *, char const *); +QChar *concat (const QChar *, const QChar *, const QChar *); +bool lines_differ (const QChar *, const QChar *); lin translate_line_number (struct file_data const *, lin); struct change *find_change (struct change *); struct change *find_reverse_change (struct change *); @@ -364,22 +346,18 @@ enum changes analyze_hunk (struct change *, lin *, lin *, lin *, lin *); void begin_output (void); void debug_script (struct change *); -void fatal (char const *) __attribute__((noreturn)); +void fatal (const QChar *) __attribute__((noreturn)); void finish_output (void); -void message (char const *, char const *, char const *); -void message5 (char const *, char const *, char const *, char const *, char const *); -void output_1_line (char const *, char const *, char const *, char const *); -void perror_with_name (char const *); -void pfatal_with_name (char const *) __attribute__((noreturn)); -void print_1_line (char const *, char const * const *); -void print_message_queue (void); -void print_number_range (char, struct file_data *, lin, lin); -void print_script (struct change *, struct change * (*) (struct change *), void (*) (struct change *)); -void setup_output (char const *, char const *, bool); +void message (const QChar *, const QChar *, const QChar *); +void message5 (const QChar *, const QChar *, const QChar *, const QChar *, const QChar *); +void output_1_line (const QChar *, const QChar *, const QChar *, const QChar *); +void perror_with_name (const QChar *); +void pfatal_with_name (const QChar *) __attribute__((noreturn)); +void setup_output (const QChar *, const QChar *, bool); void translate_range (struct file_data const *, lin, lin, long *, long *); /* version.c */ -//extern char const version_string[]; +//extern const QChar version_string[]; private: // gnudiff_analyze.cpp @@ -401,7 +379,7 @@ void *xrealloc(void *p, size_t n); void xalloc_die (void); - inline bool isWhite( char c ) + inline bool isWhite( QChar c ) { return c==' ' || c=='\t' || c=='\r'; }
--- a/kdiff3/src/gnudiff_io.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/gnudiff_io.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -1,6 +1,6 @@ /* File I/O for GNU DIFF. - Modified for KDiff3 by Joachim Eibl 2003. + Modified for KDiff3 by Joachim Eibl 2003, 2004, 2005. The original file was part of GNU DIFF. Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1998, 2001, 2002 @@ -42,7 +42,7 @@ { lin next; /* Next item in this bucket. */ hash_value hash; /* Hash of lines in this class. */ - char const *line; /* A line that fits this class. */ + const QChar *line; /* A line that fits this class. */ size_t length; /* That line's length, not counting its newline. */ }; @@ -79,13 +79,13 @@ void GnuDiff::find_and_hash_each_line (struct file_data *current) { hash_value h; - unsigned char const *p = (unsigned char const *) current->prefix_end; - unsigned char c; + const QChar *p = (const QChar *) current->prefix_end; + QChar c; lin i, *bucket; size_t length; /* Cache often-used quantities in local variables to help the compiler. */ - char const **linbuf = current->linbuf; + const QChar **linbuf = current->linbuf; lin alloc_lines = current->alloc_lines; lin line = 0; lin linbuf_base = current->linbuf_base; @@ -93,16 +93,16 @@ struct equivclass *eqs = equivs; lin eqs_index = equivs_index; lin eqs_alloc = equivs_alloc; - char const *suffix_begin = current->suffix_begin; - char const *bufend = FILE_BUFFER (current) + current->buffered; + const QChar *suffix_begin = current->suffix_begin; + const QChar *bufend = FILE_BUFFER (current) + current->buffered; bool diff_length_compare_anyway = ignore_white_space != IGNORE_NO_WHITE_SPACE || bIgnoreNumbers; bool same_length_diff_contents_compare_anyway = diff_length_compare_anyway | ignore_case; - while ((char const *) p < suffix_begin) + while ((const QChar *) p < suffix_begin) { - char const *ip = (char const *) p; + const QChar *ip = (const QChar *) p; h = 0; @@ -112,67 +112,13 @@ { case IGNORE_ALL_SPACE: while ((c = *p++) != '\n') - if (! (ISSPACE (c) || bIgnoreNumbers && (isdigit( c ) || c=='-' || c=='.' ) )) - h = HASH (h, TOLOWER (c)); - break; - - case IGNORE_SPACE_CHANGE: - while ((c = *p++) != '\n') - { - if (ISSPACE (c)) - { - do - if ((c = *p++) == '\n') - goto hashing_done; - while (ISSPACE (c)); - - h = HASH (h, ' '); - } - - /* C is now the first non-space. */ - h = HASH (h, TOLOWER (c)); - } - break; - - case IGNORE_TAB_EXPANSION: - { - size_t column = 0; - while ((c = *p++) != '\n') - { - int repetitions = 1; - - switch (c) - { - case '\b': - column -= 0 < column; - break; - - case '\t': - c = ' '; - repetitions = TAB_WIDTH - column % TAB_WIDTH; - column += repetitions; - break; - - case '\r': - column = 0; - break; - - default: - c = TOLOWER (c); - column++; - break; - } - - do - h = HASH (h, c); - while (--repetitions != 0); - } - } + if (! (isWhite(c) || bIgnoreNumbers && (c.isDigit() || c=='-' || c=='.' ) )) + h = HASH (h, c.lower().unicode()); break; default: while ((c = *p++) != '\n') - h = HASH (h, TOLOWER (c)); + h = HASH (h, c.lower().unicode()); break; } else @@ -180,75 +126,20 @@ { case IGNORE_ALL_SPACE: while ((c = *p++) != '\n') - if (! (ISSPACE (c)|| bIgnoreNumbers && (isdigit( c ) || c=='-' || c=='.' ) )) - h = HASH (h, c); - break; - - case IGNORE_SPACE_CHANGE: - while ((c = *p++) != '\n') - { - if (ISSPACE (c)) - { - do - if ((c = *p++) == '\n') - goto hashing_done; - while (ISSPACE (c)); - - h = HASH (h, ' '); - } - - /* C is now the first non-space. */ - h = HASH (h, c); - } - break; - - case IGNORE_TAB_EXPANSION: - { - size_t column = 0; - while ((c = *p++) != '\n') - { - int repetitions = 1; - - switch (c) - { - case '\b': - column -= 0 < column; - break; - - case '\t': - c = ' '; - repetitions = TAB_WIDTH - column % TAB_WIDTH; - column += repetitions; - break; - - case '\r': - column = 0; - break; - - default: - column++; - break; - } - - do - h = HASH (h, c); - while (--repetitions != 0); - } - } + if (! (isWhite(c)|| bIgnoreNumbers && (c.isDigit() || c=='-' || c=='.' ) )) + h = HASH (h, c.unicode()); break; default: while ((c = *p++) != '\n') - h = HASH (h, c); + h = HASH (h, c.unicode()); break; } - hashing_done:; + bucket = &buckets[h % nbuckets]; + length = (const QChar *) p - ip - 1; - bucket = &buckets[h % nbuckets]; - length = (char const *) p - ip - 1; - - if ((char const *) p == bufend + if ((const QChar *) p >= bufend && current->missing_newline && ROBUST_OUTPUT_STYLE (output_style)) { @@ -259,7 +150,7 @@ /* Omit the inserted newline when computing linbuf later. */ p--; - bufend = suffix_begin = (char const *) p; + bufend = suffix_begin = (const QChar *) p; } for (i = *bucket; ; i = eqs[i].next) @@ -283,7 +174,7 @@ } else if (eqs[i].hash == h) { - char const *eqline = eqs[i].line; + const QChar *eqline = eqs[i].line; /* Reuse existing class if lines_differ reports the lines equal. */ @@ -315,7 +206,7 @@ alloc_lines = 2 * alloc_lines - linbuf_base; cureqs =(lin*) xrealloc (cureqs, alloc_lines * sizeof *cureqs); linbuf += linbuf_base; - linbuf = (const char**) xrealloc (linbuf, + linbuf = (const QChar**) xrealloc (linbuf, (alloc_lines - linbuf_base) * sizeof *linbuf); linbuf -= linbuf_base; } @@ -340,13 +231,13 @@ xalloc_die (); alloc_lines = 2 * alloc_lines - linbuf_base; linbuf += linbuf_base; - linbuf = (const char**)xrealloc (linbuf, + linbuf = (const QChar**)xrealloc (linbuf, (alloc_lines - linbuf_base) * sizeof *linbuf); linbuf -= linbuf_base; } - linbuf[line] = (char const *) p; + linbuf[line] = (const QChar *) p; - if ((char const *) p == bufend) + if ((const QChar *) p >= bufend) break; if (context <= i && no_diff_means_no_output) @@ -376,8 +267,7 @@ void GnuDiff::prepare_text (struct file_data *current) { size_t buffered = current->buffered; - char *p = FILE_BUFFER (current); - char *dst; + QChar *p = FILE_BUFFER (current); if (buffered == 0 || p[buffered - 1] == '\n') current->missing_newline = 0; @@ -393,18 +283,6 @@ /* Don't use uninitialized storage when planting or using sentinels. */ memset (p + buffered, 0, sizeof (word)); - if (strip_trailing_cr && (dst = (char*)memchr (p, '\r', buffered))) - { - char const *src = dst; - char const *srclim = p + buffered; - - do - dst += ! ((*dst = *src++) == '\r' && *src == '\n'); - while (src < srclim); - - buffered -= src - dst; - } - current->buffered = buffered; } @@ -417,7 +295,7 @@ { size_t guessed_bytes_per_line = n < 10 ? 32 : s / (n - 1); lin guessed_lines = MAX (1, t / guessed_bytes_per_line); - return MIN (guessed_lines, (lin)(PTRDIFF_MAX / (2 * sizeof (char *) + 1) - 5)) + 5; + return MIN (guessed_lines, (lin)(PTRDIFF_MAX / (2 * sizeof (QChar *) + 1) - 5)) + 5; } /* Given a vector of two file_data objects, find the identical @@ -426,9 +304,9 @@ void GnuDiff::find_identical_ends (struct file_data filevec[]) { word *w0, *w1; - char *p0, *p1, *buffer0, *buffer1; - char const *end0, *beg0; - char const **linbuf0, **linbuf1; + QChar *p0, *p1, *buffer0, *buffer1; + const QChar *end0, *beg0; + const QChar **linbuf0, **linbuf1; lin i, lines; size_t n0, n1; lin alloc_lines0, alloc_lines1; @@ -442,8 +320,8 @@ w0 = filevec[0].buffer; w1 = filevec[1].buffer; - p0 = buffer0 = (char *) w0; - p1 = buffer1 = (char *) w1; + p0 = buffer0 = (QChar *) w0; + p1 = buffer1 = (QChar *) w1; n0 = filevec[0].buffered; n1 = filevec[1].buffered; @@ -467,8 +345,8 @@ w0++, w1++; /* Do the last few bytes of comparison a byte at a time. */ - p0 = (char *) w0; - p1 = (char *) w1; + p0 = (QChar *) w0; + p1 = (QChar *) w1; while (*p0 == *p1) p0++, p1++; @@ -567,7 +445,7 @@ prefix_mask = prefix_count - 1; lines = 0; - linbuf0 = (const char**) xmalloc (alloc_lines0 * sizeof *linbuf0); + linbuf0 = (const QChar**) xmalloc (alloc_lines0 * sizeof(*linbuf0)); p0 = buffer0; /* If the prefix is needed, find the prefix lines. */ @@ -584,7 +462,7 @@ if ((lin)(PTRDIFF_MAX / (2 * sizeof *linbuf0)) <= alloc_lines0) xalloc_die (); alloc_lines0 *= 2; - linbuf0 = (const char**) xrealloc (linbuf0, alloc_lines0 * sizeof *linbuf0); + linbuf0 = (const QChar**) xrealloc (linbuf0, alloc_lines0 * sizeof(*linbuf0)); } linbuf0[l] = p0; while (*p0++ != '\n') @@ -601,7 +479,7 @@ if (alloc_lines1 < buffered_prefix || (lin)(PTRDIFF_MAX / sizeof *linbuf1) <= alloc_lines1) xalloc_die (); - linbuf1 = (const char**)xmalloc (alloc_lines1 * sizeof *linbuf1); + linbuf1 = (const QChar**)xmalloc (alloc_lines1 * sizeof(*linbuf1)); if (buffered_prefix != lines) {
--- a/kdiff3/src/kdiff3.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -104,6 +104,7 @@ m_pMergeWindowFrame = 0; m_bOutputModified = false; m_bTimerBlock = false; + m_pHScrollBar = 0; // Needed before any file operations via FileAccess happen. g_pProgressDialog = new ProgressDialog(this); @@ -111,13 +112,13 @@ // All default values must be set before calling readOptions(). m_pOptionDialog = new OptionDialog( m_pKDiff3Shell!=0, this ); connect( m_pOptionDialog, SIGNAL(applyClicked()), this, SLOT(slotRefresh()) ); - + m_pOptionDialog->readOptions( isPart() ? m_pKDiff3Part->instance()->config() : kapp->config() ); m_sd1.setOptionDialog(m_pOptionDialog); m_sd2.setOptionDialog(m_pOptionDialog); m_sd3.setOptionDialog(m_pOptionDialog); - + // Option handling: Only when pParent==0 (no parent) KCmdLineArgs *args = isPart() ? 0 : KCmdLineArgs::parsedArgs(); @@ -161,18 +162,18 @@ if ( args->count() > 1 ) m_sd3.setFilename( args->url(1).url() ); } - + QCStringList aliasList = args->getOptionList("fname"); QCStringList::Iterator ali = aliasList.begin(); - + QString an1 = args->getOption("L1"); if ( !an1.isEmpty() ) { m_sd1.setAliasName(an1); } else if ( ali != aliasList.end() ) { m_sd1.setAliasName(*ali); ++ali; } - + QString an2 = args->getOption("L2"); if ( !an2.isEmpty() ) { m_sd2.setAliasName(an2); } else if ( ali != aliasList.end() ) { m_sd2.setAliasName(*ali); ++ali; } - + QString an3 = args->getOption("L3"); if ( !an3.isEmpty() ) { m_sd3.setAliasName(an3); } else if ( ali != aliasList.end() ) { m_sd3.setAliasName(*ali); ++ali; } @@ -186,7 +187,7 @@ connect( m_pFindDialog, SIGNAL(findNext()), this, SLOT(slotEditFindNext())); 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 ); @@ -236,7 +237,7 @@ } bool bSuccess = improveFilenames(); - + if ( m_bAuto && m_bDirCompare ) { std::cerr << i18n("Option --auto ignored for directory comparison.").ascii()<<std::endl; @@ -272,7 +273,7 @@ if ( FileAccess::exists( newName ) ) FileAccess::removeFile( newName ); if ( !FileAccess::exists( newName ) ) fa.rename( newName ); } - + bSuccess = pSD->saveNormalDataAs( m_outputFilename ); if ( bSuccess ) ::exit(0); else KMessageBox::error( this, i18n("Saving failed.") ); @@ -379,12 +380,20 @@ 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"); + QString omitsWhitespace = ".\n" + i18n("(Skips white space differences when \"Show White Space\" is disabled.)"); + QString includeWhitespace = ".\n" + i18n("(Doesn't skip white space differences even when \"Show White Space\" is disabled.)"); goPrevDelta = new KAction(i18n("Go to Previous Delta"), QIconSet(QPixmap(up1arrow)), CTRL+Key_Up, this, SLOT(slotGoPrevDelta()), ac, "go_prev_delta"); + goPrevDelta->setToolTip( goPrevDelta->text() + omitsWhitespace ); goNextDelta = new KAction(i18n("Go to Next Delta"), QIconSet(QPixmap(down1arrow)), CTRL+Key_Down, this, SLOT(slotGoNextDelta()), ac, "go_next_delta"); + goNextDelta->setToolTip( goNextDelta->text() + omitsWhitespace ); goPrevConflict = new KAction(i18n("Go to Previous Conflict"), QIconSet(QPixmap(up2arrow)), CTRL+Key_PageUp, this, SLOT(slotGoPrevConflict()), ac, "go_prev_conflict"); + goPrevConflict->setToolTip( goPrevConflict->text() + omitsWhitespace ); goNextConflict = new KAction(i18n("Go to Next Conflict"), QIconSet(QPixmap(down2arrow)), CTRL+Key_PageDown, this, SLOT(slotGoNextConflict()), ac, "go_next_conflict"); + goNextConflict->setToolTip( goNextConflict->text() + omitsWhitespace ); goPrevUnsolvedConflict = new KAction(i18n("Go to Previous Unsolved Conflict"), QIconSet(QPixmap(prevunsolved)), 0, this, SLOT(slotGoPrevUnsolvedConflict()), ac, "go_prev_unsolved_conflict"); + goPrevUnsolvedConflict->setToolTip( goPrevUnsolvedConflict->text() + includeWhitespace ); goNextUnsolvedConflict = new KAction(i18n("Go to Next Unsolved Conflict"), QIconSet(QPixmap(nextunsolved)), 0, this, SLOT(slotGoNextUnsolvedConflict()), ac, "go_next_unsolved_conflict"); + goNextUnsolvedConflict->setToolTip( goNextUnsolvedConflict->text() + includeWhitespace ); 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"); @@ -397,12 +406,12 @@ 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"); - 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"); + 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"); @@ -410,13 +419,13 @@ 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"); winFocusNext = new KAction(i18n("Focus Next Window"), ALT+Key_Right, this, SLOT(slotWinFocusNext()), ac, "win_focus_next"); - + overviewModeNormal = new KToggleAction(i18n("Normal Overview"), 0, this, SLOT(slotOverviewNormal()), ac, "diff_overview_normal"); overviewModeAB = new KToggleAction(i18n("A vs. B Overview"), 0, this, SLOT(slotOverviewAB()), ac, "diff_overview_ab"); overviewModeAC = new KToggleAction(i18n("A vs. C Overview"), 0, this, SLOT(slotOverviewAC()), ac, "diff_overview_ac"); overviewModeBC = new KToggleAction(i18n("B vs. C Overview"), 0, this, SLOT(slotOverviewBC()), ac, "diff_overview_bc"); wordWrap = new KToggleAction(i18n("Word Wrap Diff Windows"), 0, this, SLOT(slotWordWrapToggled()), ac, "diff_wordwrap"); - + #ifdef _WIN32 new KAction(i18n("Focus Next Window"), CTRL+Key_Tab, this, SLOT(slotWinFocusNext()), ac, "win_focus_next", false, false); #endif @@ -661,7 +670,7 @@ layout->setSpacing(5); int line=0; - layout->addMultiCellWidget( new QLabel(i18n("Searchtext:"),this), line,line,0,1 ); + layout->addMultiCellWidget( new QLabel(i18n("Search text:"),this), line,line,0,1 ); ++line; m_pSearchString = new QLineEdit( this );
--- a/kdiff3/src/kdiff3.desktop Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3.desktop Mon Jan 31 22:30:47 2005 +0000 @@ -7,21 +7,29 @@ Name[ta]=கேடிஃப்3 Name[xx]=xxKDiff3xx GenericName=Diff/Patch Frontend +GenericName[bs]=Interfejs za Diff/Patch +GenericName[cy]=Blaen Gwahaniaethau/Clytiau GenericName[da]=Forende for diff/patch GenericName[de]=Graphische Oberfläche zu Diff/Patch GenericName[es]=Interfaz Diff/Patch GenericName[et]=Võrdlemise ja liitmise rakendus GenericName[fr]=Interface graphique à diff / patch GenericName[hu]=Grafikus diff/patch +GenericName[is]=Diff/Patch viðmót GenericName[it]=Interfaccia per diff/patch +GenericName[ja]=Diff/Patch フロントエンド +GenericName[lt]=Diff/Patch vartotojo sąsaja +GenericName[ms]=Bahagian Depan Beza/Tampal GenericName[nl]=Een schil voor Diff/Patch +GenericName[pl]=Interfejs do programów Diff/Patch GenericName[pt]=Interface do Diff/Patch GenericName[pt_BR]=Um front-end para Diff/Patch GenericName[ru]=Графический интерфейс к Diff и Patch GenericName[sr]=Интерфејс за Diff и Patch -GenericName[sr@Latn]=Интерфејс за Diff и Patch GenericName[sv]=Jämförelse- och programfixgränssnitt -GenericName[ta]= ஒரு கேடியி முன்முனையில் இருந்து எஸ்எம்எஸ்அனுப்பு +GenericName[ta]= Diff/Patch Frontend +GenericName[tg]=Интерфейси графикӣ ба Diff ва Patch +GenericName[uk]=Інтерфейс до diff/patch GenericName[xx]=xxDiff/Patch Frontendxx GenericName[zh_CN]=Diff/Patch 前端 GenericName[zu]=Diff/PatchIsiqalo sokugcina @@ -30,6 +38,8 @@ Type=Application DocPath=kdiff3/index.html Comment=A File And Directory Comparison And Merge Tool +Comment[bg]=Инструмент за сравняване и сливане на файлове и директории +Comment[bs]=Alat za upoređivanje i spajanje datoteka i direktorija Comment[ca]=Una eina per a comparar i fusionar fitxers o directoris Comment[da]=Et indfletningsværktøj for filer og mapper Comment[de]=Programm zum Vergleichen und Zusammenführen von Dateien und Ordnern @@ -39,14 +49,19 @@ Comment[fr]=Un outil de comparaison et de fusion de fichiers et dossiers Comment[hi]=एक फाइल तथा डिरेक्ट्री तुलना तथा विलीन उपकरण Comment[hu]=Segédprogram fájlok, könyvtárak összehasonlításához +Comment[is]=Skráa og möppu samanburðar og sameiningartól Comment[it]=Uno strumento di confronto e unione di file e directory +Comment[ja]=ファイル/ディレクトリの比較/統合ツール +Comment[ms]=Perbandingan Fail Dan Direktori Dan Alatan Gabungan Comment[nl]=Hulpmiddel voor het vergelijken en samenvoegen van bestanden en mappen +Comment[pl]=Narzędzie do porównywania oraz łączenia plików i katalogów Comment[pt]=Uma Ferramenta de Comparação e Junção de Ficheiros e Pastas Comment[pt_BR]=Uma Comparação de Arquivos e Pastas e uma Ferramenta para Mesclar Diferenças Comment[ru]=Утилита сравнения и объединения файлов и каталогов Comment[sr]=Алат за поређење и стапање фајлова и директоријума -Comment[sr@Latn]=Алат за поређење и стапање фајлова и директоријума Comment[sv]=Ett jämförelseverktyg för fil- och katalogjämförelser +Comment[tg]=Асбоби баробаркунӣ ва пайванди файлҳо ва каталогҳо +Comment[uk]=Засіб-утиліта для порівняння і поєднання файлів та каталогів Comment[xx]=xxA File And Directory Comparison And Merge Toolxx Comment[zh_CN]=一个文件和目录的比较及合并工具 -Terminal=0 +Terminal=false
--- a/kdiff3/src/kdiff3.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3.h Mon Jan 31 22:30:47 2005 +0000 @@ -27,6 +27,7 @@ // include files for Qt #include <qdialog.h> #include <qsplitter.h> +#include <qscrollbar.h> // include files for KDE #include <kapplication.h> @@ -53,6 +54,39 @@ class DirectoryMergeInfo; +class ReversibleScrollBar : public QScrollBar +{ + Q_OBJECT + bool* m_pbRightToLeftLanguage; + int m_realVal; +public: + ReversibleScrollBar( Orientation o, QWidget* pParent, bool* pbRightToLeftLanguage ) + : QScrollBar( o, pParent ) + { + m_pbRightToLeftLanguage=pbRightToLeftLanguage; + m_realVal=0; + connect( this, SIGNAL(valueChanged(int)), this, SLOT(slotValueChanged(int))); + } + void setAgain(){ setValue(m_realVal); } +public slots: + void slotValueChanged(int i) + { + m_realVal = i; + if(m_pbRightToLeftLanguage && *m_pbRightToLeftLanguage) + m_realVal = maxValue()-(i-minValue()); + emit valueChanged2(m_realVal); + } + void setValue(int i) + { + if(m_pbRightToLeftLanguage && *m_pbRightToLeftLanguage) + QScrollBar::setValue( maxValue()-(i-minValue()) ); + else + QScrollBar::setValue( i ); + } +signals: + void valueChanged2(int); +}; + class KDiff3App : public QSplitter { Q_OBJECT @@ -199,7 +233,7 @@ QSplitter* m_pMainSplitter; QFrame* m_pMainWidget; QFrame* m_pMergeWindowFrame; - QScrollBar* m_pHScrollBar; + ReversibleScrollBar* m_pHScrollBar; QScrollBar* m_pDiffVScrollBar; QScrollBar* m_pMergeVScrollBar;
--- a/kdiff3/src/kdiff3.pro Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3.pro Mon Jan 31 22:30:47 2005 +0000 @@ -1,5 +1,7 @@ TEMPLATE = app +# When unresolved items remain during linking: Try adding "shared" in the CONFIG. CONFIG += qt warn_on thread release + HEADERS = version.h diff.h kdiff3.h merger.h optiondialog.h kreplacements/kreplacements.h \ directorymergewindow.h fileaccess.h kdiff3_shell.h kdiff3_part.h SOURCES = diff.cpp difftextwindow.cpp kdiff3.cpp main.cpp merger.cpp mergeresultwindow.cpp \ @@ -11,9 +13,9 @@ win32 { QMAKE_CXXFLAGS_DEBUG -= -Zi - QMAKE_CXXFLAGS_DEBUG += -GX -GR -Z7 /FR + QMAKE_CXXFLAGS_DEBUG += -GX -GR -Z7 /FR -DQT_NO_ASCII_CAST QMAKE_LFLAGS_DEBUG += /PDB:NONE - QMAKE_CXXFLAGS_RELEASE += -GX -GR -DNDEBUG + QMAKE_CXXFLAGS_RELEASE += -GX -GR -DNDEBUG -DQT_NO_ASCII_CAST RC_FILE = kdiff3.rc } unix {
--- a/kdiff3/src/kdiff3_part.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3_part.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -83,9 +83,37 @@ */ } +static void getNameAndVersion( const QString& str, const QString& lineStart, QString& fileName, QString& version ) +{ + if ( str.left( lineStart.length() )==lineStart && fileName.isEmpty() ) + { + unsigned int pos = lineStart.length(); + while ( pos<str.length() && (str[pos]==' ' || str[pos]=='\t') ) ++pos; + unsigned int pos2 = str.length()-1; + while ( pos2>pos ) + { + while (pos2>pos && str[pos2]!=' ' && str[pos2]!='\t') --pos2; + fileName = str.mid( pos, pos2-pos ); + std::cerr << "KDiff3: " << fileName.latin1() << std::endl; + if ( FileAccess(fileName).exists() ) break; + --pos2; + } + + int vpos = str.findRev("\t", -1); + if ( vpos>0 && vpos>(int)pos2 ) + { + version = str.mid( vpos+1 ); + while( !version.right(1)[0].isLetterOrNumber() ) + version.truncate( version.length()-1 ); + } + } +} + + bool KDiff3Part::openFile() { // m_file is always local so we can use QFile on it + std::cerr << "KDiff3: " << m_file.latin1() << std::endl; QFile file(m_file); if (file.open(IO_ReadOnly) == false) return false; @@ -101,30 +129,8 @@ while (!stream.eof() && (fileName1.isEmpty() || fileName2.isEmpty()) ) { str = stream.readLine() + "\n"; - if ( str.left(4)=="--- " && fileName1.isEmpty() ) - { - int pos = str.find("\t"); - fileName1 = str.mid( 4, pos-4 ); - int vpos = str.findRev("\t", -1); - if ( pos>0 && vpos>0 && vpos>pos ) - { - version1 = str.mid( vpos+1 ); - while( !version1.right(1)[0].isLetterOrNumber() ) - version1.truncate( version1.length()-1 ); - } - } - if ( str.left(4)=="+++ " && fileName2.isEmpty() ) - { - int pos = str.find("\t"); - fileName2 = str.mid( 4, pos-4 ); - int vpos = str.findRev("\t", -1); - if ( pos>0 && vpos>0 && vpos>pos ) - { - version2 = str.mid( vpos+1 ); - while( !version2.right(1)[0].isLetterOrNumber() ) - version2.truncate( version2.length()-1 ); - } - } + getNameAndVersion( str, "---", fileName1, version1 ); + getNameAndVersion( str, "+++", fileName2, version2 ); } file.close(); @@ -148,40 +154,42 @@ // Normal patch // patch -f -u --ignore-whitespace -i [inputfile] -o [outfile] [patchfile] QString tempFileName = FileAccess::tempFileName(); - QString cmd = "patch -f -u --ignore-whitespace -i " + m_file + - " -o "+tempFileName + " " + fileName1; + QString cmd = "patch -f -u --ignore-whitespace -i \"" + m_file + + "\" -o \""+tempFileName + "\" \"" + fileName1+ "\""; ::system( cmd.ascii() ); m_widget->slotFileOpen2( fileName1, tempFileName, "", "", "", version2.isEmpty() ? fileName2 : "REV:"+version2+":"+fileName2, "", 0 ); // alias names - FileAccess::removeFile( tempFileName ); + std::cerr << "KDiff3: f1:" << fileName1.latin1() <<"<->"<<tempFileName.latin1()<< std::endl; +// FileAccess::removeFile( tempFileName ); } else if ( version2.isEmpty() && f2.exists() ) { // Reverse patch // patch -f -u -R --ignore-whitespace -i [inputfile] -o [outfile] [patchfile] QString tempFileName = FileAccess::tempFileName(); - QString cmd = "patch -f -u -R --ignore-whitespace -i " + m_file + - " -o "+tempFileName + " " + fileName2; + QString cmd = "patch -f -u -R --ignore-whitespace -i \"" + m_file + + "\" -o \""+tempFileName + "\" \"" + fileName2+"\""; ::system( cmd.ascii() ); m_widget->slotFileOpen2( tempFileName, fileName2, "", "", version1.isEmpty() ? fileName1 : "REV:"+version1+":"+fileName1, "", "", 0 ); // alias name - FileAccess::removeFile( tempFileName ); + std::cerr << "KDiff3: f2:" << fileName2.latin1() <<"<->"<<tempFileName.latin1()<< std::endl; } else if ( !version1.isEmpty() && !version2.isEmpty() ) { + std::cerr << "KDiff3: f1/2:" << fileName1.latin1() <<"<->"<<fileName2.latin1()<< std::endl; // Assuming that files are on CVS: Try to get them // cvs update -p -r [REV] [FILE] > [OUTPUTFILE] QString tempFileName1 = FileAccess::tempFileName(); - QString cmd1 = "cvs update -p -r " + version1 + " " + fileName1 + " >"+tempFileName1; + QString cmd1 = "cvs update -p -r " + version1 + " \"" + fileName1 + "\" >\""+tempFileName1+"\""; ::system( cmd1.ascii() ); QString tempFileName2 = FileAccess::tempFileName(); - QString cmd2 = "cvs update -p -r " + version2 + " " + fileName2 + " >"+tempFileName2; + QString cmd2 = "cvs update -p -r " + version2 + " \"" + fileName2 + "\" >\""+tempFileName2+"\""; ::system( cmd2.ascii() ); m_widget->slotFileOpen2( tempFileName1, tempFileName2, "", "", @@ -190,8 +198,9 @@ "", 0 ); - FileAccess::removeFile( tempFileName1 ); - FileAccess::removeFile( tempFileName2 ); + std::cerr << "KDiff3: f1/2:" << tempFileName1.latin1() <<"<->"<<tempFileName2.latin1()<< std::endl; +// FileAccess::removeFile( tempFileName1 ); + // FileAccess::removeFile( tempFileName2 ); return true; } else
--- a/kdiff3/src/kdiff3part.desktop Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kdiff3part.desktop Mon Jan 31 22:30:47 2005 +0000 @@ -1,11 +1,13 @@ [Desktop Entry] Encoding=UTF-8 Name=KDiff3Part +Name[cs]=Komponenta KDiff3 Name[fr]=Composant KDiff3 Name[hi]=के-डिफ3पार्ट Name[pt_BR]=Componente KDiff3 Name[sv]=Kdiff3-del Name[ta]=கேடிஃப்3 பகுதி +Name[tg]=ҚисмиKDiff3 Name[xx]=xxKDiff3Partxx Name[zh_CN]=KDiff3 组件 MimeType=text/x-diff
--- a/kdiff3/src/kreplacements/kreplacements.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kreplacements/kreplacements.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -76,7 +76,7 @@ return; } - HINSTANCE hi = FindExecutableA( helpFile.fileName(), helpFile.dirPath(true), buf ); + HINSTANCE hi = FindExecutableA( helpFile.fileName().ascii(), helpFile.dirPath(true).ascii(), buf ); if ( int(hi)<=32 ) { static QTextBrowser* pBrowser = 0; @@ -91,7 +91,7 @@ else { QFileInfo prog( buf ); - _spawnlp( _P_NOWAIT , prog.filePath(), prog.fileName(), (const char*)("file:///"+helpFile.absFilePath()), NULL ); + _spawnlp( _P_NOWAIT , prog.filePath().ascii(), prog.fileName().ascii(), ("file:///"+helpFile.absFilePath()).ascii(), NULL ); } #else @@ -160,7 +160,7 @@ } -KDialogBase::KDialogBase( int, const QString& caption, int, int, QWidget* parent, const QString& name, +KDialogBase::KDialogBase( int, const QString& caption, int, int, QWidget* parent, const char* name, bool /*modal*/, bool ) : QTabDialog( parent, name, true /* modal */ ) { @@ -198,14 +198,14 @@ QVBox* KDialogBase::addVBoxPage( const QString& name, const QString& /*info*/, int ) { - QVBox* p = new QVBox(this, name); + QVBox* p = new QVBox(this, name.ascii()); addTab( p, name ); return p; } QFrame* KDialogBase::addPage( const QString& name, const QString& /*info*/, int ) { - QFrame* p = new QFrame( this, name ); + QFrame* p = new QFrame( this, name.ascii() ); addTab( p, name ); return p; } @@ -253,10 +253,10 @@ } KURL KFileDialog::getSaveURL( const QString &startDir, - const QString &filter, - QWidget *parent, const QString &caption) + const QString &filter, + QWidget *parent, const QString &caption) { - QString s = QFileDialog::getSaveFileName(startDir, filter, parent, caption); + QString s = QFileDialog::getSaveFileName(startDir, filter, parent, 0, caption); return KURL(s); } @@ -265,7 +265,7 @@ QWidget * parent, const QString & caption ) { - QString s = QFileDialog::getOpenFileName(startDir, filter, parent, caption); + QString s = QFileDialog::getOpenFileName(startDir, filter, parent, 0, caption); return KURL(s); } @@ -273,7 +273,7 @@ QWidget * parent, const QString & caption) { - QString s = QFileDialog::getExistingDirectory(startDir, parent, caption); + QString s = QFileDialog::getExistingDirectory(startDir, parent, 0, caption); return KURL(s); } @@ -302,7 +302,7 @@ } -KMainWindow::KMainWindow( QWidget* parent, const QString& name ) +KMainWindow::KMainWindow( QWidget* parent, const char* name ) : QMainWindow( parent, name ), m_actionCollection(this) { fileMenu = new QPopupMenu(); @@ -723,13 +723,10 @@ return strList; } - -KAction::KAction(const QString& text, const QIconSet& icon, int accel, - QObject* receiver, const char* slot, KActionCollection* actionCollection, - const QString& name, bool bToggle, bool bMenu - ) -: QAction ( text, icon, text, accel, actionCollection->m_pMainWindow, name, bToggle ) +void KAction::init(QObject* receiver, const char* slot, KActionCollection* actionCollection, + const char* name, bool bToggle, bool bMenu) { + QString n(name); KMainWindow* p = actionCollection->m_pMainWindow; if( slot!=0 ) { @@ -741,12 +738,10 @@ } } - if ( !icon.isNull() && p ) this->addTo( p->m_pToolBar ); - if (bMenu) { - if( name[0]=='g') addTo( p->movementMenu ); - else if( name.left(16)=="dir_current_sync") + if( n[0]=='g') addTo( p->movementMenu ); + else if( n.left(16)=="dir_current_sync") { if ( p->dirCurrentItemMenu==0 ) { @@ -757,7 +752,7 @@ } addTo( p->dirCurrentItemMenu ); } - else if( name.left(11)=="dir_current") + else if( n.left(11)=="dir_current") { if ( p->dirCurrentItemMenu==0 ) { @@ -768,7 +763,7 @@ } addTo( p->dirCurrentSyncItemMenu ); } - else if( name.left(4)=="diff") addTo( p->diffMenu ); + else if( n.left(4)=="diff") addTo( p->diffMenu ); else if( name[0]=='d') addTo( p->directoryMenu ); else if( name[0]=='f') addTo( p->fileMenu ); else if( name[0]=='w') addTo( p->windowsMenu ); @@ -776,53 +771,26 @@ } } + +KAction::KAction(const QString& text, const QIconSet& icon, int accel, + QObject* receiver, const char* slot, KActionCollection* actionCollection, + const char* name, bool bToggle, bool bMenu + ) +: QAction ( text, icon, text, accel, actionCollection->m_pMainWindow, name, bToggle ) +{ + KMainWindow* p = actionCollection->m_pMainWindow; + if ( !icon.isNull() && p ) this->addTo( p->m_pToolBar ); + + init(receiver,slot,actionCollection,name,bToggle,bMenu); +} + KAction::KAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, - const QString& name, bool bToggle, bool bMenu + const char* name, bool bToggle, bool bMenu ) : QAction ( text, text, accel, actionCollection->m_pMainWindow, name, bToggle ) { - KMainWindow* p = actionCollection->m_pMainWindow; - if( slot!=0 ) - { - if (!bToggle) - connect(this, SIGNAL(activated()), receiver, slot); - else - { - connect(this, SIGNAL(toggled(bool)), receiver, slot); - } - } - if (bMenu) - { - if( name[0]=='g') addTo( p->movementMenu ); - else if( name.left(16)=="dir_current_sync") - { - if ( p->dirCurrentItemMenu==0 ) - { - p->dirCurrentItemMenu = new QPopupMenu(); - p->directoryMenu->insertItem(i18n("Current Item Merge Operation"), p->dirCurrentItemMenu); - p->dirCurrentSyncItemMenu = new QPopupMenu(); - p->directoryMenu->insertItem(i18n("Current Item Sync Operation"), p->dirCurrentSyncItemMenu); - } - addTo( p->dirCurrentItemMenu ); - } - else if( name.left(11)=="dir_current") - { - if ( p->dirCurrentItemMenu==0 ) - { - p->dirCurrentItemMenu = new QPopupMenu(); - p->directoryMenu->insertItem(i18n("Current Item Merge Operation"), p->dirCurrentItemMenu); - p->dirCurrentSyncItemMenu = new QPopupMenu(); - p->directoryMenu->insertItem(i18n("Current Item Sync Operation"), p->dirCurrentSyncItemMenu); - } - addTo( p->dirCurrentSyncItemMenu ); - } - else if( name.left(4)=="diff") addTo( p->diffMenu ); - else if( name[0]=='d') addTo( p->directoryMenu ); - else if( name[0]=='f') addTo( p->fileMenu ); - else if( name[0]=='w') addTo( p->windowsMenu ); - else addTo( p->mergeMenu ); - } + init(receiver,slot,actionCollection,name,bToggle,bMenu); } void KAction::setStatusText(const QString&) @@ -835,17 +803,17 @@ } -KToggleAction::KToggleAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bMenu) +KToggleAction::KToggleAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bMenu) : KAction( text, icon, accel, receiver, slot, actionCollection, name, true, bMenu) { } -KToggleAction::KToggleAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bMenu) +KToggleAction::KToggleAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bMenu) : KAction( text, accel, receiver, slot, actionCollection, name, true, bMenu) { } -KToggleAction::KToggleAction(const QString& text, const QIconSet& icon, int accel, KActionCollection* actionCollection, const QString& name, bool bMenu) +KToggleAction::KToggleAction(const QString& text, const QIconSet& icon, int accel, KActionCollection* actionCollection, const char* name, bool bMenu) : KAction( text, icon, accel, 0, 0, actionCollection, name, true, bMenu) { } @@ -1382,13 +1350,13 @@ return (KLibFactory*) init_libkdiff3part(); } -QObject* KLibFactory::create(QObject* pParent, QString const& name, QString const& classname ) +QObject* KLibFactory::create(QObject* pParent, const QString& name, const QString& classname ) { KParts::Factory* f = dynamic_cast<KParts::Factory*>(this); if (f!=0) - return f->createPartObject( (QWidget*)pParent, name, - pParent, name, - classname, QStringList() ); + return f->createPartObject( (QWidget*)pParent, name.ascii(), + pParent, name.ascii(), + classname.ascii(), QStringList() ); else return 0; }
--- a/kdiff3/src/kreplacements/kreplacements.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/kreplacements/kreplacements.h Mon Jan 31 22:30:47 2005 +0000 @@ -86,7 +86,7 @@ { Q_OBJECT public: - KDialogBase( int, const QString& caption, int, int, QWidget* parent, const QString& name, + KDialogBase( int, const QString& caption, int, int, QWidget* parent, const char* name, bool /*modal*/, bool ); ~KDialogBase(); @@ -187,7 +187,7 @@ KToolBar* m_pToolBar; - KMainWindow( QWidget* parent, const QString& name ); + KMainWindow( QWidget* parent, const char* name ); KToolBar* toolBar(const QString& s = QString::null); KActionCollection* actionCollection(); void createGUI(); @@ -233,8 +233,10 @@ { Q_OBJECT public: - KAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bToggle=false, bool bMenu=true); - KAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bToggle=false, bool bMenu=true); + KAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bToggle=false, bool bMenu=true); + KAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bToggle=false, bool bMenu=true); + void init(QObject* receiver, const char* slot, KActionCollection* actionCollection, + const char* name, bool bToggle, bool bMenu); void setStatusText(const QString&); void plug(QPopupMenu*); }; @@ -242,9 +244,9 @@ class KToggleAction : public KAction { public: - KToggleAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bMenu=true); - KToggleAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const QString& name, bool bMenu=true); - KToggleAction(const QString& text, const QIconSet& icon, int accel, KActionCollection* actionCollection, const QString& name, bool bMenu=true); + KToggleAction(const QString& text, const QIconSet& icon, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bMenu=true); + KToggleAction(const QString& text, int accel, QObject* receiver, const char* slot, KActionCollection* actionCollection, const char* name, bool bMenu=true); + KToggleAction(const QString& text, const QIconSet& icon, int accel, KActionCollection* actionCollection, const char* name, bool bMenu=true); void setChecked(bool); bool isChecked(); }; @@ -447,7 +449,7 @@ class MainWindow : public KMainWindow { public: - MainWindow( QWidget* parent, const QString& name ) : KMainWindow(parent,name) {} + MainWindow( QWidget* parent, const char* name ) : KMainWindow(parent,name) {} void setXMLFile(const QString&){} void setAutoSaveSettings(){} void saveMainWindowSettings(KConfig*){}
--- a/kdiff3/src/main.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/main.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -27,7 +27,7 @@ #endif static const char *description = - I18N_NOOP("Text Diff and Merge Tool"); + I18N_NOOP("Tool for Comparison and Merge of Files and Directories"); static KCmdLineOptions options[] = { @@ -107,7 +107,7 @@ KAboutData aboutData( "kdiff3", I18N_NOOP("KDiff3"), VERSION, description, KAboutData::License_GPL, - "(c) 2002-2004 Joachim Eibl", 0, "http://kdiff3.sourceforge.net/", "joachim.eibl@gmx.de"); + "(c) 2002-2005 Joachim Eibl", 0, "http://kdiff3.sourceforge.net/", "joachim.eibl@gmx.de"); aboutData.addAuthor("Joachim Eibl",0, "joachim.eibl@gmx.de"); aboutData.addCredit("Eike Sauer", "Bugfixes, Debian package maintainer" ); aboutData.addCredit("Sebastien Fricker", "Windows installer" ); @@ -116,6 +116,7 @@ aboutData.addCredit("David Faure", "KIO-Help", "faure@kde.org" ); aboutData.addCredit("Bernd Gehrmann", "Class CvsIgnoreList from Cervisia" ); aboutData.addCredit("Andre Woebbeking", "Class StringMatcher" ); + aboutData.addCredit("Michael Denio", "Directory Equality-Coloring patch"); aboutData.addCredit("Paul Eggert, Mike Haertel, David Hayes, Richard Stallman, Len Tower", "GNU-Diffutils"); aboutData.addCredit(I18N_NOOP("+ Many thanks to those who reported bugs and contributed ideas!"));
--- a/kdiff3/src/mergeresultwindow.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/mergeresultwindow.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -115,6 +115,10 @@ g_bAutoSolve = true; update(); updateSourceMask(); + + int wsc; + m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)") + .arg(getNrOfUnsolvedConflicts(&wsc)).arg(wsc) ); } @@ -422,11 +426,11 @@ ++nrOfUnsolvedConflicts; else if ( i->bDelta ) ++nrOfSolvedConflicts; - + if ( i->bWhiteSpaceConflict ) ++nrOfWhiteSpaceConflicts; } - + m_pTotalDiffStatus->nofUnsolvedConflicts = nrOfUnsolvedConflicts; m_pTotalDiffStatus->nofSolvedConflicts = nrOfSolvedConflicts; m_pTotalDiffStatus->nofWhitespaceConflicts = nrOfWhiteSpaceConflicts; @@ -534,7 +538,7 @@ if ( isVisible() ) setFocus(); - + setFastSelector( i ); } @@ -548,9 +552,9 @@ { --i; if ( i->bDelta && !( bSkipWhiteConflicts && i->bWhiteSpaceConflict ) ) return true; - } + } while (i!=m_mergeLineList.begin()); - + return false; } @@ -558,7 +562,7 @@ { bool bSkipWhiteConflicts = ! m_pOptionDialog->m_bShowWhiteSpace; if (m_mergeLineList.empty()) return false; - + MergeLineList::iterator i = m_currentMergeLineIt; if (i!=m_mergeLineList.end()) { @@ -576,7 +580,7 @@ if (m_mergeLineList.empty()) return false; MergeLineList::iterator i = m_currentMergeLineIt; if (i == m_mergeLineList.begin()) return false; - + do { --i; @@ -689,7 +693,7 @@ { if ( line>=i->d3lLineIdx && line < i->d3lLineIdx + i->srcRangeLength ) { - if ( i->bDelta ) + //if ( i->bDelta ) { setFastSelector( i ); } @@ -698,9 +702,11 @@ } } -int MergeResultWindow::getNrOfUnsolvedConflicts() +int MergeResultWindow::getNrOfUnsolvedConflicts( int* pNrOfWhiteSpaceConflicts ) { int nrOfUnsolvedConflicts = 0; + if (pNrOfWhiteSpaceConflicts!=0) + *pNrOfWhiteSpaceConflicts = 0; MergeLineList::iterator mlIt = m_mergeLineList.begin(); for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) @@ -708,7 +714,11 @@ MergeLine& ml = *mlIt; MergeEditLineList::iterator melIt = ml.mergeEditLineList.begin(); if ( melIt->isConflict() ) + { ++nrOfUnsolvedConflicts; + if ( ml.bWhiteSpaceConflict && pNrOfWhiteSpaceConflicts!=0 ) + ++ *pNrOfWhiteSpaceConflicts; + } } return nrOfUnsolvedConflicts; @@ -789,7 +799,7 @@ { if ( m_currentMergeLineIt==m_mergeLineList.end() ) return; - + setModified(); // First find range for which this change works. @@ -856,7 +866,7 @@ ml.mergeEditLineList.push_back(mel); } - + if ( m_cursorYPos >= m_totalSize ) { m_cursorYPos = m_totalSize-1; @@ -866,7 +876,9 @@ update(); updateSourceMask(); emit updateAvailabilities(); - m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1").arg(getNrOfUnsolvedConflicts()) ); + int wsc; + m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)") + .arg(getNrOfUnsolvedConflicts(&wsc)).arg(wsc) ); } // bConflictsOnly: automatically choose for conflicts only (true) or for everywhere (false) @@ -877,7 +889,9 @@ merge( false, selector, bConflictsOnly, bWhiteSpaceOnly ); emit modified(); update(); - m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1").arg(getNrOfUnsolvedConflicts()) ); + int wsc; + m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)") + .arg(getNrOfUnsolvedConflicts(&wsc)).arg(wsc) ); } void MergeResultWindow::slotAutoSolve() @@ -886,7 +900,9 @@ merge( true, -1 ); emit modified(); update(); - m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1").arg(getNrOfUnsolvedConflicts()) ); + int wsc; + m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)") + .arg(getNrOfUnsolvedConflicts(&wsc)).arg(wsc) ); } void MergeResultWindow::slotUnsolve() @@ -895,7 +911,9 @@ merge( false, -1 ); emit modified(); update(); - m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1").arg(getNrOfUnsolvedConflicts()) ); + int wsc; + m_pStatusBar->message( i18n("Number of remaining unsolved conflicts: %1 (of which %2 are whitespace)") + .arg(getNrOfUnsolvedConflicts(&wsc)).arg(wsc) ); } void MergeResultWindow::myUpdate(int afterMilliSecs) @@ -924,16 +942,15 @@ } } -const char* MergeResultWindow::MergeEditLine::getString( const MergeResultWindow* mrw, int& size ) +QString MergeResultWindow::MergeEditLine::getString( const MergeResultWindow* mrw ) { - size=-1; - if ( isRemoved() ) { size=0; return ""; } + if ( isRemoved() ) { return QString(); } if ( ! isModified() ) { int src = m_src; const Diff3Line& d3l = *m_id3l; - if ( src == 0 ) { size=0; return ""; } + if ( src == 0 ) { return QString(); } const LineData* pld = 0; assert( src == A || src == B || src == C ); @@ -944,32 +961,30 @@ if ( pld == 0 ) { // assert(false); This is no error. - size = 0; - return ""; + return QString(); } - size = pld->size; - return pld->pLine; + return QString( pld->pLine, pld->size ); } else { - size = m_str.length(); return m_str; } return 0; } /// Converts the cursor-posOnScreen into a text index, considering tabulators. -int convertToPosInText( const char* p, int size, int posOnScreen ) +int convertToPosInText( const QString& s, int posOnScreen ) { int localPosOnScreen = 0; + int size=s.length(); for ( int i=0; i<size; ++i ) { if ( localPosOnScreen>=posOnScreen ) return i; // All letters except tabulator have width one. - int letterWidth = p[i]!='\t' ? 1 : tabber( localPosOnScreen, g_tabSize ); + int letterWidth = s[i]!='\t' ? 1 : tabber( localPosOnScreen, g_tabSize ); localPosOnScreen += letterWidth; @@ -995,8 +1010,8 @@ } void MergeResultWindow::writeLine( - QPainter& p, int line, const char* pStr, int size, - int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved + MyPainter& p, int line, const QString& str, + int srcSelect, e_MergeDetails mergeDetails, int rangeMark, bool bUserModified, bool bLineRemoved, bool bWhiteSpaceConflict ) { const QFontMetrics& fm = fontMetrics(); @@ -1023,15 +1038,16 @@ { p.fillRect( xOffset, yOffset, width(), fontHeight, m_pOptionDialog->m_currentRangeBgColor ); } - + if( (srcSelect > 0 || bUserModified ) && !bLineRemoved ) { int outPos = 0; - QCString s; + QString s; + int size = str.length(); for ( int i=0; i<size; ++i ) { int spaces = 1; - if ( pStr[i]=='\t' ) + if ( str[i]=='\t' ) { spaces = tabber( outPos, g_tabSize ); for( int j=0; j<spaces; ++j ) @@ -1039,22 +1055,22 @@ } else { - s+=pStr[i]; + s+=str[i]; } outPos += spaces; } if ( m_selection.lineWithin( line ) ) { - int firstPosInLine = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_selection.firstPosInLine(line) ) ); - int lastPosInLine = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_selection.lastPosInLine(line) ) ); + int firstPosInLine = convertToPosOnScreen( str, convertToPosInText( str, m_selection.firstPosInLine(line) ) ); + int lastPosInLine = convertToPosOnScreen( str, convertToPosInText( str, m_selection.lastPosInLine(line) ) ); int lengthInLine = max2(0,lastPosInLine - firstPosInLine); if (lengthInLine>0) m_selection.bSelectionContainsData = true; if ( lengthInLine < int(s.length()) ) { // Draw a normal line first p.setPen( m_pOptionDialog->m_fgColor ); - p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn),m_pOptionDialog) ); + p.drawText( xOffset, yOffset+fontAscent, s.mid(m_firstColumn), true ); } int firstPosInLine2 = max2( firstPosInLine, m_firstColumn ); int lengthInLine2 = max2(0,lastPosInLine - firstPosInLine2); @@ -1068,22 +1084,22 @@ p.setPen( colorGroup().highlightedText() ); p.drawText( xOffset + fontWidth*(firstPosInLine2-m_firstColumn), yOffset+fontAscent, - decodeString( s.mid(firstPosInLine2,lengthInLine2), m_pOptionDialog ) ); + s.mid(firstPosInLine2,lengthInLine2), true ); } else { p.setPen( m_pOptionDialog->m_fgColor ); - p.drawText( xOffset, yOffset+fontAscent, decodeString( s.mid(m_firstColumn), m_pOptionDialog ) ); + p.drawText( xOffset, yOffset+fontAscent, s.mid(m_firstColumn), true ); } p.setPen( m_pOptionDialog->m_fgColor ); if ( m_cursorYPos==line ) { m_cursorXPos = minMaxLimiter( m_cursorXPos, 0, outPos ); - m_cursorXPos = convertToPosOnScreen( pStr, convertToPosInText( pStr, size, m_cursorXPos ) ); + m_cursorXPos = convertToPosOnScreen( str, convertToPosInText( str, m_cursorXPos ) ); } - p.drawText( 1, yOffset+fontAscent, srcName ); + p.drawText( 1, yOffset+fontAscent, srcName, true ); } else if ( bLineRemoved ) { @@ -1095,7 +1111,10 @@ else if ( srcSelect == 0 ) { p.setPen( m_pOptionDialog->m_colorForConflict ); - p.drawText( xOffset, yOffset+fontAscent, i18n("<Merge Conflict>") ); + if ( bWhiteSpaceConflict ) + p.drawText( xOffset, yOffset+fontAscent, i18n("<Merge Conflict (Whitespace only)>") ); + else + p.drawText( xOffset, yOffset+fontAscent, i18n("<Merge Conflict>") ); p.drawText( 1, yOffset+fontAscent, "?" ); if ( m_cursorYPos==line ) m_cursorXPos = 0; } @@ -1155,9 +1174,9 @@ if ( size() != m_pixmap.size() ) m_pixmap.resize(size()); - QPainter p(&m_pixmap); + MyPainter p(&m_pixmap, m_pOptionDialog->m_bRightToLeftLanguage, width(), fontWidth); p.setFont( font() ); - p.fillRect( rect(), m_pOptionDialog->m_bgColor ); + p.QPainter::fillRect( rect(), m_pOptionDialog->m_bgColor ); //int visibleLines = height() / fontHeight; @@ -1177,7 +1196,7 @@ p.fillRect( 0, 0, width(), topLineYOffset, m_pOptionDialog->m_bgColor ); } p.setPen( m_pOptionDialog->m_fgColor ); - p.drawText( 0, fontAscent+1, s ); + p.QPainter::drawText( 0, fontAscent+1, s ); p.drawLine( 0, fontHeight + 2, width(), fontHeight + 2 ); } @@ -1209,14 +1228,13 @@ if ( mlIt == m_currentMergeLineIt ) rangeMark |= 4; // Mark of the current line - const char* s; - int size; - s = mel.getString( this, size ); - if (size>nofColumns) - nofColumns = size; + QString s; + s = mel.getString( this ); + if ( convertToPosOnScreen(s,s.length()) >nofColumns) + nofColumns = s.length(); - writeLine( p, line, s, size, mel.src(), ml.mergeDetails, rangeMark, - mel.isModified(), mel.isRemoved() ); + writeLine( p, line, s, mel.src(), ml.mergeDetails, rangeMark, + mel.isModified(), mel.isRemoved(), ml.bWhiteSpaceConflict ); } ++line; } @@ -1249,12 +1267,18 @@ if ( e!= 0 ) painter.drawPixmap(0,0, m_pixmap); else - painter.drawPixmap(xCursor-2, yOffset, m_pixmap, - xCursor-2, yOffset, 5, fontAscent+2 ); - + { + if (!m_pOptionDialog->m_bRightToLeftLanguage) + painter.drawPixmap(xCursor-2, yOffset, m_pixmap, + xCursor-2, yOffset, 5, fontAscent+2 ); + else + painter.drawPixmap(width()-1-4-(xCursor-2), yOffset, m_pixmap, + width()-1-4-(xCursor-2), yOffset, 5, fontAscent+2 ); + } if ( m_bCursorOn && hasFocus() && m_cursorYPos>=m_firstLine ) { + MyPainter painter(this, m_pOptionDialog->m_bRightToLeftLanguage, width(), fontWidth); int topLineYOffset = fontHeight + 3; int xOffset = fontWidth * leftInfoWidth; @@ -1298,14 +1322,14 @@ if ( mel.src()==3 ) srcMask |= 4; if ( mel.isModified() || !mel.isEditableText() ) bModified = true; } - + if ( ml.mergeDetails == eNoChange ) { srcMask = 0; enabledMask = bModified ? 1 : 0; } } - + emit sourceMask( srcMask, enabledMask ); } @@ -1326,7 +1350,10 @@ int yOffset = topLineYOffset - m_firstLine * fontHeight; line = min2( ( y - yOffset ) / fontHeight, m_totalSize-1 ); - pos = ( x - xOffset ) / fontWidth; + if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) + pos = ( x - xOffset ) / fontWidth; + else + pos = ( (width() - 1 - x) - xOffset ) / fontWidth; } void MergeResultWindow::mousePressEvent ( QMouseEvent* e ) @@ -1418,17 +1445,16 @@ // Get the string data of the current line - int size; MergeLineList::iterator mlIt; MergeEditLineList::iterator melIt; calcIteratorFromLineNr( line, mlIt, melIt ); - const char* s = melIt->getString( this, size ); + QString s = melIt->getString( this ); - if ( s!=0 && size>0 ) + if ( !s.isEmpty() ) { int pos1, pos2; - calcTokenPos( s, size, pos, pos1, pos2 ); + calcTokenPos( s, pos, pos1, pos2 ); resetSelection(); m_selection.start( line, convertToPosOnScreen( s, pos1 ) ); @@ -1475,8 +1501,16 @@ int topLineYOffset = fontHeight + 3; int deltaX=0; int deltaY=0; - if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; - if ( e->x() > width() ) deltaX=+1; + if ( ! m_pOptionDialog->m_bRightToLeftLanguage ) + { + if ( e->x() < leftInfoWidth*fontWidth ) deltaX=-1; + if ( e->x() > width() ) deltaX=+1; + } + else + { + if ( e->x() > width()-1-leftInfoWidth*fontWidth ) deltaX=-1; + if ( e->x() < fontWidth ) deltaX=+1; + } if ( e->y() < topLineYOffset ) deltaY=-1; if ( e->y() > height() ) deltaY=+1; m_scrollDeltaX = deltaX; @@ -1516,9 +1550,8 @@ MergeEditLineList::iterator melIt; calcIteratorFromLineNr( y, mlIt, melIt ); - int stringLength; - const char* ps = melIt->getString( this, stringLength ); - int x = convertToPosInText( ps, stringLength, m_cursorXPos ); + QString str = melIt->getString( this ); + int x = convertToPosInText( str, m_cursorXPos ); bool bCtrl = ( e->state() & ControlButton ) != 0 ; bool bShift = ( e->state() & ShiftButton ) != 0 ; @@ -1536,24 +1569,20 @@ case Key_Backtab: break; case Key_Delete: { - if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break; + if ( deleteSelection2( str, x, y, mlIt, melIt )) break; if( !melIt->isEditableText() ) break; - if (x>=stringLength) + if (x>=(int)str.length()) { if ( y<m_totalSize-1 ) { setModified(); - QCString s1( ps, stringLength+1 ); MergeLineList::iterator mlIt1; MergeEditLineList::iterator melIt1; calcIteratorFromLineNr( y+1, mlIt1, melIt1 ); if ( melIt1->isEditableText() ) { - int stringLength1; - ps = melIt1->getString( this, stringLength1 ); - assert(ps!=0); - QCString s2( ps, stringLength1+1 ); - melIt->setString( s1 + s2 ); + QString s2 = melIt1->getString( this ); + melIt->setString( str + s2 ); // Remove the line if ( mlIt1->mergeEditLineList.size()>1 ) @@ -1565,8 +1594,8 @@ } else { - QCString s( ps, x+1 ); - s += QCString( ps+x+1, stringLength - x ); + QString s = str.left(x); + s += str.mid( x+1 ); melIt->setString( s ); setModified(); } @@ -1574,23 +1603,20 @@ } case Key_Backspace: { - if ( deleteSelection2( ps, stringLength, x, y, mlIt, melIt )) break; + if ( deleteSelection2( str, x, y, mlIt, melIt )) break; if( !melIt->isEditableText() ) break; if (x==0) { if ( y>0 ) { setModified(); - QCString s2( ps, stringLength+1 ); MergeLineList::iterator mlIt1; MergeEditLineList::iterator melIt1; calcIteratorFromLineNr( y-1, mlIt1, melIt1 ); if ( melIt1->isEditableText() ) { - int stringLength1; - ps = melIt1->getString( this, stringLength1 ); - QCString s1( ps, stringLength1+1 ); - melIt1->setString( s1 + s2 ); + QString s1 = melIt1->getString( this ); + melIt1->setString( s1 + str ); // Remove the previous line if ( mlIt->mergeEditLineList.size()>1 ) @@ -1599,14 +1625,14 @@ melIt->setRemoved(); --y; - x=stringLength1; + x=str.length(); } } } else { - QCString s( ps, x ); - s += QCString( ps+x, stringLength - x + 1 ); + QString s = str.left( x-1 ); + s += str.mid( x ); --x; melIt->setString( s ); setModified(); @@ -1617,21 +1643,20 @@ case Key_Enter: { if( !melIt->isEditableText() ) break; - deleteSelection2( ps, stringLength, x, y, mlIt, melIt ); + deleteSelection2( str, x, y, mlIt, melIt ); setModified(); - QCString indentation; + QString indentation; if ( m_pOptionDialog->m_bAutoIndentation ) { // calc last indentation MergeLineList::iterator mlIt1 = mlIt; MergeEditLineList::iterator melIt1 = melIt; for(;;) { - int size; - const char* s = melIt1->getString(this, size); - if ( s!=0 ) { - int i; - for( i=0; i<size; ++i ){ if(s[i]!=' ' && s[i]!='\t') break; } - if (i<size) { - indentation = QCString( s, i+1 ); + const QString s = melIt1->getString(this); + if ( !s.isEmpty() ) { + unsigned int i; + for( i=0; i<s.length(); ++i ){ if(s[i]!=' ' && s[i]!='\t') break; } + if (i<s.length()) { + indentation = s.left(i); break; } } @@ -1645,18 +1670,18 @@ } } MergeEditLine mel; - mel.setString( indentation + QCString( ps+x, stringLength - x + 1 ) ); + mel.setString( indentation + str.mid(x) ); - if ( x<stringLength ) // Cut off the old line. + if ( x<(int)str.length() ) // Cut off the old line. { // Since ps possibly points into melIt->str, first copy it into a temporary. - QCString temp = QCString( ps, x + 1 ); + QString temp = str.left(x); melIt->setString( temp ); } ++melIt; mlIt->mergeEditLineList.insert( melIt, mel ); - x=indentation.length(); + x = indentation.length(); ++y; break; } @@ -1668,28 +1693,32 @@ case Key_End: x=INT_MAX; if(bCtrl){y=INT_MAX;} break; case Key_Left: - if ( !bCtrl ) + case Key_Right: + if ( (e->key()==Key_Left) ^ m_pOptionDialog->m_bRightToLeftLanguage ) // operator^: XOR { - --x; - if(x<0 && y>0){--y; x=INT_MAX;} + if ( !bCtrl ) + { + --x; + if(x<0 && y>0){--y; x=INT_MAX;} + } + else + { + while( x>0 && (str[x-1]==' ' || str[x-1]=='\t') ) --x; + while( x>0 && (str[x-1]!=' ' && str[x-1]!='\t') ) --x; + } } else { - while( x>0 && (ps[x-1]==' ' || ps[x-1]=='\t') ) --x; - while( x>0 && (ps[x-1]!=' ' && ps[x-1]!='\t') ) --x; - } - break; + if ( !bCtrl ) + { + ++x; if(x>(int)str.length() && y<m_totalSize-1){ ++y; x=0; } + } - case Key_Right: - if ( !bCtrl ) - { - ++x; if(x>stringLength && y<m_totalSize-1){ ++y; x=0; } - } - - else - { - while( x<stringLength && (ps[x]==' ' || ps[x]=='\t') ) ++x; - while( x<stringLength && (ps[x]!=' ' && ps[x]!='\t') ) ++x; + else + { + while( x<(int)str.length() && (str[x]==' ' || str[x]=='\t') ) ++x; + while( x<(int)str.length() && (str[x]!=' ' && str[x]!='\t') ) ++x; + } } break; @@ -1711,20 +1740,20 @@ else { if( !melIt->isEditableText() ) break; - deleteSelection2( ps, stringLength, x, y, mlIt, melIt ); + deleteSelection2( str, x, y, mlIt, melIt ); setModified(); // Characters to insert - QCString s( ps, stringLength+1 ); + QString s=str; if ( t[0]=='\t' && m_pOptionDialog->m_bReplaceTabs ) { int spaces = (m_cursorXPos / g_tabSize + 1)*g_tabSize - m_cursorXPos; t.fill( ' ', spaces ); } if ( m_bInsertMode ) - s.insert( x, encodeString(t, m_pOptionDialog) ); + s.insert( x, t ); else - s.replace( x, t.length(), encodeString(t, m_pOptionDialog) ); + s.replace( x, t.length(), t ); melIt->setString( s ); x += t.length(); @@ -1737,9 +1766,9 @@ y = minMaxLimiter( y, 0, m_totalSize-1 ); calcIteratorFromLineNr( y, mlIt, melIt ); - ps = melIt->getString( this, stringLength ); + str = melIt->getString( this ); - x = minMaxLimiter( x, 0, stringLength ); + x = minMaxLimiter( x, 0, (int)str.length() ); int newFirstLine = m_firstLine; int newFirstColumn = m_firstColumn; @@ -1750,9 +1779,9 @@ newFirstLine = y - getNofVisibleLines(); if (bYMoveKey) - x=convertToPosInText( ps, stringLength, m_cursorOldXPos ); + x=convertToPosInText( str, m_cursorOldXPos ); - int xOnScreen = convertToPosOnScreen( ps, x ); + int xOnScreen = convertToPosOnScreen( str, x ); if ( xOnScreen<m_firstColumn ) newFirstColumn = xOnScreen; else if ( xOnScreen > m_firstColumn + getNofVisibleColumns() ) @@ -1831,25 +1860,21 @@ int outPos = 0; if (mel.isEditableText()) { - int size; - const char* pLine = mel.getString( this, size ); + const QString str = mel.getString( this ); // Consider tabs - for( int i=0; i<size; ++i ) + for( unsigned int i=0; i<str.length(); ++i ) { int spaces = 1; - if ( pLine[i]=='\t' ) + if ( str[i]=='\t' ) { spaces = tabber( outPos, g_tabSize ); } if( m_selection.within( line, outPos ) ) { - char buf[2]; - buf[0] = pLine[i]; - buf[1] = '\0'; - selectionString += decodeString( buf, m_pOptionDialog ); + selectionString += str[i]; } outPos += spaces; @@ -1859,7 +1884,7 @@ { selectionString += i18n("<Merge Conflict>"); } - + if( m_selection.within( line, outPos ) ) { #ifdef _WIN32 @@ -1876,7 +1901,7 @@ return selectionString; } -bool MergeResultWindow::deleteSelection2( const char*& ps, int& stringLength, int& x, int& y, +bool MergeResultWindow::deleteSelection2( QString& s, int& x, int& y, MergeLineList::iterator& mlIt, MergeEditLineList::iterator& melIt ) { if (m_selection.firstLine!=-1 && m_selection.bSelectionContainsData ) @@ -1884,8 +1909,8 @@ deleteSelection(); y = m_cursorYPos; calcIteratorFromLineNr( y, mlIt, melIt ); - ps = melIt->getString( this, stringLength ); - x = convertToPosInText( ps, stringLength, m_cursorXPos ); + s = melIt->getString( this ); + x = convertToPosInText( s, m_cursorXPos ); return true; } return false; @@ -1902,7 +1927,7 @@ int line = 0; MergeLineList::iterator mlItFirst; MergeEditLineList::iterator melItFirst; - QCString firstLineString; + QString firstLineString; int firstLine = -1; int lastLine = -1; @@ -1945,8 +1970,7 @@ if ( mel.isEditableText() && m_selection.lineWithin(line) ) { - int size; - const char* pLine = mel.getString( this, size ); + QString lineString = mel.getString( this ); int firstPosInLine = m_selection.firstPosInLine(line); int lastPosInLine = m_selection.lastPosInLine(line); @@ -1955,15 +1979,15 @@ { mlItFirst = mlIt; melItFirst = melIt; - int pos = convertToPosInText( pLine, size, firstPosInLine ); - firstLineString = QCString( pLine, pos+1 ); + int pos = convertToPosInText( lineString, firstPosInLine ); + firstLineString = lineString.left( pos ); } if ( line==lastLine ) { // This is the last line in the selection - int pos = convertToPosInText( pLine, size, lastPosInLine ); - firstLineString += QCString( pLine+pos, 1+max2( 0,size-pos)); + int pos = convertToPosInText( lineString, lastPosInLine ); + firstLineString += lineString.mid( pos ); // rest of line melItFirst->setString( firstLineString ); } @@ -2002,24 +2026,21 @@ calcIteratorFromLineNr( y, mlIt, melIt ); melItAfter = melIt; ++melItAfter; - int stringLength; - const char* ps = melIt->getString( this, stringLength ); - int x = convertToPosInText( ps, stringLength, m_cursorXPos ); + QString str = melIt->getString( this ); + int x = convertToPosInText( str, m_cursorXPos ); if ( !QApplication::clipboard()->supportsSelection() ) bFromSelection = false; - - QCString clipBoard = encodeString( - QApplication::clipboard()->text( bFromSelection ? QClipboard::Selection : QClipboard::Clipboard ), - m_pOptionDialog - ); - QCString currentLine = QCString( ps, x+1 ); - QCString endOfLine = QCString( ps+x, stringLength-x+1 ); + QString clipBoard = QApplication::clipboard()->text( bFromSelection ? QClipboard::Selection : QClipboard::Clipboard ); + + QString currentLine = str.left(x); + QString endOfLine = str.mid(x); int i; - for( i=0; i<(int)clipBoard.length(); ++i ) + int len = clipBoard.length(); + for( i=0; i<len; ++i ) { - char c = clipBoard[i]; + QChar c = clipBoard[i]; if ( c == '\r' ) continue; if ( c == '\n' ) { @@ -2085,65 +2106,44 @@ bool bSuccess = file.createBackup(".orig"); if ( !bSuccess ) { - KMessageBox::error( this, file.getStatusText() + i18n("\n\nFile not saved."), i18n("File Save Error") ); + KMessageBox::error( this, file.getStatusText() + i18n("\n\nCreating backup failed. File not saved."), i18n("File Save Error") ); return false; } } - // Loop twice over all data: First to calculate the needed size, - // then alloc memory and in the second loop copy the data into the memory. - long neededBufferSize = 0; - long dataIndex = 0; QByteArray dataArray; - for ( int i=0; i<2; ++i ) + QTextStream textOutStream(dataArray, IO_WriteOnly); + textOutStream.setCodec( m_pOptionDialog->m_pEncodingOut ); + + int line = 0; + MergeLineList::iterator mlIt = m_mergeLineList.begin(); + for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) { - if(i==1) + MergeLine& ml = *mlIt; + MergeEditLineList::iterator melIt; + for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) { - if ( ! dataArray.resize(neededBufferSize) ) + MergeEditLine& mel = *melIt; + + if ( mel.isEditableText() ) { - KMessageBox::error(this, i18n("Out of memory while preparing to save.") ); - return false; - } - } + QString str = mel.getString( this ); - int line = 0; - MergeLineList::iterator mlIt = m_mergeLineList.begin(); - for(mlIt = m_mergeLineList.begin();mlIt!=m_mergeLineList.end(); ++mlIt) - { - MergeLine& ml = *mlIt; - MergeEditLineList::iterator melIt; - for( melIt = ml.mergeEditLineList.begin(); melIt != ml.mergeEditLineList.end(); ++melIt ) - { - MergeEditLine& mel = *melIt; - - if ( mel.isEditableText() ) + if (line>0) // Prepend line feed, but not for first line { - int size; - const char* pLine = mel.getString( this, size ); - - QCString s(pLine, size+1); - - if (line>0) // Prepend line feed, but not for first line - { - if ( m_pOptionDialog->m_lineEndStyle == eLineEndDos ) - { s.prepend("\r\n"); size+=2; } - else - { s.prepend("\n"); size+=1; } - } - - if (i==0) neededBufferSize += size; + if ( m_pOptionDialog->m_lineEndStyle == eLineEndDos ) + { str.prepend("\r\n"); } else - { - memcpy( dataArray.data() + dataIndex, s, size ); - dataIndex+=size; - } + { str.prepend("\n"); } } - ++line; + textOutStream << str; } + + ++line; } } - bool bSuccess = file.writeFile( dataArray.data(), neededBufferSize ); + bool bSuccess = file.writeFile( dataArray.data(), dataArray.size() ); if ( ! bSuccess ) { KMessageBox::error( this, i18n("Error while writing."), i18n("File Save Error") ); @@ -2156,18 +2156,16 @@ return true; } -QCString MergeResultWindow::getString( int lineIdx ) +QString MergeResultWindow::getString( int lineIdx ) { MergeResultWindow::MergeLineList::iterator mlIt; MergeResultWindow::MergeEditLineList::iterator melIt; calcIteratorFromLineNr( lineIdx, mlIt, melIt ); - int length=0; - const char* p = melIt->getString( this, length ); - QCString line( p, length+1 ); - return line; + QString s = melIt->getString( this ); + return s; } -bool MergeResultWindow::findString( const QCString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ) +bool MergeResultWindow::findString( const QString& s, int& d3vLine, int& posInLine, bool bDirDown, bool bCaseSensitive ) { int it = d3vLine; int endIt = bDirDown ? getNofLines() : -1; @@ -2176,7 +2174,7 @@ for( ; it!=endIt; it+=step ) { - QCString line = getString( it ); + QString line = getString( it ); if ( !line.isEmpty() ) { int pos = line.find( s, startPos, bCaseSensitive );
--- a/kdiff3/src/optiondialog.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/optiondialog.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -290,29 +290,117 @@ } }; +class OptionEncodingComboBox : public QComboBox, public OptionItem +{ + std::vector<QTextCodec*> m_codecVec; + QTextCodec** m_ppVarCodec; +public: + OptionEncodingComboBox( const QString& saveName, QTextCodec** ppVarCodec, + QWidget* pParent, OptionDialog* pOD ) + : QComboBox( pParent ), OptionItem( pOD, saveName ) + { + m_ppVarCodec = ppVarCodec; + insertCodec( i18n("Unicode, 8 bit"), QTextCodec::codecForName("UTF-8") ); + insertCodec( i18n("Unicode"), QTextCodec::codecForName("iso-10646-UCS-2") ); + insertCodec( i18n("Latin1"), QTextCodec::codecForName("iso 8859-1") ); + + // First sort codec names: + std::map<QString, QTextCodec*> names; + int i; + for(i=0;;++i) + { + QTextCodec* c = QTextCodec::codecForIndex(i); + if ( c==0 ) break; + else names[QString(c->name()).upper()]=c; + } + + std::map<QString, QTextCodec*>::iterator it; + for(it=names.begin();it!=names.end();++it) + { + insertCodec( "", it->second ); + } + + QToolTip::add( this, i18n( + "Change this if non-ASCII characters are not displayed correctly." + )); + } + void insertCodec( const QString& visibleCodecName, QTextCodec* c ) + { + if (c!=0) + { + for( unsigned int i=0; i<m_codecVec.size(); ++i ) + { + if ( c==m_codecVec[i] ) + return; // don't insert any codec twice + } + insertItem( visibleCodecName.isEmpty() ? QString(c->name()) : visibleCodecName+" ("+c->name()+")", m_codecVec.size() ); + m_codecVec.push_back( c ); + } + } + void setToDefault() + { + setCurrentItem( 0 ); + if (m_ppVarCodec!=0){ *m_ppVarCodec=m_codecVec[0]; } + } + void setToCurrent() + { + if (m_ppVarCodec!=0) + { + for(unsigned int i=0; i<m_codecVec.size(); ++i) + { + if ( *m_ppVarCodec==m_codecVec[i] ) + { + setCurrentItem( i ); + break; + } + } + } + } + void apply() + { + if (m_ppVarCodec!=0){ *m_ppVarCodec = m_codecVec[ currentItem() ]; } + } + void write(KConfig* config) + { + if (m_ppVarCodec!=0) config->writeEntry(m_saveName, (*m_ppVarCodec)->name() ); + } + void read (KConfig* config) + { + QString codecName = config->readEntry( m_saveName, m_codecVec[ currentItem() ]->name() ); + for(unsigned int i=0; i<m_codecVec.size(); ++i) + { + if ( codecName == m_codecVec[i]->name() ) + { + setCurrentItem( i ); + if (m_ppVarCodec!=0) *m_ppVarCodec = m_codecVec[i]; + break; + } + } + } +}; + + OptionDialog::OptionDialog( bool bShowDirMergeSettings, QWidget *parent, char *name ) :KDialogBase( IconList, i18n("Configure"), Help|Default|Apply|Ok|Cancel, Ok, parent, name, true /*modal*/, true ) { - setHelp( "kdiff3/index.html", QString::null ); + setHelp( "kdiff3/index.html", QString::null ); - setupFontPage(); - setupColorPage(); - setupEditPage(); - setupDiffPage(); - setupOtherOptions(); - if (bShowDirMergeSettings) - setupDirectoryMergePage(); - -#ifdef KREPLACEMENTS_H - setupRegionalPage(); -#endif + setupFontPage(); + setupColorPage(); + setupEditPage(); + setupDiffPage(); + setupOtherOptions(); + if (bShowDirMergeSettings) + setupDirectoryMergePage(); - //setupKeysPage(); + setupRegionalPage(); - // Initialize all values in the dialog - resetToDefaults(); - slotApply(); + //setupKeysPage(); + + // Initialize all values in the dialog + resetToDefaults(); + slotApply(); } OptionDialog::~OptionDialog( void ) @@ -433,7 +521,7 @@ void OptionDialog::setupEditPage( void ) { - QFrame *page = addPage( i18n("Editor"), i18n("Editor Behaviour"), + QFrame *page = addPage( i18n("Editor"), i18n("Editor Behavior"), BarIcon("edit", KIcon::SizeMedium ) ); QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); @@ -471,7 +559,7 @@ )); ++line; - label = new QLabel( i18n("Line End Style:"), page ); + label = new QLabel( i18n("Line end style:"), page ); gbox->addWidget( label, line, 0 ); #ifdef _WIN32 int defaultLineEndStyle = eLineEndDos; @@ -483,18 +571,11 @@ pLineEndStyle->insertItem( "Unix", eLineEndUnix ); pLineEndStyle->insertItem( "Dos/Windows", eLineEndDos ); QToolTip::add( label, i18n( - "Sets the line endings for when a edited file is saved.\n" - "DOS/Windows: CR+LF; Unix: LF; with CR=0D, LF=0A") + "Sets the line endings for when an edited file is saved.\n" + "DOS/Windows: CR+LF; UNIX: LF; with CR=0D, LF=0A") ); ++line; - OptionCheckBox* pStringEncoding = new OptionCheckBox( i18n("Use locale encoding"), true, "LocaleEncoding", &m_bStringEncoding, page, this ); - gbox->addMultiCellWidget( pStringEncoding, line, line, 0, 1 ); - QToolTip::add( pStringEncoding, i18n( - "Change this if non-ASCII characters are not displayed correctly." - )); - ++line; - topLayout->addStretch(10); } @@ -527,7 +608,7 @@ ); ++line; - OptionCheckBox* pIgnoreComments = new OptionCheckBox( i18n("Ignore C/C++ Comments"), false, "IgnoreComments", &m_bIgnoreComments, page, this ); + OptionCheckBox* pIgnoreComments = new OptionCheckBox( i18n("Ignore C/C++ comments"), false, "IgnoreComments", &m_bIgnoreComments, page, this ); gbox->addMultiCellWidget( pIgnoreComments, line, line, 0, 1 ); QToolTip::add( pIgnoreComments, i18n( "Treat C/C++ comments like white space.") ); @@ -576,7 +657,7 @@ gbox->addWidget( label, line, 0 ); OptionComboBox* pWhiteSpace2FileMergeDefault = new OptionComboBox( 0, "WhiteSpace2FileMergeDefault", &m_whiteSpace2FileMergeDefault, page, this ); gbox->addWidget( pWhiteSpace2FileMergeDefault, line, 1 ); - pWhiteSpace2FileMergeDefault->insertItem( i18n("Manual choice"), 0 ); + pWhiteSpace2FileMergeDefault->insertItem( i18n("Manual Choice"), 0 ); pWhiteSpace2FileMergeDefault->insertItem( "A", 1 ); pWhiteSpace2FileMergeDefault->insertItem( "B", 2 ); QToolTip::add( label, i18n( @@ -589,7 +670,7 @@ gbox->addWidget( label, line, 0 ); OptionComboBox* pWhiteSpace3FileMergeDefault = new OptionComboBox( 0, "WhiteSpace3FileMergeDefault", &m_whiteSpace3FileMergeDefault, page, this ); gbox->addWidget( pWhiteSpace3FileMergeDefault, line, 1 ); - pWhiteSpace3FileMergeDefault->insertItem( i18n("Manual choice"), 0 ); + pWhiteSpace3FileMergeDefault->insertItem( i18n("Manual Choice"), 0 ); pWhiteSpace3FileMergeDefault->insertItem( "A", 1 ); pWhiteSpace3FileMergeDefault->insertItem( "B", 2 ); pWhiteSpace3FileMergeDefault->insertItem( "C", 3 ); @@ -692,10 +773,10 @@ gbox->addMultiCellWidget( pBG, line, line, 0, 1 ); ++line; - OptionRadioButton* pBinaryComparison = new OptionRadioButton( i18n("Binary Comparison"), true, "BinaryComparison", &m_bDmBinaryComparison, pBG, this ); + OptionRadioButton* pBinaryComparison = new OptionRadioButton( i18n("Binary comparison"), true, "BinaryComparison", &m_bDmBinaryComparison, pBG, this ); QToolTip::add( pBinaryComparison, i18n("Binary comparison of each file. (Default)") ); - OptionRadioButton* pFullAnalysis = new OptionRadioButton( i18n("Full Analysis"), false, "FullAnalysis", &m_bDmFullAnalysis, pBG, this ); + OptionRadioButton* pFullAnalysis = new OptionRadioButton( i18n("Full analysis"), false, "FullAnalysis", &m_bDmFullAnalysis, pBG, this ); QToolTip::add( pFullAnalysis, i18n("Do a full analysis and show statistics information in extra columns.\n" "(Slower than a binary comparison, much slower for binary files.)") ); @@ -716,6 +797,16 @@ "Works only when comparing two directories without specifying a destination." ) ); ++line; + // Allow white-space only differences to be considered equal + OptionCheckBox* pWhiteSpaceDiffsEqual = new OptionCheckBox( i18n("White space differences considered equal"), false,"WhiteSpaceEqual", &m_bDmWhiteSpaceEqual, page, this ); + gbox->addMultiCellWidget( pWhiteSpaceDiffsEqual, line, line, 0, 1 ); + QToolTip::add( pWhiteSpaceDiffsEqual, i18n( + "If files differ only by white space consider them equal.\n" + "This is only active when full analysis is chosen." ) ); + connect(pFullAnalysis, SIGNAL(toggled(bool)), pWhiteSpaceDiffsEqual, SLOT(setEnabled(bool))); + pWhiteSpaceDiffsEqual->setEnabled(false); + ++line; + OptionCheckBox* pCopyNewer = new OptionCheckBox( i18n("Copy newer instead of merging (unsafe)"), false, "CopyNewer", &m_bDmCopyNewer, page, this ); gbox->addMultiCellWidget( pCopyNewer, line, line, 0, 1 ); QToolTip::add( pCopyNewer, i18n( @@ -754,6 +845,16 @@ void OptionDialog::setupRegionalPage( void ) { + QFrame *page = addPage( i18n("Regional Settings"), i18n("Regional Settings"), + BarIcon("locale"/*"charset"*/, KIcon::SizeMedium ) ); + QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); + + QGridLayout *gbox = new QGridLayout( 3, 2 ); + topLayout->addLayout( gbox ); + int line=0; + + QLabel* label; + #ifdef KREPLACEMENTS_H static char* countryMap[]={ @@ -836,15 +937,6 @@ "zu Zulu" }; - QFrame *page = addPage( i18n("Regional Settings"), i18n("Regional Settings"), - BarIcon("locale"/*"charset"*/, KIcon::SizeMedium ) ); - QVBoxLayout *topLayout = new QVBoxLayout( page, 0, spacingHint() ); - - QGridLayout *gbox = new QGridLayout( 3, 2 ); - topLayout->addLayout( gbox ); - int line=0; - - QLabel* label; label = new QLabel( i18n("Language (restart required)"), page ); gbox->addWidget( label, line, 0 ); OptionComboBox* pLanguage = new OptionComboBox( 0, "Language", &m_language, page, this ); @@ -893,10 +985,81 @@ ); ++line; */ +#endif + + m_pSameEncoding = new OptionCheckBox( i18n("Use the same encoding for everything:"), true, "SameEncoding", &m_bSameEncoding, page, this ); + gbox->addMultiCellWidget( m_pSameEncoding, line, line, 0, 1 ); + QToolTip::add( m_pSameEncoding, i18n( + "Enable this allows to change all encodings by changing the first only.\n" + "Disable this if different individual settings are needed." + ) ); + ++line; + + label = new QLabel( i18n("Note: Local Encoding is ") + QTextCodec::codecForLocale()->name(), page ); + gbox->addWidget( label, line, 0 ); + ++line; + + label = new QLabel( i18n("File Encoding for A:"), page ); + gbox->addWidget( label, line, 0 ); + m_pEncodingAComboBox = new OptionEncodingComboBox( "EncodingForA", &m_pEncodingA, page, this ); + gbox->addWidget( m_pEncodingAComboBox, line, 1 ); + ++line; + label = new QLabel( i18n("File Encoding for B:"), page ); + gbox->addWidget( label, line, 0 ); + m_pEncodingBComboBox = new OptionEncodingComboBox( "EncodingForB", &m_pEncodingB, page, this ); + gbox->addWidget( m_pEncodingBComboBox, line, 1 ); + ++line; + label = new QLabel( i18n("File Encoding for C:"), page ); + gbox->addWidget( label, line, 0 ); + m_pEncodingCComboBox = new OptionEncodingComboBox( "EncodingForC", &m_pEncodingC, page, this ); + gbox->addWidget( m_pEncodingCComboBox, line, 1 ); + ++line; + label = new QLabel( i18n("File Encoding for Merge Output and Saving:"), page ); + gbox->addWidget( label, line, 0 ); + m_pEncodingOutComboBox = new OptionEncodingComboBox( "EncodingForOutput", &m_pEncodingOut, page, this ); + gbox->addWidget( m_pEncodingOutComboBox, line, 1 ); + ++line; + label = new QLabel( i18n("File Encoding for Preprocessor Files:"), page ); + gbox->addWidget( label, line, 0 ); + m_pEncodingPPComboBox = new OptionEncodingComboBox( "EncodingForPP", &m_pEncodingPP, page, this ); + gbox->addWidget( m_pEncodingPPComboBox, line, 1 ); + ++line; + + connect(m_pSameEncoding, SIGNAL(toggled(bool)), this, SLOT(slotEncodingChanged())); + connect(m_pEncodingAComboBox, SIGNAL(activated(int)), this, SLOT(slotEncodingChanged())); + + OptionCheckBox* pRightToLeftLanguage = new OptionCheckBox( i18n("Right To Left Language"), false, "RightToLeftLanguage", &m_bRightToLeftLanguage, page, this ); + gbox->addMultiCellWidget( pRightToLeftLanguage, line, line, 0, 1 ); + QToolTip::add( pRightToLeftLanguage, i18n( + "Some languages are read from right to left.\n" + "This setting will change the viewer and editor accordingly.")); + ++line; + + topLayout->addStretch(10); -#endif } +void OptionDialog::slotEncodingChanged() +{ + if ( m_pSameEncoding->isChecked() ) + { + m_pEncodingBComboBox->setEnabled( false ); + m_pEncodingBComboBox->setCurrentItem( m_pEncodingAComboBox->currentItem() ); + m_pEncodingCComboBox->setEnabled( false ); + m_pEncodingCComboBox->setCurrentItem( m_pEncodingAComboBox->currentItem() ); + m_pEncodingOutComboBox->setEnabled( false ); + m_pEncodingOutComboBox->setCurrentItem( m_pEncodingAComboBox->currentItem() ); + m_pEncodingPPComboBox->setEnabled( false ); + m_pEncodingPPComboBox->setCurrentItem( m_pEncodingAComboBox->currentItem() ); + } + else + { + m_pEncodingBComboBox->setEnabled( true ); + m_pEncodingCComboBox->setEnabled( true ); + m_pEncodingOutComboBox->setEnabled( true ); + m_pEncodingPPComboBox->setEnabled( true ); + } +} void OptionDialog::setupKeysPage( void ) { @@ -972,6 +1135,7 @@ #else m_fontChooser->setFont( KGlobalSettings::fixedFont(), true /*only fixed*/ ); #endif + slotEncodingChanged(); } /** Initialise the widgets using the values in the public varibles. */ @@ -984,6 +1148,7 @@ } m_fontChooser->setFont( m_font, true /*only fixed*/ ); + slotEncodingChanged(); } void OptionDialog::saveOptions( KConfig* config ) @@ -1040,6 +1205,4 @@ KDialogBase::slotHelp(); } - - #include "optiondialog.moc"
--- a/kdiff3/src/optiondialog.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/optiondialog.h Mon Jan 31 22:30:47 2005 +0000 @@ -33,9 +33,11 @@ #include <list> class OptionItem; +class OptionCheckBox; +class OptionEncodingComboBox; class KKeyDialog; -enum eLineEndStyle +enum e_LineEndStyle { eLineEndUnix=0, eLineEndDos @@ -65,12 +67,17 @@ QColor m_currentRangeDiffBgColor; bool m_bWordWrap; - + bool m_bReplaceTabs; bool m_bAutoIndentation; int m_tabSize; bool m_bAutoCopySelection; - bool m_bStringEncoding; + bool m_bSameEncoding; + QTextCodec* m_pEncodingA; + QTextCodec* m_pEncodingB; + QTextCodec* m_pEncodingC; + QTextCodec* m_pEncodingOut; + QTextCodec* m_pEncodingPP; int m_lineEndStyle; bool m_bPreserveCarriageReturn; @@ -111,11 +118,13 @@ bool m_bDmCopyNewer; bool m_bDmShowOnlyDeltas; bool m_bDmUseCvsIgnore; + bool m_bDmWhiteSpaceEqual; QString m_DmFilePattern; QString m_DmFileAntiPattern; QString m_DmDirAntiPattern; QString m_language; + bool m_bRightToLeftLanguage; //QString m_fileCodec; void saveOptions(KConfig* config); @@ -130,7 +139,8 @@ virtual void slotOk( void ); virtual void slotApply( void ); virtual void slotHelp( void ); - + + void slotEncodingChanged(); private: void resetToDefaults(); @@ -138,6 +148,13 @@ // FontConfigDlg KFontChooser *m_fontChooser; + + OptionCheckBox* m_pSameEncoding; + OptionEncodingComboBox* m_pEncodingAComboBox; + OptionEncodingComboBox* m_pEncodingBComboBox; + OptionEncodingComboBox* m_pEncodingCComboBox; + OptionEncodingComboBox* m_pEncodingOutComboBox; + OptionEncodingComboBox* m_pEncodingPPComboBox; private: void setupFontPage();
--- a/kdiff3/src/pdiff.cpp Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/pdiff.cpp Mon Jan 31 22:30:47 2005 +0000 @@ -64,46 +64,11 @@ bool g_bIgnoreTrivialMatches = true; -QString createTempFile( const LineData* p, int size, bool bIgnoreWhiteSpace, bool bIgnoreNumbers ) -{ - QString fileName = FileAccess::tempFileName(); - - QFile file( fileName ); - bool bSuccess = file.open( IO_WriteOnly ); - if ( !bSuccess ) return ""; - for (int l=0; l<size; ++l) - { - // We don't want any white space in the diff output - QCString s( p[l].size+1 ); - int is=0; - for(int j=0; j<p[l].size; ++j ) - { - char c = p[l].pLine[j]; - if ( !( bIgnoreWhiteSpace && isWhite( c ) || - bIgnoreNumbers && (isdigit( c ) || c=='-' || c=='.' ) - ) - ) - { - if ( c=='\0' ) // Replace zeros with something else. - s[is]=(char)0xFF; - else - s[is]=c; - ++is; - } - } - s[is]='\n'; - ++is; - if( is != file.writeBlock( &s[0], is ) ) - return ""; - } - return fileName; -} - bool KDiff3App::runDiff( const LineData* p1, int size1, const LineData* p2, int size2, DiffList& diffList ) { ProgressProxy pp; - static GnuDiff gnuDiff; - + static GnuDiff gnuDiff; // All values are initialized with zeros. + pp.setCurrent(0); diffList.clear(); @@ -121,22 +86,22 @@ diffList.push_back(d); } else - { + { GnuDiff::comparison comparisonInput; memset( &comparisonInput, 0, sizeof(comparisonInput) ); comparisonInput.parent = 0; comparisonInput.file[0].buffer = (word*)p1[0].pLine;//ptr to buffer - comparisonInput.file[0].buffered = p1[size1-1].pLine-p1[0].pLine+p1[size1-1].size; // size of buffer + comparisonInput.file[0].buffered = (p1[size1-1].pLine-p1[0].pLine+p1[size1-1].size); // size of buffer comparisonInput.file[1].buffer = (word*)p2[0].pLine;//ptr to buffer - comparisonInput.file[1].buffered = p2[size2-1].pLine-p2[0].pLine+p2[size2-1].size; // size of buffer - + comparisonInput.file[1].buffered = (p2[size2-1].pLine-p2[0].pLine+p2[size2-1].size); // size of buffer + gnuDiff.ignore_white_space = GnuDiff::IGNORE_ALL_SPACE; // I think nobody needs anything else ... gnuDiff.bIgnoreWhiteSpace = true; gnuDiff.bIgnoreNumbers = m_pOptionDialog->m_bIgnoreNumbers; gnuDiff.minimal = m_pOptionDialog->m_bTryHard; gnuDiff.ignore_case = false; GnuDiff::change* script = gnuDiff.diff_2_files( &comparisonInput ); - + int equalLinesAtStart = comparisonInput.file[0].prefix_lines; int currentLine1 = 0; int currentLine2 = 0; @@ -151,11 +116,11 @@ currentLine1 += d.nofEquals + d.diff1; currentLine2 += d.nofEquals + d.diff2; diffList.push_back(d); - + p = e->link; free (e); } - + if ( diffList.empty() ) { Diff d(0,0,0); @@ -174,7 +139,7 @@ else if ( !gnuDiff.files[0].missing_newline ) { ++d.nofEquals; - } + } diffList.push_back(d); */ } @@ -183,7 +148,7 @@ diffList.front().nofEquals += equalLinesAtStart; currentLine1 += equalLinesAtStart; currentLine2 += equalLinesAtStart; - + int nofEquals = min2(size1-currentLine1,size2-currentLine2); if ( nofEquals==0 ) { @@ -195,7 +160,7 @@ Diff d( nofEquals,size1-currentLine1-nofEquals,size2-currentLine2-nofEquals); diffList.push_back(d); } - + /* if ( gnuDiff.files[0].missing_newline != gnuDiff.files[1].missing_newline ) { @@ -209,7 +174,7 @@ */ } } - + #ifndef NDEBUG // Verify difflist { @@ -262,8 +227,8 @@ i18n("The following option(s) you selected might change data:\n") + msg + i18n("\nMost likely this is not wanted during a merge.\n" "Do you want to disable these settings or continue with these settings active?"), - i18n("Option unsafe for merging"), - i18n("Use these options during the merge"), i18n("Disable unsafe options") + i18n("Option Unsafe for Merging"), + i18n("Use These Options During Merge"), i18n("Disable Unsafe Options") ); if (result == KMessageBox::No ) @@ -291,11 +256,11 @@ // First get all input data. pp.setInformation(i18n("Loading A")); - m_sd1.readAndPreprocess(); + m_sd1.readAndPreprocess(m_pOptionDialog->m_pEncodingA); pp.step(); pp.setInformation(i18n("Loading B")); - m_sd2.readAndPreprocess(); + m_sd2.readAndPreprocess(m_pOptionDialog->m_pEncodingB); pp.step(); pTotalDiffStatus->reset(); @@ -319,7 +284,7 @@ else { pp.setInformation(i18n("Loading C")); - m_sd3.readAndPreprocess(); + m_sd3.readAndPreprocess(m_pOptionDialog->m_pEncodingC); pp.step(); pTotalDiffStatus->bBinaryAEqB = m_sd1.isBinaryEqualWith( m_sd2 ); @@ -462,12 +427,12 @@ // 2. If the files don't have the same name then show all names if ( caption.isEmpty() && (!f1.isEmpty() || !f2.isEmpty() || !f3.isEmpty()) ) { - caption = ( f1.isEmpty()? "" : ".../"+f1 ); - caption += QString(caption.isEmpty() || f2.isEmpty() ? "" : " <-> ") + ( f2.isEmpty()? "" : ".../"+f2 ); - caption += QString(caption.isEmpty() || f3.isEmpty() ? "" : " <-> ") + ( f3.isEmpty()? "" : ".../"+f3 ) ; + caption = ( f1.isEmpty()? QString("") : QString(".../")+f1 ); + caption += QString(caption.isEmpty() || f2.isEmpty() ? "" : " <-> ") + ( f2.isEmpty()? QString("") : QString(".../")+f2 ); + caption += QString(caption.isEmpty() || f3.isEmpty() ? "" : " <-> ") + ( f3.isEmpty()? QString("") : QString(".../")+f3 ) ; } - m_pKDiff3Shell->setCaption( caption.isEmpty() ? "KDiff3" : caption+" - KDiff3"); + m_pKDiff3Shell->setCaption( caption.isEmpty() ? QString("KDiff3") : caption+QString(" - KDiff3")); } @@ -678,7 +643,7 @@ m_pMergeResultWindow->installEventFilter( this ); // for Cut/Copy/Paste-shortcuts QHBoxLayout* pHScrollBarLayout = new QHBoxLayout( pVLayout ); - m_pHScrollBar = new QScrollBar( Horizontal, m_pMainWidget ); + m_pHScrollBar = new ReversibleScrollBar( Horizontal, m_pMainWidget, &m_pOptionDialog->m_bRightToLeftLanguage ); pHScrollBarLayout->addWidget( m_pHScrollBar ); m_pCornerWidget = new QWidget( m_pMainWidget ); pHScrollBarLayout->addWidget( m_pCornerWidget ); @@ -686,21 +651,21 @@ connect( m_pDiffVScrollBar, SIGNAL(valueChanged(int)), m_pOverview, SLOT(setFirstLine(int))); connect( m_pDiffVScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow1, SLOT(setFirstLine(int))); - connect( m_pHScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow1, SLOT(setFirstColumn(int))); + connect( m_pHScrollBar, SIGNAL(valueChanged2(int)), m_pDiffTextWindow1, SLOT(setFirstColumn(int))); connect( m_pDiffTextWindow1, SIGNAL(newSelection()), this, SLOT(slotSelectionStart())); connect( m_pDiffTextWindow1, SIGNAL(selectionEnd()), this, SLOT(slotSelectionEnd())); connect( m_pDiffTextWindow1, SIGNAL(scroll(int,int)), this, SLOT(scrollDiffTextWindow(int,int))); m_pDiffTextWindow1->installEventFilter( this ); connect( m_pDiffVScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow2, SLOT(setFirstLine(int))); - connect( m_pHScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow2, SLOT(setFirstColumn(int))); + connect( m_pHScrollBar, SIGNAL(valueChanged2(int)), m_pDiffTextWindow2, SLOT(setFirstColumn(int))); connect( m_pDiffTextWindow2, SIGNAL(newSelection()), this, SLOT(slotSelectionStart())); connect( m_pDiffTextWindow2, SIGNAL(selectionEnd()), this, SLOT(slotSelectionEnd())); connect( m_pDiffTextWindow2, SIGNAL(scroll(int,int)), this, SLOT(scrollDiffTextWindow(int,int))); m_pDiffTextWindow2->installEventFilter( this ); connect( m_pDiffVScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow3, SLOT(setFirstLine(int))); - connect( m_pHScrollBar, SIGNAL(valueChanged(int)), m_pDiffTextWindow3, SLOT(setFirstColumn(int))); + connect( m_pHScrollBar, SIGNAL(valueChanged2(int)), m_pDiffTextWindow3, SLOT(setFirstColumn(int))); connect( m_pDiffTextWindow3, SIGNAL(newSelection()), this, SLOT(slotSelectionStart())); connect( m_pDiffTextWindow3, SIGNAL(selectionEnd()), this, SLOT(slotSelectionEnd())); connect( m_pDiffTextWindow3, SIGNAL(scroll(int,int)), this, SLOT(scrollDiffTextWindow(int,int))); @@ -709,7 +674,7 @@ MergeResultWindow* p = m_pMergeResultWindow; connect( m_pMergeVScrollBar, SIGNAL(valueChanged(int)), p, SLOT(setFirstLine(int))); - connect( m_pHScrollBar, SIGNAL(valueChanged(int)), p, SLOT(setFirstColumn(int))); + connect( m_pHScrollBar, SIGNAL(valueChanged2(int)), p, SLOT(setFirstColumn(int))); connect( p, SIGNAL(scroll(int,int)), this, SLOT(scrollMergeResultWindow(int,int))); connect( p, SIGNAL(sourceMask(int,int)), this, SLOT(sourceMask(int,int))); connect( p, SIGNAL( resizeSignal() ),this, SLOT(resizeMergeResultWindow())); @@ -1241,6 +1206,12 @@ { if ( !canContinue() ) return; + if(fn1=="" && fn2=="" && fn3=="" && ofn=="" && m_pMainWidget!=0 ) + { + m_pMainWidget->hide(); + return; + } + slotStatusMsg(i18n("Opening files...")); m_sd1.setFilename( fn1 ); @@ -1264,7 +1235,7 @@ bool bDirCompare = m_bDirCompare; improveFilenames(); - + if( m_bDirCompare ) { } @@ -1440,7 +1411,7 @@ void KDiff3App::slotChooseC() { choose( C ); } // bConflictsOnly automatically choose for conflicts only (true) or for everywhere -static void mergeChooseGlobal( KDiff3App* pThis, MergeResultWindow* pMRW, int selector, bool bConflictsOnly, bool bWhiteSpaceOnly ) +static void mergeChooseGlobal( MergeResultWindow* pMRW, int selector, bool bConflictsOnly, bool bWhiteSpaceOnly ) { if ( pMRW ) { @@ -1448,15 +1419,15 @@ } } -void KDiff3App::slotChooseAEverywhere() { mergeChooseGlobal( this, m_pMergeResultWindow, A, false, false ); } -void KDiff3App::slotChooseBEverywhere() { mergeChooseGlobal( this, m_pMergeResultWindow, B, false, false ); } -void KDiff3App::slotChooseCEverywhere() { mergeChooseGlobal( this, m_pMergeResultWindow, C, false, false ); } -void KDiff3App::slotChooseAForUnsolvedConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, A, true, false ); } -void KDiff3App::slotChooseBForUnsolvedConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, B, true, false ); } -void KDiff3App::slotChooseCForUnsolvedConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, C, true, false ); } -void KDiff3App::slotChooseAForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, A, true, true ); } -void KDiff3App::slotChooseBForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, B, true, true ); } -void KDiff3App::slotChooseCForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( this, m_pMergeResultWindow, C, true, true ); } +void KDiff3App::slotChooseAEverywhere() { mergeChooseGlobal( m_pMergeResultWindow, A, false, false ); } +void KDiff3App::slotChooseBEverywhere() { mergeChooseGlobal( m_pMergeResultWindow, B, false, false ); } +void KDiff3App::slotChooseCEverywhere() { mergeChooseGlobal( m_pMergeResultWindow, C, false, false ); } +void KDiff3App::slotChooseAForUnsolvedConflicts() { mergeChooseGlobal( m_pMergeResultWindow, A, true, false ); } +void KDiff3App::slotChooseBForUnsolvedConflicts() { mergeChooseGlobal( m_pMergeResultWindow, B, true, false ); } +void KDiff3App::slotChooseCForUnsolvedConflicts() { mergeChooseGlobal( m_pMergeResultWindow, C, true, false ); } +void KDiff3App::slotChooseAForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( m_pMergeResultWindow, A, true, true ); } +void KDiff3App::slotChooseBForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( m_pMergeResultWindow, B, true, true ); } +void KDiff3App::slotChooseCForUnsolvedWhiteSpaceConflicts() { mergeChooseGlobal( m_pMergeResultWindow, C, true, true ); } void KDiff3App::slotAutoSolve() @@ -1515,7 +1486,10 @@ m_pMergeResultWindow->setFont(m_pOptionDialog->m_font); m_pMergeResultWindow->update(); } - + if (m_pHScrollBar!=0) + { + m_pHScrollBar->setAgain(); + } if ( m_pDiffWindowSplitter!=0 ) { m_pDiffWindowSplitter->setOrientation( m_pOptionDialog->m_bHorizDiffWindowSplitting ? Horizontal : Vertical ); @@ -1904,7 +1878,7 @@ void KDiff3App::slotEditFindNext() { - QCString s = m_pFindDialog->m_pSearchString->text().utf8(); + QString s = m_pFindDialog->m_pSearchString->text(); if ( s.isEmpty() ) { slotEditFind();
--- a/kdiff3/src/version.h Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/src/version.h Mon Jan 31 22:30:47 2005 +0000 @@ -1,2 +1,2 @@ #undef VERSION -#define VERSION "0.9.86" +#define VERSION "0.9.87"
--- a/kdiff3/windows_installer/README_WIN.txt Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/windows_installer/README_WIN.txt Mon Jan 31 22:30:47 2005 +0000 @@ -2,8 +2,8 @@ ========================= Author: Joachim Eibl (joachim.eibl@gmx.de) -Copyright: (C) 2002-2004 by Joachim Eibl -KDiff3-Version: 0.9.84 +Copyright: (C) 2002-2005 by Joachim Eibl +KDiff3-Version: 0.9.87 Homepage: http://kdiff3.sourceforge.net KDiff3 is a program that
--- a/kdiff3/windows_installer/VERSION.NSI Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/windows_installer/VERSION.NSI Mon Jan 31 22:30:47 2005 +0000 @@ -1,1 +1,1 @@ -!define MUI_VERSION "0.9.86" +!define MUI_VERSION "0.9.87"
--- a/kdiff3/windows_installer/kdiff3.nsi Thu Sep 16 02:45:37 2004 +0000 +++ b/kdiff3/windows_installer/kdiff3.nsi Mon Jan 31 22:30:47 2005 +0000 @@ -223,7 +223,7 @@ SubSection "Integration" Section "WinCVS" DetailPrint "Integration to WinCVS" - MessageBox MB_OK "Please close WinCVS" + MessageBox MB_OK "If WinCVS is running, please close it before proceeding." WriteRegStr HKCU "Software\WinCvs\wincvs\CVS settings" "P_Extdiff" '$INSTDIR\kdiff3.exe' WriteRegBin HKCU "Software\WinCvs\wincvs\CVS settings" "P_DiffUseExtDiff" 01