Full Code of KDE/kdiff3 for AI

master 04eba624ed6f cached
391 files
8.5 MB
2.2M tokens
483 symbols
1 requests
Download .txt
Showing preview only (9,476K chars total). Download the full file or copy to clipboard to get everything.
Repository: KDE/kdiff3
Branch: master
Commit: 04eba624ed6f
Files: 391
Total size: 8.5 MB

Directory structure:
gitextract_ofgqlzq8/

├── .clang-format
├── .clang-tidy
├── .craft.ini
├── .editorconfig
├── .flatpak-manifest.json
├── .flatpak-manifest.json.license
├── .gitignore
├── .gitlab-ci.yml
├── .kde-ci.yml
├── CMakeLists.txt
├── COPYING
├── ChangeLog
├── CppCheckSuppressions.txt
├── INSTALL
├── LICENSES/
│   ├── BSD-2-Clause.txt
│   ├── CC0-1.0.txt
│   ├── GPL-2.0-or-later.txt
│   └── MIT.txt
├── README
├── UBSan.supp
├── diff_ext_for_kdiff3/
│   ├── .krazy
│   ├── CMakeLists.txt
│   ├── LICENSE
│   ├── Messages.sh
│   ├── README
│   ├── class_factory.cpp
│   ├── class_factory.h
│   ├── diff_ext.cpp
│   ├── diff_ext.h
│   ├── diff_ext_for_kdiff3.def
│   ├── diff_ext_for_kdiff3.rc
│   ├── diff_ext_for_kdiff3_msvc.def
│   ├── server.cpp
│   └── server.h
├── doc/
│   ├── CMakeLists.txt
│   └── en/
│       ├── CMakeLists.txt
│       ├── index.docbook
│       └── man-kdiff3.1.docbook
├── kdiff3fileitemactionplugin/
│   ├── CMakeLists.txt
│   ├── Messages.sh
│   ├── kdiff3fileitemaction.cpp
│   ├── kdiff3fileitemaction.h
│   └── kdiff3fileitemaction.json
├── po/
│   ├── ar/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ast/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── bg/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── br/
│   │   └── kdiff3.po
│   ├── bs/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ca/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ca@valencia/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── cs/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── cy/
│   │   └── kdiff3.po
│   ├── da/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── de/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── el/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── en_GB/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── eo/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── es/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── et/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── eu/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── fi/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── fr/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ga/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── gl/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── he/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── hi/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── hne/
│   │   └── kdiff3.po
│   ├── hr/
│   │   └── kdiff3.po
│   ├── hu/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ia/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── id/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── is/
│   │   └── kdiff3.po
│   ├── it/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ja/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ka/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ko/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── lt/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── mai/
│   │   └── kdiff3.po
│   ├── ml/
│   │   └── kdiff3.po
│   ├── mr/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nb/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nds/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nl/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nn/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pl/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pt/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       └── index.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pt_BR/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ro/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ru/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── rw/
│   │   └── kdiff3.po
│   ├── sa/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sk/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sl/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@ijekavian/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@ijekavianlatin/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@latin/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sv/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ta/
│   │   └── kdiff3.po
│   ├── tg/
│   │   └── kdiff3.po
│   ├── tr/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ug/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── uk/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── zh_CN/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   └── zh_TW/
│       ├── diff_ext.po
│       ├── kdiff3.po
│       └── kdiff3fileitemactionplugin.po
├── setup.cfg
├── src/
│   ├── CMakeLists.txt
│   ├── CommentParser.cpp
│   ├── CommentParser.h
│   ├── CompositeIgnoreList.cpp
│   ├── CompositeIgnoreList.h
│   ├── ConfigValueMap.h
│   ├── CvsIgnoreList.cpp
│   ├── CvsIgnoreList.h
│   ├── DefaultFileAccessJobHandler.cpp
│   ├── DefaultFileAccessJobHandler.h
│   ├── DirectoryInfo.cpp
│   ├── DirectoryInfo.h
│   ├── DirectoryList.h
│   ├── EncodedData.h
│   ├── FileAccessJobHandler.h
│   ├── FileNameLineEdit.cpp
│   ├── FileNameLineEdit.h
│   ├── FontChooser.ui
│   ├── GitIgnoreList.cpp
│   ├── GitIgnoreList.h
│   ├── IgnoreList.h
│   ├── LineRef.h
│   ├── Logging.cpp
│   ├── Logging.h
│   ├── MacOSXBundleInfo.plist.in
│   ├── MergeEditLine.cpp
│   ├── MergeEditLine.h
│   ├── MergeFileInfos.cpp
│   ├── MergeFileInfos.h
│   ├── Messages.sh
│   ├── OptionItems.h
│   ├── Options.cpp
│   ├── Overview.cpp
│   ├── Overview.h
│   ├── PixMapUtils.cpp
│   ├── PixMapUtils.h
│   ├── ProgressProxy.cpp
│   ├── ProgressProxy.h
│   ├── ProgressProxyExtender.cpp
│   ├── ProgressProxyExtender.h
│   ├── RLPainter.h
│   ├── RecentItems.h
│   ├── SourceData.cpp
│   ├── SourceData.h
│   ├── StandardMenus.cpp
│   ├── StandardMenus.h
│   ├── TypeUtils.h
│   ├── UndoRecord.h
│   ├── Utils.cpp
│   ├── Utils.h
│   ├── autotests/
│   │   ├── CMakeLists.txt
│   │   ├── CompositeIgnoreListTest.cpp
│   │   ├── CvsIgnoreListTest.cpp
│   │   ├── Diff3LineTest.cpp
│   │   ├── DiffTest.cpp
│   │   ├── FileAccessJobHandlerMoc.h
│   │   ├── FileAccessTest.cpp
│   │   ├── GitIgnoreListTest.cpp
│   │   ├── ManualDiffHelpListTest.cpp
│   │   ├── MocIgnoreFile.h
│   │   ├── SourceDataMoc.h
│   │   ├── combinertest.cpp
│   │   ├── commentparser.cpp
│   │   ├── connectiontest.cpp
│   │   └── datareadtest.cpp
│   ├── combiners.h
│   ├── common.cpp
│   ├── common.h
│   ├── compat.h
│   ├── defmac.h
│   ├── diff.cpp
│   ├── diff.h
│   ├── difftextwindow.cpp
│   ├── difftextwindow.h
│   ├── directorymergewindow.cpp
│   ├── directorymergewindow.h
│   ├── fileaccess.cpp
│   ├── fileaccess.h
│   ├── gnudiff_analyze.cpp
│   ├── gnudiff_diff.h
│   ├── gnudiff_io.cpp
│   ├── gnudiff_xmalloc.cpp
│   ├── guiutils.h
│   ├── icons/
│   │   ├── CMakeLists.txt
│   │   └── sc-apps-kdiff3.svgz
│   ├── kdiff3.cpp
│   ├── kdiff3.h
│   ├── kdiff3.qrc
│   ├── kdiff3_shell.cpp
│   ├── kdiff3_shell.h
│   ├── kdiff3_shell.rc
│   ├── kdiff3win.rc
│   ├── main.cpp
│   ├── merger.cpp
│   ├── merger.h
│   ├── mergeresultwindow.cpp
│   ├── mergeresultwindow.h
│   ├── opendialog.ui
│   ├── optiondialog.cpp
│   ├── optiondialog.h
│   ├── options.h
│   ├── org.kde.kdiff3.appdata.xml
│   ├── org.kde.kdiff3.desktop
│   ├── pdiff.cpp
│   ├── progress.cpp
│   ├── progress.h
│   ├── progressdialog.ui
│   ├── scroller.ui
│   ├── selection.cpp
│   ├── selection.h
│   ├── smalldialogs.cpp
│   ├── smalldialogs.h
│   └── xpm/
│       ├── autoadvance.xpm
│       ├── autoadvance.xpm.license
│       ├── currentpos.xpm
│       ├── currentpos.xpm.license
│       ├── down1arrow.xpm
│       ├── down1arrow.xpm.license
│       ├── down2arrow.xpm
│       ├── down2arrow.xpm.license
│       ├── downend.xpm
│       ├── downend.xpm.license
│       ├── file.xpm
│       ├── file.xpm.license
│       ├── folder.xpm
│       ├── folder.xpm.license
│       ├── gotoline.xpm
│       ├── gotoline.xpm.license
│       ├── iconA.xpm
│       ├── iconA.xpm.license
│       ├── iconB.xpm
│       ├── iconB.xpm.license
│       ├── iconC.xpm
│       ├── iconC.xpm.license
│       ├── link_arrow.xpm
│       ├── link_arrow.xpm.license
│       ├── nextunsolved.xpm
│       ├── nextunsolved.xpm.license
│       ├── prevunsolved.xpm
│       ├── prevunsolved.xpm.license
│       ├── showequalfiles.xpm
│       ├── showequalfiles.xpm.license
│       ├── showfilesonlyina.xpm
│       ├── showfilesonlyina.xpm.license
│       ├── showfilesonlyinb.xpm
│       ├── showfilesonlyinb.xpm.license
│       ├── showfilesonlyinc.xpm
│       ├── showfilesonlyinc.xpm.license
│       ├── showlinenumbers.xpm
│       ├── showlinenumbers.xpm.license
│       ├── showwhitespace.xpm
│       ├── showwhitespace.xpm.license
│       ├── showwhitespacechars.xpm
│       ├── showwhitespacechars.xpm.license
│       ├── startmerge.xpm
│       ├── startmerge.xpm.license
│       ├── up1arrow.xpm
│       ├── up1arrow.xpm.license
│       ├── up2arrow.xpm
│       ├── up2arrow.xpm.license
│       ├── upend.xpm
│       └── upend.xpm.license
└── test/
    ├── alignmenttest.cpp
    ├── fakefileaccess.cpp
    ├── generate_testdata_from_git_merges.py
    ├── generate_testdata_from_permutations.py
    └── testdata/
        ├── 1_simpletest_base.txt
        ├── 1_simpletest_contrib1.txt
        ├── 1_simpletest_contrib2.txt
        ├── 1_simpletest_expected_result.txt
        ├── 2_prefer_identical_to_space_differences_base.txt
        ├── 2_prefer_identical_to_space_differences_contrib1.txt
        ├── 2_prefer_identical_to_space_differences_contrib2.txt
        ├── 2_prefer_identical_to_space_differences_expected_result.txt
        └── README

================================================
FILE CONTENTS
================================================

================================================
FILE: .clang-format
================================================
---
Language: Cpp
BasedOnStyle: LLVM
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: Never
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
IndentCaseLabels: true
IndentWidth: 4
TabWidth: 4
UseTab: Never
AllowShortFunctionsOnASingleLine: Inline
AllowShortBlocksOnASingleLine: true
AllowShortIfStatementsOnASingleLine: true
AllowShortCaseLabelsOnASingleLine: false
AllowShortLoopsOnASingleLine: true
ColumnLimit: 0
DerivePointerAlignment: true
PointerAlignment: Left
BreakBeforeBraces: Custom
BraceWrapping:
  AfterClass:      true
  AfterControlStatement: true
  AfterEnum:       true
  AfterFunction:   true
  AfterNamespace:  false
  AfterStruct:     false
  AfterUnion:      false
  BeforeCatch:     true
  BeforeElse:      true
  IndentBraces:    false
...


================================================
FILE: .clang-tidy
================================================
---
Checks:          '-clang-analyzer-cplusplus.NewDeleteLeaks,-clang-analyzer-optin.cplusplus.VirtualCall,-clang-analyzer-optin.performance.Padding,
                    readability-delete-*,readability-misleading-*,readability-non-const-parameter,readability-redundant-*,
                    -readability-redundant-inline-specifier, -readability-redundant-access-specifiers,readability-simplify-*,readability-static-*,
                    modernize-use-equals-delete, modernize-use-default-member-init, modernize-use-equals-default, modernize-use-override, modernize-redundant-void-arg, modernize-use-noexcept,
                    misc-redundant-expression, misc-misplaced-const,misc-unused*,-bugprone-macro-parentheses, -bugprone-suspicious-include, -bugprone-branch-clone, -performance-no-automatic-move'
WarningsAsErrors: ''
HeaderFilterRegex: '.*'
CheckOptions:
  - key:             google-readability-braces-around-statements.ShortStatementLines
    value:           '1'
  - key:             google-readability-function-size.StatementThreshold
    value:           '800'
  - key:             google-readability-namespace-comments.ShortNamespaceLines
    value:           '10'
  - key:             google-readability-namespace-comments.SpacesBeforeComments
    value:           '2'
  - key:             modernize-loop-convert.MaxCopySize
    value:           '16'
  - key:             modernize-loop-convert.MinConfidence
    value:           reasonable
  - key:             modernize-loop-convert.NamingStyle
    value:           CamelCase
  - key:             modernize-pass-by-value.IncludeStyle
    value:           llvm
  - key:             modernize-replace-auto-ptr.IncludeStyle
    value:           llvm
  - key:             modernize-use-nullptr.NullMacros
    value:           'NULL'
  - key:             readability-simplify-boolean-expr.SimplifyDeMorgan
    value:           'false'
...



================================================
FILE: .craft.ini
================================================
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0

[BlueprintSettings]
extragear/kdiff3.packageAppx=True



================================================
FILE: .editorconfig
================================================
root = true

[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true


================================================
FILE: .flatpak-manifest.json
================================================
{
    "id": "org.kde.kdiff3",
    "runtime": "org.kde.Platform",
    "runtime-version": "6.10",
    "sdk": "org.kde.Sdk",
    "command": "kdiff3",
    "finish-args": [
        "--device=dri",
        "--share=ipc",
        "--socket=cups",
        "--socket=fallback-x11",
        "--socket=pulseaudio",
        "--socket=wayland",
        "--filesystem=host",
        "--filesystem=home",
        "--filesystem=xdg-run/gvfs"
    ],
    "modules": [
        {
            "name": "boost",
            "buildsystem": "simple",
            "build-commands": [
                "./bootstrap.sh --prefix=/app --with-libraries=system",
                "./b2 -j $FLATPAK_BUILDER_N_JOBS install"
            ],
            "sources": [
                {
                    "type": "archive",
                    "url": "https://ftp.osuosl.org/pub/blfs/conglomeration/boost/boost_1_84_0.tar.bz2",
                    "sha256": "cc4b893acf645c9d4b698e9a0f08ca8846aa5d6c68275c14c3e7949c24109454",
                    "x-checker-data": {
                        "type": "anitya",
                        "project-id": 6845,
                        "stable-only": true,
                        "url-template": "https://boostorg.jfrog.io/artifactory/main/release/$version/source/boost_${major}_${minor}_$patch.tar.bz2"
                    }
                }
            ]
        },
        {
            "name": "kdiff3",
            "buildsystem": "cmake-ninja",
            "sources": [
                {
                    "type": "dir",
                    "path": "."
                }
            ]
        }
    ]
}


================================================
FILE: .flatpak-manifest.json.license
================================================
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0


================================================
FILE: .gitignore
================================================
# general
apidocs
.directory
.kdev4
build
*~
*.patch
*.diff
*.bak
*.orig
*.pyc
*.rej
*.swp
doxygen.log
Doxyfile
*.kdevelop
*.kdevelop.filelist
*.kdevelop.pcs
*.kdevses
.*kate-swp
build/
mem.log.*
massif.*
callgrind.*
perf.data*

# from kdiff3
*.BACKUP.*
*.BASE.*
*.LOCAL.*
*.REMOTE.*


================================================
FILE: .gitlab-ci.yml
================================================
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0
include:
  - project: sysadmin/ci-utilities
    file:
    - /gitlab-templates/linux-qt6.yml
    - /gitlab-templates/freebsd-qt6.yml
    - /gitlab-templates/windows-qt6.yml
    - /gitlab-templates/flatpak.yml
    - /gitlab-templates/craft-windows-x86-64-qt6.yml
    - /gitlab-templates/craft-windows-appx-qt6.yml
    - /gitlab-templates/craft-macos-arm64-qt6.yml
    - /gitlab-templates/craft-macos-x86-64-qt6.yml
    - /gitlab-templates/linux-qt6-next.yml


================================================
FILE: .kde-ci.yml
================================================
# SPDX-FileCopyrightText: None
# SPDX-License-Identifier: CC0-1.0

Dependencies:
- 'on': ['Linux', 'FreeBSD', 'Windows']
  'require':
    'frameworks/extra-cmake-modules': '@stable-kf6'
    'frameworks/kconfig': '@stable-kf6'
    'frameworks/kcoreaddons': '@stable-kf6'
    'frameworks/kcrash': '@stable-kf6'
    'frameworks/kdoctools': '@stable-kf6'
    'frameworks/ki18n': '@stable-kf6'
    'frameworks/kio': '@stable-kf6'
    'frameworks/kwidgetsaddons': '@stable-kf6'
    'frameworks/kxmlgui': '@stable-kf6'

Options:
    cppcheck-arguments: '--enable=warning,style,performance -i build -i test -i src/xpm --suppressions-list=CppCheckSuppressions.txt --inline-suppr'
    require-passing-tests-on: ['Linux', 'FreeBSD', 'Windows']


================================================
FILE: CMakeLists.txt
================================================
# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de
# SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
# SPDX-License-Identifier: GPL-2.0-or-later

# Turn off policy change notices from CMake 3.30 and earlier
cmake_minimum_required(VERSION 3.22...3.30)

project(kdiff3 VERSION 1.12.70)

if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.2)
    message(WARNING "gcc < 9.2 is not recommended support is best effort-only.")
endif()

set(CMAKE_CXX_OUTPUT_EXTENSION_REPLACE ON)
set(CMAKE_CXX_EXTENSIONS ON ) #Disable trigraphs in clang/gcc -- officially removed in c++17
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CXX_STANDARD_REQUIRED ON) #Force early fail if we can't get c++17.

set(KF_MIN_VERSION "6.2.0")

find_package(ECM ${KF_MIN_VERSION} CONFIG REQUIRED)
set(
    CMAKE_MODULE_PATH
    ${CMAKE_MODULE_PATH}
    ${ECM_MODULE_PATH}
)

set(QT_MAJOR_VERSION "6")
set(QT_MIN_VERSION "6.7.0")

set(KF_MAJOR_VERSION "6")

# project uses settings default as of KDECompilerSettings in ECM 5.85.0
set(KDE_QT_MODERNCODE_DEFINITIONS_LEVEL 5.85.0)
set(KDE_COMPILERSETTINGS_LEVEL 5.85.0)
# pedantic compilers are not supported at this time.
set(KDE_SKIP_PEDANTIC_WARNINGS_SETTINGS TRUE)

include(KDEInstallDirs)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(KDECMakeSettings NO_POLICY_SCOPE)
include(FeatureSummary)

# Full QT_NO_CAST_FROM_ASCII is not compatible with kdiff3 code and not worth enforcing
# we use the slightly less strict QT_RESTRICTED_CAST_FROM_ASCII
# Disallowing implicit cast from QByteArray doesn't make sense for this project
remove_definitions(-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_FROM_BYTEARRAY)
#new in QT 6.10+ apparently our auto tests trigger this warning.
add_definitions(-DQT_NO_USE_NODISCARD_FILE_OPEN)

include(ECMInstallIcons)
include(ECMAddAppIcon)
include(ECMSetupVersion)
include(ECMAddTests)
include(ECMOptionalAddSubdirectory)
include(ECMSetupQtPluginMacroNames)

ecm_setup_version(${PROJECT_VERSION} VARIABLE_PREFIX KDIFF3 VERSION_HEADER ${CMAKE_BINARY_DIR}/src/version.h)

# Some older versions on boost contain a bug that prevents compiling gcc offers a built-in workaround
# but that isn't enough to ship as clang has no such workaround. 1.65 is known to be affected.
#
# 1.71 or later is required for safe_numerics to work on MSVC otherwise we get a link-time error.
# 1.84+ drops problematic pre-c++11 support and is preferred on linux and required for OS X.
# KDiff3 has hard coded BOOST_NO_CXX98_FUNCTION_BASE to compensate for a known issue.
# While this allows compiling with older boost versions we can not use pre-built binaries from boost only the headers.
find_package(Boost 1.83 REQUIRED)
#needed on craft and possibly other custom setups.
include_directories(${Boost_INCLUDE_DIRS})

find_package(ICU 70.0 COMPONENTS uc i18n REQUIRED)

find_package(
    Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION}
    REQUIRED
    COMPONENTS
    Core
    Gui
    Widgets
    PrintSupport
)

find_package(
    KF${KF_MAJOR_VERSION} ${KF_MIN_VERSION}
    REQUIRED
    COMPONENTS
    I18n
    CoreAddons
    XmlGui
    WidgetsAddons
    Config
    Crash
    KIO #Not fully ready for to build without KIO
    OPTIONAL_COMPONENTS
    DocTools
)

set_package_properties(KF${KF_MAJOR_VERSION}DocTools PROPERTIES PURPOSE "Allows generating and installing docs.")

string(REPLACE "." ";" VERSION_LIST "${KF${KF_MAJOR_VERSION}_VERSION}")
list(GET VERSION_LIST 0 KF_VERSION_MAJOR)
list(GET VERSION_LIST 1 KF_VERSION_MINOR)
list(GET VERSION_LIST 2 KF_VERSION_PATCH)

option(ENABLE_AUTO "Enable kdiff3's '--auto' flag" ON)
option(ENABLE_CLANG_TIDY "Run clang-tidy if available and cmake version >=3.6" OFF)
option(ENABLE_GDBINDEX OFF)

set(CMAKE_CXX_STANDARD 17)
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
    if(ENABLE_CLAZY)
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Xclang -plugin-arg-clazy -Xclang level0,level1,no-overloaded-signal,auto-unexpected-qstringbuilder,unused-non-trivial-variable,returning-void-expression,isempty-vs-count,container-inside-loop,assert-with-side-effects")
    endif()
    # Adjust clang specific warnings
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wshadow -fexceptions")
    set(CLANG_WARNING_FLAGS "-Wno-unknown-warning-option -Wundef -Wno-trigraphs  -Wno-comment -Wshorten-64-to-32 -Wstring-conversion -Wc++11-narrowing -fstack-protector-all")
    set(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${CLANG_WARNING_FLAGS}")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    # Make MSVC obey standard C++ exception handling by destroying all objects going out of scope as a result of the exception.
    # This also separates a Microsoft specific extension SEH which catches non-c++ asynchronous exceptions.
    add_compile_options("/EHsc")
    # Suppress MSVCs min/max macros
    add_definitions(-DNOMINMAX)
    # Suppress Microsoft specific C4996 "deprecation" warnings. Not helpful for code intended to run on any other platform.
    add_definitions(-D_CRT_NONSTDC_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS -D_CRT_SECURE_NO_WARNINGS_GLOBALS)
    # force compliant use of __cplusplus
    add_compile_options("/Zc:__cplusplus")
elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-trigraphs -Wduplicated-cond -Wduplicated-branches -Wshadow -fexceptions")
endif()

#new in cmake 3.6+ integrate clang-tidy
if(ENABLE_CLANG_TIDY)
    find_program(CLANG_TIDY_EXE NAMES "clang-tidy" DOC "Path to clang-tidy executable")
    if(NOT CLANG_TIDY_EXE)
        message(STATUS "clang-tidy not found disabling integration.")
    else()
        message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXE}")
        set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}" "-header-filter=.*")
    endif()
endif()

set(CMAKE_C_FLAGS  "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}")

if(ENABLE_AUTO)
    add_definitions(
        -DENABLE_AUTO
    )
endif()

add_definitions(
    -DBOOST_NO_CXX98_FUNCTION_BASE # since we use the header only portion of boost we can hardcode this. This forces boost to avoid long depricated Cxx98 processing functions (i.e. std::unary_function and friends).
    -DQT_NO_CONTEXTLESS_CONNECT # Avoid this confusing unexpected static overload
    -DQT_DEPRECATED_WARNINGS # Get warnings from QT about deprecated functions.
    -DQT_NO_URL_CAST_FROM_STRING # casting from string to url does not always behave as you might think
    -DQT_RESTRICTED_CAST_FROM_ASCII # casting from char*/QByteArray to QString can produce unexpected results for non-latin characters.
    -DQT_NO_KEYWORDS
    -DQT_NO_CAST_TO_ASCII
    -DQT_NO_PROCESS_COMBINED_ARGUMENT_START
    -DQT_EXPLICIT_QFILE_CONSTRUCTION_FROM_PATH # preemptive for forward compatibility with Qt 6.9+
    -DQT_DEPRECATED_WARNINGS_SINCE=0x060800    # warn if deprecated at 6.8 or before. Qt default setting is not useful for kdiff3.
    -DQT_DISABLE_DEPRECATED_BEFORE=0x060700    # disable deprecated api for Qt<6.7.
    # Boost 1.74 and possibly others trigger these warnings in boosts own internal headers making
    # the warning useless.
    -DBOOST_ALLOW_DEPRECATED_HEADERS
    # KF5 5.64+ flags
    # Don't warn for API deprecated after 6.6.0 (below as hex.hex.hex number)
    -DKF_DISABLE_DEPRECATED_BEFORE=0x060200#disable deprecated api for KF 6.2.
    -DKF_DEPRECATED_WARNINGS_SINCE=0x060900
    -DKIOCORE_DEPRECATED_WARNINGS_SINCE=0x060900
    -DKXMLGUI_DEPRECATED_WARNINGS_SINCE=0x060900
    -DKF_VERSION_MAJOR=${KF_VERSION_MAJOR}
    -DKF_VERSION_MINOR=${KF_VERSION_MINOR}
    -DKF_VERSION_PATCH=${KF_VERSION_PATCH}
)

# The CMake boolean value is not properly translated if we assign the variable directly to a C/C++ define.
# clangd will catch this in syntax highlighting other language servers may not.
if(KF${KF_MAJOR_VERSION}KIO_FOUND)
    add_definitions(
        -DHAS_KFKIO=1
    )
endif()

add_subdirectory(src)
if(KF${KF_MAJOR_VERSION}DocTools_FOUND)
    ecm_optional_add_subdirectory(doc)
    kdoctools_install(po)
else()
    message(WARNING "DocTools not found. Docs will not be generated.")
endif()

ki18n_install(po)

add_subdirectory(kdiff3fileitemactionplugin)

if(WIN32)
add_subdirectory(diff_ext_for_kdiff3)
endif()

feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)


================================================
FILE: COPYING
================================================
		    GNU GENERAL PUBLIC LICENSE
		       Version 2, June 1991

 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
               51 Franklin Street, Fifth Floor, Boston, MA  02111-1307  USA
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

			    Preamble

  The licenses for most software are designed to take away your
freedom to share and change it.  By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users.  This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it.  (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.)  You can apply it to
your programs, too.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.

  To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.

  For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have.  You must make sure that they, too, receive or can get the
source code.  And you must show them these terms so they know their
rights.

  We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.

  Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software.  If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.

  Finally, any free program is threatened constantly by software
patents.  We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary.  To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.

  The precise terms and conditions for copying, distribution and
modification follow.

		    GNU GENERAL PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License.  The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language.  (Hereinafter, translation is included without limitation in
the term "modification".)  Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope.  The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.

  1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.

You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.

  2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:

    a) You must cause the modified files to carry prominent notices
    stating that you changed the files and the date of any change.

    b) You must cause any work that you distribute or publish, that in
    whole or in part contains or is derived from the Program or any
    part thereof, to be licensed as a whole at no charge to all third
    parties under the terms of this License.

    c) If the modified program normally reads commands interactively
    when run, you must cause it, when started running for such
    interactive use in the most ordinary way, to print or display an
    announcement including an appropriate copyright notice and a
    notice that there is no warranty (or else, saying that you provide
    a warranty) and that users may redistribute the program under
    these conditions, and telling the user how to view a copy of this
    License.  (Exception: if the Program itself is interactive but
    does not normally print such an announcement, your work based on
    the Program is not required to print an announcement.)

These requirements apply to the modified work as a whole.  If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works.  But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.

Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.

In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.

  3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:

    a) Accompany it with the complete corresponding machine-readable
    source code, which must be distributed under the terms of Sections
    1 and 2 above on a medium customarily used for software interchange; or,

    b) Accompany it with a written offer, valid for at least three
    years, to give any third party, for a charge no more than your
    cost of physically performing source distribution, a complete
    machine-readable copy of the corresponding source code, to be
    distributed under the terms of Sections 1 and 2 above on a medium
    customarily used for software interchange; or,

    c) Accompany it with the information you received as to the offer
    to distribute corresponding source code.  (This alternative is
    allowed only for noncommercial distribution and only if you
    received the program in object code or executable form with such
    an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for
making modifications to it.  For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable.  However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.

If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.

  4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License.  Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.

  5. You are not required to accept this License, since you have not
signed it.  However, nothing else grants you permission to modify or
distribute the Program or its derivative works.  These actions are
prohibited by law if you do not accept this License.  Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

  6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions.  You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.

  7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all.  For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.

If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.

It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices.  Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.

This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.

  8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded.  In such case, this License incorporates
the limitation as if written in the body of this License.

  9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time.  Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

Each version is given a distinguishing version number.  If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation.  If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.

  10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission.  For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this.  Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.

			    NO WARRANTY

  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.

  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.

		     END OF TERMS AND CONDITIONS

	    How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:

    Gnomovision version 69, Copyright (C) year name of author
    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
    This is free software, and you are welcome to redistribute it
    under certain conditions; type `show c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License.  Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary.  Here is a sample; alter the names:

  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
  `Gnomovision' (which makes passes at compilers) written by James Hacker.

  <signature of Ty Coon>, 1 April 1989
  Ty Coon, President of Vice

This General Public License does not permit incorporating your program into
proprietary programs.  If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library.  If this is what you want to do, use the GNU Library General
Public License instead of this License.


================================================
FILE: ChangeLog
================================================
*Completed port away from Qt5, 6.6 now required version due to delayed ICU support in Qt

Version 1.11.x - 2024
===========================
*Fix false memory error when using "admin://" protocol
*Cleanup BOM handling lock detection to only known UTF-* encodings that use it.
*Fix bugged connection to non-existent signal (This is why we now use new style connections only.)
*fix crash in  Diff3Line::getLineData when doing history check for nonexistent lines.
*fix crash on some setups that create 0 height widgets when no data is loaded.
*Fixed encoding handling for non-UTF encodings
*Fixed encoding detection for lower case 'HTML' and 'XML' tags
*Fix handling of KIO jobs for non-file urls.
-Actually wait for secondary event loop to end (Not sure if this is a documentation bug in qt or behavior bug.)
-Don't arbitrarily kill jobs when progress dialog is hidden.
*Fix possible invalid line given by mousedown in Overview pane. (Caught by SafeInt range checking)
*Fix bad algorithm in getBestFirstLine.
-Related regression also fixed (BUG:486909)
*craft based builds are now Qt6/kf6.

Version 1.10.x - 2023
===========================

*improved handling of oversized files
*follows links to links to a maximum depth of 15.
*8c14db62775d6233 Fix attempts to set out of range value for LineRef
 Follow symlinks recursively
a038a3da250ee9683075a6742f33ac1312229e83 Make invalid calls to MergeBlock::split crash in debug mode
Fix crash on exit.
*Resolve thread safety issues in word wrap runner
*Fix Bug: 471234
*Fix horizontal scroll broken for first diff window
*Fixed no UI shown for failed auto-merge.
*Fix 469817 no text if word wrap is on.

*Prevent false error due to faulty check when m_pOptions->m_bDiff3AlignBC = true
*468492 fix crash when word wrap enabled
*Rework KDiff3App::completeInit to avoid crash on exit in auto mode
*467652 - "Escape" shortcut ignored if merge output in focus
*466522 - save and restore dock states
*439148 - Show UI before comparison start
*466241 - Don't crash on broken links
*466524 - Fix memory safety issues during reload.
*Fix mishandling line count for files containing '0x0b'
*Make DirectoryMergeWindow and DirecoryMergeInfo QDockWidgets.
*Use Qt native saveState/restoreState


See git history for complete log.


================================================
FILE: CppCheckSuppressions.txt
================================================
unmatchedSuppression:*
assertWithSideEffect
useInitializationList
cstyleCast
uninitMemberVar:src/OptionItems.h:*
variableScope
unsafeClassCanLeak


================================================
FILE: INSTALL
================================================

Building KDiff3 requires the following minimum versions:
 1) Qt 6.7.0 or later
 2) KDE Frameworks (KF) 6.2.0 or later
 3) CMake 3.22 or later
 4) ECM 6.2.0 or later
 5) boost 1.71+
Supported compilers: (Must have full C++17 support; version cutoffs are approximate)
 6) MSVC 2019+, gcc 9.0+, clang 10+

*nix:
On debian based systems you needed to install the fallowing.

gettext, qtbase6-dev, extra-cmake-modules, libboost-dev, libkf6i18n-dev, libkf6coreaddons-dev, libkf6iconthemes-dev, libkf6doctools-dev, libkf6crash-dev, cmake, (gcc or clang)
These should be available as part of the standard repos.
To build KDiff3 run:
  cmake . && make
  sudo make install
CMake will automatically verify that the requirements are met before attempting to build.

Windows:

For windows the build should be done via. craft. Although other methods may work they are not
tested.

Craft requires python 3.7 or later to be installed it can be downloaded here:
https://www.python.org/downloads/windows/
This should be automatically installed by craft.

You will also need to start a power shell environment as administrator instruction for that are at:
https://docs.microsoft.com/en-us/powershell/scripting/getting-started/starting-windows-powershell?view=powershell-6

On Windows 10 this will be the default shell.
Run the following:
1)Set-ExecutionPolicy -Scope CurrentUser RemoteSigned
2)iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/KDE/craft/master/setup/install_craft.ps1'))

You may also have to exempt your craft directory from virus scans as these can interfere with the build process.

1)cd to your craft root
Run:
2)C:\CraftRoot\craft\craftenv.ps1
3)craft png2ico
4)craft kdiff3
If you what to build 1.12.x than use:
4) craft --target 1.12 kdiff3

Otherwise craft will use master which is the development branch and therefor more likely to experience breakage.

At this point you can run kdiff3 itself via the following:
cb kdiff3
bin/kdiff3

If you want to create an install package you would run:
5)craft nsis

6)craft --package kdiff3 or craft --target 1.12 --package kdiff3

This will be a time consuming process on first run as craft will have to download all dependencies.
KDiff3 does not require special configuration for craft.

There should be an installer package generated in CraftRoot/tmp

Please contact kde-windows@kde.org before filing a bug report regarding this process.


================================================
FILE: LICENSES/BSD-2-Clause.txt
================================================
Copyright (c) <year> <owner>. All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: LICENSES/CC0-1.0.txt
================================================
Creative Commons Legal Code

CC0 1.0 Universal

    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
    HEREUNDER.

Statement of Purpose

The laws of most jurisdictions throughout the world automatically confer
exclusive Copyright and Related Rights (defined below) upon the creator
and subsequent owner(s) (each and all, an "owner") of an original work of
authorship and/or a database (each, a "Work").

Certain owners wish to permanently relinquish those rights to a Work for
the purpose of contributing to a commons of creative, cultural and
scientific works ("Commons") that the public can reliably and without fear
of later claims of infringement build upon, modify, incorporate in other
works, reuse and redistribute as freely as possible in any form whatsoever
and for any purposes, including without limitation commercial purposes.
These owners may contribute to the Commons to promote the ideal of a free
culture and the further production of creative, cultural and scientific
works, or to gain reputation or greater distribution for their Work in
part through the use and efforts of others.

For these and/or other purposes and motivations, and without any
expectation of additional consideration or compensation, the person
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
is an owner of Copyright and Related Rights in the Work, voluntarily
elects to apply CC0 to the Work and publicly distribute the Work under its
terms, with knowledge of his or her Copyright and Related Rights in the
Work and the meaning and intended legal effect of CC0 on those rights.

1. Copyright and Related Rights. A Work made available under CC0 may be
protected by copyright and related or neighboring rights ("Copyright and
Related Rights"). Copyright and Related Rights include, but are not
limited to, the following:

  i. the right to reproduce, adapt, distribute, perform, display,
     communicate, and translate a Work;
 ii. moral rights retained by the original author(s) and/or performer(s);
iii. publicity and privacy rights pertaining to a person's image or
     likeness depicted in a Work;
 iv. rights protecting against unfair competition in regards to a Work,
     subject to the limitations in paragraph 4(a), below;
  v. rights protecting the extraction, dissemination, use and reuse of data
     in a Work;
 vi. database rights (such as those arising under Directive 96/9/EC of the
     European Parliament and of the Council of 11 March 1996 on the legal
     protection of databases, and under any national implementation
     thereof, including any amended or successor version of such
     directive); and
vii. other similar, equivalent or corresponding rights throughout the
     world based on applicable law or treaty, and any national
     implementations thereof.

2. Waiver. To the greatest extent permitted by, but not in contravention
of, applicable law, Affirmer hereby overtly, fully, permanently,
irrevocably and unconditionally waives, abandons, and surrenders all of
Affirmer's Copyright and Related Rights and associated claims and causes
of action, whether now known or unknown (including existing as well as
future claims and causes of action), in the Work (i) in all territories
worldwide, (ii) for the maximum duration provided by applicable law or
treaty (including future time extensions), (iii) in any current or future
medium and for any number of copies, and (iv) for any purpose whatsoever,
including without limitation commercial, advertising or promotional
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
member of the public at large and to the detriment of Affirmer's heirs and
successors, fully intending that such Waiver shall not be subject to
revocation, rescission, cancellation, termination, or any other legal or
equitable action to disrupt the quiet enjoyment of the Work by the public
as contemplated by Affirmer's express Statement of Purpose.

3. Public License Fallback. Should any part of the Waiver for any reason
be judged legally invalid or ineffective under applicable law, then the
Waiver shall be preserved to the maximum extent permitted taking into
account Affirmer's express Statement of Purpose. In addition, to the
extent the Waiver is so judged Affirmer hereby grants to each affected
person a royalty-free, non transferable, non sublicensable, non exclusive,
irrevocable and unconditional license to exercise Affirmer's Copyright and
Related Rights in the Work (i) in all territories worldwide, (ii) for the
maximum duration provided by applicable law or treaty (including future
time extensions), (iii) in any current or future medium and for any number
of copies, and (iv) for any purpose whatsoever, including without
limitation commercial, advertising or promotional purposes (the
"License"). The License shall be deemed effective as of the date CC0 was
applied by Affirmer to the Work. Should any part of the License for any
reason be judged legally invalid or ineffective under applicable law, such
partial invalidity or ineffectiveness shall not invalidate the remainder
of the License, and in such case Affirmer hereby affirms that he or she
will not (i) exercise any of his or her remaining Copyright and Related
Rights in the Work or (ii) assert any associated claims and causes of
action with respect to the Work, in either case contrary to Affirmer's
express Statement of Purpose.

4. Limitations and Disclaimers.

 a. No trademark or patent rights held by Affirmer are waived, abandoned,
    surrendered, licensed or otherwise affected by this document.
 b. Affirmer offers the Work as-is and makes no representations or
    warranties of any kind concerning the Work, express, implied,
    statutory or otherwise, including without limitation warranties of
    title, merchantability, fitness for a particular purpose, non
    infringement, or the absence of latent or other defects, accuracy, or
    the present or absence of errors, whether or not discoverable, all to
    the greatest extent permissible under applicable law.
 c. Affirmer disclaims responsibility for clearing rights of other persons
    that may apply to the Work or any use thereof, including without
    limitation any person's Copyright and Related Rights in the Work.
    Further, Affirmer disclaims responsibility for obtaining any necessary
    consents, permissions or other rights required for any use of the
    Work.
 d. Affirmer understands and acknowledges that Creative Commons is not a
    party to this document and has no duty or obligation with respect to
    this CC0 or use of the Work.


================================================
FILE: LICENSES/GPL-2.0-or-later.txt
================================================
GNU GENERAL PUBLIC LICENSE

Version 2, June 1991

Copyright (C) 1989, 1991 Free Software Foundation, Inc. 

51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA

Everyone is permitted to copy and distribute verbatim copies of this license
document, but changing it is not allowed.

Preamble

The licenses for most software are designed to take away your freedom to share
and change it. By contrast, the GNU General Public License is intended to
guarantee your freedom to share and change free software--to make sure the
software is free for all its users. This General Public License applies to
most of the Free Software Foundation's software and to any other program whose
authors commit to using it. (Some other Free Software Foundation software
is covered by the GNU Lesser General Public License instead.) You can apply
it to your programs, too.

When we speak of free software, we are referring to freedom, not price. Our
General Public Licenses are designed to make sure that you have the freedom
to distribute copies of free software (and charge for this service if you
wish), that you receive source code or can get it if you want it, that you
can change the software or use pieces of it in new free programs; and that
you know you can do these things.

To protect your rights, we need to make restrictions that forbid anyone to
deny you these rights or to ask you to surrender the rights. These restrictions
translate to certain responsibilities for you if you distribute copies of
the software, or if you modify it.

For example, if you distribute copies of such a program, whether gratis or
for a fee, you must give the recipients all the rights that you have. You
must make sure that they, too, receive or can get the source code. And you
must show them these terms so they know their rights.

We protect your rights with two steps: (1) copyright the software, and (2)
offer you this license which gives you legal permission to copy, distribute
and/or modify the software.

Also, for each author's protection and ours, we want to make certain that
everyone understands that there is no warranty for this free software. If
the software is modified by someone else and passed on, we want its recipients
to know that what they have is not the original, so that any problems introduced
by others will not reflect on the original authors' reputations.

Finally, any free program is threatened constantly by software patents. We
wish to avoid the danger that redistributors of a free program will individually
obtain patent licenses, in effect making the program proprietary. To prevent
this, we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.

The precise terms and conditions for copying, distribution and modification
follow.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License applies to any program or other work which contains a notice
placed by the copyright holder saying it may be distributed under the terms
of this General Public License. The "Program", below, refers to any such program
or work, and a "work based on the Program" means either the Program or any
derivative work under copyright law: that is to say, a work containing the
Program or a portion of it, either verbatim or with modifications and/or translated
into another language. (Hereinafter, translation is included without limitation
in the term "modification".) Each licensee is addressed as "you".

Activities other than copying, distribution and modification are not covered
by this License; they are outside its scope. The act of running the Program
is not restricted, and the output from the Program is covered only if its
contents constitute a work based on the Program (independent of having been
made by running the Program). Whether that is true depends on what the Program
does.

1. You may copy and distribute verbatim copies of the Program's source code
as you receive it, in any medium, provided that you conspicuously and appropriately
publish on each copy an appropriate copyright notice and disclaimer of warranty;
keep intact all the notices that refer to this License and to the absence
of any warranty; and give any other recipients of the Program a copy of this
License along with the Program.

You may charge a fee for the physical act of transferring a copy, and you
may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Program or any portion of it,
thus forming a work based on the Program, and copy and distribute such modifications
or work under the terms of Section 1 above, provided that you also meet all
of these conditions:

a) You must cause the modified files to carry prominent notices stating that
you changed the files and the date of any change.

b) You must cause any work that you distribute or publish, that in whole or
in part contains or is derived from the Program or any part thereof, to be
licensed as a whole at no charge to all third parties under the terms of this
License.

c) If the modified program normally reads commands interactively when run,
you must cause it, when started running for such interactive use in the most
ordinary way, to print or display an announcement including an appropriate
copyright notice and a notice that there is no warranty (or else, saying that
you provide a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this License.
(Exception: if the Program itself is interactive but does not normally print
such an announcement, your work based on the Program is not required to print
an announcement.)

These requirements apply to the modified work as a whole. If identifiable
sections of that work are not derived from the Program, and can be reasonably
considered independent and separate works in themselves, then this License,
and its terms, do not apply to those sections when you distribute them as
separate works. But when you distribute the same sections as part of a whole
which is a work based on the Program, the distribution of the whole must be
on the terms of this License, whose permissions for other licensees extend
to the entire whole, and thus to each and every part regardless of who wrote
it.

Thus, it is not the intent of this section to claim rights or contest your
rights to work written entirely by you; rather, the intent is to exercise
the right to control the distribution of derivative or collective works based
on the Program.

In addition, mere aggregation of another work not based on the Program with
the Program (or with a work based on the Program) on a volume of a storage
or distribution medium does not bring the other work under the scope of this
License.

3. You may copy and distribute the Program (or a work based on it, under Section
2) in object code or executable form under the terms of Sections 1 and 2 above
provided that you also do one of the following:

a) Accompany it with the complete corresponding machine-readable source code,
which must be distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,

b) Accompany it with a written offer, valid for at least three years, to give
any third party, for a charge no more than your cost of physically performing
source distribution, a complete machine-readable copy of the corresponding
source code, to be distributed under the terms of Sections 1 and 2 above on
a medium customarily used for software interchange; or,

c) Accompany it with the information you received as to the offer to distribute
corresponding source code. (This alternative is allowed only for noncommercial
distribution and only if you received the program in object code or executable
form with such an offer, in accord with Subsection b above.)

The source code for a work means the preferred form of the work for making
modifications to it. For an executable work, complete source code means all
the source code for all modules it contains, plus any associated interface
definition files, plus the scripts used to control compilation and installation
of the executable. However, as a special exception, the source code distributed
need not include anything that is normally distributed (in either source or
binary form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component itself
accompanies the executable.

If distribution of executable or object code is made by offering access to
copy from a designated place, then offering equivalent access to copy the
source code from the same place counts as distribution of the source code,
even though third parties are not compelled to copy the source along with
the object code.

4. You may not copy, modify, sublicense, or distribute the Program except
as expressly provided under this License. Any attempt otherwise to copy, modify,
sublicense or distribute the Program is void, and will automatically terminate
your rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses terminated
so long as such parties remain in full compliance.

5. You are not required to accept this License, since you have not signed
it. However, nothing else grants you permission to modify or distribute the
Program or its derivative works. These actions are prohibited by law if you
do not accept this License. Therefore, by modifying or distributing the Program
(or any work based on the Program), you indicate your acceptance of this License
to do so, and all its terms and conditions for copying, distributing or modifying
the Program or works based on it.

6. Each time you redistribute the Program (or any work based on the Program),
the recipient automatically receives a license from the original licensor
to copy, distribute or modify the Program subject to these terms and conditions.
You may not impose any further restrictions on the recipients' exercise of
the rights granted herein. You are not responsible for enforcing compliance
by third parties to this License.

7. If, as a consequence of a court judgment or allegation of patent infringement
or for any other reason (not limited to patent issues), conditions are imposed
on you (whether by court order, agreement or otherwise) that contradict the
conditions of this License, they do not excuse you from the conditions of
this License. If you cannot distribute so as to satisfy simultaneously your
obligations under this License and any other pertinent obligations, then as
a consequence you may not distribute the Program at all. For example, if a
patent license would not permit royalty-free redistribution of the Program
by all those who receive copies directly or indirectly through you, then the
only way you could satisfy both it and this License would be to refrain entirely
from distribution of the Program.

If any portion of this section is held invalid or unenforceable under any
particular circumstance, the balance of the section is intended to apply and
the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents
or other property right claims or to contest validity of any such claims;
this section has the sole purpose of protecting the integrity of the free
software distribution system, which is implemented by public license practices.
Many people have made generous contributions to the wide range of software
distributed through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing to
distribute software through any other system and a licensee cannot impose
that choice.

This section is intended to make thoroughly clear what is believed to be a
consequence of the rest of this License.

8. If the distribution and/or use of the Program is restricted in certain
countries either by patents or by copyrighted interfaces, the original copyright
holder who places the Program under this License may add an explicit geographical
distribution limitation excluding those countries, so that distribution is
permitted only in or among countries not thus excluded. In such case, this
License incorporates the limitation as if written in the body of this License.

9. The Free Software Foundation may publish revised and/or new versions of
the General Public License from time to time. Such new versions will be similar
in spirit to the present version, but may differ in detail to address new
problems or concerns.

Each version is given a distinguishing version number. If the Program specifies
a version number of this License which applies to it and "any later version",
you have the option of following the terms and conditions either of that version
or of any later version published by the Free Software Foundation. If the
Program does not specify a version number of this License, you may choose
any version ever published by the Free Software Foundation.

10. If you wish to incorporate parts of the Program into other free programs
whose distribution conditions are different, write to the author to ask for
permission. For software which is copyrighted by the Free Software Foundation,
write to the Free Software Foundation; we sometimes make exceptions for this.
Our decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing and reuse
of software generally.

   NO WARRANTY

11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS

How to Apply These Terms to Your New Programs

If you develop a new program, and you want it to be of the greatest possible
use to the public, the best way to achieve this is to make it free software
which everyone can redistribute and change under these terms.

To do so, attach the following notices to the program. It is safest to attach
them to the start of each source file to most effectively convey the exclusion
of warranty; and each file should have at least the "copyright" line and a
pointer to where the full notice is found.

<one line to give the program's name and an idea of what it does.>

Copyright (C) <yyyy> <name of author>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
Street, Fifth Floor, Boston, MA 02110-1301, USA.

Also add information on how to contact you by electronic and paper mail.

If the program is interactive, make it output a short notice like this when
it starts in an interactive mode:

Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
and you are welcome to redistribute it under certain conditions; type `show
c' for details.

The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may be
called something other than `show w' and `show c'; they could even be mouse-clicks
or menu items--whatever suits your program.

You should also get your employer (if you work as a programmer) or your school,
if any, to sign a "copyright disclaimer" for the program, if necessary. Here
is a sample; alter the names:

Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
(which makes passes at compilers) written by James Hacker.

<signature of Ty Coon>, 1 April 1989 Ty Coon, President of Vice This General
Public License does not permit incorporating your program into proprietary
programs. If your program is a subroutine library, you may consider it more
useful to permit linking proprietary applications with the library. If this
is what you want to do, use the GNU Lesser General Public License instead
of this License.


================================================
FILE: LICENSES/MIT.txt
================================================
MIT License Copyright (c) <year> <copyright holders>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: README
================================================
KDiff3-Readme
=============

Author: Joachim Eibl  (joachim.eibl at gmx.de)
Port to KF5/Qt5 by Michael Reeves (reeves.87@gmail.com)
KDiff3-Version: 1.12

Now requires Qt 5.12 or later and KF5 5.70+. Legacy 0.9.98 and earlier builds are not supported.
MacOS X build is 64-bit only unfortunately I can't test build locally. The Konqueror specific plug-in
is not ported and no longer maintained. This plug-in would only apply to KDE before 4.6. As of 1/13/17
cmake 3.1+ is the targeted cmake version.

cmake is now the only build system supported. KF5/Qt5 was big jump. A lot changed besides just the API.
I am not against a Qt5-only build variant but see no reason to maintain two separate build systems.
At present KF5 is my focus.

Known Issues:
*Binary comparison has been temporarily disabled due to stability issues.
*Network comparison operation via non file urls may fail for some configurations. This is under investigation.

The current repository is at https://invent.kde.org/sdk/kdiff3

Binaries can be downloaded at https://download.kde.org/stable/kdiff3/?C=M;O=D

Bugs can be reported at https://bugs.kde.org

The original pre KF5/Qt5 Readme follows old build instructions have been removed to avoid confusion:


Copyright: (C) 2002-2014 by Joachim Eibl

KDiff3 runs best on KDE but can be built without it, depending only on Qt-libs.
These are available for Un*x, Windows, Mac.
Thus there are many setup possibilities to consider.

Supported Qt-versions: 4.8, 5.2 or higher.
Supported KDE-version: 4, 5
(For KDE3/Qt3 use KDiff3-0.9.92 or older.)

Contents
--------

- Introduction
- License
- Additional hints


Introduction
------------

KDiff3 is a program that
- compares and merges two or three input files or directories,
- shows the differences line by line and character by character (!),
- provides an automatic merge-facility and
- an integrated editor for comfortable solving of merge-conflicts
- has support for KDE-KIO (ftp, sftp, http, fish, smb),
- has an intuitive graphical user interface,
- provides a context menu for KDE-Dolphin and Windows-Explorer,
- supports 64 bit systems. (Some build issues are discussed in here.)
- Support for many encodings and Unicode.

Do you want help translating? Read the instructions on https://l10n.kde.org/ !


License
-------

    GNU GENERAL PUBLIC LICENSE, Version 2, June 1991
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307
    USA

    For details see file "COPYING".


------------------------------------------------------------------------

Additional hints
----------------

   Start from commandline:
   - Comparing 2 files:     kdiff3 file1 file2
   - Merging 2 files:       kdiff3 file1 file2 -o outputfile
   - Comparing 3 files:     kdiff3 file1 file2 file3
   - Merging 3 files:       kdiff3 file1 file2 file3 -o outputfile
        Note that file1 will be treated as base of file2 and file3.

   If all files have the same name but are in different directories, you can
   reduce typework by specifying the filename only for the first file. E.g.:
   - Comparing 3 files:     kdiff3 dir1/filename dir2 dir3
   (This also works in the open-dialog.)

   If you start without arguments, then a dialog will appear where you can
   select your files via a filebrowser.

   For more documentation, see the help-menu or the subdirectory doc.

   Have fun!


================================================
FILE: UBSan.supp
================================================
#beyond my control KF is being flagged.
enum:KStandardAction::*


================================================
FILE: diff_ext_for_kdiff3/.krazy
================================================
EXCLUDE system


================================================
FILE: diff_ext_for_kdiff3/CMakeLists.txt
================================================
#  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
#  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
#  SPDX-License-Identifier: BSD-2-Clause

# This does not work for our shell extension.
remove_definitions(-DQT_USE_QSTRINGBUILDER)

set(kdiff3ext_SRCS
    class_factory.cpp
    diff_ext.cpp
    server.cpp
)

set(kdiff3ext_RCS
    diff_ext_for_kdiff3.rc
)

add_library(kdiff3ext MODULE ${kdiff3ext_SRCS} ${kdiff3ext_RCS})

target_link_libraries(kdiff3ext KF${KF_MAJOR_VERSION}::I18n uuid ole32)
target_compile_definitions(kdiff3ext PRIVATE -DTRANSLATION_DOMAIN=\"kdiff3\" -DUNICODE=1 -Dkdiff3ext)
# Work around buggy windows sdk headers that prevent certain symbols from being exported the normal way
# even though they are required exports for shell extensions.
#
# This works here because we actually only need four "C" style symbols exported.
# C++ symbols are not properly supported by this mechanism
set_target_properties(kdiff3ext PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)


# If we don't do this the nsi packer won't pickup the shell extension library.
install(TARGETS kdiff3ext DESTINATION  ${KDE_INSTALL_PLUGINDIR} )


================================================
FILE: diff_ext_for_kdiff3/LICENSE
================================================
Diff-Ext: Copyright (c) 2003-2006, Sergey Zorin
          All rights reserved.

Redistribution and use in source and binary forms, with or without 
modification, are permitted provided that the following conditions
are met:
   1. Redistributions  of  source  code   must  retain  the  above 
      copyright notice,  this list of conditions and the following
      disclaimer.
   2. Redistributions in binary  form  must  reproduce  the  above
      copyright notice,  this list of conditions and the following 
      disclaimer  in  the  documentation  and/or  other  materials 
      provided with the distribution.

THIS SOFTWARE  IS  PROVIDED  BY  THE  COPYRIGHT  HOLDERS  AND  CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT LIMITED
TO, THE IMPLIED WARRANTIES  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE  ARE  DISCLAIMED.  IN  NO  EVENT  SHALL  THE  COPYRIGHT   OWNER  OR
CONTRIBUTORS  BE  LIABLE  FOR  ANY DIRECT,  INDIRECT, INCIDENTAL,  SPECIAL,
EXEMPLARY,  OR  CONSEQUENTIAL  DAMAGES  (INCLUDING,  BUT  NOT  LIMITED  TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION)  HOWEVER CAUSED AND ON ANY THEORY  OF  LIABILITY,
WHETHER IN CONTRACT,  STRICT LIABILITY,  OR  TORT  (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING  IN  ANY WAY OUT OF THE USE  OF THIS  SOFTWARE,  EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


================================================
FILE: diff_ext_for_kdiff3/Messages.sh
================================================
#! /usr/bin/env bash
$XGETTEXT *.cpp -o $podir/diff_ext.pot


================================================
FILE: diff_ext_for_kdiff3/README
================================================
Diff-Ext for KDiff3 - Readme
============================

Authors: 
   Sergey Zorin (Author of diff-ext, see http://diff-ext.sourceforge.net)
   Joachim Eibl (KDiff3-specific extensions and integration.)


Copyright (c):
Original Diff-Ext:     Copyright (c) 2003-2006, Sergey Zorin, All rights reserved.
Extensions for KDiff3: Copyright (c) 2006, Joachim Eibl


License: See file LICENSE in this subdirectory


Building:
Via MinGW-compiler package (http://www.mingw.org/): Compile via gnu-make (Makefile)
Via MSVC2005: Use vcproj-file.


Installation:
For basic testing you can run "regsvr32 diff_ext_for_kdiff3.dll".
To use all features the installation that comes with the KDiff3-setup*.exe is recommended.


Translation:
If you would like help translating diff-ext-for-kdiff3 please copy the diff_ext.pot to
diff_ext_xx.po (where xx is the language-shortcut).
Then edit that file and fill in the msgstr-string for each respective msgid-string.
Then place the for in the KDiff3-translations subdirectory.
Use the language selection within KDiff3 to switch the language or set the language shortcut
in the registry HKEY_CURRENT_USER\Software\KDiff3\diff-ext: Language
If everything works, please send me the created file.


Have fun,
Joachim



================================================
FILE: diff_ext_for_kdiff3/class_factory.cpp
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/
#include "class_factory.h"
#include "diff_ext.h"
#include "server.h"

CLASS_FACTORY::CLASS_FACTORY() {
  _ref_count = 0L;

  SERVER::instance()->lock();
}

CLASS_FACTORY::~CLASS_FACTORY() {
  SERVER::instance()->release();
}

STDMETHODIMP
CLASS_FACTORY::QueryInterface(REFIID riid, void** ppv) {
  HRESULT ret = E_NOINTERFACE;
  *ppv = nullptr;

  if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) {
    *ppv = static_cast<CLASS_FACTORY*>(this);

    AddRef();

    ret = NOERROR;
  }

  return ret;
}

STDMETHODIMP_(ULONG)
CLASS_FACTORY::AddRef() {
  return InterlockedIncrement((LPLONG)&_ref_count);
}

STDMETHODIMP_(ULONG)
CLASS_FACTORY::Release() {
  ULONG ret = 0L;

  if(InterlockedDecrement((LPLONG)&_ref_count) != 0)
    ret = _ref_count;
  else
    delete this;

  return ret;
}

STDMETHODIMP
CLASS_FACTORY::CreateInstance(IUnknown* outer, REFIID refiid, void** obj) {
  HRESULT ret = CLASS_E_NOAGGREGATION;
  *obj = nullptr;

  // Shell extensions typically don't support aggregation (inheritance)
  if(outer == nullptr) {
    DIFF_EXT* ext = new DIFF_EXT();

    if(ext == nullptr)
      ret = E_OUTOFMEMORY;
    else
      ret = ext->QueryInterface(refiid, obj);
  }

  return ret;
}

STDMETHODIMP
CLASS_FACTORY::LockServer(BOOL) {
  return NOERROR;
}


================================================
FILE: diff_ext_for_kdiff3/class_factory.h
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/

#ifndef class_factory_h
#define class_factory_h

#include <shlobj.h>
#include <shlguid.h>

class CLASS_FACTORY : public IClassFactory {
  public:
    CLASS_FACTORY();
    virtual ~CLASS_FACTORY();

    //IUnknown members
    STDMETHODIMP QueryInterface(REFIID, void**);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    //ICLASS_FACTORY members
    STDMETHODIMP CreateInstance(IUnknown*, REFIID, void**);
    STDMETHODIMP LockServer(BOOL);

  private:
    ULONG _ref_count;
};

#endif //class_factory_h


================================================
FILE: diff_ext_for_kdiff3/diff_ext.cpp
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/

#include "diff_ext.h"

#include <KLocalizedString>

#include <QString>

#include <assert.h>
#include <stdio.h>
#include <tchar.h>

#include <map>
#include <vector>

DIFF_EXT::DIFF_EXT():
    m_nrOfSelectedFiles(0), _ref_count(0L),
    m_recentFiles(SERVER::instance()->recent_files())
{
    LOG();
    _resource = SERVER::instance()->handle();

    SERVER::instance()->lock();
}

DIFF_EXT::~DIFF_EXT()
{
    LOG();
    if(_resource != SERVER::instance()->handle())
    {
        FreeLibrary(_resource);
    }

    SERVER::instance()->release();
}

STDMETHODIMP
DIFF_EXT::QueryInterface(REFIID refiid, void** ppv)
{
    HRESULT ret = E_NOINTERFACE;
    *ppv = nullptr;

    if(IsEqualIID(refiid, IID_IShellExtInit) || IsEqualIID(refiid, IID_IUnknown))
    {
        *ppv = static_cast<IShellExtInit*>(this);
    }
    else if(IsEqualIID(refiid, IID_IContextMenu))
    {
        *ppv = static_cast<IContextMenu*>(this);
    }

    if(*ppv != nullptr)
    {
        AddRef();

        ret = NOERROR;
    }

    return ret;
}

STDMETHODIMP_(ULONG)
DIFF_EXT::AddRef()
{
    return InterlockedIncrement((LPLONG)&_ref_count);
}

STDMETHODIMP_(ULONG)
DIFF_EXT::Release()
{
    ULONG ret = 0L;

    if(InterlockedDecrement((LPLONG)&_ref_count) != 0)
    {
        ret = _ref_count;
    }
    else
    {
        delete this;
    }

    return ret;
}

STDMETHODIMP
DIFF_EXT::Initialize(LPCITEMIDLIST /*folder not used*/, IDataObject* data, HKEY /*key not used*/)
{
    LOG();

    FORMATETC format = {CF_HDROP, nullptr, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
    STGMEDIUM medium;
    medium.tymed = TYMED_HGLOBAL;
    HRESULT ret = E_INVALIDARG;

    if(data->GetData(&format, &medium) == S_OK)
    {
        HDROP drop = (HDROP)medium.hGlobal;
        m_nrOfSelectedFiles = DragQueryFile(drop, 0xFFFFFFFF, nullptr, 0);

        TCHAR tmp[MAX_PATH];

        if(m_nrOfSelectedFiles >= 1 && m_nrOfSelectedFiles <= 3)
        {
            DragQueryFile(drop, 0, tmp, MAX_PATH);
            _file_name1 = tmp;

            if(m_nrOfSelectedFiles >= 2)
            {
                DragQueryFile(drop, 1, tmp, MAX_PATH);
                _file_name2 = tmp;
            }

            if(m_nrOfSelectedFiles == 3)
            {
                DragQueryFile(drop, 2, tmp, MAX_PATH);
                _file_name3 = tmp;
            }

            ret = S_OK;
        }
    }
    else
    {
        SYSERRORLOG(TEXT("GetData"));
    }

    return ret;
}

static int insertMenuItemHelper(HMENU menu, UINT id, UINT position, const tstring& text,
                                UINT fState = MFS_ENABLED, HMENU hSubMenu = nullptr)
{
    MENUITEMINFO item_info;
    ZeroMemory(&item_info, sizeof(item_info));
    item_info.cbSize = sizeof(MENUITEMINFO);
    item_info.wID = id;
    if(text.empty())
    { // Separator
        item_info.fMask = MIIM_TYPE;
        item_info.fType = MFT_SEPARATOR;
        item_info.dwTypeData = nullptr;
    }
    else
    {
        item_info.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE | (hSubMenu != nullptr ? MIIM_SUBMENU : 0);
        item_info.fType = MFT_STRING;
        item_info.fState = fState;
        item_info.dwTypeData = (LPTSTR)text.c_str();
        item_info.hSubMenu = hSubMenu;
    }
    if(0 == InsertMenuItem(menu, position, TRUE, &item_info))
        SYSERRORLOG(TEXT("InsertMenuItem"));
    return id;
}

STDMETHODIMP
DIFF_EXT::QueryContextMenu(HMENU menu, UINT position, UINT first_cmd, UINT /*last_cmd not used*/, UINT flags)
{
    LOG();

    SERVER::instance()->recent_files(); // updates recent files list (reads from registry)

    m_id_Diff = UINT(-1);
    m_id_DiffWith = UINT(-1);
    m_id_DiffLater = UINT(-1);
    m_id_MergeWith = UINT(-1);
    m_id_Merge3 = UINT(-1);
    m_id_Diff3 = UINT(-1);
    m_id_DiffWith_Base = UINT(-1);
    m_id_ClearList = UINT(-1);
    m_id_About = UINT(-1);

    HRESULT ret = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, 0);

    if(!(flags & CMF_DEFAULTONLY))
    {
        /* Menu structure:
           KDiff3 -> (1 File selected):  Save 'selection' for later comparison (push onto history stack)
                                         Compare 'selection' with first file on history stack.
                                         Compare 'selection' with -> choice from history stack
                                         Merge 'selection' with first file on history stack.
                                         Merge 'selection' with last two files on history stack.
                     (2 Files selected): Compare 's1' with 's2'
                                         Merge 's1' with 's2'
                     (3 Files selected): Compare 's1', 's2' and 's3'
        */
        HMENU subMenu = CreateMenu();

        UINT id = first_cmd;
        m_id_FirstCmd = first_cmd;

        insertMenuItemHelper(menu, id++, position++, TEXT("")); // begin separator

        tstring menuString;
        UINT pos2 = 0;
        if(m_nrOfSelectedFiles == 1)
        {
            size_t nrOfRecentFiles = m_recentFiles.size();
            tstring menuStringCompare;
            tstring menuStringMerge;
            tstring firstFileName;
            if(nrOfRecentFiles >= 1)
            {
                firstFileName = TEXT("'") + cut_to_length(m_recentFiles.front()) + TEXT("'");
            }

            menuStringCompare = fromQString(i18nc("Contexualmenu option", "Compare with %1", toQString(firstFileName)));
            menuStringMerge = fromQString(i18nc("Contexualmenu option", "Merge with %1", toQString(firstFileName)));

            m_id_DiffWith = insertMenuItemHelper(subMenu, id++, pos2++, menuStringCompare, nrOfRecentFiles >= 1 ? MFS_ENABLED : MFS_DISABLED);
            m_id_MergeWith = insertMenuItemHelper(subMenu, id++, pos2++, menuStringMerge, nrOfRecentFiles >= 1 ? MFS_ENABLED : MFS_DISABLED);

            m_id_Merge3 = insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "3-way merge with base")),
                                               nrOfRecentFiles >= 2 ? MFS_ENABLED : MFS_DISABLED);

            menuString = fromQString(i18nc("Contexualmenu option", "Save '%1' for later", toQString(_file_name1)));
            m_id_DiffLater = insertMenuItemHelper(subMenu, id++, pos2++, menuString);

            HMENU file_list = CreateMenu();
            std::list<tstring>::iterator i;
            m_id_DiffWith_Base = id;
            int n = 0;
            for(i = m_recentFiles.begin(); i != m_recentFiles.end(); ++i)
            {
                tstring s = cut_to_length(*i);
                insertMenuItemHelper(file_list, id++, n, s);
                ++n;
            }

            insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "Compare with ...")),
                                 nrOfRecentFiles > 0 ? MFS_ENABLED : MFS_DISABLED, file_list);

            m_id_ClearList = insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "Clear list")), nrOfRecentFiles >= 1 ? MFS_ENABLED : MFS_DISABLED);
        }
        else if(m_nrOfSelectedFiles == 2)
        {
            //= "Diff " + cut_to_length(_file_name1, 20)+" and "+cut_to_length(_file_name2, 20);
            m_id_Diff = insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "Compare")));
        }
        else if(m_nrOfSelectedFiles == 3)
        {
            m_id_Diff3 = insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "3 way comparison")));
        }
        else
        {
            // More than 3 files selected?
        }
        m_id_About = insertMenuItemHelper(subMenu, id++, pos2++, fromQString(i18nc("Contexualmenu option", "About Diff-Ext ...")));

        insertMenuItemHelper(menu, id++, position++, TEXT("KDiff3"), MFS_ENABLED, subMenu);

        insertMenuItemHelper(menu, id++, position++, TEXT("")); // final separator

        ret = MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_NULL, id - first_cmd);
    }

    return ret;
}

STDMETHODIMP
DIFF_EXT::InvokeCommand(LPCMINVOKECOMMANDINFO ici)
{
    HRESULT ret = NOERROR;

    _hwnd = ici->hwnd;

    if(HIWORD(ici->lpVerb) == 0)
    {
        UINT id = m_id_FirstCmd + LOWORD(ici->lpVerb);
        if(id == m_id_Diff)
        {
            LOG();
            diff(TEXT("\"") + _file_name1 + TEXT("\" \"") + _file_name2 + TEXT("\""));
        }
        else if(id == m_id_Diff3)
        {
            LOG();
            diff(TEXT("\"") + _file_name1 + TEXT("\" \"") + _file_name2 + TEXT("\" \"") + _file_name3 + TEXT("\""));
        }
        else if(id == m_id_Merge3)
        {
            LOG();
            std::list<tstring>::iterator iFrom = m_recentFiles.begin();
            std::list<tstring>::iterator iBase = iFrom;
            ++iBase;
            diff(TEXT("-m \"") + *iBase + TEXT("\" \"") + *iFrom + TEXT("\" \"") + _file_name1 + TEXT("\""));
        }
        else if(id == m_id_DiffWith)
        {
            LOG();
            diff_with(0, false);
        }
        else if(id == m_id_MergeWith)
        {
            LOG();
            diff_with(0, true);
        }
        else if(id == m_id_ClearList)
        {
            LOG();
            m_recentFiles.clear();
            SERVER::instance()->save_history();
        }
        else if(id == m_id_DiffLater)
        {
            MESSAGELOG(TEXT("Diff Later: ") + _file_name1);
            m_recentFiles.remove(_file_name1);
            m_recentFiles.push_front(_file_name1);
            SERVER::instance()->save_history();
        }
        else if(id >= m_id_DiffWith_Base && id < m_id_DiffWith_Base + m_recentFiles.size())
        {
            LOG();
            diff_with(id - m_id_DiffWith_Base, false);
        }
        else if(id == m_id_About)
        {
            LOG();

            MessageBox(_hwnd, (fromQString(i18n(u8"Diff-Ext Copyright ©2003-2006, Sergey Zorin. All rights reserved.\n") + i18n("This software is distributable under the BSD-2-Clause license.\n") + i18n(u8"Some extensions for KDiff3 ©2006-2013 by Joachim Eibl.\n") + i18n("Ported to Qt5/Kf5 by Michael Reeves\n") + i18n("Homepage for Diff-Ext: http://diff-ext.sourceforge.net\n"))).c_str(), fromQString(i18n("About Diff-Ext for KDiff3 (64 Bit)")).c_str(), MB_OK);
        }
        else
        {
            ret = E_INVALIDARG;
            TCHAR verb[80];
            _sntprintf(verb, 79, TEXT("Command id: %d"), LOWORD(ici->lpVerb));
            verb[79] = 0;
            ERRORLOG(verb);
        }
    }
    else
    {
        ret = E_INVALIDARG;
    }

    return ret;
}

STDMETHODIMP
DIFF_EXT::GetCommandString(UINT_PTR idCmd, UINT uFlags, UINT*, LPSTR pszName, UINT cchMax)
{
    HRESULT ret = NOERROR;

    if(uFlags == GCS_HELPTEXT)
    {
        QString helpString;
        if(idCmd == m_id_Diff)
        {
            helpString = i18nc("Contexualmenu option", "Compare selected files");
        }
        else if(idCmd == m_id_DiffWith)
        {
            if(!m_recentFiles.empty())
            {
                helpString = i18nc("Contexualmenu option", "Compare '%1' with '%2'", toQString(_file_name1), toQString(m_recentFiles.front()));
            }
        }
        else if(idCmd == m_id_DiffLater)
        {
            helpString = i18nc("Contexualmenu option", "Save '%1' for later operation", toQString(_file_name1));
        }
        else if((idCmd >= m_id_DiffWith_Base) && (idCmd < m_id_DiffWith_Base + m_recentFiles.size()))
        {
            if(!m_recentFiles.empty())
            {
                unsigned long long num = idCmd - m_id_DiffWith_Base;
                std::list<tstring>::iterator i = m_recentFiles.begin();
                for(unsigned long long j = 0; j < num && i != m_recentFiles.end(); j++)
                    i++;

                if(i != m_recentFiles.end())
                {
                    helpString = i18nc("Contexualmenu option", "Compare '%1' with '%2'", toQString(_file_name1), toQString(*i));
                }
            }
        }
        lstrcpyn((LPTSTR)pszName, fromQString(helpString).c_str(), cchMax);
    }
    else
    {
        ret = E_INVALIDARG;
    }

    return ret;
}

void DIFF_EXT::diff(const tstring& arguments)
{
    LOG();
    STARTUPINFO si;
    PROCESS_INFORMATION pi;
    bool bError = true;
    tstring command = SERVER::instance()->getRegistryKeyString(TEXT(""), TEXT("diffcommand"), true); //look in user registry first so it can be overridden
    if(command.empty()) command = SERVER::instance()->getRegistryKeyString(TEXT(""), TEXT("diffcommand"), false);
    tstring commandLine = TEXT("\"") + command + TEXT("\" ") + arguments;
    if(!command.empty())
    {
        ZeroMemory(&si, sizeof(si));
        si.cb = sizeof(si);
        if(CreateProcess(command.c_str(), (LPTSTR)commandLine.c_str(), nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi) == 0)
        {
            SYSERRORLOG(TEXT("CreateProcess") + command);
        }
        else
        {
            bError = false;
            CloseHandle(pi.hProcess);
            CloseHandle(pi.hThread);
        }
    }

    if(bError)
    {
        tstring message = fromQString(i18n("Could not start KDiff3. Please rerun KDiff3 installation."));
        message += TEXT("\n") + fromQString(i18n("Command")) + TEXT(": ") + command;
        message += TEXT("\n") + fromQString(i18n("CommandLine")) + TEXT(": ") + commandLine;
        MessageBox(_hwnd, message.c_str(), fromQString(i18n("Diff-Ext For KDiff3")).c_str(), MB_OK);
    }
}

void DIFF_EXT::diff_with(unsigned int num, bool bMerge)
{
    LOG();
    std::list<tstring>::iterator i = m_recentFiles.begin();
    for(unsigned int j = 0; j < num && i != m_recentFiles.end(); j++)
    {
        i++;
    }

    if(i != m_recentFiles.end())
        _file_name2 = *i;

    diff((bMerge ? TEXT("-m \"") : TEXT("\"")) + _file_name2 + TEXT("\" \"") + _file_name1 + TEXT("\""));
}

tstring
DIFF_EXT::cut_to_length(const tstring& in, size_t max_len)
{
    tstring ret;
    if(in.length() > max_len)
    {
        ret = in.substr(0, (max_len - 3) / 2);
        ret += TEXT("...");
        ret += in.substr(in.length() - (max_len - 3) / 2);
    }
    else
    {
        ret = in;
    }

    return ret;
}


================================================
FILE: diff_ext_for_kdiff3/diff_ext.h
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/


#ifndef diff_ext_h
#define diff_ext_h

//This option is not compatible with our shell extension.
#undef WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <windowsx.h>
#include <shlobj.h>

#include "server.h"


// this is the actual OLE Shell context menu handler
class DIFF_EXT : public IContextMenu, IShellExtInit {
  public:
    DIFF_EXT();
    virtual ~DIFF_EXT();

    //IUnknown members
    STDMETHODIMP QueryInterface(REFIID interface_id, void** result);
    STDMETHODIMP_(ULONG) AddRef();
    STDMETHODIMP_(ULONG) Release();

    //IShell members
    STDMETHODIMP QueryContextMenu(HMENU menu, UINT index, UINT cmd_first, UINT cmd_last, UINT flags);
    STDMETHODIMP InvokeCommand(LPCMINVOKECOMMANDINFO info);
    STDMETHODIMP GetCommandString(UINT_PTR cmd, UINT flags, UINT* reserved, LPSTR name, UINT name_length);

    //IShellExtInit methods
    STDMETHODIMP Initialize(LPCITEMIDLIST folder, IDataObject* subj, HKEY key);

  private:
    void diff( const tstring& arguments );
    void diff_with(unsigned int num, bool bMerge);
    tstring cut_to_length(const tstring&, size_t length = 64);

  private:
    UINT m_nrOfSelectedFiles;
    tstring _file_name1;
    tstring _file_name2;
    tstring _file_name3;
    HINSTANCE _resource;
    HWND _hwnd;

    ULONG  _ref_count;

    std::list< tstring >& m_recentFiles;
    UINT m_id_FirstCmd;
    UINT m_id_Diff;
    UINT m_id_DiffWith;
    UINT m_id_DiffLater;
    UINT m_id_MergeWith;
    UINT m_id_Merge3;
    UINT m_id_Diff3;
    UINT m_id_DiffWith_Base;
    UINT m_id_About;
    UINT m_id_ClearList;
};

#endif // __diff_ext_h__


================================================
FILE: diff_ext_for_kdiff3/diff_ext_for_kdiff3.def
================================================
LIBRARY	"kdiff3ext"
EXPORTS
    DllCanUnloadNow=DllCanUnloadNow@0
    DllGetClassObject=DllGetClassObject@12
    DllRegisterServer=DllRegisterServer@0
    DllUnregisterServer=DllUnregisterServer@0


================================================
FILE: diff_ext_for_kdiff3/diff_ext_for_kdiff3.rc
================================================
/*
 * Copyright (c) 2003-2006, Sergey Zorin. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:

 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include <windows.h>

LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

VS_VERSION_INFO VERSIONINFO
  FILEVERSION 1,6,1,145
  PRODUCTVERSION 1,6,1,145
  FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
  FILEFLAGS VS_FF_DEBUG
#else
  FILEFLAGS 0L
#endif
  FILEOS VOS_NT_WINDOWS32
  FILETYPE VFT_DLL
  FILESUBTYPE VFT_UNKNOWN
{
    BLOCK "StringFileInfo"
    {
        BLOCK "040904b0"
        {
            VALUE "Comments", ""
            VALUE "CompanyName", ""
            VALUE "FileDescription", "diff shell extension"
            VALUE "FileVersion", "Release 1.6.1"
            VALUE "InternalName", "diff shell extension"
            VALUE "LegalCopyright", "Copyright  2003-2005 Sergey Zorin"
            VALUE "LegalTrademarks", ""
            VALUE "OriginalFilename", "diff_ext.dll"
            VALUE "PrivateBuild", ""
            VALUE "ProductName", "Diff Context Menu Extension"
            VALUE "ProductVersion", "Release 1.6.1"
        }
    }
    BLOCK "VarFileInfo"
    {
        VALUE "Translation", 0x409, 1200
    }
}


================================================
FILE: diff_ext_for_kdiff3/diff_ext_for_kdiff3_msvc.def
================================================
LIBRARY	"kdiff3ext"
EXPORTS
    DllCanUnloadNow PRIVATE
    DllGetClassObject PRIVATE
    DllRegisterServer PRIVATE
    DllUnregisterServer PRIVATE


================================================
FILE: diff_ext_for_kdiff3/server.cpp
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/

#define _CRT_NON_CONFORMING_SWPRINTFS

#include "server.h"

#include <stdio.h>

#include <tchar.h>

#include <shlguid.h>
#include <olectl.h>
#include <objidl.h>

#include <objbase.h>
#include <initguid.h>

#include <KLocalizedString>

#include "class_factory.h"

#define DllExport   __declspec( dllexport )

// registry key util struct
struct REGSTRUCT {
  LPCTSTR subkey;
  LPCTSTR name;
  LPCTSTR value;
};

SERVER* SERVER::_instance = nullptr;
static HINSTANCE server_instance; // Handle to this DLL itself.

//DEFINE_GUID(CLSID_DIFF_EXT, 0xA0482097, 0xC69D, 0x4DEC, 0x8A, 0xB6, 0xD3, 0xA2, 0x59, 0xAC, 0xC1, 0x51);
// New class id for DIFF_EXT for KDiff3
#ifdef Q_OS_WIN64
// {34471FFB-4002-438b-8952-E4588D0C0FE9}
DEFINE_GUID( CLSID_DIFF_EXT, 0x34471FFB, 0x4002, 0x438b, 0x89, 0x52, 0xE4, 0x58, 0x8D, 0x0C, 0x0F, 0xE9 );
#else
#error unsupported configuration
#endif

tstring SERVER::getRegistryKeyString( const tstring& subKey, const tstring& value, bool isUserKey /*= true*/ )
{
   tstring keyName = m_registryBaseName;
   if (!subKey.empty())
      keyName += TEXT("\\")+subKey;

   HKEY key;
   HKEY baseKey = isUserKey ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE;
   tstring result;
   for(;;)
   {
      if( RegOpenKeyEx( baseKey, keyName.c_str(), 0, KEY_READ | KEY_WOW64_64KEY, &key ) == ERROR_SUCCESS )
      {
         DWORD neededSizeInBytes = 0;
         if (RegQueryValueEx(key, value.c_str(), nullptr, nullptr, nullptr, &neededSizeInBytes) == ERROR_SUCCESS)
         {
            DWORD length = neededSizeInBytes / sizeof( TCHAR );
            result.resize( length );
            if ( RegQueryValueEx( key, value.c_str(), nullptr, nullptr, (LPBYTE)&result[0], &neededSizeInBytes ) == ERROR_SUCCESS)
            {
               //Everything is ok, but we want to cut off the terminating 0-character
               result.resize( length - 1 );
               RegCloseKey(key);
               return result;
            }
            else
            {
               result.resize(0);
            }
         }

         RegCloseKey(key);
      }
      if (baseKey==HKEY_LOCAL_MACHINE)
         break;
      baseKey = HKEY_LOCAL_MACHINE;
   }

   // Error
   {
      LPTSTR message;
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
         GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &message, 0, nullptr);
      ERRORLOG( (tstring(TEXT("RegOpenKeyEx: ")+keyName+TEXT("->")+value) + TEXT(": ")) + message );                                        \
      LocalFree(message);
   }
   return result;
}


STDAPI
DllCanUnloadNow(void) {
  HRESULT ret = S_FALSE;

  if(SERVER::instance()->reference_count() == 0) {
    ret = S_OK;
  }

  return ret;
}

extern "C" int APIENTRY
DllMain(HINSTANCE instance, DWORD reason, LPVOID /* reserved */) {
//  char str[1024];
//  char* reason_string[] = {"DLL_PROCESS_DETACH", "DLL_PROCESS_ATTACH", "DLL_THREAD_ATTACH", "DLL_THREAD_DETACH"};
//  sprintf(str, "instance: %x; reason: '%s'", instance, reason_string[reason]);
//  MessageBox(0, str, TEXT("Info"), MB_OK);
  switch (reason) {
    case DLL_PROCESS_ATTACH:
      server_instance = instance;
      SERVER::instance()->save_history();
      MESSAGELOG(TEXT("DLL_PROCESS_ATTACH"));
      break;

    case DLL_PROCESS_DETACH:
      MESSAGELOG(TEXT("DLL_PROCESS_DETACH"));
      SERVER::instance()->save_history();
      break;
  }

  return 1;
}

STDAPI
DllGetClassObject(REFCLSID rclsid, REFIID riid, void** class_object) {
  HRESULT ret = CLASS_E_CLASSNOTAVAILABLE;
  *class_object = nullptr;

  if (IsEqualIID(rclsid, CLSID_DIFF_EXT)) {
    CLASS_FACTORY* pcf = new CLASS_FACTORY();

    ret = pcf->QueryInterface(riid, class_object);
  }

  return ret;
}

/*extern "C" HRESULT STDAPICALLTYPE*/  STDAPI
DllRegisterServer() {
  return SERVER::instance()->do_register();
}

STDAPI
DllUnregisterServer() {
  return SERVER::instance()->do_unregister();
}

SERVER* SERVER::instance()
{
   if(_instance == nullptr)
   {
      _instance = new SERVER();
      _instance->initLogging();
      MESSAGELOG(TEXT("New Server instance"));
   }

   return _instance;
}

SERVER::SERVER()  : _reference_count(0)
{
   m_registryBaseName = TEXT("Software\\KDE e.V.\\KDiff3\\diff-ext");
   m_pRecentFiles = nullptr;
   m_pLogFile = nullptr;
}

void SERVER::initLogging()
{
   tstring logFileName = getRegistryKeyString( TEXT(""), TEXT("LogFile") );
   if ( !logFileName.empty() )
   {
      m_pLogFile = _tfopen( logFileName.c_str(), TEXT("a+, ccs=UTF-8") );
      if (m_pLogFile)
      {
         _ftprintf( m_pLogFile, TEXT("\nSERVER::SERVER()\n") );
      }
   }
}

SERVER::~SERVER()
{
   if ( m_pLogFile )
   {
      _ftprintf( m_pLogFile, TEXT("SERVER::~SERVER()\n\n") );
      fclose( m_pLogFile );
   }

   delete m_pRecentFiles;
}

HINSTANCE
SERVER::handle() const
{
   return server_instance;
}

void
SERVER::lock() {
  InterlockedIncrement(&_reference_count);
}

void
SERVER::release() {
  InterlockedDecrement(&_reference_count);

  //if(InterlockedDecrement((LPLONG)&_reference_count) == 0)
  //   delete this;
}

void SERVER::logMessage( const char* function, const char* file, int line, const tstring& msg )
{
   SERVER* pServer = SERVER::instance();
   if ( pServer && pServer->m_pLogFile )
   {
      SYSTEMTIME st;
      GetSystemTime( &st );
      _ftprintf( pServer->m_pLogFile, TEXT("%04d/%02d/%02d %02d:%02d:%02d ")
         TEXT("%S (%S:%d) %s\n"), // integrate char-string into wchar_t string
         st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, function, file, line, msg.c_str() );
      fflush(pServer->m_pLogFile);
   }
}

std::list<tstring>&
SERVER::recent_files()
{
   LOG();
   if ( m_pRecentFiles==nullptr )
   {
      m_pRecentFiles = new std::list<tstring>;
   }
   else
   {
      m_pRecentFiles->clear();
   }
   MESSAGELOG(TEXT("Reading history from registry..."));
   for( int i=0; i<32; ++i )  // Max history size
   {
      TCHAR numAsString[10];
      _sntprintf( numAsString, 10, TEXT("%d"), i );
      tstring historyItem = getRegistryKeyString( TEXT("history"), numAsString );
      if ( ! historyItem.empty() )
         m_pRecentFiles->push_back( historyItem );
   }
   return *m_pRecentFiles;
}

void
SERVER::save_history() const
{
   if( m_pRecentFiles )
   {
      HKEY key;
      if( RegCreateKeyEx(HKEY_CURRENT_USER, (m_registryBaseName + TEXT("\\history")).c_str(), 0, nullptr,
                         REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_WOW64_64KEY, nullptr, &key, nullptr) == ERROR_SUCCESS )
      {
         LOG();
         //DWORD len = MAX_PATH;
         int n = 0;

         std::list<tstring>::const_iterator i;

         for(i = m_pRecentFiles->begin(); i!=m_pRecentFiles->end(); ++i, ++n )
         {
            tstring str = *i;
            TCHAR numAsString[10];
            _sntprintf( numAsString, 10, TEXT("%d"), n );
            if(RegSetValueEx(key, numAsString, 0, REG_SZ, (const BYTE*)str.c_str(), (DWORD)(str.size()+1)*sizeof(TCHAR) ) != ERROR_SUCCESS)
            {
               LPTSTR message;
               FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,
                  GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                  (LPTSTR) &message, 0, nullptr);
               MessageBox(nullptr, message, TEXT("KDiff3-diff-ext: Save history failed"), MB_OK | MB_ICONINFORMATION);
               LocalFree(message);
            }
         }
         for(; n<32; ++n )
         {
            TCHAR numAsString[10];
            _sntprintf( numAsString, 10, TEXT("%d"), n );
            RegDeleteValue(key, numAsString );
         }

         RegCloseKey(key);
      }
      else
      {
         SYSERRORLOG(TEXT("RegOpenKeyEx"));
      }
   }
}

HRESULT
SERVER::do_register() {
   LOG();
  TCHAR   class_id[MAX_PATH];
  LPWSTR  tmp_guid;
  HRESULT ret = SELFREG_E_CLASS;

  if (StringFromIID(CLSID_DIFF_EXT, &tmp_guid) == S_OK) {
    _tcsncpy(class_id, tmp_guid, MAX_PATH);

    CoTaskMemFree((void*)tmp_guid);

    TCHAR    subkey[MAX_PATH];
    TCHAR    server_path[MAX_PATH];
    HKEY     key;
    LRESULT  result = NOERROR;
    DWORD    dwDisp;

    GetModuleFileName(SERVER::instance()->handle(), server_path, MAX_PATH);

    REGSTRUCT entry[] = {
      {TEXT("Software\\Classes\\CLSID\\%s"), nullptr, TEXT("kdiff3ext")},
      {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), nullptr, TEXT("%s")},
      {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), TEXT("ThreadingModel"), TEXT("Apartment")}
    };

    for(unsigned int i = 0; (i < sizeof(entry)/sizeof(entry[0])) && (result == NOERROR); i++) {
      _sntprintf(subkey, MAX_PATH, entry[i].subkey, class_id);
      result = RegCreateKeyEx(HKEY_CURRENT_USER, subkey, 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &key, &dwDisp);

      if(result == NOERROR) {
        TCHAR szData[MAX_PATH];

        _sntprintf(szData, MAX_PATH, entry[i].value, server_path);
        szData[MAX_PATH-1]=0;

        result = RegSetValueEx(key, entry[i].name, 0, REG_SZ, (LPBYTE)szData, DWORD(_tcslen(szData)*sizeof(TCHAR)));
      }

      RegCloseKey(key);
    }

    if(result == NOERROR) {
      result = RegCreateKeyEx(HKEY_CURRENT_USER, TEXT("Software\\Classes\\*\\shellex\\ContextMenuHandlers\\kdiff3ext"), 0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &key, &dwDisp);

      if(result == NOERROR) {

        result = RegSetValueEx(key, nullptr, 0, REG_SZ, (LPBYTE)class_id, DWORD(_tcslen(class_id)*sizeof(TCHAR)));

        RegCloseKey(key);

        // NT needs to have shell extensions "approved".
         result = RegCreateKeyEx(HKEY_CURRENT_USER,
            TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"),
            0, nullptr, REG_OPTION_NON_VOLATILE, KEY_WRITE, nullptr, &key, &dwDisp);

         if(result == NOERROR) {
         TCHAR szData[MAX_PATH];

         lstrcpy(szData, TEXT("diff-ext"));

         result = RegSetValueEx(key, class_id, 0, REG_SZ, (LPBYTE)szData, DWORD(_tcslen(szData)*sizeof(TCHAR)));

         RegCloseKey(key);

         ret = S_OK;
         } else if (result == ERROR_ACCESS_DENIED) {
      TCHAR msg[] = TEXT("Warning! You have unsufficient rights to write to a specific registry key.\n")
         TEXT("The application may work anyway, but it is advised to register this module ")
         TEXT("again while having administrator rights.");

	    MessageBox(nullptr, msg, TEXT("Warning"), MB_ICONEXCLAMATION);

	    ret = S_OK;
          }
      }
    }
  }

  return ret;
}

HRESULT
SERVER::do_unregister() {
   LOG();
  TCHAR class_id[MAX_PATH];
  LPWSTR tmp_guid;
  HRESULT ret = SELFREG_E_CLASS;

  if (StringFromIID(CLSID_DIFF_EXT, &tmp_guid) == S_OK) {
    _tcsncpy(class_id, tmp_guid, MAX_PATH);

    CoTaskMemFree((void*)tmp_guid);

    LRESULT result = NOERROR;
    TCHAR subkey[MAX_PATH];

    REGSTRUCT entry[] = {
      {TEXT("Software\\Classes\\CLSID\\%s\\InProcServer32"), nullptr, nullptr},
      {TEXT("Software\\Classes\\CLSID\\%s"), nullptr, nullptr}
    };

    for(unsigned int i = 0; (i < sizeof(entry)/sizeof(entry[0])) && (result == NOERROR); i++) {
      _stprintf(subkey, entry[i].subkey, class_id);
      result = RegDeleteKey(HKEY_CURRENT_USER, subkey);
    }

    if(result == NOERROR) {
      result = RegDeleteKey(HKEY_CURRENT_USER, TEXT("Software\\Classes\\*\\shellex\\ContextMenuHandlers\\kdiff3ext"));

      if(result == NOERROR) {
        // NT needs to have shell extensions "approved".
         HKEY key;

         RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved"), 0, KEY_ALL_ACCESS, &key);

         result = RegDeleteValue(key, class_id);

         RegCloseKey(key);

         if(result == ERROR_SUCCESS) {
         ret = S_OK;
         }
      }
    }
  }

  return ret;
}


================================================
FILE: diff_ext_for_kdiff3/server.h
================================================
/*
  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.
  SPDX-FileCopyrightText:  2018-2020 Michael Reeves reeves.87@gmail.com
  SPDX-License-Identifier: BSD-2-Clause
*/
#ifndef server_h
#define server_h

//This option is not compatible with our shell extension.
#undef WIN32_LEAN_AND_MEAN

#include <list>   // std::list
#include <windows.h>

#include <string> // std::wstring

#ifdef UNICODE

typedef std::wstring tstring;

#define toQString(s) QString::fromStdWString(s)
#define fromQString(s) (s).toStdWString()

#else

#error  "Unsupported configuration"

#endif

#define MESSAGELOG( msg ) SERVER::logMessage( __FUNCTION__, __FILE__, __LINE__, msg )
#define LOG()             MESSAGELOG( TEXT("") )
#define ERRORLOG( msg )   MESSAGELOG( TEXT("Error: ")+tstring(msg) )
#define SYSERRORLOG( msg )                                                                    \
   {                                                                                          \
      LPTSTR message;                                                                         \
      FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, nullptr,     \
         GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &message, 0, nullptr); \
      ERRORLOG( (tstring(msg) + TEXT(": ")) + message );                                        \
      LocalFree(message);                                                                     \
   }


class SERVER {
  public:
    static SERVER* instance();
    void initLogging();

  public:
    virtual ~SERVER();

    tstring getRegistryKeyString( const tstring& subKey, const tstring& value, bool isUserKey = true );

    HINSTANCE handle() const;

    HRESULT do_register();
    HRESULT do_unregister();

    void lock();
    void release();

    ULONG reference_count() const {
      return _reference_count;
    }

    std::list< tstring >& recent_files();

    void save_history() const;

    static void logMessage( const char* function, const char* file, int line, const tstring& msg );

  private:
    SERVER();
    SERVER(const SERVER&) {}

  private:
    LONG _reference_count;
    std::list<tstring>* m_pRecentFiles;
    static SERVER* _instance;
    tstring m_registryBaseName;
    FILE* m_pLogFile;
};

#endif // __server_h__


================================================
FILE: doc/CMakeLists.txt
================================================
# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de
# SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
# SPDX-License-Identifier: GPL-2.0-or-later

add_subdirectory(en)


================================================
FILE: doc/en/CMakeLists.txt
================================================
# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de
# SPDX-FileCopyrightText: 2018-2020 Michael Reeves reeves.87@gmail.com
# SPDX-License-Identifier: GPL-2.0-or-later

kdoctools_create_handbook(index.docbook INSTALL_DESTINATION ${KDE_INSTALL_DOCBUNDLEDIR}/en SUBDIR kdiff3)
kdoctools_create_manpage (man-kdiff3.1.docbook 1 INSTALL_DESTINATION ${KDE_INSTALL_MANDIR})


================================================
FILE: doc/en/index.docbook
================================================
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE book PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
  <!ENTITY kdiff3 "<application>KDiff3</application>">
  <!ENTITY % addindex "IGNORE">
  <!ENTITY % English "INCLUDE">
]>

<book lang="&language;">

<!-- This header contains all of the meta-information for the document such
as Authors, publish date, the abstract, and Keywords -->

<bookinfo>
<title>The &kdiff3; Handbook</title>

<authorgroup>
  <othercredit role="developer">
    <firstname>Michael</firstname>
    <surname>Reeves</surname>
    <affiliation><address>
    <email>reeves.87@gmail.com</email>
    </address></affiliation>
  </othercredit>
  <othercredit role="developer">
    <firstname>Joachim</firstname>
    <surname>Eibl</surname>
    <affiliation><address>
    <email>joachim.eibl at gmx.de</email>
    </address></affiliation>
  </othercredit>
<!-- TRANS:ROLES_OF_TRANSLATORS -->
</authorgroup>

<copyright>
<year>2002-2007</year>
<holder>Joachim Eibl</holder>
</copyright>
<copyright>
<year>2017-2019</year>
<holder>Michael Reeves</holder>
</copyright>
<!-- Translators: put here the copyright notice of the translation -->
<!-- Put here the FDL notice.  Read the explanation in fdl-notice.docbook
     and in the FDL itself on how to use it. -->
<legalnotice>&FDLNotice;</legalnotice>

<!-- Date and version information of the documentation
Don't forget to include this last date and this last revision number, we
need them for translation coordination !
Please respect the format of the date (YYYY-MM-DD) and of the version
(V.MM.LL), it could be used by automation scripts.
Do NOT change these in the translation. -->

<date>2023-12-23</date>
<releaseinfo>1.11.0</releaseinfo>


<abstract>
<para>
   &kdiff3; is a file and folder diff and merge tool which
<itemizedlist>
<listitem><para>compares and merges two or three text input files or folders,</para></listitem>
<listitem><para>shows the differences line by line and character by character(!),</para></listitem>
<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 network transparency via KIO,</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>
<listitem><para>prints differences,</para></listitem>
<listitem><para>supports version control keyword and history merging.</para></listitem>
</itemizedlist>
</para><para>
   This document describes &kdiff3;-version 1.12.
</para>
</abstract>

<!-- This is a set of Keywords for indexing by search engines.
Please at least include KDE, the KDE package it is in, the name
 of your application, and a few relevant keywords. -->

<keywordset>
<keyword>KDE</keyword>
<keyword>kdiff3</keyword>
<keyword>diff</keyword>
<keyword>merge</keyword>
<keyword>CVS</keyword>
<keyword>triple diff</keyword>
<keyword>compare</keyword>
<keyword>files</keyword>
<keyword>folders</keyword>
<keyword>directories</keyword>
<keyword>version control</keyword>
<keyword>three-way-merge</keyword>
<keyword>in-line-differences</keyword>
<keyword>synchronise</keyword>
<keyword>kio</keyword>
<keyword>network transparent</keyword>
<keyword>editor</keyword>
<keyword>white space</keyword>
<keyword>comments</keyword>
</keywordset>

</bookinfo>

<chapter id="introduction"><title>Introduction</title>
<sect1 id="why"><title>Yet Another Diff Frontend?</title>
<para>
Several graphical diff tools exist. Why choose &kdiff3;? Let me say, why I wrote it.
</para><para>
&kdiff3; started because I had to do a difficult merge. Merging is necessary when several
people work on the same files in a project. A merge can be somewhat automated, when the
merge-tool not only has the new modified files (called "branches"), but also the original file
(called "base"). The merge tool will automatically choose any modification that was only
done in one branch. When several contributors change the same lines, then the merge tool
detects a conflict which must be solved manually.
</para><para>
The merge then was difficult because one contributor had changed many things and corrected
the indentation in many places. Another contributor also had changed much text in the same file,
which resulted in several merge conflicts.
</para><para>
The tool I used then, only showed the changed lines, but not what had changed within these
lines. And there was no information about where only the indentation was changed. The merge
was a little nightmare.
</para><para>
So this was the start. The first version could show differences within a line and showed white space differences.
Later many other features were added to increase the usefulness.
</para><para>
For example if you want to compare some text quickly, then you can copy it to the clipboard and
paste it into either diff window.
</para><para>
A feature that required a big effort was the folder comparison and merge facility, which turned
the program almost into a full file browser.
</para><para>
I hope &kdiff3; works for you too. Have fun!
</para><para>
Joachim Eibl (2003)
</para>
</sect1>

<sect1 id="screenshots"><title>Screenshots and Features</title>
<para>This screenshot shows the difference between two text files (using an early version of &kdiff3;):</para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="screenshot_diff.png" format="PNG"/></imageobject>
</mediaobject></screenshot>

<para>
   3-way-merging is fully supported. This is useful if two people change code independently.
   The original file (the base) is used to help &kdiff3; to automatically select the correct
   changes.
   The merge-editor below the diff-windows allows you to solve conflicts, while showing you the output you will get.
   You can even edit the output.
   This screenshot shows three input files being merged:
</para><para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="screenshot_merge.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
</para>

<para id="dirmergebigscreenshot">&kdiff3; also helps you to compare and merge complete folders.
This screenshot shows &kdiff3; during a folder merge:
</para><para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="dirmergebig.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
</para>
</sect1>

<sect1 id="features"><title>More Features</title>
<sect2><title> Line-By-Line And Char-By-Char Diff-Viewer</title>
<para>By using the possibilities of a graphical color display &kdiff3; shows
   exactly what the difference is. When you have to do many code-reviews, you will like this.
</para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="letter_by_letter.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
</sect2>

<sect2><title> See White-Space Differences At One Glance</title>
<para>Spaces and tabs that differ appear visibly. When lines differ only
   in  the  amount of white space this can be seen at one look in the summary
   column on the left side. (No more worries when people change the indentation.)
</para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="white_space.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
</sect2>

<sect2><title> Triple-Diff</title>
<para> Analyze three files and see where they differ.
</para><para>
   The left/middle/right windows are named <guilabel>A</guilabel>/<guilabel>B</guilabel>/<guilabel>C</guilabel> and have the blue/green/magenta color respectively.
</para><para>
   If one file is the same and one file is different on a line then the
   color   shows which file is different. The red color means that both other
   files  are different.
</para>
<screenshot><mediaobject>
   <imageobject><imagedata fileref="triple_diff.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
</sect2>

<sect2><title> Comfortable Merge Of Two Or Three Input Files</title>
<para> &kdiff3; can be used to merge two or three input files and automatically
   merges as much as possible. The result is presented in an editable window
   where most conflicts can be solved with a single mouseclick: Select the
   respective <guibutton>...</guibutton> buttons at the <guilabel>A</guilabel>/
   <guilabel>B</guilabel>/<guilabel>C</guilabel> windows to select the source
   that should be used. You can also select more than one source. Since this
   output window is an editor even conflicts which need further corrections
   can be solved here without requiring another tool.
</para>
</sect2>

<sect2><title>And ...</title>
<itemizedlist>
   <listitem><para>Fast navigation via buttons.</para></listitem>
   <listitem><para>A mouse-click into a summary column sync's all windows to show the same position.</para></listitem>
   <listitem><para>Select and copy from any window and paste into the merge result window.</para></listitem>
   <listitem><para>Overview column that shows where the changes and conflicts are.</para></listitem>
   <listitem><para>The colors are adjustable to your specific preferences.</para></listitem>
   <listitem><para>Adjustable Tab size.</para></listitem>
   <listitem><para>Option to insert spaces instead of tabs.</para></listitem>
   <listitem><para>Open files comfortably via dialog or specify files on the command line.</para></listitem>
   <listitem><para>Search for strings in all text windows with <menuchoice><guimenu>Edit</guimenu><guimenuitem>Find</guimenuitem></menuchoice> (<keycombo>&Ctrl;<keycap>F</keycap></keycombo>) and <menuchoice><guimenu>Edit</guimenu><guimenuitem>Find Next</guimenuitem></menuchoice> (<keycap>F3</keycap>) menu items.</para></listitem>
   <listitem><para>Show the line numbers for each line. </para></listitem>
   <listitem><para>Paste clipboard or drag text into a diff input window.</para></listitem>
   <listitem><para>Network transparency via KIO.</para></listitem>
   <listitem><para>Can be used as diff-viewer from the &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>
</sect1>
</chapter>

<chapter id="documentation"><title>File Comparison And Merge</title>

<sect1 id="commandline"><title>Command-Line Options</title>

<sect2><title>Comparing 2 files: </title>
<screen>
   <command>kdiff3</command> <replaceable>file1 file2</replaceable>
</screen>
</sect2>

<sect2><title>Merging 2 files: </title>
<screen>
   <command>kdiff3</command> <replaceable>file1 file2</replaceable> -m
   <command>kdiff3</command> <replaceable>file1 file2</replaceable> -o <replaceable>outputfile</replaceable>
</screen>
</sect2>

<sect2><title>Comparing 3 files: </title>
<screen>
   <command>kdiff3</command> <replaceable>file1 file2 file3</replaceable>
</screen>
</sect2>

<sect2><title>Merging 3 files: </title>
<screen>
   <command>kdiff3</command> <replaceable>file1 file2 file3</replaceable> -m
   <command>kdiff3</command> <replaceable>file1 file2 file3</replaceable> -o <replaceable>outputfile</replaceable>
</screen>
<para>
   Note that <replaceable>file1</replaceable> will be treated as
   base of <replaceable>file2</replaceable> and
   <replaceable>file3</replaceable>.
</para>
</sect2>

<sect2><title>Special case: Files with the same name </title>
<para>
If all files have the same name but are in different folders, you can
reduce typework by specifying the filename only for the first file, &eg;:
</para>
<screen>
   <command>kdiff3</command> <replaceable>folder1/filename folder2 folder3</replaceable>
</screen>
</sect2>

<sect2><title>Commandline for starting a folder comparison or merge: </title>
<para>This is very similar, but now it's about folders.</para>
<screen>
   <command>kdiff3</command> <replaceable>folder1 folder2</replaceable>
   <command>kdiff3</command> <replaceable>folder1 folder2</replaceable> -o <replaceable>destdir</replaceable>
   <command>kdiff3</command> <replaceable>folder1 folder2 folder3</replaceable>
   <command>kdiff3</command> <replaceable>folder1 folder2 folder3</replaceable> -o <replaceable>destdir</replaceable>
</screen>
<para>For folder comparison and merge you can continue to read <link linkend="dirmerge">here</link>.</para>
</sect2>

<sect2><title>Other command line options</title>
<para>To see all available command line options type</para>
<screen>
<command>kdiff3</command> --help
</screen>
<para>Example output:</para>
<screen>
Options:
  -m, --merge               Merge the input.
  -b, --base file           Explicit base file. For compatibility with certain tools.
  -o, --output file         Output file. Implies -m. E.g.: -o newfile.txt
  --out file                Output file, again. (For compatibility with certain tools.)
  --noauto                  Ignore --auto and always show GUI.
  --auto                    No GUI if all conflicts are auto-solvable. (Needs -o file)
  --L1 alias1               Visible name replacement for input file 1 (base).
  --L2 alias2               Visible name replacement for input file 2.
  --L3 alias3               Visible name replacement for input file 3.
  -L, --fname alias         Alternative visible name replacement. Supply this once for every input.
  --cs string               Override a config setting. Use once for every setting. E.g.: --cs "AutoAdvance=1"
  --confighelp              Show list of config settings and current values.
  --config file             Use a different config file.
</screen>
<para>The option <option>--cs</option> allows you to adjust a configuration value that is otherwise only adjustable via the configure dialogs.
But be aware that when &kdiff3; then terminates the changed value will be stored along with the other settings.
With <option>--confighelp</option> you can find out the names of the available items and current values.</para>
<para>Via <option>--config</option> you can specify a different config file. When you often use &kdiff3;
with completely different setups this allows you to easily switch between them.</para>
</sect2>
<sect2><title>Ignorable command line options</title>
<para>Many people want to use &kdiff3; with some version control system. But when that version control system calls &kdiff3; using command line parameters that &kdiff3; doesn't recognise, then &kdiff3; terminates with an error.
The <guilabel>Integration</guilabel> item in the settings dialog allow to specify command line parameters that should be ignored by &kdiff3;.
They will appear in the usage help like in this example:</para>
<screen>
  --<replaceable>foo</replaceable>                     Ignored. (User defined.)
</screen>
<variablelist>
  <varlistentry><term><guilabel>Command line options to ignore:</guilabel></term><listitem><para>
     A list of options, separated via semicolon ';'. When one of these options appears on the commandline,
     then &kdiff3; will ignore it and run without reporting an error.
     (Default is "<literal>u;query;html;abort</literal>").</para></listitem></varlistentry>
</variablelist>
<para>When this isn't enough, then it is recommended to write a shell script that does the option translation.</para>
</sect2>

</sect1>

<sect1 id="opendialog"><title>Open-Dialog</title>
<para>
   Since many input files must be selectable, the program has a special open dialog:
</para>
<screenshot><mediaobject>
<imageobject><imagedata fileref="open_dialog.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
<para>
   The open dialog allows you to edit the filenames by hand, selecting a file
   via the file-browser via the <guibutton>File...</guibutton> button or allows
   you to choose recent files from the drop-down lists. If you open the dialog
   again, then the current names still remain there. The third input file is not
   required. If the entry for <guilabel>C</guilabel> remains empty, then only a
   two file diff analysis will be done.
</para><para>
   You can also select a folder via the <guibutton>Folder...</guibutton> button.
   If for <guilabel>A</guilabel> a folder is specified then a folder-comparison
   /merge starts. If <guilabel>A</guilabel> specifies a file but <guilabel>B</guilabel>,
   <guilabel>C</guilabel> or the output specify a folder, then &kdiff3; uses the
   filename from <guilabel>A</guilabel> in the specified folders.
</para><para>
   If <guilabel>Merge</guilabel> check box is selected, then the <guilabel>Output</guilabel>
   line becomes editable. But it is not required to specify the output filename
   immediately. You can also postpone this until saving.
</para><para>
   The <guibutton>Configure...</guibutton> button opens the settings dialog, so that you can set
   the options before running the analysis.
</para>
</sect1>

<sect1 id="pasteinput"><title>Paste and Drop Input</title>
<para>
   Sometimes you want to compare parts of a text that is not an own file. &kdiff3; also
   allows you to paste text from the clipboard into the diff input window that has the focus.
   The diff analysis happens immediately then.
   In the open dialog you need not specify files then, but just close it via <guibutton>Cancel</guibutton> button.
</para><para>
   You can also use drag and drop: Drag a file from a file manager
   or selected text from an editor and drop it onto a diff input window.
</para><para>
   What's the idea? Sometimes a file contains two similar functions, but checking how similar
   they really are is a big effort if you first must create two files and then load them. Now
   you can simply copy, paste and compare the relevant sections.
</para><note><para>
   Currently you cannot drag anything from &kdiff3;. Only dropping in the diff input
   is supported.
</para></note><warning><para>
   Some editors still interpret the drag and drop into another program like cut
   (instead of copy) and paste. Your original data might be lost then.
</para></warning>
</sect1>

<sect1 id="interpretinginformation"><title>Comparing Files And Interpreting The Information In The Input Windows</title>
<screenshot><mediaobject>
<imageobject><imagedata fileref="screenshot_diff.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
<sect2><title>Info Line</title><para>
   At the top of each text window is its "info line". The info lines of
   the input windows contain a letter <guilabel>A</guilabel>, <guilabel>B</guilabel>
   or <guilabel>C</guilabel>, the editable filename, a button for browsing, and the
   line number of the first visible line in the window. (Note that window <guilabel>C</guilabel>
   is  optional.) Each info line appears in a different color.
</para><para>
   When you selected another file via browsing or finished editing the filename here
   by pressing &Enter;, the new file will be loaded and
   compared with the already loaded file(s).
</para></sect2><sect2><title>Coloring</title><para>
   The three input windows are assigned the letters <guilabel>A</guilabel>, <guilabel>B</guilabel>
   and <guilabel>C</guilabel>.
   <guilabel>A</guilabel> has color blue, <guilabel>B</guilabel> has green and <guilabel>C</guilabel>
   has magenta. (These are the defaults, but can be changed in the <guilabel>Color</guilabel>
   item in the settings dialog.)
</para><para>
   When a difference is detected then the color shows which input file differs.
   When both other input files differ then the color used to express this is
   red by default (<guilabel>Conflict color</guilabel> option in the <guilabel>Color</guilabel>
   item in the settings dialog). This colorscheme is especially useful in the
   case of three input files, which will be seen in the next section
   (<link linkend="merging">Merging</link>).
</para></sect2><sect2><title>Summary Column</title><para>
   Left of each text is the "summary" column. If differences occurred on a
   line then the summary column shows the respective color. For a white-space-only
   difference the summary is chequered. For programming languages where white
   space is not so important this is useful to see at one glance if anything
   of importance was modified. (In C/C++ white space is only interesting within
   strings, comments, for the preprocessor, and some only very esoteric situations.)
</para><para>
   The vertical line separating the summary column and the text is interrupted
   if the input file had no lines there. When word-wrap is enabled then this vertical
   line appears dotted for wrapped lines.
</para></sect2><sect2><title>Overview Column</title><para>
   On the right side a "overview" column is visible left of the vertical scrollbar.
   It shows the compressed summary column of input <guilabel>A</guilabel>. All the differences
   and conflicts are visible at one glance. When only two input windows are
   used, then all differences appear red here because every difference is
   also a conflict. A black rectangle frames the visible part of the inputs.
   For  very long input files, when the number of input lines is bigger than
   the height of the overview column in pixels, then several input lines share
   one overview line. A conflict then has top priority over simple differences,
   which have priority over no change, so that no difference or conflict is
   lost here. By clicking into this overview column the corresponding text
   will be shown.
</para></sect2><sect2 id="manualdiffhelp"><title>Manually Aligning Lines</title><para>
   Sometimes the algorithm places the wrong lines next to each other. Or you want to compare
   one piece of text with text at a completely different position in the other file.
   For these situations you can manually instruct &kdiff3; to align certain lines.
   Mark the text for which you want to improve the alignment with the mouse as you would
   for copy and paste in the first diff view and then choose <menuchoice><guimenu>Diffview</guimenu><guimenuitem>Add Manual Diff Alignment</guimenuitem></menuchoice> menu item (<keycombo>&Ctrl;<keycap>Y</keycap></keycombo>). An orange bar will appear in
   the summary column next to the chosen text. Repeat this for the second and
   (if available) third diff view. &kdiff3; will immediately recalculate the differences everytime you do this,
   and will align the chosen lines. Of course some of the previously matching lines in between
   might not match anymore.
</para><para>
   Currently merging doesn't support the use of manual diff help.
</para></sect2><sect2 id="joinsplitsections"><title>Manually Joining and Splitting Diff Sections</title><para>
   In some cases &kdiff3; will see too many or too few diff sections for merging. In such a
   case you can join or split existing sections.
</para><para>
   Add new sections by first selecting text in the lines that belong together in either input window (as for copying to the clipboard).
   Then choose <menuchoice><guimenu>Merge</guimenu><guimenuitem>Split Diff At Selection</guimenuitem></menuchoice> menu item.
   Splits will be added above the first line and below the last line of the selected text.
   If you only want to add one section, then select text beginning at another section-split.
</para><para>
   For joining sections in either input window select something in the lines from the sections to join.
   (You can join several sections in one step too.) Then choose <menuchoice><guimenu>Merge</guimenu><guimenuitem>Join Selected Diffs</guimenuitem></menuchoice> menu item.
</para></sect2>
</sect1>


<sect1 id="merging"><title>Merging And The Merge Output Editor Window</title>
<screenshot><mediaobject>
<imageobject><imagedata fileref="screenshot_merge.png" format="PNG"/></imageobject>
</mediaobject></screenshot>
<para>
   The merge output editor window (below the diff input windows) also has an info line at the top showing <guilabel>Output:</guilabel>, the filename and <replaceable>[Modified]</replaceable> tag if you edited something. Usually it will contain some text through the automatic merge facilities, but often it will also contain conflicts.
</para><para>
!!! Saving is disabled until all conflicts are resolved !!! (Use the <guibutton>Go to Previous/Next Unsolved Conflict</guibutton> buttons to find the remaining conflicts.)
</para><para>
   With only two input files every difference is also a conflict that must
   be solved manually.
</para><para>
   With three input files the first file is treated as base, while the second and third input files contain modifications. When at any line only either input <guilabel>B</guilabel> or input <guilabel>C</guilabel> have changed but not both then the changed source will automatically be selected. Only when <guilabel>B</guilabel> and <guilabel>C</guilabel> have changed on the same lines, then the tool detects a conflict that must be solved manually. When <guilabel>B</guilabel> and <guilabel>C</guilabel> are the same, but not the same as <guilabel>A</guilabel>, then <guilabel>C</guilabel> is selected.
</para><sect2><title>The Summary Column</title><para>
   The merge output editor window also has a summary column on the left. It shows the
   letter of the input from which a line was selected or nothing if all three
   sources where equal on a line. For conflicts it shows a questionmark "?"
   and the line shows "&lt;Merge Conflict&gt;", all in red. Because solving
   conflicts  line by line would take very long, the lines are grouped into
   groups that  have the same difference and conflict characteristics.
   But only-white-space-conflicts are separated from non-white-space-conflicts
   in order to ease the merging of files were the indentation changed for many
   lines.
</para></sect2><sect2 id="synchronise_views"><title>Setting The Current Group And Synchronising Merge And Diff View Position</title><para>
   When clicking into the summary column with the &LMB; in either window then the beginning of the group belonging to that line will shown in all windows. This group then becomes the "current group". It is highlighted with the <guilabel>Current range diff background color</guilabel> option of <guilabel>Integration</guilabel> item in the settings dialog and a black bar appears on the left side of the text.
</para></sect2><sect2><title>Choosing Inputs A, B or C For Current Conflict And Editing</title><para>
   The Button bar below the menubar contains three input selector buttons containing the letters <guilabel>A</guilabel>, <guilabel>B</guilabel> and <guilabel>C</guilabel>. Click the input selector button to insert (or remove if already inserted) the lines from the respective source. To choose the lines from several inputs click the respective buttons in the needed order. For example if you want that the lines from <guilabel>B</guilabel> appear before the lines from <guilabel>A</guilabel> in the output, first click <guilabel>B</guilabel>, then <guilabel>A</guilabel>.
</para><para>
   If you use the <guibutton>Automatically Go to Next Unsolved Conflict After Source Selection</guibutton> button (see <link linkend="autoadvance">Auto-Advance</link> section), you should disable this before choosing lines from several inputs or if you want to edit the lines after your choice. Otherwise &kdiff3; will jump to the next conflict after choosing the first input.
</para><para>
   It is often helpful directly edit the merge output.
   The summary column will show "m" for every line that was manually modified.
   When for instance the differences are aligned in a way that simply choosing
   the inputs won't be satisfactory, then you can mark the needed text and use
   normal <link linkend="selections">copy and paste</link> to put it into the merge output.
</para><para>
   Sometimes, when a line is removed either by automatic merge or by editing
   and no other lines remain in that group, then the text &lt;No src line&gt;
   will appear in that line. This is just a placeholder for the group for
   when  you might change your mind and select some source again. This text won't
   appear in the saved file or in any selections you want to copy and paste.
</para><para>
   The text "&lt;Merge Conflict&gt;" will appear in the clipboard if you
   copy and   paste some text containing such a line. But still be careful to
   do so.
</para></sect2><sect2><title>Choosing Input A, B, or C for All Conflicts</title><para>
   The normal merge will start by solving simple conflicts automatically. But the <guimenu>Merge</guimenu> menu provides some actions for other common needs. If you have to select the same source for most conflicts, then you can choose <guilabel>A</guilabel>, <guilabel>B</guilabel> or <guilabel>C</guilabel> everywhere, or only for the remaining unsolved conflicts, or for unsolved white space conflicts. If you want to decide every single delta yourself, you can <guimenuitem>Set Deltas to Conflicts</guimenuitem>. Or if you want to return to the automatic choices of &kdiff3; then select <guimenuitem>Automatically Solve Simple Conflicts</guimenuitem>. &kdiff3; then restarts the merge. For actions that change your previous modifications &kdiff3; will ask for your confirmation before proceeding.
</para><note><para>
   When choosing either source for unsolved white space conflicts and the <guilabel>Ignore numbers (treat as white space)</guilabel> or <guilabel>Ignore C/C++ comments (treat as white space)</guilabel> options at <guilabel>Diff</guilabel> item in the settings dialog are used then changes in numbers or comments will be treated like white space too.

</para></note></sect2><sect2 id="vcskeywordsmergesupport"><title>Automatic Merge of Version Control Keywords and History (Log)</title><para>
   Many version control systems support special keywords in the file. (&eg; "<literal>&#36;Date&#36;</literal>", "<literal>&#36;Header&#36;</literal>", "<literal>&#36;Author&#36;</literal>", "<literal>&#36;Log&#36;</literal>", &etc;) During the check-in the version control system (VCS) changes these lines. For instance "<literal>&#36;Date&#36;</literal>" will turn into "<literal>&#36;Date: 2005/03/22 18:45:01 &#36;</literal>". Since this line will be different in every version of the file, it would require manual interaction during the merge.
</para><para>
   &kdiff3; offers automatic merge for these items at <guilabel>Merge</guilabel> item in the settings dialog. For simple lines that match the <guilabel>Auto merge regular expression</guilabel> option in all input-files &kdiff3; will choose the line from <guilabel>B</guilabel> or - if available - from <guilabel>C</guilabel>. (Additionally it is necessary that the lines in question line up in the comparison and the previous line contains no conflict.) This auto merge can either be run immediately after a merge starts (activate the option <guilabel>Run regular expression auto merge on merge start</guilabel>) or later via <menuchoice><guimenu>Merge</guimenu><guimenuitem>Run Regular Expression Auto Merge</guimenuitem></menuchoice> menu item.
</para><para>
   Automatic merge for version control history (also called "log") is also supported. The history auto-merge can either run immediately when the merge starts by activating the option <guilabel>Merge version control history on merge start</guilabel> at <guilabel>Merge</guilabel> item in the settings dialog or later via the <menuchoice><guimenu>Merge</guimenu><guimenuitem>Automatically Solve History Conflicts</guimenuitem></menuchoice> menu item.
</para><para>
   Usually the version control history begins with a line containing the keyword "<literal>&#36;Log&#36;</literal>". This must be matched by the <guilabel>History start regular expression:</guilabel> option. &kdiff3; detects which subsequent lines are in the history by analysing the leading characters that came before the "<literal>&#36;Log&#36;</literal>" keyword. If the same "leading comment" characters also appears in the following lines, then they are also included in the history.
</para><para>
During each check-in the VCS writes a unique line specifying version-, date- and time-information
followed by lines with user comments.
These lines form one history-entry. This history section grows with every check-in and the
most recent entries appear at the top (after the history start line).
</para><para>
When for parallel development two or more developers check-in a branch of the file then
the merge history will contain several entries that appear as conflicts during the merge
of the branches. Since merging these can become very tedious, &kdiff3; offers support with two
possible strategies: Just insert the history information from both contributors at the top
or sort the history information by a user defined key.
</para><para>
   The just-insert-all-entries-method is easier to configure. &kdiff3; just needs a method to detect, which lines belong to one history entry. Most VCS insert an empty line after each history entry. If there are no other empty lines, this is a sufficient criterion for &kdiff3;. Just set an empty <guilabel>History entry start regular expression</guilabel> at <guilabel>Merge</guilabel> item in the settings dialog. If the empty line criterion isn't sufficient, you can specify a regular expression to detect the history entry start.
</para><para>
Note that &kdiff3; will remove duplicate history entries. If a history entry appeared several times
in the history of a input file, only one entry will remain in the output.
</para><para>
   If you want to sort the history, then you have to specify how the sort key should be built. Use parentheses in the <guilabel>History entry start regular expression</guilabel> at <guilabel>Merge</guilabel> item in the settings dialog to group parts of the regular expression that should later be used for the sort key. Then specify the <guilabel>History entry start sort key order</guilabel> option specifying a comma "," separated list of numbers referring to the position of the group in the regular expression.
</para><para>
   Because this is not so easy to get right immediately, you are able to test and improve the regular expressions and key-generation in a dedicated dialog by pressing the <guibutton>Test your regular expressions</guibutton> button.
</para><para>Example: Assume a history that looks like this:
</para>
<screen>
/**************************************************************************
** HISTORY:    &#36;Log: \toms_merge_main_view\MyApplication\src\complexalgorithm.cpp &#36;
**
**     \main\integration_branch_12   2 Apr 2001 10:45:41   tom
**  Merged branch simon_branch_15.
**
**     \main\henry_bugfix_branch_7\1   30 Mar 2001 19:22:05   henry
**  Improved the speed for subroutine convertToMesh().
**  Fixed crash.
**************************************************************************/
</screen>
<para>
   The history start line matches the regular expression "<literal>.*\&#36;Log.*\&#36;.*</literal>". Then follow the history entries.
</para><para>
   The line with the "<literal>&#36;Log&#36;</literal>" keyword begins with two "*" after which follows a space. &kdiff3; uses the first non-white-space string as "leading comment" and assumes that the history ends in the first line without this leading comment. In this example the last line ends with a string that also starts with two "*", but instead of a space character more "*" follow. Hence this line ends the history.
</para><para>
If history sorting isn't required then the history entry start line regular expression
could look like this. (This line is split in two because it wouldn't fit otherwise.)
</para>
<screen>
\s*\\main\\\S+\s+[0-9]+ (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
 [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]\s+.*
</screen>
<para>
   For details about regular expressions please see the <ulink url="https://doc.qt.io/qt-5/qregularexpression.html">regular expression documentation</ulink>. Note that "<literal>\s</literal>" (with lowercase "<literal>s</literal>") matches any white space and "<literal>\S</literal>" (with uppercase "<literal>S</literal>") matches any non-white-space. In our example the history entry start contains first the version info with reg. exp. "<literal>\\main\\\S+</literal>", the date consisting of day "<literal>[0-9]+</literal>", month "<literal>(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)</literal>" and year "<literal>[0-9][0-9][0-9][0-9]</literal>", the time "<literal>[0-9][0-9]:[0-9][0-9]:[0-9][0-9]</literal>" and finally the developers login name "<literal>.*</literal>".
</para><para>
   Note that the "leading comment" characters (in the example "<literal>**</literal>") will already be removed by &kdiff3; before trying to match, hence the regular expression begins with a match for none or more white-space characters "<literal>\s*</literal>". Because comment characters can differ in each file (&eg; C/C++ uses other comment characters than a Perl script) &kdiff3; takes care of the leading comment characters and you should not specify them in the regular expression.
</para><para>
If you require a sorted history. Then the sortkey must be calculated. For this the
relevant parts in the regular expression must be grouped by parentheses.
(The extra parentheses can also stay in if history sorting is disabled.)
</para>
<screen>
\s*\\main\\(\S+)\s+([0-9]+) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)
 ([0-9][0-9][0-9][0-9]) ([0-9][0-9]:[0-9][0-9]:[0-9][0-9])\s+(.*)
</screen>
<para>
   The parentheses now contain <literal>1</literal>. version info, <literal>2</literal>. day, <literal>3</literal>. month, <literal>4</literal>. year, <literal>5</literal>. time, <literal>6</literal>. name.
   But if we want to sort by date and time, we need to construct a key with the elements in a different order of appearance:
   First the year, followed by month, day, time, version info and name. Hence the sortkey order to specify is "<literal>4,3,2,5,1,6</literal>".
</para><para>
   Because  month names aren't good for sorting ("<literal>Apr</literal>" would be first) &kdiff3; detects in which order the month names were given and uses that number instead ("<literal>Apr</literal>" -&gt; "<literal>04</literal>"). And if a pure number is found it will be transformed to a 4-digit value with leading zeros for sorting. Finally the resulting sort key for the first history entry start line will be:
</para>
<screen>
2001 04 0002 10:45:41 integration_branch_12   tom
</screen>
<para>
For more information also see <link linkend="mergeoptions">Merge Settings</link> section.
</para>
</sect2>
</sect1>

<sect1 id="navigation"><title>Navigation And Editing</title>
<para>
   Much navigation will be done with the scroll bars and the mouse but you can also navigate with the keys. If you click into either window then you can use the shortcuts &Left;, &Right;, &Up;, &Down;, &PgUp;, &PgDn;,  &Home;, &End;, <keycombo>&Ctrl;&Home;</keycombo> and <keycombo>&Ctrl;&End;</keycombo> as you would in other programs. The overview-column next to the vertical scroll bar of the input files can also be used for navigating by clicking into it.
</para><para>
   You can also use the <mousebutton>wheel</mousebutton> mouse to scroll up and down.
</para><para>
   In the merge output editor you can also use the other keys for editing.
   You can toggle between insert and overwrite mode with the &Ins; key. (Default
   is insert-mode.)
</para><para>
   A click with the &LMB; into any summary column will synchronise all
   windows to show the beginning of the same group of lines (as explained
   in section <link linkend="synchronise_views">Setting The Current Group And Synchronising Merge And Diff View Position</link>).
</para><para>
   The Button bar also contains nine navigation buttons with which you can
   jump to the current/first/last difference, to the previous/next difference
   (<keycombo>&Ctrl;&Down;</keycombo>/<keycombo>&Ctrl;&Up;</keycombo>), to the
   previous/next conflict (<keycombo>&Ctrl;&PgDn;</keycombo>/<keycombo>&Ctrl;&PgUp;</keycombo>),
   or to the previous/next unsolved conflict. Note that for &kdiff3; a "conflict"
   that was not automatically solved at the start of the merge stays a "conflict"
   even if it is solved. Hence the necessity to distinguish "unsolved conflicts".
</para>
<sect2 id="autoadvance"><title>Auto-Advance</title>
<para>
   There also is a button <guibutton>Automatically Go to Next Unsolved Conflict After
   Source Selection</guibutton> (Auto-Advance). If you enable this, then, when one source
   is selected, &kdiff3; will jump to and select the next unsolved conflict
   automatically. This can help when you always want to choose one source only.
   When you need both sources, or you want to edit after selecting, then you
   probably want to switch this off. Before proceeding to the next unsolved conflict
   &kdiff3; shows you the effect of your choice for a short time. This delay is
   adjustable in the <guilabel>Merge</guilabel> item in the settings dialog: You can
   specify the <guilabel>Auto advance delay (ms):</guilabel> in milli seconds between 0 and 2000. Hint:
   Tired of many clicks? - Use a small Auto-Advance-delay and the shortcuts
   <keycombo>&Ctrl;<keycap>1</keycap></keycombo>/<keycap>2</keycap>/<keycap>3</keycap>
   to select <guilabel>A</guilabel>/<guilabel>B</guilabel>/<guilabel>C</guilabel> for many conflicts.
</para>
</sect2>
</sect1>

<sect1 id="selections"><title>Select, Copy And Paste</title>
<para>
   The input windows don't show a cursor, so selections must be made with the
   mouse by clicking with the &RMB; at the start, holding down the
   mousebutton and moving to the end, where you release the mouse button again.
   You can also select a word by double clicking it. In the merge output editor
   you can also select via the keyboard by holding the &Shift; key and
   navigation with the cursor keys.
</para><para>
   If the selection exceeds the visible range you can move the mouse over the
   window borders which causes &kdiff3; to scroll in that direction.
</para><para>
   For very large selections you can also use the navigation keys while holding down
   the mouse. E.g. use &PgUp; and &PgDn; to quickly go to a certain position. At the
   end position release the mouse button.
</para><para>
   In order to select everything in the current window use <menuchoice><guimenu>Edit</guimenu>
   <guimenuitem>Select All</guimenuitem></menuchoice> menu item (<keycombo>&Ctrl;<keycap>A</keycap></keycombo>).
</para><para>
   To copy to the clipboard you must press the <guibutton>Copy</guibutton> button (<keycombo>&Ctrl;<keycap>C</keycap></keycombo> or <keycombo>&Ctrl;&Ins;</keycombo>). But there exists an option <guilabel>Auto copy selection</guilabel> at <guilabel>Editor</guilabel> item in the settings dialog. If this is enabled, then whatever you select is copied immediately and you don't need to explicitly copy. But pay attention when using this because the contents of the clipboard might then be destroyed accidentally.
</para><para>
   <guibutton>Cut</guibutton> (<keycombo>&Ctrl;<keycap>X</keycap></keycombo> or <keycombo>&Shift;&Del;</keycombo>) copies to the clipboard and deletes the selected text.
</para><para>
   <guibutton>Paste</guibutton> (<keycombo>&Ctrl;<keycap>V</keycap></keycombo> or <keycombo>&Shift;&Ins;</keycombo>)
   inserts the text in the clipboard at the cursorposition or over the current selection.
   If you paste to either diff input window the contents of the clipboard will
   be shown in that window and the comparison will restart immediately. This is
   useful if you want to quickly grab a piece of text from somewhere and
   compare it with something else without first creating files.
</para>
</sect1>

<sect1 id="saving"><title>Saving</title>
<para>
   Saving will only be allowed, when all conflicts were solved. If the file already exists and the <guilabel>Backup files</guilabel> option is enabled at <guilabel>Folder</guilabel> item in the settings dialog then the existing file will be renamed with an <literal role="extension">.orig</literal> extension, but if such a file exists it will be deleted. When you exit or start another diff-analysis and data wasn't saved yet, then &kdiff3; will ask if you want to save, cancel or proceed without saving. (&kdiff3; does not catch any signals. So if you "kill" a &kdiff3; instance then your data will be lost.)
</para><para>
   Line endings are saved according to the normal method on the underlying operating system. For Unices each line ends with an linefeed-character "<literal>\n</literal>", while for Win32-based systems each line ends with a carriage-return + a linefeed "<literal>\r\n</literal>". &kdiff3; does not preserve the line-endings of the input files, which also means that you shouldn't use &kdiff3; with binary files.
</para>
</sect1>

<sect1 id="find"><title>Finding Strings</title>
<para>
   You can search for a string in any text-window of &kdiff3;. The <menuchoice><guimenu>Edit</guimenu><guimenuitem>Find...</guimenuitem></menuchoice> menu item (<keycombo>&Ctrl;<keycap>F</keycap></keycombo>) opens a dialog that lets you specify the string to search for. You can also select the windows which should be searched. Searching will always start at the top. Use the <menuchoice><guimenu>Edit</guimenu><guimenuitem>Find Next...</guimenuitem></menuchoice> menu item (<keycap>F3</keycap>) to proceed to the next occurrence. If you select to search several windows then the first window will be searched from top to bottom before the search starts in the next window at the top again, &etc;
</para>
</sect1>

<sect1 id="printing"><title>Printing</title>
<para>
   &kdiff3; supports printing for textfile differences. The <menuchoice><guimenu>File</guimenu><guimenuitem>Print...</guimenuitem></menuchoice> menu item (<keycombo>&Ctrl;<keycap>P</keycap></keycombo>) opens a dialog that allows you to select the printer and to adjust other options.
</para><para>
   There are several possibilities to adjust the range. Due to different printing
   dialogs on different operating systems, the method to achieve certain range selections varies.
</para>
<variablelist>
   <varlistentry><term>All:</term><listitem><para>Print everything.</para></listitem></varlistentry>
   <varlistentry><term>Current:</term><listitem><para>Print a page starting at the first visible line in the window.
       (On systems without this option this can be achieved by specifying page number 10000 for printing.)</para></listitem></varlistentry>
   <varlistentry><term>Selection:</term><listitem><para>
       Before choosing to print select text with the mouse (like for copy and paste)
       in one of the diff input windows to define the start and end line. If no text
       in one of the diff input windows was selected, then this won't be an available
       choice. (On systems without this option this can be achived by specifying page
       number 9999 for printing.)</para></listitem></varlistentry>
   <varlistentry><term>Range:</term><listitem><para>Specify the first and last page.
       </para></listitem></varlistentry>
</variablelist>
<para>
   Other important options for printing will be taken from the normal options:
</para><itemizedlist>
   <listitem><para>Font, font size</para></listitem>
   <listitem><para>Show line numbers</para></listitem>
   <listitem><para>Word wrap</para></listitem>
   <listitem><para>Colors</para></listitem>
   <listitem><para>&etc;</para></listitem>
</itemizedlist>
<para>
   Landscape formatting is also recommended for printing.
</para>
</sect1>

<sect1 id="options"><title>Options</title>
<para>
   Options and the recent-file-list will be saved when you exit the program,
   and reloaded when you start it. (<menuchoice><guimenu>Settings</guimenu>
   <guimenuitem>Configure &kdiff3;...</guimenuitem></menuchoice> menu item).
</para>
<sect2><title>Font</title>
<para>
   Select a fixed width font. (On some systems this dialog will also
   present variable width fonts, but you should not use them.)
</para>
</sect2>

<sect2><title>Colors</title>
<variablelist>
  <varlistentry><term><guilabel>Editor and Diff Views:</guilabel></term><listitem>
  <variablelist>
    <varlistentry><term><guilabel>Foreground color:</guilabel></term><listitem><para> Usually black. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Background color:</guilabel></term><listitem><para> Usually white. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Diff background color:</guilabel></term><listitem><para> Usually light gray. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Color A:</guilabel></term><listitem><para> Usually dark blue. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Color B:</guilabel></term><listitem><para> Usually dark green. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Color C:</guilabel></term><listitem><para> Usually dark magenta. </para></listitem></varlistentry>
    <varlistentry><term><guilabel>Conflict color:</guilabel></term><listitem><para> Usually red.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Current range background color:</guilabel></term><listitem><para> Usually light yellow.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Current range diff background color:</guilabel></term><listitem><para> Usually dark yellow.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Color for manually aligned difference ranges:</guilabel></term><listitem><para> Usually orange.</para></listitem></varlistentry>
  </variablelist></listitem></varlistentry>
  <varlistentry><term><guilabel>Folder Comparison View:</guilabel></term><listitem>
  <variablelist>
    <varlistentry><term><guilabel>Newest file color:</guilabel></term><listitem><para> Usually green.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Oldest file color:</guilabel></term><listitem><para> Usually red.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Middle age file color:</guilabel></term><listitem><para> Usually strong yellow.</para></listitem></varlistentry>
    <varlistentry><term><guilabel>Color for missing files:</guilabel></term><listitem><para> Usually black.</para></listitem></varlistentry>
  </variablelist></listitem></varlistentry>
</variablelist>
<para>
   Changing the colors for folder comparison will be effective only when starting the next folder comparison.
</para>
<para>
   On systems with only 16 or 256 colors some colors are not available in pure
   form. On such systems the <guibutton>Defaults</guibutton> button will choose a pure color.
</para>
</sect2>

<sect2><title>Editor Settings</title>
<variablelist>
   <varlistentry><term><guilabel>Tab inserts spaces</guilabel></term><listitem><para>
      If this is disabled and you press the &Tab; key, a tab-character is inserted,
      otherwise the appropriate amount of characters is inserted.</para></listitem></varlistentry>
   <varlistentry><term><guilabel>Tab size:</guilabel></term><listitem><para>
               Can be adjusted for your specific needs. Default is <literal>8</literal>.</para></listitem></varlistentry>
   <varlistentry><term><guilabel>Auto indentation</guilabel></term><listitem><para>
      When pressing &Enter; or <keycap>Return</keycap> the indentation of the previous
      line is used for the new line.</para></listitem></varlistentry>
   <varlistentry><term><guilabel>Auto copy selection</guilabel></term><listitem><para>
      Every selection is immediately copied to the clipboard when active and you needn't
      explicitly copy it.</para></listitem></varlistentry>
   <varlistentry><term><guilabel>Line end style:</guilabel></term><listitem><para>
      When saving you can select what line end style you prefer. The default setting is
      the common choice for the used operating system.</para></listitem></varlistentry>
</variablelist>
</sect2>

<sect2 id="diffoptions"><title>Diff Settings</title>
<para>
   When comparing files, &kdiff3; first it tries to match lines that are equal
   in all input files. Only during this step it might ignore white space. The
   second step compares each line. In this step white space will not be ignored.
   Also during the merge white space will not be ignored.
</para>

<variablelist>
   <varlistentry><term><guilabel>Ignore numbers (treat as white space)</guilabel></term><listitem><para> Default is off. Number characters ('0'-'9', '.', '-')
      will be ignored  in the first  part of the analysis in which the line matching is
      done. In the result the differences will be shown nevertheless, but they are treated
      as white space.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Ignore C/C++ comments (treat as white space)</guilabel></term><listitem><para> Default is off.
      Changes in comments will be treated like changes in white space.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Ignore case (treat as white space)</guilabel></term><listitem><para>  Default is off.
      Case-differences of characters (like 'A' vs. 'a') will be treated like changes in white space.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Preprocessor command:</guilabel></term><listitem><para>
      See <link linkend="preprocessors">next section</link>.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Line-matching preprocessor command:</guilabel></term><listitem><para>
      See <link linkend="preprocessors">next section</link>.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Try hard (slower)</guilabel></term><listitem><para>
      Try hard to find an even smaller delta. (Default is on.) This will probably
      be effective for complicated and big files. And slow for very big files.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Align B and C for 3 input files</guilabel></term><listitem><para>
      Try to align <guilabel>B</guilabel> and <guilabel>C</guilabel> when comparing
      or merging three input files. Not recommended for merging because merge might
      get more complicated. (Default is off.)
   </para></listitem></varlistentry>
</variablelist>
</sect2>

<sect2 id="mergeoptions"><title>Merge Settings</title>
<variablelist>
   <varlistentry><term><guilabel>Auto advance delay (ms):</guilabel></term><listitem><para>
      When in auto-advance-mode this setting specifies how long to show the result of the
      selection before jumping to the next unsolved conflict.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Show info dialogs</guilabel></term><listitem><para>
      Show a dialog with information about the number of conflicts.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>White space 2/3-file merge default:</guilabel></term><listitem><para>
      Automatically solve all white-space conflict by choosing the specified file.
      (Default is manual choice.) Useful if white space really isn't important in many files.
      If you need this only occasionally better use <guilabel>Choose A/B/C for All
      Unsolved Whitespace Conflicts</guilabel> in the <guimenu>Merge</guimenu> menu. Note that
      if you enable either <guilabel>Ignore numbers (treat as white space)</guilabel> or
      <guilabel>Ignore C/C++ comments (treat as white space)</guilabel> then this auto-choice
      also applies for conflicts in numbers or comments.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Auto merge regular expression:</guilabel></term><listitem><para>
      Regular expression for lines where &kdiff3; should automatically choose one source. See also <link linkend="vcskeywordsmergesupport">Automatic Merge...</link>.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Run regular expression auto merge on merge start</guilabel></term><listitem><para>
      If activated &kdiff3; runs the automatic merge using the <guilabel>Auto merge regular expression:</guilabel> option when a merge is started.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>History entry start regular expression:</guilabel></term><listitem><para>
      Regular expression for the start of the merge history entry.
      Usually this line contains the "<literal>&#36;Log&#36;</literal>" keyword.
      Default value: "<literal>.*\&#36;Log.*\&#36;.*</literal>"
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>History entry start regular expression:</guilabel></term><listitem><para>
      A merge history entry consists of several lines.
      Specify the regular expression to detect the first line (without the leading comment).
      Use parentheses to group the keys you want to use for sorting.
      If left empty, then &kdiff3; assumes that empty lines separate history entries.
      See also <link linkend="vcskeywordsmergesupport">Automatic Merge...</link>.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>History merge sorting</guilabel></term><listitem><para>
      Enable version control history sorting.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>History entry start sort key order:</guilabel></term><listitem><para>
      Each pair of parentheses used in the regular expression for the history start entry
      groups a key that can be used for sorting.
      Specify the list of keys (that are numbered in order of occurrence
      starting with <literal>1</literal>) using ',' as separator (&eg; "<literal>4,5,6,1,2,3,7</literal>").
      If left empty, then no sorting will be done.
      See also <link linkend="vcskeywordsmergesupport">Automatic Merge...</link>.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Merge version control history on merge start</guilabel></term><listitem><para>
      If activated &kdiff3; runs the automatic history merging using aforementioned options when a merge is started.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Max number of history entries:</guilabel></term><listitem><para>
      &kdiff3; truncates the history list after the specified number of entries. Use <literal>-1</literal> to avoid truncation. (Default is <literal>-1</literal>).
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Test your regular expressions</guilabel></term><listitem><para>
      This button shows a dialog that allows you to improve and test the regular expressions above.
      Just copy the respective data from your files into the example lines. The <guilabel>Match result:</guilabel> option will immediately show whether the match succeeds or not.
      The <guilabel>Sort key result:</guilabel> will display the key used for history merge sorting.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Irrelevant merge command:</guilabel></term><listitem><para>
      Specify a command of your own that should be called when &kdiff3; detects
      that for a three file merge the file from <guilabel>B</guilabel> doesn't contribute any
      relevant data that isn't already contained in the file from <guilabel>C</guilabel>.
      The command is called with the three filenames as parameters.
      Data matched by the <guilabel>Auto merge regular expression</guilabel> or in the
      history isn't considered relevant.
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Auto save and quit on merge without conflicts</guilabel></term><listitem><para>
      If &kdiff3; was started for a file-merge from the command line and all conflicts are
      solvable without user interaction then automatically save and quit.
      (Similar to command line option <option>--auto</option>.)
   </para></listitem></varlistentry>
</variablelist>

</sect2>

<sect2><title>Folder Merge</title>
<para>
   These options are concerned with scanning the folder and handling the
   merge: See the <link linkend="dirmergeoptions">Folder Comparison/Merge
   Docs</link> for details.
</para><para>
Yet there is one option here that is also relevant for saving single files:
</para>
<variablelist>
   <varlistentry><term><guilabel>Backup files (.orig)</guilabel></term><listitem><para> When a file is saved and an older version already exists, then the original version will be renamed with an <literal role="extension">.orig</literal> extension. If an old backup file with <literal role="extension">.orig</literal> extension already exists then this will be deleted without backup.
   </para></listitem></varlistentry>
</variablelist>
</sect2>

<sect2><title>Regional and Language Options</title>
  <variablelist>
    <varlistentry><term><guilabel>Use the same encoding for everything</guilabel></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><guilabel>Note: Local Encoding is "..."</guilabel></term><listitem><para>Above the codec-selectors appears this 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><guilabel>Auto Detect</guilabel></term><listitem><para> This option attempts to use the BOM or meta data from XML/HTML documents to detect encoding. Failing that it will check if a short sample from the beginning of the file can be interpreted as UTF-8. If this check passes UTF-8 will be used. Otherwise it will fall back to the user selected codec. Only UTF-8 is supported with no BOM or metadata present.
	</para></listitem></varlistentry>
    <varlistentry><term><guilabel>File Encoding for A/B/C:</guilabel></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><guilabel>File Encoding for Merge Output and Saving:</guilabel></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><guilabel>File Encoding for Preprocessor Files:</guilabel></term><listitem><para>When you define preprocessors then they might not be able to operate on your codec. (&eg;: 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><guilabel>Right To Left Language:</guilabel></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 <option>--reverse</option> then all layouting will be done right to left too. (This is a feature provided by &Qt;.)
    </para><note><para>
    This documentation was written assuming that this option 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></note></listitem></varlistentry>

  </variablelist>
</sect2>

<sect2><title>Miscellaneous</title>
<para>(These options and actions are available in menus or the buttonbar.)</para>
<variablelist>
  <varlistentry><term><emphasis>Overview options:</emphasis></term><listitem><para>
    These choices are only available when you compare three files. In normal mode all
    differences are shown in one color-coded overview-column. But sometimes you are
    especially interested in the differences between only two of these three files.
    Selecting "A vs. B", "A vs. C" or "B vs. C"-overview will show a second overview
    column with the required information next to the normal overview.
  </para></listitem></varlistentry>
  <varlistentry><term><guimenuitem>Word Wrap Diff Windows</guimenuitem></term><listitem><para>
    Wrap lines when their length would exceed the width of a window.
  </para></listitem></varlistentry>
  <varlistentry><term><guibutton>Show Window A/B/C:</guibutton></term><listitem><para> Sometimes you want to use the space on
    the screen better for long lines. Hide the windows that are not important.
    (In the Windows-menu.)</para></listitem></varlistentry>
  <varlistentry><term><guibutton>Toggle Split Orientation</guibutton></term><listitem><para>
    Switch between diff windows shown next to each other (<guilabel>A</guilabel> left of <guilabel>B</guilabel> left of <guilabel>C</guilabel>) or above each other (<guilabel>A</guilabel> above <guilabel>B</guilabel> above <guilabel>C</guilabel>). This should also help for long lines. (In the <guimenu>Window</guimenu> menu.)
  </para></listitem></varlistentry>
  <varlistentry><term><guibutton>Merge Current File</guibutton></term><listitem><para> Works if you only compare
    two files. A single click starts the merge and uses the filename of the last
    input-file as the default output filename. (When this is used to restart
    a merge, then the output filename will be preserved.)</para></listitem></varlistentry>
  <varlistentry><term><guibutton>Show White Space</guibutton></term><listitem><para> Turn this off to suppress
    any highlighting of white-space-only changes in the text or overview-columns.
    (Note that this also applies to changes in numbers or comments if the options
    <guilabel>Ignore numbers (treat as white space)</guilabel> or <guilabel>Ignore C/C++ comments
    (treat as white space)</guilabel> are active.)</para></listitem></varlistentry>
  <varlistentry><term><guibutton>Show Space &amp;&amp; Tabulator Characters</guibutton></term><listitem><para> Sometimes
    the visible spaces and tabs are disturbing. You can turn this off.</para></listitem></varlistentry>
  <varlistentry><term><guibutton>Show Line Numbers</guibutton></term><listitem><para> You can select if line numbers should be
    shown for the input files.</para></listitem></varlistentry>
</variablelist>
</sect2>

<sect2 id="shortcuts"><title>Configuring Keyboard-Shortcuts</title>
<para>
   Currently only the &frameworks; version supports user-configurable keyboard-shortcuts.
   (Menu <menuchoice><guimenu>Settings</guimenu><guimenuitem>Configure Shortcuts...</guimenuitem></menuchoice>)
</para>
</sect2>
</sect1>

<sect1 id="preprocessors"><title>Preprocessor Commands</title>
<para>
&kdiff3; supports two preprocessor options.
</para><para>
<variablelist>
   <varlistentry><term><guilabel>Preprocessor command:</guilabel></term><listitem><para>
      When any file is read, it will be piped through this external command.
      The output of this command will be visible instead of the original file.
      You can write your own preprocessor that fulfills your specific needs.
      Use this to cut away disturbing parts of the file, or to automatically
      correct the indentation &etc;
   </para></listitem></varlistentry>
   <varlistentry><term><guilabel>Line-matching preprocessor command:</guilabel></term><listitem><para>
      When any file is read, it will be piped through this external command. If
      a preprocessor-command (see above) is also specified, then the output of the
      preprocessor is the input of the line-matching preprocessor.
      The output will only be used during the line matching phase of the analysis.
      You can write your own preprocessor that fulfills your specific needs.
      Each input line must have a corresponding output line.
   </para></listitem></varlistentry>
</variablelist>
</para>
<para>
The idea is to allow the user greater flexibility while configuring the diff-result.
But this requires an external program, and many users don't want to write one themselves.
The good news is that very often <command>sed</command> or <command>perl</command>
will do the job.
</para>
<para>Example: Simple testcase: Consider file a.txt (6 lines):
</para>
<screen>
      aa
      ba
      ca
      da
      ea
      fa
</screen>
<para>
And file b.txt (3 lines):
</para>
<screen>
      cg
      dg
      eg
</screen>
<para>
Without a preprocessor the following lines would be placed next to each other:
</para>
<screen>
      aa - cg
      ba - dg
      ca - eg
      da
      ea
      fa
</screen>
<para>
This is probably not wanted since the first letter contains the actually interesting information.
To help the matching algorithm to ignore the second letter we can use a line matching preprocessor
command, that replaces 'g' with 'a':
</para>
<screen>
   <command>sed</command> 's/g/a/'
</screen>
<para>
With this command the result of the comparison would be:
</para>
<screen>
      aa
      ba
      ca - cg
      da - dg
      ea - eg
      fa
</screen>
<para>
Internally the matching algorithm sees the files after running the line matching preprocessor,
but on the screen the file is unchanged. (The normal preprocessor would change the data also on
the screen.)
</para>

<sect2 id="sedbasics"><title><command>sed</command> Basics</title>
<para>
This section only introduces some very basic features of <command>sed</command>. For more
information see <ulink url="info:/sed">info:/sed</ulink> or
<ulink url="https://www.gnu.org/software/sed/manual/html_mono/sed.html">
https://www.gnu.org/software/sed/manual/html_mono/sed.html</ulink>.
A precompiled version for &Windows; can be found at <ulink url="http://unxutils.sourceforge.net">
http://unxutils.sourceforge.net</ulink>.
Note that the following examples assume that the <command>sed</command> command is in some
folder in the <envar>PATH</envar> environment variable. If this is not the case, you have to specify the full absolute
path for the command.
</para>
<para>
In this context only the <command>sed</command> substitute command is used:
</para>
<screen>
   <command>sed</command> 's/<replaceable>REGEXP</replaceable>/<replaceable>REPLACEMENT</replaceable>/<replaceable>FLAGS</replaceable>'
</screen>
<para>
Before you use a new command within &kdiff3;, you should first test it in a console.
Here the <command>echo</command> command is useful. Example:
</para>
<screen>
   <command>echo</command> abrakadabra | <command>sed</command> 's/a/o/'
   -> obrakadabra
</screen>
<para>
This example shows a very simple sed-command that replaces the first occurrence
of "a" with "o". If you want to replace all occurrences then you need the "g" flag:
</para>
<screen>
   <command>echo</command> abrakadabra | <command>sed</command> 's/a/o/g'
   -> obrokodobro
</screen>
<para>
The "|"-symbol is the pipe-command that transfers the output of the previous
command to the input of the following command. If you want to test with a longer file
then you can use <command>cat</command> on &UNIX; like systems or <command>type</command>
on &Windows; like systems. <command>sed</command> will do the substitution for each line.
<screen>
   <command>cat</command> <replaceable>filename</replaceable> | <command>sed</command> <replaceable>options</replaceable>
</screen>
</para>
</sect2>
<sect2 id="sedforkdiff3"><title>Examples For <command>sed</command> Use In &kdiff3;</title>
<sect3><title>Ignoring Other Types Of Comments</title>
<para>
Currently &kdiff3; understands only C/C++ comments. Using the
<guilabel>Line-matching preprocessor command:</guilabel> option you can also ignore
other types of comments, by converting them into C/C++-comments.
</para>
<para>
Example: To ignore comments starting with "<literal>#</literal>", you would like to convert them to "<literal>//</literal>". Note that you also must enable the <guilabel>Ignore C/C++ comments (treat as white space)</guilabel> option to get an effect. An appropriate <guilabel>Line-matching preprocessor command:</guilabel> would be:
</para>
<screen>
   <command>sed</command> 's/#/\/\//'
</screen>
<para>
Since for <command>sed</command> the "<literal>/</literal>" character has a special meaning, it is necessary to place the "<literal>\</literal>" character before each "<literal>/</literal>" in the replacement-string. Sometimes the "<literal>\</literal>" is required to add or remove a special meaning of certain characters. The single quotation marks (') are only important when testing on the command shell as it will otherwise attempt to process some characters.
&kdiff3; does not do this except for the escape sequences '<literal>\"</literal>' and '<literal>\\</literal>'.
</para>
</sect3>
<sect3><title>Caseinsensitive Diff</title>
<para>
Use the following <guilabel>Line-matching preprocessor command:</guilabel> to convert all input to uppercase:
</para>
<screen>
   <command>sed</command> 's/\(.*\)/\U\1/'
</screen>
<para>
Here the "<literal>.*</literal>" is a regular expression that matches any string and in this context matches all characters in the line.
The "<literal>\1</literal>" in the replacement string refers to the matched text within the first pair of "<literal>\(</literal>" and "<literal>\)</literal>".
The "<literal>\U</literal>" converts the inserted text to uppercase.
</para>
</sect3>

<sect3><title>Ignoring Version Control Keywords</title>
<para>
CVS and other version control systems use several keywords to insert automatically
generated strings (<ulink url="info:/cvs/Keyword substitution">info:/cvs/Keyword substitution</ulink>).
All of them follow the pattern "<replaceable>$KEYWORD generated text$</replaceable>". We now need a
line-matching preprocessor command that removes only the generated text:
</para>
<screen>
   <command>sed</command> 's/\$\(Revision\|Author\|Log\|Header\|Date\).*\$/\$\1\$/'
</screen>
<para>
The "<literal>\|</literal>" separates the possible keywords. You might want to modify this list
according to your needs.
The "<literal>\</literal>" before the "<literal>$</literal>" is necessary because otherwise the "<literal>$</literal>" matches the end of the line.
</para>
<para>
While experimenting with <command>sed</command> you might come to understand and even like
these regular expressions. They are useful because there are many other programs that also
support similar things.
</para>
</sect3>

<sect3><title>Ignoring Numbers</title>
<para>
Ignoring numbers actually is a built-in option. But as another example, this is how
it would look as a line-matching preprocessor command.
</para>
<screen>
   <command>sed</command> 's/[0123456789.-]//g'
</screen>
<para>
Any character within '<literal>[</literal>' and '<literal>]</literal>' is a match and will be replaced with nothing.
</para>
</sect3>

<sect3><title>Ignoring Certain Columns</title>
<para>
Sometimes a text is very strictly formatted, and contains columns that you always want to ignore, while there are
other columns you want to preserve for analysis. In the following example the first five columns (characters) are
ignored, the next ten columns are preserved, then again five columns are ignored and the rest of the line is preserved.
</para>
<screen>
   <command>sed</command> 's/.....\(..........\).....\(.*\)/\1\2/'
</screen>
<para>
Each dot '<literal>.</literal>' matches any single character. The "<literal>\1</literal>" and "<literal>\2</literal>" in the replacement string refer to the matched text within the first
and second pair of "<literal>\(</literal>" and "<literal>\)</literal>" denoting the text to be preserved.
</para>
</sect3>

<sect3><title>Combining Several Substitutions</title>
<para>
Sometimes you want to apply several substitutions at once. You can then use the
semicolon '<literal>;</literal>' to separate these from each other. Example:
</para>
<screen>
   <command>echo</command> abrakadabra | <command>sed</command> 's/a/o/g;s/\(.*\)/\U\1/'
   -> OBROKODOBRO
</screen>
</sect3>

<sect3><title>Using <command>perl</command> instead of <command>sed</command></title>
<para>
Instead of <command>sed</command> you might want to use something else like
<command>perl</command>.
</para>
<screen>
   <command>perl</command> -p -e 's/<replaceable>REGEXP</replaceable>/<replaceable>REPLACEMENT</replaceable>/<replaceable>FLAGS</replaceable>'
</screen>
<para>
But some details are different in <command>perl</command>. Note that where
<command>sed</command> needed "<literal>\(</literal>" and "<literal>\)</literal>" <command>perl</command>
requires the simpler "<literal>(</literal>" and "<literal>)</literal>" without preceding '<literal>\</literal>'. Example:
</para>
<screen>
   <command>sed</command> 's/\(.*\)/\U\1/'
   <command>perl</command> -p -e 's/(.*)/\U\1/'
</screen>
</sect3>
</sect2>

<sect2><title>Order Of Preprocessor Execution</title>
<para>
The data is piped through all internal and external preprocessors in the
following order:
</para>
<itemizedlist>
<listitem><para>Normal preprocessor,</para></listitem>
<listitem><para>Line-matching preprocessor,</para></listitem>
<listitem><para>Ignore case (treat as white space) (conversion to uppercase),</para></listitem>
<listitem><para>Detection of C/C++ comments,</para></listitem>
<listitem><para>Ignore numbers (treat as white space),</para></listitem>
<listitem><para>Ignore white space</para></listitem>
</itemizedlist>
<para>
The data after the normal preprocessor will be preserved for display and merging. The
other operations only modify the data that the line-matching-diff-algorithm sees.
</para><para>
In the rare cases where you use a normal preprocessor note that
the line-matching-preprocessor sees the output of the normal preprocessor as input.
</para>
</sect2>

<sect2><title>Warning</title>
<para>
The preprocessor-commands are often very useful, but as with any option that modifies
your texts or hides away certain differences automatically, you might accidentally overlook
certain differences and in the worst case destroy important data.
</para><para>
For this reason during a merge if a normal preprocessor-command is being used &kdiff3; will tell you so and ask you if it should be disabled or not. But it won't warn you if a <guilabel>Line-matching preprocessor command:</guilabel> option is active. The merge will not complete until all conflicts are solved. If you disabled <menuchoice><guimenu>Diffview</guimenu><guimenuitem>Show White Space</guimenuitem></menuchoice> menu item then the differences that were removed with the <guilabel>Line-matching preprocessor command:</guilabel> option will also be invisible. If the <guibutton>Save</guibutton> button remains disabled during a merge (because of remaining conflicts), make sure to enable <menuchoice><guimenu>Diffview</guimenu><guimenuitem>Show White Space</guimenuitem></menuchoice> menu item. If you don't want to merge these less important differences manually
you can select <menuchoice><guimenu>Merge</guimenu><guimenuitem>Choose [A|B|C] for All Unsolved Whitespace Conflicts</guimenuitem></menuchoice> menu item.
</para>
</sect2>
</sect1>
</chapter>


<chapter id="dirmerge"><title>Folder Comparison and Merge with &kdiff3;</title>
<sect1 id="dirmergeintro"><title>Introduction into Folder Comparison and Merge</title>
<para>
   Often programmers must modify many files in a folder to achieve their
   purpose. For this &kdiff3; also lets you compare and merge complete folders
   recursively!
</para><para>
   Even though comparing and merging folders seems to be quite obvious,
   there are several details that you should know about. Most important is of
   course the fact that now many files might be affected by each operation.
   If you don't have backups of your original data, then it can be very hard
   or even impossible to return to the original state. So before starting a merge,
   make sure that your data is safe, and going back is possible. If you make
   an archive or use some version control system is your decision, but even
   experienced programmers and integrators need the old sources now and then.
   And note that even though I (the author of &kdiff3;) try to do my best, I can't
   guarantee that there are no bugs. According to the &GNU; GPL there is NO WARRANTY
   whatsoever for this program. So be humble and always keep in mind:
</para>
<blockquote><para>
   <emphasis>To err is human, but to really mess things up you need a computer.</emphasis>
</para></blockquote>
<para>
So this is what this program can do for you: &kdiff3; ...
</para>
<itemizedlist>
     <listitem><para>... reads and compares two or three folders recursively,</para></listitem>
     <listitem><para>... takes special care of symbolic links,</para></listitem>
     <listitem><para>... lets you browse files on mouse double click,</para></listitem>
     <listitem><para>... for each item proposes a merge operation, which you can change
                         before starting the folder merge,</para></listitem>
     <listitem><para>... lets you simulate the merge and lists the actions that would
                         take  place, without actually doing them,</para></listitem>
     <listitem><para>... lets you really do the merge, and lets you interact whenever
                         manual interaction is needed,</para></listitem>
     <listitem><para>... lets you run the selected operation for all items (<keycap>F7</keycap> key) or the selected item (<keycap>F6</keycap> key),</para></listitem>
     <listitem><para>... lets you continue the merge after manual interaction with <keycap>F7</keycap> key,</para></listitem>
     <listitem><para>... optionally creates backups, with the <literal role="extension">.orig</literal> extension,</para></listitem>
     <listitem><para>...</para></listitem>
</itemizedlist>
</sect1>

<sect1 id="startingdirmerge"><title>Starting Folder Comparison Or Merge</title>
<para>
   This is very similar to the single file merge and comparison. You just
   have  to specify folders on the command line or in the file-open
   dialog.
</para>
<sect2><title>Compare/Merge two folders: </title>
<screen>
   <command>kdiff3</command> <replaceable>folder1 folder2</replaceable>
   <command>kdiff3</command> <replaceable>folder1 folder2</replaceable> -o <replaceable>destdir</replaceable>
</screen>
<para>
   If no destination folder is specified, then &kdiff3; will use <replaceable>folder2</replaceable>.
</para>
</sect2>

<sect2><title>Compare/Merge three folders: </title>
<screen>
   <command>kdiff3</command> <replaceable>folder1 folder2 folder3</replaceable>
   <command>kdiff3</command> <replaceable>folder1 folder2 folder3</replaceable> -o <replaceable>destdir</replaceable>
</screen>
<para>
   When three folders are merged then <replaceable>folder1</replaceable>
   is used as the base for the merge.
   If no destination folder is specified, then &kdiff3; will use <replaceable>folder3</replaceable>
   as the  destination folder for the merge.
</para>

<para>
   Note that only the comparison starts automatically, not the merge. For this you first must
   select a menu entry or the <keycap>F7</keycap> key. (More details later.)
</para>
</sect2>
</sect1>

<sect1 id="dirmergevisible"><title>Folder Merge Visible Information</title>
<para>
   While reading the folders a message-box appears that informs you of
   the progress. If you abort the folder scan, then only files that have
   been  compared until then will be listed.
</para><para>
   When the folder scan is complete then &kdiff3; will show a listbox with
   the results left, ...
</para>
<screenshot><mediaobject>
<imageobject><imagedata fileref="dirbrowser.png" format="PNG"/></imageobject> <!--alt="Image of the folder browser."-->
</mediaobject></screenshot>
<para>
   ... and details about the currently selected item on the right:
</para>
<screenshot><mediaobject>
<imageobject><imagedata fileref="iteminfo.png" format="PNG"/></imageobject>
   <!--alt="Image with information about the selected item."-->
</mediaobject></screenshot>

<sect2 id="name"><title>The Name Column</title>
<para>
   Each file and folder that was found during the scan is shown here in
   a tree. You can select an item by clicking it with the mouse once.
</para><para>
   The folders are collapsed by default. You can expand and collapse
   them by clicking on the "+"/"-" or by double-clicking the item or
   by using the &Left;/&Right; cursor keys. The <guimenu>Folder</guimenu> menu also contains two
   actions <guimenuitem>Fold All Subfolders</guimenuitem> and <guimenuitem>Unfold All Subfolders</guimenuitem> with which you can
   collapse or expand all folders at once.
</para><para>
   If you double-click a file item then the file comparison starts and the
   file-diff-window will appear.
</para>
<para>
   The image in the name column reflects the file type in the first
   folder  (<guilabel>A</guilabel>). It can be one of these:
</para>
<itemizedlist>
     <listitem><para>Normal file</para></listitem>
     <listitem><para>Normal folder (folder image)</para></listitem>
     <listitem><para>Link to a file (file image with a link arrow)</para></listitem>
     <listitem><para>Link to a folder (folder image with a link arrow)</para></listitem>
</itemizedlist>
<para>
   If the file type is different in the other folders, then this is visible
   in the columns <guilabel>A</guilabel>/<guilabel>B</guilabel>/<guilabel>C</guilabel>
   and in the window that shows the details about the selected item. Note that
   for such a case no merge operation can be selected automatically. When starting
   the merge, then the user will be informed of problems of that kind.
</para>
</sect2>

<sect2 id="coloring"><title>The Columns A/B/C and the Coloring Scheme</title>
<para>
   As can be seen in the image above the colors red, green, yellow and black
   are used in the columns <guilabel>A</guilabel>/<guilabel>B</guilabel>/<guilabel>C</guilabel>.
</para>
<itemizedlist>
     <listitem><para>Black: This item doesn't exist in this folder.</para></listitem>
     <listitem><para>Green: Newest item.</para></listitem>
     <listitem><para>Yellow: Older than green, newer than red.</para></listitem>
     <listitem><para>Red: Oldest item.</para></listitem>
</itemizedlist>
<para>
   But for items that were identical in the comparison their color also is
   identical even if the age is not.
</para><para>
   Folders are considered equal if all items they contain are identical.
   Then they also will have the same color. But the age of a folder is not
   considered for its color.
</para><para>
   The idea for this coloring scheme I came upon in
   <ulink url="https://www.samba.org/ftp/paulus/"><command>dirdiff</command> command</ulink>. The colors
   resemble the colors of a leaf that is green when new, turns yellow later and red
   when old.
</para>

</sect2><sect2 id="operation"><title>The Operation Column</title>
<para>
   After comparing t
Download .txt
gitextract_ofgqlzq8/

├── .clang-format
├── .clang-tidy
├── .craft.ini
├── .editorconfig
├── .flatpak-manifest.json
├── .flatpak-manifest.json.license
├── .gitignore
├── .gitlab-ci.yml
├── .kde-ci.yml
├── CMakeLists.txt
├── COPYING
├── ChangeLog
├── CppCheckSuppressions.txt
├── INSTALL
├── LICENSES/
│   ├── BSD-2-Clause.txt
│   ├── CC0-1.0.txt
│   ├── GPL-2.0-or-later.txt
│   └── MIT.txt
├── README
├── UBSan.supp
├── diff_ext_for_kdiff3/
│   ├── .krazy
│   ├── CMakeLists.txt
│   ├── LICENSE
│   ├── Messages.sh
│   ├── README
│   ├── class_factory.cpp
│   ├── class_factory.h
│   ├── diff_ext.cpp
│   ├── diff_ext.h
│   ├── diff_ext_for_kdiff3.def
│   ├── diff_ext_for_kdiff3.rc
│   ├── diff_ext_for_kdiff3_msvc.def
│   ├── server.cpp
│   └── server.h
├── doc/
│   ├── CMakeLists.txt
│   └── en/
│       ├── CMakeLists.txt
│       ├── index.docbook
│       └── man-kdiff3.1.docbook
├── kdiff3fileitemactionplugin/
│   ├── CMakeLists.txt
│   ├── Messages.sh
│   ├── kdiff3fileitemaction.cpp
│   ├── kdiff3fileitemaction.h
│   └── kdiff3fileitemaction.json
├── po/
│   ├── ar/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ast/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── bg/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── br/
│   │   └── kdiff3.po
│   ├── bs/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ca/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ca@valencia/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── cs/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── cy/
│   │   └── kdiff3.po
│   ├── da/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── de/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── el/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── en_GB/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── eo/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── es/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── et/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── eu/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── fi/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── fr/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ga/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── gl/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── he/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── hi/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── hne/
│   │   └── kdiff3.po
│   ├── hr/
│   │   └── kdiff3.po
│   ├── hu/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ia/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── id/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── is/
│   │   └── kdiff3.po
│   ├── it/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ja/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ka/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ko/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── lt/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── mai/
│   │   └── kdiff3.po
│   ├── ml/
│   │   └── kdiff3.po
│   ├── mr/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nb/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nds/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nl/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── nn/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pl/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pt/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       └── index.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── pt_BR/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ro/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ru/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── rw/
│   │   └── kdiff3.po
│   ├── sa/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sk/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sl/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@ijekavian/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@ijekavianlatin/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sr@latin/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── sv/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ta/
│   │   └── kdiff3.po
│   ├── tg/
│   │   └── kdiff3.po
│   ├── tr/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── ug/
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── uk/
│   │   ├── diff_ext.po
│   │   ├── docs/
│   │   │   └── kdiff3/
│   │   │       ├── index.docbook
│   │   │       └── man-kdiff3.1.docbook
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   ├── zh_CN/
│   │   ├── diff_ext.po
│   │   ├── kdiff3.po
│   │   └── kdiff3fileitemactionplugin.po
│   └── zh_TW/
│       ├── diff_ext.po
│       ├── kdiff3.po
│       └── kdiff3fileitemactionplugin.po
├── setup.cfg
├── src/
│   ├── CMakeLists.txt
│   ├── CommentParser.cpp
│   ├── CommentParser.h
│   ├── CompositeIgnoreList.cpp
│   ├── CompositeIgnoreList.h
│   ├── ConfigValueMap.h
│   ├── CvsIgnoreList.cpp
│   ├── CvsIgnoreList.h
│   ├── DefaultFileAccessJobHandler.cpp
│   ├── DefaultFileAccessJobHandler.h
│   ├── DirectoryInfo.cpp
│   ├── DirectoryInfo.h
│   ├── DirectoryList.h
│   ├── EncodedData.h
│   ├── FileAccessJobHandler.h
│   ├── FileNameLineEdit.cpp
│   ├── FileNameLineEdit.h
│   ├── FontChooser.ui
│   ├── GitIgnoreList.cpp
│   ├── GitIgnoreList.h
│   ├── IgnoreList.h
│   ├── LineRef.h
│   ├── Logging.cpp
│   ├── Logging.h
│   ├── MacOSXBundleInfo.plist.in
│   ├── MergeEditLine.cpp
│   ├── MergeEditLine.h
│   ├── MergeFileInfos.cpp
│   ├── MergeFileInfos.h
│   ├── Messages.sh
│   ├── OptionItems.h
│   ├── Options.cpp
│   ├── Overview.cpp
│   ├── Overview.h
│   ├── PixMapUtils.cpp
│   ├── PixMapUtils.h
│   ├── ProgressProxy.cpp
│   ├── ProgressProxy.h
│   ├── ProgressProxyExtender.cpp
│   ├── ProgressProxyExtender.h
│   ├── RLPainter.h
│   ├── RecentItems.h
│   ├── SourceData.cpp
│   ├── SourceData.h
│   ├── StandardMenus.cpp
│   ├── StandardMenus.h
│   ├── TypeUtils.h
│   ├── UndoRecord.h
│   ├── Utils.cpp
│   ├── Utils.h
│   ├── autotests/
│   │   ├── CMakeLists.txt
│   │   ├── CompositeIgnoreListTest.cpp
│   │   ├── CvsIgnoreListTest.cpp
│   │   ├── Diff3LineTest.cpp
│   │   ├── DiffTest.cpp
│   │   ├── FileAccessJobHandlerMoc.h
│   │   ├── FileAccessTest.cpp
│   │   ├── GitIgnoreListTest.cpp
│   │   ├── ManualDiffHelpListTest.cpp
│   │   ├── MocIgnoreFile.h
│   │   ├── SourceDataMoc.h
│   │   ├── combinertest.cpp
│   │   ├── commentparser.cpp
│   │   ├── connectiontest.cpp
│   │   └── datareadtest.cpp
│   ├── combiners.h
│   ├── common.cpp
│   ├── common.h
│   ├── compat.h
│   ├── defmac.h
│   ├── diff.cpp
│   ├── diff.h
│   ├── difftextwindow.cpp
│   ├── difftextwindow.h
│   ├── directorymergewindow.cpp
│   ├── directorymergewindow.h
│   ├── fileaccess.cpp
│   ├── fileaccess.h
│   ├── gnudiff_analyze.cpp
│   ├── gnudiff_diff.h
│   ├── gnudiff_io.cpp
│   ├── gnudiff_xmalloc.cpp
│   ├── guiutils.h
│   ├── icons/
│   │   ├── CMakeLists.txt
│   │   └── sc-apps-kdiff3.svgz
│   ├── kdiff3.cpp
│   ├── kdiff3.h
│   ├── kdiff3.qrc
│   ├── kdiff3_shell.cpp
│   ├── kdiff3_shell.h
│   ├── kdiff3_shell.rc
│   ├── kdiff3win.rc
│   ├── main.cpp
│   ├── merger.cpp
│   ├── merger.h
│   ├── mergeresultwindow.cpp
│   ├── mergeresultwindow.h
│   ├── opendialog.ui
│   ├── optiondialog.cpp
│   ├── optiondialog.h
│   ├── options.h
│   ├── org.kde.kdiff3.appdata.xml
│   ├── org.kde.kdiff3.desktop
│   ├── pdiff.cpp
│   ├── progress.cpp
│   ├── progress.h
│   ├── progressdialog.ui
│   ├── scroller.ui
│   ├── selection.cpp
│   ├── selection.h
│   ├── smalldialogs.cpp
│   ├── smalldialogs.h
│   └── xpm/
│       ├── autoadvance.xpm
│       ├── autoadvance.xpm.license
│       ├── currentpos.xpm
│       ├── currentpos.xpm.license
│       ├── down1arrow.xpm
│       ├── down1arrow.xpm.license
│       ├── down2arrow.xpm
│       ├── down2arrow.xpm.license
│       ├── downend.xpm
│       ├── downend.xpm.license
│       ├── file.xpm
│       ├── file.xpm.license
│       ├── folder.xpm
│       ├── folder.xpm.license
│       ├── gotoline.xpm
│       ├── gotoline.xpm.license
│       ├── iconA.xpm
│       ├── iconA.xpm.license
│       ├── iconB.xpm
│       ├── iconB.xpm.license
│       ├── iconC.xpm
│       ├── iconC.xpm.license
│       ├── link_arrow.xpm
│       ├── link_arrow.xpm.license
│       ├── nextunsolved.xpm
│       ├── nextunsolved.xpm.license
│       ├── prevunsolved.xpm
│       ├── prevunsolved.xpm.license
│       ├── showequalfiles.xpm
│       ├── showequalfiles.xpm.license
│       ├── showfilesonlyina.xpm
│       ├── showfilesonlyina.xpm.license
│       ├── showfilesonlyinb.xpm
│       ├── showfilesonlyinb.xpm.license
│       ├── showfilesonlyinc.xpm
│       ├── showfilesonlyinc.xpm.license
│       ├── showlinenumbers.xpm
│       ├── showlinenumbers.xpm.license
│       ├── showwhitespace.xpm
│       ├── showwhitespace.xpm.license
│       ├── showwhitespacechars.xpm
│       ├── showwhitespacechars.xpm.license
│       ├── startmerge.xpm
│       ├── startmerge.xpm.license
│       ├── up1arrow.xpm
│       ├── up1arrow.xpm.license
│       ├── up2arrow.xpm
│       ├── up2arrow.xpm.license
│       ├── upend.xpm
│       └── upend.xpm.license
└── test/
    ├── alignmenttest.cpp
    ├── fakefileaccess.cpp
    ├── generate_testdata_from_git_merges.py
    ├── generate_testdata_from_permutations.py
    └── testdata/
        ├── 1_simpletest_base.txt
        ├── 1_simpletest_contrib1.txt
        ├── 1_simpletest_contrib2.txt
        ├── 1_simpletest_expected_result.txt
        ├── 2_prefer_identical_to_space_differences_base.txt
        ├── 2_prefer_identical_to_space_differences_contrib1.txt
        ├── 2_prefer_identical_to_space_differences_contrib2.txt
        ├── 2_prefer_identical_to_space_differences_expected_result.txt
        └── README
Download .txt
SYMBOL INDEX (483 symbols across 88 files)

FILE: diff_ext_for_kdiff3/class_factory.cpp
  function STDMETHODIMP (line 20) | STDMETHODIMP
  function STDMETHODIMP (line 53) | STDMETHODIMP
  function STDMETHODIMP (line 71) | STDMETHODIMP

FILE: diff_ext_for_kdiff3/class_factory.h
  function class (line 13) | class CLASS_FACTORY : public IClassFactory {

FILE: diff_ext_for_kdiff3/diff_ext.cpp
  function STDMETHODIMP (line 41) | STDMETHODIMP
  function STDMETHODIMP (line 89) | STDMETHODIMP
  function insertMenuItemHelper (line 134) | static int insertMenuItemHelper(HMENU menu, UINT id, UINT position, cons...
  function STDMETHODIMP (line 160) | STDMETHODIMP
  function STDMETHODIMP (line 264) | STDMETHODIMP
  function STDMETHODIMP (line 343) | STDMETHODIMP
  function tstring (line 440) | tstring

FILE: diff_ext_for_kdiff3/server.cpp
  type REGSTRUCT (line 29) | struct REGSTRUCT {
  function tstring (line 47) | tstring SERVER::getRegistryKeyString( const tstring& subKey, const tstri...
  function STDAPI (line 97) | STDAPI
  function DllMain (line 108) | int APIENTRY
  function STDAPI (line 130) | STDAPI
  function STDAPI (line 144) | STDAPI
  function STDAPI (line 149) | STDAPI
  function SERVER (line 154) | SERVER* SERVER::instance()
  function HINSTANCE (line 197) | HINSTANCE
  function HRESULT (line 300) | HRESULT
  function HRESULT (line 382) | HRESULT

FILE: diff_ext_for_kdiff3/server.h
  type std (line 19) | typedef std::wstring tstring;
  function class (line 43) | class SERVER {

FILE: kdiff3fileitemactionplugin/kdiff3fileitemaction.cpp
  class KDiff3PluginHistory (line 32) | class KDiff3PluginHistory
    method KDiff3PluginHistory (line 38) | KDiff3PluginHistory()

FILE: kdiff3fileitemactionplugin/kdiff3fileitemaction.h
  function class (line 17) | class KDiff3FileItemAction: public KAbstractFileItemActionPlugin

FILE: src/CommentParser.h
  function virtual (line 25) | [[nodiscard]] virtual bool inComment() const = 0;

FILE: src/CompositeIgnoreList.h
  function class (line 21) | class CompositeIgnoreList : public IgnoreList

FILE: src/ConfigValueMap.h
  function class (line 23) | class ConfigValueMap : public ValueMap

FILE: src/CvsIgnoreList.h
  type CvsIgnorePatterns (line 24) | struct CvsIgnorePatterns
  function class (line 32) | class CvsIgnoreList : public IgnoreList

FILE: src/DefaultFileAccessJobHandler.h
  function namespace (line 23) | namespace KIO {
  function class (line 29) | class DefaultFileAccessJobHandler: public FileAccessJobHandler

FILE: src/DirectoryInfo.h
  function class (line 15) | class DirectoryInfo

FILE: src/EncodedData.h
  function class (line 32) | class EncodedData: public QByteArray
  function setGenerateByteOrderMark (line 88) | void setGenerateByteOrderMark(bool generate) { mGenerateBOM = generate; }
  function setEncoding (line 92) | void setEncoding(const QByteArray &inEncoding)
  function qint64 (line 114) | qint64 readNext(QString &s)
  function quint64 (line 143) | quint64 peekChar(QString &s)
  function class (line 194) | class EncodedFile: public QFile

FILE: src/FileAccessJobHandler.h
  function namespace (line 23) | namespace KIO {
  function class (line 29) | class FileAccessJobHandler: public QObject

FILE: src/FileNameLineEdit.h
  function class (line 15) | class FileNameLineEdit : public QLineEdit

FILE: src/GitIgnoreList.cpp
  function isComment (line 25) | bool isComment(const QString& line)
  function QString (line 83) | QString GitIgnoreList::readFile(const QString& fileName) const

FILE: src/GitIgnoreList.h
  function class (line 22) | class GitIgnoreList : public IgnoreList

FILE: src/IgnoreList.h
  function class (line 22) | class IgnoreList

FILE: src/LineRef.h
  function class (line 19) | class LineRef
  function operator (line 34) | operator SafeInt<LineType>() const noexcept { return mLineNumber; }
  function invalidate (line 73) | void invalidate() { mLineNumber = invalid; }

FILE: src/MergeEditLine.cpp
  function QString (line 25) | QString MergeEditLine::getString() const

FILE: src/MergeEditLine.h
  function class (line 23) | class MergeEditLine
  function setConflict (line 34) | void setConflict()
  function setString (line 54) | void setString(const QString& s)
  function QString (line 61) | [[nodiscard]] QString getString() const;
  function class (line 88) | class MergeBlock
  function hasModfiedText (line 115) | [[nodiscard]] bool hasModfiedText()
  function split (line 126) | void split(MergeBlock& mb2, LineType d3lLineIdx2) // The caller must ins...
  function join (line 159) | void join(MergeBlock& mb2) // The caller must remove the ml2 from the m_...
  function class (line 183) | class MergeBlockList: public std::list<MergeBlock>

FILE: src/MergeFileInfos.cpp
  function QString (line 90) | QString MergeFileInfos::subPath() const
  function QString (line 101) | QString MergeFileInfos::fileName() const
  function QString (line 139) | QString MergeFileInfos::fullNameA() const
  function QString (line 147) | QString MergeFileInfos::fullNameB() const
  function QString (line 155) | QString MergeFileInfos::fullNameC() const
  function QString (line 171) | QString MergeFileInfos::fullNameDest() const
  type FileIndex (line 183) | enum class FileIndex
  function QTextStream (line 560) | QTextStream& operator<<(QTextStream& ts, MergeFileInfos& mfi)

FILE: src/MergeFileInfos.h
  type e_MergeOperation (line 19) | enum e_MergeOperation
  type e_Age (line 45) | enum e_Age
  type e_OperationStatus (line 54) | enum e_OperationStatus
  function class (line 67) | class MergeFileInfos
  function class (line 212) | class MfiCompare

FILE: src/OptionItems.h
  function class (line 27) | class OptionItemBase
  function unpreserveImp (line 111) | void unpreserveImp() override { *m_pVar = m_preservedVal; }
  function explicit (line 125) | explicit OptionNum(T* pVar, const QString& saveName)
  function setCurrent (line 135) | void setCurrent(const T& inValue) override
  function QString (line 140) | static const QString toString(const T inValue)
  type Option (line 155) | typedef Option<bool> OptionToggleAction;
  type OptionNum (line 156) | typedef OptionNum<qint32> OptionInt;
  type Option (line 157) | typedef Option<QPoint> OptionPoint;
  type Option (line 158) | typedef Option<QSize> OptionSize;
  type Option (line 159) | typedef Option<QStringList> OptionStringList;
  type Option (line 161) | typedef Option<bool> OptionBool;
  type Option (line 162) | typedef Option<QFont> OptionFont;
  type Option (line 163) | typedef Option<QColor> OptionColor;
  type Option (line 164) | typedef Option<QString> OptionString;
  function class (line 166) | class OptionCodec : public OptionString

FILE: src/Options.cpp
  function QString (line 106) | const QString Options::parseOptions(const QStringList& optionList)
  function QString (line 133) | QString Options::calcOptionHelp()

FILE: src/Overview.cpp
  function e_OverviewMode (line 85) | e_OverviewMode Overview::getOverviewMode()

FILE: src/Overview.h
  type class (line 24) | enum class
  function class (line 32) | class Overview : public QWidget

FILE: src/PixMapUtils.cpp
  type PixMapUtils (line 19) | namespace PixMapUtils {
    function QPixmap (line 47) | QPixmap colorToPixmap(const QColor& inColor)
    function QPixmap (line 61) | QPixmap pixCombiner(const QPixmap* pm1, const QPixmap* pm2, const qrea...
    function initPixmaps (line 74) | void initPixmaps(const QColor& newest, const QColor& oldest, const QCo...
    function QPixmap (line 138) | QPixmap getOnePixmap(e_Age eAge, bool bLink, bool bDir)

FILE: src/PixMapUtils.h
  function namespace (line 18) | namespace PixMapUtils

FILE: src/ProgressProxy.h
  function class (line 27) | class ProgressScope
  function class (line 34) | class ProgressProxy

FILE: src/ProgressProxyExtender.h
  function Q_OBJECT (line 21) | Q_OBJECT

FILE: src/RLPainter.h
  function class (line 22) | class RLPainter: public QPainter
  function drawLine (line 68) | void drawLine(qint32 x1, qint32 y1, qint32 x2, qint32 y2)

FILE: src/RecentItems.h
  function push_front (line 31) | void push_front(const T &s) { prepend(s); }
  function prepend (line 33) | void prepend(const T &s)

FILE: src/SourceData.cpp
  function QString (line 99) | QString SourceData::getFilename() const
  function QString (line 104) | QString SourceData::getAliasName() const
  function LineType (line 176) | LineType SourceData::lineCount() const
  function qint64 (line 181) | qint64 SourceData::getSizeBytes() const
  function QString (line 191) | const QString& SourceData::getText() const

FILE: src/SourceData.h
  function class (line 26) | class SourceData

FILE: src/StandardMenus.h
  function class (line 22) | class StandardMenus

FILE: src/UndoRecord.h
  function class (line 17) | class UndoRecord
  function push (line 26) | void push(const MergeBlock& mb) { savedLines.push_back(mb); }
  function push (line 27) | void push(const MergeBlock&& mb)
  function MergeBlock (line 33) | const MergeBlock& pop()
  function undo (line 40) | void undo()

FILE: src/Utils.cpp
  function QString (line 36) | QString Utils::getArguments(QString cmd, QString& program, QStringList& ...
  function QString (line 155) | QString Utils::calcHistoryLead(const QString& s)
  function QString (line 175) | QString Utils::urlToString(const QUrl &url)
  function QStringList (line 191) | QStringList Utils::availableCodecs(){

FILE: src/Utils.h
  function class (line 21) | class Utils

FILE: src/autotests/CompositeIgnoreListTest.cpp
  class IgnoreListMock (line 15) | class IgnoreListMock final : public IgnoreList {
    method enterDir (line 19) | void enterDir(const QString&, const DirectoryList&) final {}
    method matches (line 20) | [[nodiscard]] bool matches([[maybe_unused]] const QString& dir, [[mayb...
  class CompositeIgnoreListTest (line 27) | class CompositeIgnoreListTest : public QObject
    method Q_OBJECT (line 29) | Q_OBJECT

FILE: src/autotests/CvsIgnoreListTest.cpp
  class IgnoreListTestInterface (line 16) | class IgnoreListTestInterface: public CvsIgnoreList
    method isEmpty (line 19) | bool isEmpty(const QString& dir) const
    method QStringList (line 24) | QStringList getExactMatchList(const QString& dir) const
  class CvsIgnoreListTest (line 31) | class CvsIgnoreListTest : public QObject
    method Q_OBJECT (line 36) | Q_OBJECT
    method addEntriesFromString (line 51) | void addEntriesFromString()
    method matches (line 61) | void matches()
    method testDefaults (line 109) | void testDefaults()

FILE: src/autotests/Diff3LineTest.cpp
  class Diff3LineTest (line 19) | class Diff3LineTest: public QObject
    method initTestCase (line 23) | void initTestCase()
    method calcDiffTest (line 37) | void calcDiffTest()

FILE: src/autotests/DiffTest.cpp
  class Diff3LineMoc (line 22) | class Diff3LineMoc: public Diff3Line
    method Diff3LineMoc (line 25) | Diff3LineMoc(const LineRef inLineA, const LineRef inLineB, const LineR...
  class DiffTest (line 43) | class DiffTest: public QObject
    method initTestCase (line 51) | void initTestCase()
    method testLineData (line 82) | void testLineData()
    method testTwoWayDiffLineChanged (line 120) | void testTwoWayDiffLineChanged()
    method testWhiteLineComment (line 183) | void testWhiteLineComment()

FILE: src/autotests/FileAccessJobHandlerMoc.h
  function class (line 16) | class FileAccessJobHandlerMoc: public FileAccessJobHandler

FILE: src/autotests/FileAccessTest.cpp
  class FileAccessMoc (line 17) | class FileAccessMoc: public FileAccess
    method setEngine (line 20) | void setEngine(FileAccessJobHandler* handler)
    method setParent (line 25) | void setParent(FileAccessMoc* parent)
    method setFileName (line 30) | void setFileName(const QString& name) { m_name = name; }
    method setUrl (line 31) | void setUrl(const QUrl& url) { m_url = url; }
    method loadData (line 33) | void loadData() override {}
  class FileAccessTest (line 36) | class FileAccessTest: public QObject
    method testFileRelPath (line 42) | void testFileRelPath()
    method testUrl (line 63) | void testUrl()
    method testIsLocal (line 95) | void testIsLocal()
    method testAbsolutePath (line 116) | void testAbsolutePath()
    method liveTest (line 155) | void liveTest()

FILE: src/autotests/GitIgnoreListTest.cpp
  class GitIgnoreListStub (line 16) | class GitIgnoreListStub final : public GitIgnoreList
    method QString (line 20) | [[nodiscard]] QString readFile([[maybe_unused]] const QString& fileNam...
  class GitIgnoreListTest (line 26) | class GitIgnoreListTest : public QObject
    method Q_OBJECT (line 28) | Q_OBJECT

FILE: src/autotests/ManualDiffHelpListTest.cpp
  class ManualDiffHelpListTest (line 8) | class ManualDiffHelpListTest: public QObject
    method Q_OBJECT (line 10) | Q_OBJECT
    method testListKeeptSorted (line 24) | void testListKeeptSorted()
    method testDeleteAndSort (line 41) | void testDeleteAndSort()

FILE: src/autotests/MocIgnoreFile.h
  function class (line 23) | class MocIgnoreFile: public FileAccess

FILE: src/autotests/SourceDataMoc.h
  function class (line 18) | class SourceDataMoc: public SourceData

FILE: src/autotests/combinertest.cpp
  class CombinertestTest (line 15) | class CombinertestTest: public QObject
    method QString (line 20) | QString nonEmpty2(){ return "test 2";}
    method QString (line 22) | QString nonEmpty1(){ return "test 1";}
    method QString (line 23) | QString emptyString(){ return "";}
    method yes (line 24) | bool yes() { return true; }
    method no (line 25) | bool no() { return false;}
    method testOrCombiner (line 28) | void testOrCombiner()
    method testAndCombiner (line 55) | void testAndCombiner()
    method testFirstNonEmpty (line 82) | void testFirstNonEmpty()

FILE: src/autotests/commentparser.cpp
  class CommentParserTest (line 14) | class CommentParserTest : public QObject
    method Q_OBJECT (line 16) | Q_OBJECT
    method singleLineComment (line 30) | void singleLineComment()
    method inComment (line 65) | void inComment()
    method multiLineComment (line 79) | void multiLineComment()
    method stringTest (line 182) | void stringTest()
    method quotedCharacter (line 232) | void quotedCharacter()
    method nonComment (line 267) | void nonComment()
    method removeComment (line 313) | void removeComment()

FILE: src/autotests/connectiontest.cpp
  class SigTest (line 17) | class SigTest: public QObject
    method slot (line 26) | void slot() { fired=true;}
  class ConnectionTest (line 29) | class ConnectionTest: public QObject
    method testConnect (line 33) | void testConnect()

FILE: src/autotests/datareadtest.cpp
  class DataReadTest (line 19) | class DataReadTest: public QObject
    method initTestCase (line 23) | void initTestCase()
    method testRead (line 69) | void testRead()
    method testEOLStyle (line 150) | void testEOLStyle()
    method trailingEOLTest (line 290) | void trailingEOLTest()

FILE: src/combiners.h
  type or_ (line 18) | struct or_
  type and_ (line 39) | struct and_
  type T (line 66) | typedef T result_type;
  type find (line 85) | struct find
  function throw_exception (line 107) | inline void boost::throw_exception([[maybe_unused]] std::exception const...

FILE: src/common.cpp
  function QString (line 40) | QString ValueMap::getAsString()
  function QString (line 70) | QString safeStringJoin(const QStringList& sl, char sepChar, char metaChar)
  function QStringList (line 100) | QStringList safeStringSplit(const QString& s, char sepChar, char metaChar)
  function QFont (line 181) | QFont ValueMap::readFontEntry(const QString& k, const QFont* defaultVal)
  function QColor (line 194) | QColor ValueMap::readColorEntry(const QString& k, const QColor* defaultVal)
  function QSize (line 207) | QSize ValueMap::readSizeEntry(const QString& k, const QSize* defaultVal)
  function QPoint (line 221) | QPoint ValueMap::readPointEntry(const QString& k, const QPoint* defaultVal)
  function qint32 (line 247) | qint32 ValueMap::readNumEntry(const QString& k, qint32 iDefault)
  function QString (line 260) | QString ValueMap::readStringEntry(const QString& k, const QString& sDefa...
  function QStringList (line 272) | QStringList ValueMap::readListEntry(const QString& k, const QStringList&...
  function QString (line 286) | QString ValueMap::readEntry(const QString& s, const QString& defaultVal)
  function QString (line 291) | QString ValueMap::readEntry(const QString& s, const char* defaultVal)
  function QFont (line 296) | QFont ValueMap::readEntry(const QString& s, const QFont& defaultVal)
  function QColor (line 301) | QColor ValueMap::readEntry(const QString& s, const QColor defaultVal)
  function QSize (line 306) | QSize ValueMap::readEntry(const QString& s, const QSize defaultVal)
  function QPoint (line 311) | QPoint ValueMap::readEntry(const QString& s, const QPoint defaultVal)
  function qint32 (line 321) | qint32 ValueMap::readEntry(const QString& s, qint32 iDefault)
  function QStringList (line 326) | QStringList ValueMap::readEntry(const QString& s, const QStringList& def...

FILE: src/common.h
  function class (line 27) | class ValueMap

FILE: src/compat.h
  function namespace (line 29) | namespace Compat {

FILE: src/diff.cpp
  function qint32 (line 38) | qint32 LineData::width(qint32 tabSize) const
  class StringIter (line 60) | class StringIter {
    method StringIter (line 65) | StringIter(QString const& s)
    method hasPeek (line 70) | bool hasPeek() const {
    method tryPeek (line 74) | std::optional<QChar> tryPeek() const {
    method next (line 82) | void next() {
  function qint32 (line 603) | qint32 ManualDiffHelpEntry::calcManualDiffFirstDiff3LineIdx(const Diff3L...

FILE: src/diff.h
  function e_SrcSelector (line 34) | enum class e_SrcSelector
  function class (line 214) | class DiffBufferInfo
  function IgnoreFlag (line 242) | enum class IgnoreFlag
  function isLineInRange (line 576) | bool isLineInRange(LineRef line, e_SrcSelector winIdx)
  function getRangeForUI (line 589) | void getRangeForUI(const e_SrcSelector winIdx, LineRef* rangeLine1, Line...
  function LineRef (line 608) | [[nodiscard]] const LineRef& getLine1(const e_SrcSelector winIdx) const ...
  function LineRef (line 610) | [[nodiscard]] const LineRef& getLine2(const e_SrcSelector winIdx) const ...
  function class (line 616) | class ManualDiffHelpList: public std::list<ManualDiffHelpEntry>
  function qint32 (line 630) | inline qint32 tabber(qint32 outPos, qint32 tabSize)
  type e_CoordType (line 641) | enum e_CoordType

FILE: src/difftextwindow.cpp
  class RecalcWordWrapRunner (line 57) | class RecalcWordWrapRunner : public QObject
    method RecalcWordWrapRunner (line 71) | RecalcWordWrapRunner(DiffTextWindow* parent, qint32 visibleTextWidth, ...
    method connect (line 75) | void connect()
    method run (line 82) | void run()
  class WrapLineCacheData (line 101) | class WrapLineCacheData
    method WrapLineCacheData (line 104) | WrapLineCacheData() = default;
    method WrapLineCacheData (line 105) | WrapLineCacheData(qint32 d3LineIdx, qint32 textStart, qint32 textLength):
    method qint32 (line 107) | [[nodiscard]] qint32 d3LineIdx() const { return m_d3LineIdx; }
    method qint32 (line 108) | [[nodiscard]] qint32 textStart() const { return m_textStart; }
    method qint32 (line 109) | [[nodiscard]] qint32 textLength() const { return m_textLength; }
  class DiffTextWindowData (line 117) | class DiffTextWindowData
    method DiffTextWindowData (line 120) | explicit DiffTextWindowData(QPointer<DiffTextWindow> p)
    method init (line 125) | void init(
    method reset (line 140) | void reset()
    method qint32 (line 173) | [[nodiscard]] qint32 leftInfoWidth() const { return 4 + (gOptions->m_b...
    method isThreeWay (line 178) | [[nodiscard]] bool isThreeWay() const { return KDiff3App::isTripleDiff...
    method QString (line 179) | [[nodiscard]] const QString getFileName() const { return mSourceData->...
    method Diff3LineVector (line 181) | [[nodiscard]] const Diff3LineVector* getDiff3LineVector() const { retu...
    method Diff3WrapLineVector (line 183) | [[nodiscard]] const Diff3WrapLineVector& getDiff3WrapLineVector() { re...
    method hasLineData (line 184) | [[nodiscard]] bool hasLineData() const { return m_pLineData != nullptr...
    method initColors (line 186) | void initColors()
    method QColor (line 209) | [[nodiscard]] QColor thisColor() const { return m_cThis; }
    method QColor (line 210) | [[nodiscard]] QColor diff1Color() const { return m_cDiff1; }
    method QColor (line 211) | [[nodiscard]] QColor diff2Color() const { return m_cDiff2; }
    method QColor (line 212) | [[nodiscard]] QColor diffBothColor() const { return m_cDiffBoth; }
    method Diff3LineVector (line 213) | [[nodiscard]] const Diff3LineVector* diff3LineVector() { return mDiff3...
    method e_SrcSelector (line 217) | [[nodiscard]] e_SrcSelector getWindowIndex() const { return m_pDiffTex...
  function QString (line 272) | const QString DiffTextWindow::getFileName() const
  function e_SrcSelector (line 277) | e_SrcSelector DiffTextWindow::getWindowIndex() const
  function QString (line 282) | const QString DiffTextWindow::getEncodingDisplayString() const
  function e_LineEndStyle (line 287) | e_LineEndStyle DiffTextWindow::getLineEndStyle() const
  function Diff3LineVector (line 292) | const Diff3LineVector* DiffTextWindow::getDiff3LineVector() const
  function qint32 (line 297) | qint32 DiffTextWindow::getLineNumberWidth() const
  function LineRef (line 508) | LineRef DiffTextWindow::getFirstLine() const
  function qint32 (line 528) | qint32 DiffTextWindow::getMaxTextWidth() const
  function LineType (line 554) | LineType DiffTextWindow::getNofLines() const
  function LineType (line 559) | LineType DiffTextWindow::convertLineToDiff3LineIdx(const LineRef line) c...
  function LineRef (line 567) | LineRef DiffTextWindow::convertDiff3LineIdxToLine(const LineType d3lIdx)...
  function LineRef (line 581) | LineRef getBestFirstLine(LineRef line, LineType nofLines, LineRef firstL...
  class FormatRangeHelper (line 933) | class FormatRangeHelper
    method FormatRangeHelper (line 945) | FormatRangeHelper()
    method setFont (line 952) | void setFont(const QFont& f)
    method setPen (line 957) | void setPen(const QPen& pen)
    method setBackground (line 962) | void setBackground(const QColor& background)
    method next (line 967) | void next()
  function QString (line 1353) | QString DiffTextWindowData::getString(const LineType d3lIdx) const
  function QString (line 1373) | QString DiffTextWindowData::getLineString(const LineType line) const
  function LineType (line 1407) | LineType DiffTextWindow::getNofVisibleLines() const
  function qint32 (line 1414) | qint32 DiffTextWindow::getVisibleTextAreaWidth() const
  function QString (line 1422) | QString DiffTextWindow::getSelection() const
  function LineRef (line 1620) | LineRef DiffTextWindowData::convertLineOnScreenToLineInSource(const qint...
  function LineRef (line 2008) | LineRef DiffTextWindow::calcTopLineInFile(const LineRef firstLine) const

FILE: src/difftextwindow.h
  function class (line 47) | class DiffTextWindow: public QWidget
  function class (line 179) | class DiffTextWindowFrame: public QWidget
  function class (line 220) | class EncodingLabel: public QLabel

FILE: src/directorymergewindow.cpp
  type DirectoryMergeWindow::ItemInfo (line 50) | struct DirectoryMergeWindow::ItemInfo {
  class StatusInfo (line 57) | class StatusInfo: public QDialog
    method StatusInfo (line 63) | explicit StatusInfo(QWidget* pParent):
    method isEmpty (line 78) | bool isEmpty()
    method addText (line 83) | void addText(const QString& s)
    method clear (line 88) | void clear()
    method setVisible (line 93) | void setVisible(bool bVisible) override
  type Columns (line 108) | enum Columns
  class DirectoryMergeWindow::DirectoryMergeWindowPrivate (line 124) | class DirectoryMergeWindow::DirectoryMergeWindowPrivate: public QAbstrac...
    method DirectoryMergeWindowPrivate (line 129) | DirectoryMergeWindowPrivate(DirectoryMergeWindow* pDMW, KDiff3App& app):
    method QModelIndex (line 147) | [[nodiscard]] QModelIndex parent(const QModelIndex& index) const override
    method qint32 (line 157) | [[nodiscard]] qint32 rowCount(const QModelIndex& parent = QModelIndex(...
    method qint32 (line 166) | [[nodiscard]] qint32 columnCount(const QModelIndex& /*parent*/) const ...
    method QModelIndex (line 171) | [[nodiscard]] QModelIndex index(qint32 row, qint32 column, const QMode...
    method setOpStatus (line 188) | void setOpStatus(const QModelIndex& mi, e_OperationStatus eOpStatus)
    method MergeFileInfos (line 200) | [[nodiscard]] MergeFileInfos* getMFI(const QModelIndex& mi) const
    method isDirThreeWay (line 214) | [[nodiscard]] bool isDirThreeWay() const
    method MergeFileInfos (line 219) | [[nodiscard]] MergeFileInfos* rootMFI() const { return m_pRoot; }
    class FileKey (line 252) | class FileKey
      method FileKey (line 258) | explicit FileKey(const FileAccess& fa):
      method quint32 (line 261) | quint32 getParents(const FileAccess* pFA, const FileAccess* v[], qui...
  function QVariant (line 377) | QVariant DirectoryMergeWindow::DirectoryMergeWindowPrivate::data(const Q...
  function QVariant (line 519) | QVariant DirectoryMergeWindow::DirectoryMergeWindowPrivate::headerData(q...
  function qint32 (line 552) | qint32 DirectoryMergeWindow::getIntFromIndex(const QModelIndex& index) c...
  class DirectoryMergeWindow::DirMergeItemDelegate (line 558) | class DirectoryMergeWindow::DirMergeItemDelegate: public QStyledItemDele...
    method DirMergeItemDelegate (line 564) | explicit DirMergeItemDelegate(DirectoryMergeWindow* pParent):
    method paint (line 569) | void paint(QPainter* thePainter, const QStyleOptionViewItem& option, c...
    method QSize (line 635) | [[nodiscard]] QSize sizeHint(const QStyleOptionViewItem& option, const...
  function qint32 (line 676) | qint32 DirectoryMergeWindow::totalColumnWidth()
  function QString (line 1021) | QString DirectoryMergeWindow::getDirNameA() const
  function QString (line 1026) | QString DirectoryMergeWindow::getDirNameB() const
  function QString (line 1031) | QString DirectoryMergeWindow::getDirNameC() const
  function QString (line 1036) | QString DirectoryMergeWindow::getDirNameDest() const
  function QModelIndex (line 1262) | QModelIndex DirectoryMergeWindow::DirectoryMergeWindowPrivate::nextSibli...
  function QModelIndex (line 1272) | QModelIndex DirectoryMergeWindow::DirectoryMergeWindowPrivate::treeItera...
  function QString (line 1741) | QString DirectoryMergeWindow::DirectoryMergeWindowPrivate::getFileName(c...

FILE: src/directorymergewindow.h
  function class (line 33) | class DirectoryMergeWindow : public QTreeView
  function class (line 133) | class DirectoryMergeInfo : public QFrame

FILE: src/fileaccess.cpp
  function FileAccess (line 128) | FileAccess& FileAccess::operator=(const FileAccess& b)
  function FileAccess (line 161) | FileAccess& FileAccess::operator=(FileAccess&& b) noexcept
  function qint64 (line 657) | qint64 FileAccess::size() const
  function QUrl (line 665) | const QUrl& FileAccess::url() const
  function QString (line 714) | const QString& FileAccess::readLink() const
  function QString (line 719) | QString FileAccess::absoluteFilePath() const
  function QString (line 728) | const QString& FileAccess::fileName(bool needTmp) const
  function QString (line 736) | QString FileAccess::fileRelPath() const
  function FileAccess (line 768) | FileAccess* FileAccess::parent() const
  function QString (line 775) | QString FileAccess::prettyAbsPath() const
  function QDateTime (line 780) | const QDateTime& FileAccess::lastModified() const
  function QString (line 932) | QString FileAccess::getTempName() const
  function QString (line 940) | const QString& FileAccess::errorString() const
  function qint64 (line 973) | qint64 FileAccess::read(char* data, const qint64 maxlen)
  function qint64 (line 1063) | qint64 FileAccess::sizeForReading()
  function QString (line 1086) | const QString& FileAccess::getStatusText() const
  function QString (line 1096) | QString FileAccess::cleanPath(const QString& path) // static

FILE: src/fileaccess.h
  function isNormal (line 56) | [[nodiscard]] bool isNormal() const;
  function virtual (line 59) | [[nodiscard]] virtual bool isFile() const;
  function isLocal (line 95) | [[nodiscard]] bool isLocal() const;

FILE: src/gnudiff_analyze.cpp
  type partition (line 52) | struct partition {
  function GNULineRef (line 89) | GNULineRef GnuDiff::diag(GNULineRef xoff, GNULineRef xlim, GNULineRef yo...

FILE: src/gnudiff_diff.h
  type qint64 (line 40) | typedef qint64 GNULineRef;
  function class (line 45) | class GnuDiff

FILE: src/gnudiff_io.cpp
  type equivclass (line 37) | struct equivclass {
  function GNULineRef (line 309) | GNULineRef

FILE: src/guiutils.h
  function namespace (line 21) | namespace GuiUtils {

FILE: src/kdiff3.cpp
  function KActionCollection (line 73) | KActionCollection* KDiff3App::actionCollection() const
  function QStatusBar (line 80) | QStatusBar* KDiff3App::statusBar() const
  function KToolBar (line 87) | KToolBar* KDiff3App::toolBar(const QLatin1String& toolBarId) const

FILE: src/kdiff3.h
  type class (line 42) | enum class
  function class (line 62) | class ReversibleScrollBar : public QScrollBar
  function setAgain (line 76) | void setAgain() { setValue(m_realVal); }
  function setValue (line 78) | void setValue(qint32 i)
  function slotValueChanged (line 91) | void slotValueChanged(qint32 i)
  type FileNames (line 103) | struct FileNames {
  type class (line 111) | enum class
  function class (line 123) | class KDiff3App: public QMainWindow

FILE: src/kdiff3_shell.h
  function class (line 32) | class KDiff3Shell: public KXmlGuiWindow

FILE: src/main.cpp
  function initialiseCmdLineArgs (line 35) | void initialiseCmdLineArgs(QCommandLineParser* cmdLineParser)
  function qint32 (line 77) | qint32 main(qint32 argc, char* argv[])

FILE: src/merger.cpp
  function ChangeFlags (line 65) | ChangeFlags Merger::whatChanged()

FILE: src/mergeresultwindow.cpp
  function qint32 (line 404) | qint32 MergeResultWindow::getMaxTextWidth()
  function LineType (line 431) | LineType MergeResultWindow::getNofLines() const
  function qint32 (line 436) | qint32 MergeResultWindow::getVisibleTextAreaWidth() const
  function qint32 (line 441) | qint32 MergeResultWindow::getNofVisibleLines() const
  function qint32 (line 448) | qint32 MergeResultWindow::getTextXOffset() const
  function e_OverviewMode (line 460) | e_OverviewMode MergeResultWindow::getOverviewMode() const
  function qint32 (line 706) | qint32 MergeResultWindow::getNumberOfUnsolvedConflicts(qint32* pNrOfWhit...
  function findParenthesesGroups (line 923) | bool findParenthesesGroups(const QString& s, QStringList& sl)
  function QString (line 952) | QString calcHistorySortKey(const QString& keyOrder, QRegularExpressionMa...
  function MergeEditLineList (line 1083) | MergeEditLineList& MergeResultWindow::HistoryMapEntry::choice(bool bThre...
  function LineRef (line 1705) | LineRef MergeResultWindow::convertToLine(qint32 y)
  function QString (line 2386) | QString MergeResultWindow::getSelection() const
  function QString (line 2694) | QString MergeResultWindow::getString(qint32 lineIdx)
  function QString (line 2805) | QString WindowTitleWidget::getFileName()
  function e_LineEndStyle (line 2889) | e_LineEndStyle WindowTitleWidget::getLineEndStyle()

FILE: src/mergeresultwindow.h
  type HistoryMapEntry (line 102) | struct HistoryMapEntry {
  type class (line 111) | enum class
  type class (line 117) | enum class
  function RangeMark (line 126) | enum class RangeMark
  function class (line 302) | class WindowTitleWidget: public QWidget

FILE: src/optiondialog.cpp
  function OptionCheckBox (line 50) | OptionCheckBox(const QString& text, bool bDefaultVal, const QString& sav...
  function setToDefault (line 56) | void setToDefault() override { setChecked(getDefault()); }
  function setToCurrent (line 57) | void setToCurrent() override { setChecked(getCurrent()); }
  function apply (line 60) | void apply() override { apply(isChecked()); }
  function OptionRadioButton (line 69) | OptionRadioButton(const QString& text, bool bDefaultVal, const QString& ...
  function setToDefault (line 76) | void setToDefault() override { setChecked(getDefault()); }
  function setToCurrent (line 77) | void setToCurrent() override { setChecked(getCurrent()); }
  function apply (line 80) | void apply() override { apply(isChecked()); }
  function QFont (line 94) | QFont FontChooser::font()
  function OptionFontChooser (line 125) | OptionFontChooser(const QFont& defaultVal, const QString& saveName, QFon...
  function setToDefault (line 131) | void setToDefault() override { setFont(getDefault(), false); }
  function setToCurrent (line 132) | void setToCurrent() override { setFont(getCurrent(), false); }
  function apply (line 134) | void apply() override { apply(font()); }
  function OptionColorButton (line 143) | OptionColorButton(const QColor& defaultVal, const QString& saveName, QCo...
  function setToDefault (line 148) | void setToDefault() override { setColor(getDefault()); }
  function setToCurrent (line 149) | void setToCurrent() override { setColor(getCurrent()); }
  function apply (line 151) | void apply() override { apply(color()); }
  class OptionLineEdit (line 157) | class OptionLineEdit: public QComboBox, public OptionString
    method OptionLineEdit (line 160) | OptionLineEdit(const QString& defaultVal, const QString& saveName, QSt...
    method setToDefault (line 171) | void setToDefault() override
    method setToCurrent (line 176) | void setToCurrent() override
    method apply (line 182) | void apply() override
    method write (line 188) | void write(ValueMap* config) const override
    method read (line 193) | void read(ValueMap* config) override
    method insertText (line 202) | void insertText()
  function OptionIntEdit (line 220) | OptionIntEdit(qint32 defaultVal, const QString& saveName, qint32* pVar, ...
  function setToDefault (line 230) | void setToDefault() override
  function setToCurrent (line 236) | void setToCurrent() override
  function apply (line 242) | void apply() override
  class OptionComboBox (line 254) | class OptionComboBox: public QComboBox, public OptionItemBase
    method OptionComboBox (line 257) | OptionComboBox(qint32 defaultVal, const QString& saveName, qint32* pVa...
    method OptionComboBox (line 269) | OptionComboBox(qint32 defaultVal, const QString& saveName, QString* pV...
    method setToDefault (line 280) | void setToDefault() override
    method setToCurrent (line 289) | void setToCurrent() override
    method apply (line 298) | void apply() override
    method write (line 310) | void write(ValueMap* config) const override
    method read (line 318) | void read(ValueMap* config) override
    method preserveImp (line 326) | void preserveImp() override
    method unpreserveImp (line 338) | void unpreserveImp() override
    method setText (line 358) | void setText(const QString& s)
  class OptionEncodingComboBox (line 374) | class OptionEncodingComboBox: public QComboBox, public OptionCodec
    method OptionEncodingComboBox (line 381) | OptionEncodingComboBox(const QString& saveName, QByteArray* inVarCodec,
    method insertCodec (line 401) | void insertCodec(const QString& visibleCodecName, const QByteArray& name)
    method setToDefault (line 418) | void setToDefault() override
    method setToCurrent (line 429) | void setToCurrent() override
    method apply (line 445) | void apply() override
    method write (line 453) | void write(ValueMap* config) const override
    method read (line 458) | void read(ValueMap* config) override
    method preserveImp (line 473) | void preserveImp() override { m_preservedVal = currentIndex(); }
    method unpreserveImp (line 474) | void unpreserveImp() override { setCurrentIndex(m_preservedVal); }
  function QString (line 1525) | const QString OptionDialog::parseOptions(const QStringList& optionList)
  function QString (line 1531) | QString OptionDialog::calcOptionHelp()

FILE: src/optiondialog.h
  function class (line 29) | class OptionDialog: public KPageDialog
  function class (line 102) | class FontChooser: public QGroupBox

FILE: src/options.h
  type e_LineEndStyle (line 36) | enum e_LineEndStyle
  function class (line 46) | class Options

FILE: src/progress.h
  function class (line 30) | class ProgressDialog: public QDialog

FILE: src/selection.cpp
  function qsizetype (line 18) | qsizetype Selection::firstPosInLine(LineRef l) const
  function qsizetype (line 42) | qsizetype Selection::lastPosInLine(LineRef l) const

FILE: src/selection.h
  function class (line 18) | class Selection
  function clearOldSelection (line 41) | void clearOldSelection() { oldLastLine.invalidate(), oldFirstLine.invali...
  function reset (line 47) | void reset()
  function start (line 55) | void start(LineRef l, qsizetype p)
  function end (line 61) | void end(LineRef l, qsizetype p)

FILE: src/smalldialogs.cpp
  function QString (line 482) | QString RegExpTester::autoMergeRegExp() const
  function QString (line 487) | QString RegExpTester::historyStartRegExp() const
  function QString (line 492) | QString RegExpTester::historyEntryStartRegExp() const
  function QString (line 497) | QString RegExpTester::historySortKeyOrder() const

FILE: src/smalldialogs.h
  type class (line 28) | enum class
  function class (line 38) | class OpenDialog: public QDialog
  function class (line 91) | class FindDialog: public QDialog
  function class (line 147) | class RegExpTester: public QDialog

FILE: test/alignmenttest.cpp
  function printDiffList (line 29) | void printDiffList(const QString caption, const DiffList &diffList)
  function printDiff3List (line 43) | void printDiff3List(const Diff3LineList &diff3LineList,
  function printDiff3List (line 100) | void printDiff3List(QString caption,
  function determineFileAlignment (line 112) | void determineFileAlignment(SourceData &m_sd1, SourceData &m_sd2, Source...
  function QString (line 166) | QString getLineFromSourceData(const SourceData &sd, int line)
  function loadExpectedAlignmentFile (line 176) | void loadExpectedAlignmentFile(QString expectedResultFileName, Diff3Line...
  function writeActualAlignmentFile (line 200) | void writeActualAlignmentFile(QString actualResultFileName, const Diff3L...
  function dataIsConsistent (line 219) | bool dataIsConsistent(LineRef line1, QString &line1Text, LineRef line2, ...
  function runTest (line 255) | bool runTest(QString file1, QString file2, QString file3, QString expect...
  function QStringList (line 407) | QStringList gettestdatafiles(QString testdir)
  function main (line 440) | int main(int argc, char *argv[])

FILE: test/fakefileaccess.cpp
  function qint64 (line 33) | qint64 FileAccess::size() const
  function qint64 (line 38) | qint64 FileAccess::sizeForReading()
  function QString (line 55) | QString FileAccess::prettyAbsPath() const
  function QString (line 60) | QString FileAccess::absoluteFilePath() const
  function QString (line 93) | QString FileAccess::getTempName() const

FILE: test/generate_testdata_from_permutations.py
  function permutations (line 34) | def permutations(nr_of_options, count, currentlist):
Copy disabled (too large) Download .json
Condensed preview — 391 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,084K chars).
[
  {
    "path": ".clang-format",
    "chars": 789,
    "preview": "---\nLanguage: Cpp\nBasedOnStyle: LLVM\nSpaceBeforeAssignmentOperators: true\nSpaceBeforeParens: Never\nSpaceInEmptyParenthe"
  },
  {
    "path": ".clang-tidy",
    "chars": 1905,
    "preview": "---\nChecks:          '-clang-analyzer-cplusplus.NewDeleteLeaks,-clang-analyzer-optin.cplusplus.VirtualCall,-clang-analyz"
  },
  {
    "path": ".craft.ini",
    "chars": 122,
    "preview": "# SPDX-FileCopyrightText: None\n# SPDX-License-Identifier: CC0-1.0\n\n[BlueprintSettings]\nextragear/kdiff3.packageAppx=True"
  },
  {
    "path": ".editorconfig",
    "chars": 130,
    "preview": "root = true\n\n[*]\nindent_style = space\nindent_size = 4\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newli"
  },
  {
    "path": ".flatpak-manifest.json",
    "chars": 1613,
    "preview": "{\n    \"id\": \"org.kde.kdiff3\",\n    \"runtime\": \"org.kde.Platform\",\n    \"runtime-version\": \"6.10\",\n    \"sdk\": \"org.kde.Sdk\""
  },
  {
    "path": ".flatpak-manifest.json.license",
    "chars": 66,
    "preview": "# SPDX-FileCopyrightText: None\n# SPDX-License-Identifier: CC0-1.0\n"
  },
  {
    "path": ".gitignore",
    "chars": 284,
    "preview": "# general\napidocs\n.directory\n.kdev4\nbuild\n*~\n*.patch\n*.diff\n*.bak\n*.orig\n*.pyc\n*.rej\n*.swp\ndoxygen.log\nDoxyfile\n*.kdevel"
  },
  {
    "path": ".gitlab-ci.yml",
    "chars": 522,
    "preview": "# SPDX-FileCopyrightText: None\n# SPDX-License-Identifier: CC0-1.0\ninclude:\n  - project: sysadmin/ci-utilities\n    file:\n"
  },
  {
    "path": ".kde-ci.yml",
    "chars": 733,
    "preview": "# SPDX-FileCopyrightText: None\n# SPDX-License-Identifier: CC0-1.0\n\nDependencies:\n- 'on': ['Linux', 'FreeBSD', 'Windows']"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 8174,
    "preview": "# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de\n# SPDX-FileCopyrightText: 2018-2020 Michael Ree"
  },
  {
    "path": "COPYING",
    "chars": 18006,
    "preview": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc."
  },
  {
    "path": "ChangeLog",
    "chars": 2260,
    "preview": "*Completed port away from Qt5, 6.6 now required version due to delayed ICU support in Qt\n\nVersion 1.11.x - 2024\n========"
  },
  {
    "path": "CppCheckSuppressions.txt",
    "chars": 146,
    "preview": "unmatchedSuppression:*\nassertWithSideEffect\nuseInitializationList\ncstyleCast\nuninitMemberVar:src/OptionItems.h:*\nvariabl"
  },
  {
    "path": "INSTALL",
    "chars": 2420,
    "preview": "\nBuilding KDiff3 requires the following minimum versions:\n 1) Qt 6.7.0 or later\n 2) KDE Frameworks (KF) 6.2.0 or later\n "
  },
  {
    "path": "LICENSES/BSD-2-Clause.txt",
    "chars": 1288,
    "preview": "Copyright (c) <year> <owner>. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without m"
  },
  {
    "path": "LICENSES/CC0-1.0.txt",
    "chars": 7048,
    "preview": "Creative Commons Legal Code\n\nCC0 1.0 Universal\n\n    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\n"
  },
  {
    "path": "LICENSES/GPL-2.0-or-later.txt",
    "chars": 17622,
    "preview": "GNU GENERAL PUBLIC LICENSE\n\nVersion 2, June 1991\n\nCopyright (C) 1989, 1991 Free Software Foundation, Inc. \n\n51 Franklin "
  },
  {
    "path": "LICENSES/MIT.txt",
    "chars": 1108,
    "preview": "MIT License Copyright (c) <year> <copyright holders>\n\nPermission is hereby granted, free of charge, to any person obtain"
  },
  {
    "path": "README",
    "chars": 4000,
    "preview": "KDiff3-Readme\n=============\n\nAuthor: Joachim Eibl  (joachim.eibl at gmx.de)\nPort to KF5/Qt5 by Michael Reeves (reeves.87"
  },
  {
    "path": "UBSan.supp",
    "chars": 64,
    "preview": "#beyond my control KF is being flagged.\nenum:KStandardAction::*\n"
  },
  {
    "path": "diff_ext_for_kdiff3/.krazy",
    "chars": 15,
    "preview": "EXCLUDE system\n"
  },
  {
    "path": "diff_ext_for_kdiff3/CMakeLists.txt",
    "chars": 1172,
    "preview": "#  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n#  SPDX-FileCopyrightText:  2018-2020 Michael R"
  },
  {
    "path": "diff_ext_for_kdiff3/LICENSE",
    "chars": 1422,
    "preview": "Diff-Ext: Copyright (c) 2003-2006, Sergey Zorin\n          All rights reserved.\n\nRedistribution and use in source and bin"
  },
  {
    "path": "diff_ext_for_kdiff3/Messages.sh",
    "chars": 60,
    "preview": "#! /usr/bin/env bash\n$XGETTEXT *.cpp -o $podir/diff_ext.pot\n"
  },
  {
    "path": "diff_ext_for_kdiff3/README",
    "chars": 1245,
    "preview": "Diff-Ext for KDiff3 - Readme\n============================\n\nAuthors: \n   Sergey Zorin (Author of diff-ext, see http://dif"
  },
  {
    "path": "diff_ext_for_kdiff3/class_factory.cpp",
    "chars": 1478,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "diff_ext_for_kdiff3/class_factory.h",
    "chars": 720,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "diff_ext_for_kdiff3/diff_ext.cpp",
    "chars": 14381,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "diff_ext_for_kdiff3/diff_ext.h",
    "chars": 1783,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "diff_ext_for_kdiff3/diff_ext_for_kdiff3.def",
    "chars": 197,
    "preview": "LIBRARY\t\"kdiff3ext\"\nEXPORTS\n    DllCanUnloadNow=DllCanUnloadNow@0\n    DllGetClassObject=DllGetClassObject@12\n    DllRegi"
  },
  {
    "path": "diff_ext_for_kdiff3/diff_ext_for_kdiff3.rc",
    "chars": 2345,
    "preview": "/*\n * Copyright (c) 2003-2006, Sergey Zorin. All rights reserved.\n *\n * Redistribution and use in source and binary form"
  },
  {
    "path": "diff_ext_for_kdiff3/diff_ext_for_kdiff3_msvc.def",
    "chars": 148,
    "preview": "LIBRARY\t\"kdiff3ext\"\nEXPORTS\n    DllCanUnloadNow PRIVATE\n    DllGetClassObject PRIVATE\n    DllRegisterServer PRIVATE\n    "
  },
  {
    "path": "diff_ext_for_kdiff3/server.cpp",
    "chars": 12056,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "diff_ext_for_kdiff3/server.h",
    "chars": 2320,
    "preview": "/*\n  SPDX-FileCopyrightText: 2003-2006, Sergey Zorin. All rights reserved.\n  SPDX-FileCopyrightText:  2018-2020 Michael "
  },
  {
    "path": "doc/CMakeLists.txt",
    "chars": 210,
    "preview": "# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de\n# SPDX-FileCopyrightText: 2018-2020 Michael Ree"
  },
  {
    "path": "doc/en/CMakeLists.txt",
    "chars": 387,
    "preview": "# SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachim.eibl at gmx.de\n# SPDX-FileCopyrightText: 2018-2020 Michael Ree"
  },
  {
    "path": "doc/en/index.docbook",
    "chars": 123952,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "doc/en/man-kdiff3.1.docbook",
    "chars": 6294,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "kdiff3fileitemactionplugin/CMakeLists.txt",
    "chars": 736,
    "preview": "add_definitions(-DTRANSLATION_DOMAIN=\\\"kdiff3fileitemactionplugin\\\")\n\nfind_package(KF${KF_MAJOR_VERSION} ${KF_MIN_VERSIO"
  },
  {
    "path": "kdiff3fileitemactionplugin/Messages.sh",
    "chars": 78,
    "preview": "#! /usr/bin/env bash\n$XGETTEXT *.cpp -o $podir/kdiff3fileitemactionplugin.pot\n"
  },
  {
    "path": "kdiff3fileitemactionplugin/kdiff3fileitemaction.cpp",
    "chars": 9919,
    "preview": "// clang-format off\n/*\n * KDiff3 - Text Diff And Merge Tool\n *\n * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachi"
  },
  {
    "path": "kdiff3fileitemactionplugin/kdiff3fileitemaction.h",
    "chars": 1217,
    "preview": "// clang-format off\n/*\n * KDiff3 - Text Diff And Merge Tool\n *\n * SPDX-FileCopyrightText: 2002-2011 Joachim Eibl, joachi"
  },
  {
    "path": "kdiff3fileitemactionplugin/kdiff3fileitemaction.json",
    "chars": 2768,
    "preview": "{\n    \"KPlugin\": {\n        \"MimeTypes\": [\n            \"application/octet-stream\",\n            \"inode/directory\"\n        "
  },
  {
    "path": "po/ar/diff_ext.po",
    "chars": 3508,
    "preview": "# Copyright (C) 2025 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/ar/kdiff3.po",
    "chars": 87060,
    "preview": "# translation of kdiff3.po to Arabic\n# SPDX-FileCopyrightText: 2022, 2025 Zayed Al-Saidi <zayed.alsaidi@gmail.com>\n# محم"
  },
  {
    "path": "po/ar/kdiff3fileitemactionplugin.po",
    "chars": 3199,
    "preview": "# Copyright (C) 2025 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/ast/diff_ext.po",
    "chars": 2877,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/ast/kdiff3.po",
    "chars": 66448,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/ast/kdiff3fileitemactionplugin.po",
    "chars": 2629,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/bg/diff_ext.po",
    "chars": 3568,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/bg/kdiff3.po",
    "chars": 91826,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/bg/kdiff3fileitemactionplugin.po",
    "chars": 3527,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/br/kdiff3.po",
    "chars": 76397,
    "preview": "# KDE breton translation\n# Thierry Vignaud <tvignaud@mandriva.com>, 2004-2005\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kd"
  },
  {
    "path": "po/bs/kdiff3.po",
    "chars": 116986,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3\\n\"\n\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n\"POT-Creation-Date: 202"
  },
  {
    "path": "po/bs/kdiff3fileitemactionplugin.po",
    "chars": 4668,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same licens"
  },
  {
    "path": "po/ca/diff_ext.po",
    "chars": 3814,
    "preview": "# Translation of diff_ext.po to Catalan\n# Copyright (C) 2018-2024 This_file_is_part_of_KDE\n# This file is distributed un"
  },
  {
    "path": "po/ca/docs/kdiff3/index.docbook",
    "chars": 137056,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/ca/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6885,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/ca/kdiff3.po",
    "chars": 93764,
    "preview": "# Translation of kdiff3.po to Catalan\n# Copyright (C) 2011-2026 This_file_is_part_of_KDE\n# This file is distributed unde"
  },
  {
    "path": "po/ca/kdiff3fileitemactionplugin.po",
    "chars": 3772,
    "preview": "# Translation of kdiff3fileitemactionplugin.po to Catalan\n# Copyright (C) 2011-2024 This_file_is_part_of_KDE\n# This file"
  },
  {
    "path": "po/ca@valencia/diff_ext.po",
    "chars": 3822,
    "preview": "# Translation of diff_ext.po to Catalan (Valencian)\n# Copyright (C) 2018-2024 This_file_is_part_of_KDE\n# This file is di"
  },
  {
    "path": "po/ca@valencia/kdiff3.po",
    "chars": 94108,
    "preview": "# Translation of kdiff3.po to Catalan (Valencian)\n# Copyright (C) 2011-2026 This_file_is_part_of_KDE\n# This file is dist"
  },
  {
    "path": "po/ca@valencia/kdiff3fileitemactionplugin.po",
    "chars": 3802,
    "preview": "# Translation of kdiff3fileitemactionplugin.po to Catalan (Valencian)\n# Copyright (C) 2011-2024 This_file_is_part_of_KDE"
  },
  {
    "path": "po/cs/diff_ext.po",
    "chars": 3207,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/cs/kdiff3.po",
    "chars": 88042,
    "preview": "# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER\n# This file is distributed under the same license as the PACKAGE pac"
  },
  {
    "path": "po/cs/kdiff3fileitemactionplugin.po",
    "chars": 2807,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/cy/kdiff3.po",
    "chars": 71257,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: ../cy/messages//kdeextragear-1/kdiff3.po\\n\"\n\"Report-Msgid-Bugs-To: https://bugs."
  },
  {
    "path": "po/da/kdiff3.po",
    "chars": 116593,
    "preview": "# translation of kdiff3.po to\n# Danish translation of kdiff3\n# Copyright (C).\n#\n# Erik Kjær Pedersen <erik@binghamton.ed"
  },
  {
    "path": "po/da/kdiff3fileitemactionplugin.po",
    "chars": 4591,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/de/diff_ext.po",
    "chars": 3871,
    "preview": "# Copyright (C) 2025 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/de/docs/kdiff3/index.docbook",
    "chars": 141119,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/de/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6806,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/de/kdiff3.po",
    "chars": 110854,
    "preview": "# SPDX-FileCopyrightText: 2023 Johannes Obermayr <johannesobermayr@gmx.de>\n# SPDX-FileCopyrightText: 2003, 2004 Thomas D"
  },
  {
    "path": "po/de/kdiff3fileitemactionplugin.po",
    "chars": 3603,
    "preview": "# SPDX-FileCopyrightText: 2011, 2018, 2022, 2023 Frederik Schwarzer <schwarzer@kde.org>\n# SPDX-FileCopyrightText: 2013, "
  },
  {
    "path": "po/el/diff_ext.po",
    "chars": 3959,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/el/kdiff3.po",
    "chars": 109770,
    "preview": "# translation of kdiff3.po to Greek\n#\n# Spiros Georgaras <sng@hellug.gr>, 2005, 2006, 2007.\n# Toussis Manolis <manolis@k"
  },
  {
    "path": "po/el/kdiff3fileitemactionplugin.po",
    "chars": 3727,
    "preview": "# el translation of kdiff3fileitemactionplugin.po\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distribut"
  },
  {
    "path": "po/en_GB/diff_ext.po",
    "chars": 3717,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/en_GB/kdiff3.po",
    "chars": 104554,
    "preview": "# translation of kdiff3.po to British English\n# Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc.\n#\n# Malcol"
  },
  {
    "path": "po/en_GB/kdiff3fileitemactionplugin.po",
    "chars": 3423,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/eo/diff_ext.po",
    "chars": 3605,
    "preview": "# Translation of diff_ext.pot into esperanto.\n# Copyright (C) 2018 Free Software Foundation, Inc.\n# This file is distrib"
  },
  {
    "path": "po/eo/kdiff3.po",
    "chars": 89459,
    "preview": "# Translation of kdiff3 into esperanto.\n# Copyright (C) 2007 Free Software Foundation, Inc.\n# This file is distributed u"
  },
  {
    "path": "po/eo/kdiff3fileitemactionplugin.po",
    "chars": 3552,
    "preview": "# Translation of kdiff3fileitemactionplugin.pot into esperanto.\n# Copyright (C) 2018 Free Software Foundation, Inc.\n# Th"
  },
  {
    "path": "po/es/diff_ext.po",
    "chars": 3783,
    "preview": "# Spanish translations for diff_ext.po package.\n# Copyright (C) 2018-2025 This file is copyright:\n# This file is distrib"
  },
  {
    "path": "po/es/docs/kdiff3/index.docbook",
    "chars": 122223,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd\" [\n"
  },
  {
    "path": "po/es/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 7019,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/es/kdiff3.po",
    "chars": 93401,
    "preview": "# Spanish translations for kdiff3.po package.\n# Copyright (C) 2003-2025 This file is copyright:\n# This file is distribut"
  },
  {
    "path": "po/es/kdiff3fileitemactionplugin.po",
    "chars": 3770,
    "preview": "# Spanish translations for kdiff3fileitemactionplugin.po package.\n# Copyright (C) 2011-2025 This_file_is_part_of_KDE\n# T"
  },
  {
    "path": "po/et/diff_ext.po",
    "chars": 4419,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/et/kdiff3.po",
    "chars": 115901,
    "preview": "# translation of kdiff3.po to Estonian\n# Copyright (C) 2003 Free Software Foundation, Inc.\n#\n# Marek Laane <bald@starman"
  },
  {
    "path": "po/et/kdiff3fileitemactionplugin.po",
    "chars": 3865,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/eu/diff_ext.po",
    "chars": 3961,
    "preview": "# Translation for diff_ext.po to Euskara/Basque (eu).\n# Copyright (C) 2020-2024 This file is copyright:\n# This file is d"
  },
  {
    "path": "po/eu/kdiff3.po",
    "chars": 99186,
    "preview": "# Translation for kdiff3.po to Euskara/Basque (eu).\n# Copyright (C) 2018-2025 This file is copyright:\n# This file is dis"
  },
  {
    "path": "po/eu/kdiff3fileitemactionplugin.po",
    "chars": 3695,
    "preview": "# Translation for kdiff3fileitemactionplugin.po to Euskara/Basque (eu).\n# Copyright (C) 2020-2024 This file is copyright"
  },
  {
    "path": "po/fi/diff_ext.po",
    "chars": 3859,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/fi/kdiff3.po",
    "chars": 104460,
    "preview": "# KDE Finnish translation sprint participants:\n# Author: Artnay\n# Author: Lliehu\n# Author: Niklas Laxström\n# SPDX-FileCo"
  },
  {
    "path": "po/fi/kdiff3fileitemactionplugin.po",
    "chars": 3670,
    "preview": "# Copyright © 2012 This_file_is_part_of_KDE\n# This file is distributed under the same license as the kdiff3 package.\n# S"
  },
  {
    "path": "po/fr/diff_ext.po",
    "chars": 3961,
    "preview": "# SPDX-FileCopyrightText: 2020, 2021, 2024 Xavier Besnard <xavier.besnard@kde.org>\n# Simon Depiets <sdepiets@gmail.com>,"
  },
  {
    "path": "po/fr/kdiff3.po",
    "chars": 103903,
    "preview": "# translation of kdiff3.po to Français\n# traduction de kdiff3.po vers le Français\n# Copyright (C) 2004, 2005, 2008, 2009"
  },
  {
    "path": "po/fr/kdiff3fileitemactionplugin.po",
    "chars": 4133,
    "preview": "# translation of kdiff3fileitemactionplugin.po to Français\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is "
  },
  {
    "path": "po/ga/diff_ext.po",
    "chars": 2871,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license"
  },
  {
    "path": "po/ga/kdiff3.po",
    "chars": 73538,
    "preview": "# Irish translation of kdiff3\n# Copyright (C) 2009 This_file_is_part_of_KDE\n# This file is distributed under the same li"
  },
  {
    "path": "po/ga/kdiff3fileitemactionplugin.po",
    "chars": 2848,
    "preview": "# Irish translation of kdiff3fileitemactionplugin\n# Copyright (C) 2011 This_file_is_part_of_KDE\n# This file is distribut"
  },
  {
    "path": "po/gl/diff_ext.po",
    "chars": 3779,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/gl/kdiff3.po",
    "chars": 108701,
    "preview": "# translation of kdiff3.po to galician\n#\n# SPDX-FileCopyrightText: 2023, 2024, 2025 Adrián Chaves (Gallaecio)\n# mvillari"
  },
  {
    "path": "po/gl/kdiff3fileitemactionplugin.po",
    "chars": 3581,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/he/diff_ext.po",
    "chars": 3520,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/he/kdiff3.po",
    "chars": 84171,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/he/kdiff3fileitemactionplugin.po",
    "chars": 3352,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/hi/diff_ext.po",
    "chars": 2830,
    "preview": "# Hindi translations for kdiff3 package.\n# Copyright (C) 2024 This file is copyright:\n# This file is distributed under t"
  },
  {
    "path": "po/hi/kdiff3.po",
    "chars": 90517,
    "preview": "#\n# Raghavendra Kamath <raghu@raghukamath.com>, 2021.\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3\\n\"\n\"Report-Msgid-Bu"
  },
  {
    "path": "po/hi/kdiff3fileitemactionplugin.po",
    "chars": 2589,
    "preview": "# Hindi translations for kdiff3 package.\n# Copyright (C) 2024 This file is copyright:\n# This file is distributed under t"
  },
  {
    "path": "po/hne/kdiff3.po",
    "chars": 89652,
    "preview": "#\n# Ravishankar Shrivastava <raviratlami@aol.in>, 2009.\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3\\n\"\n\"Report-Msgid-"
  },
  {
    "path": "po/hr/kdiff3.po",
    "chars": 66532,
    "preview": "# Translation of kdiff3 to Croatian\n#\n# Andrej Dundovic <adundovi@gmail.com>, 2010.\nmsgid \"\"\nmsgstr \"\"\n\"Project-Id-Versi"
  },
  {
    "path": "po/hu/kdiff3.po",
    "chars": 109464,
    "preview": "# Copyright (C) 2012 Free Software Foundation, Inc.\n#\n# Tamas Szanto <tszanto@mol.hu>, 2003.\n# Balázs Úr <urbalazs@gmail"
  },
  {
    "path": "po/hu/kdiff3fileitemactionplugin.po",
    "chars": 4641,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/ia/diff_ext.po",
    "chars": 3652,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/ia/kdiff3.po",
    "chars": 71348,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/ia/kdiff3fileitemactionplugin.po",
    "chars": 3511,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/id/diff_ext.po",
    "chars": 3478,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/id/kdiff3.po",
    "chars": 83911,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/id/kdiff3fileitemactionplugin.po",
    "chars": 3383,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/is/kdiff3.po",
    "chars": 70332,
    "preview": "# translation of kdiff3.po to icelandic\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under t"
  },
  {
    "path": "po/it/diff_ext.po",
    "chars": 3799,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/it/docs/kdiff3/index.docbook",
    "chars": 137040,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/it/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6818,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/it/kdiff3.po",
    "chars": 108294,
    "preview": "# translation of kdiff3.po to Italian\n# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009 Free Software Foundation, Inc.\n"
  },
  {
    "path": "po/it/kdiff3fileitemactionplugin.po",
    "chars": 3562,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the kdiff3 package.\n#"
  },
  {
    "path": "po/ja/diff_ext.po",
    "chars": 2705,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: diff_ext\\n\"\n\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n\"POT-Creation-Date: 2"
  },
  {
    "path": "po/ja/kdiff3.po",
    "chars": 90303,
    "preview": "# Translation of kdiff3 into Japanese.\n# SATOH Satoru <ss@kde.gr.jp>, 2004.\n# Yukiko Bando <ybando@k6.dion.ne.jp>, 2008."
  },
  {
    "path": "po/ja/kdiff3fileitemactionplugin.po",
    "chars": 2482,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3fileitemactionplugin\\n\"\n\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n\"PO"
  },
  {
    "path": "po/ka/diff_ext.po",
    "chars": 3583,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license"
  },
  {
    "path": "po/ka/kdiff3.po",
    "chars": 90624,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license"
  },
  {
    "path": "po/ka/kdiff3fileitemactionplugin.po",
    "chars": 3483,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license"
  },
  {
    "path": "po/ko/diff_ext.po",
    "chars": 3570,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/ko/kdiff3.po",
    "chars": 91326,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/ko/kdiff3fileitemactionplugin.po",
    "chars": 3117,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/lt/diff_ext.po",
    "chars": 2901,
    "preview": "# Lithuanian translations for kdiff3 package.\n# Copyright (C) 2019 This file is copyright:\n# This file is distributed un"
  },
  {
    "path": "po/lt/kdiff3.po",
    "chars": 77798,
    "preview": "# Lithuanian translation of the KDiff3 pakckage\n#\n# Remigijus Jarmalavičius <remigijus@jarmalavicius.lt>, 2011.\nmsgid \"\""
  },
  {
    "path": "po/lt/kdiff3fileitemactionplugin.po",
    "chars": 2671,
    "preview": "# Lithuanian translations for l package.\n# Copyright (C) 2011 This_file_is_part_of_KDE\n# This file is distributed under "
  },
  {
    "path": "po/mai/kdiff3.po",
    "chars": 70617,
    "preview": "# translation of kdiff3.po to Maithili\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under th"
  },
  {
    "path": "po/ml/kdiff3.po",
    "chars": 89298,
    "preview": "# Malayalam Translation of kdiff3\n# Copyright (C) 2009 This_file_is_part_of_KDE\n# This file is distributed under the sam"
  },
  {
    "path": "po/mr/kdiff3.po",
    "chars": 70702,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/mr/kdiff3fileitemactionplugin.po",
    "chars": 2884,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/nb/kdiff3.po",
    "chars": 76465,
    "preview": "# Translation of kdiff3 to Norwegian Bokmål\n#\n# Knut Yrvin <knut.yrvin@gmail.com>, 2003.\n# Bjørn Steensrud <bjornst@skog"
  },
  {
    "path": "po/nb/kdiff3fileitemactionplugin.po",
    "chars": 2750,
    "preview": "# Translation of kdiff3fileitemactionplugin to Norwegian Bokmål\n#\n# Bjørn Steensrud <bjornst@skogkatt.homelinux.org>, 20"
  },
  {
    "path": "po/nds/kdiff3.po",
    "chars": 117858,
    "preview": "# Translation of kdiff3.po to Low Saxon\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under t"
  },
  {
    "path": "po/nds/kdiff3fileitemactionplugin.po",
    "chars": 4670,
    "preview": "# translation of kdiff3fileitemactionplugin.po to Low Saxon\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is"
  },
  {
    "path": "po/nl/diff_ext.po",
    "chars": 3808,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/nl/docs/kdiff3/index.docbook",
    "chars": 132983,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/nl/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6850,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/nl/kdiff3.po",
    "chars": 99763,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/nl/kdiff3fileitemactionplugin.po",
    "chars": 3610,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/nn/kdiff3.po",
    "chars": 67429,
    "preview": "# Translation of kdiff3 to Norwegian Nynorsk\n#\n# Karl Ove Hufthammer <karl@huftis.org>, 2020.\nmsgid \"\"\nmsgstr \"\"\n\"Projec"
  },
  {
    "path": "po/nn/kdiff3fileitemactionplugin.po",
    "chars": 2736,
    "preview": "# Translation of kdiff3fileitemactionplugin to Norwegian Nynorsk\n#\n# Karl Ove Hufthammer <karl@huftis.org>, 2020.\nmsgid "
  },
  {
    "path": "po/pl/diff_ext.po",
    "chars": 3829,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n# "
  },
  {
    "path": "po/pl/kdiff3.po",
    "chars": 106443,
    "preview": "# translation of kdiff3.po to Polish\n# translation of pl.po to\n# Copyright (C) 2003, 2004, 2005, 2009, 2010, 2011 Free S"
  },
  {
    "path": "po/pl/kdiff3fileitemactionplugin.po",
    "chars": 3579,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/pt/diff_ext.po",
    "chars": 3853,
    "preview": "# SOME DESCRIPTIVE TITLE.\n# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same licens"
  },
  {
    "path": "po/pt/docs/kdiff3/index.docbook",
    "chars": 124985,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd\" [\n"
  },
  {
    "path": "po/pt/kdiff3.po",
    "chars": 94999,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3\\n\"\n\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n\"POT-Creation-Date: 202"
  },
  {
    "path": "po/pt/kdiff3fileitemactionplugin.po",
    "chars": 3510,
    "preview": "msgid \"\"\nmsgstr \"\"\n\"Project-Id-Version: kdiff3fileitemactionplugin\\n\"\n\"Report-Msgid-Bugs-To: https://bugs.kde.org\\n\"\n\"PO"
  },
  {
    "path": "po/pt_BR/diff_ext.po",
    "chars": 3865,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/pt_BR/docs/kdiff3/index.docbook",
    "chars": 136782,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/pt_BR/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6914,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/pt_BR/kdiff3.po",
    "chars": 99345,
    "preview": "# Translation of kdiff3.po to Brazilian Portuguese\n# Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013,"
  },
  {
    "path": "po/pt_BR/kdiff3fileitemactionplugin.po",
    "chars": 3804,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/ro/kdiff3.po",
    "chars": 80924,
    "preview": "#\n# Claudiu Costin <claudiuc@kde.org>, 2003.\n# Sergiu Bivol <sergiu@cip.md>, 2008, 2009, 2012, 2021.\n# Ovidiu-Florin Bog"
  },
  {
    "path": "po/ro/kdiff3fileitemactionplugin.po",
    "chars": 4609,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/ru/diff_ext.po",
    "chars": 3776,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/ru/kdiff3.po",
    "chars": 108159,
    "preview": "# KDE3 - kdiff3.pot Russian translation.\n# KDE3 - kdeextragear-1/kdiff3.po Russian translation.\n# Nick Shaforostoff <sha"
  },
  {
    "path": "po/ru/kdiff3fileitemactionplugin.po",
    "chars": 3783,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/rw/kdiff3.po",
    "chars": 91327,
    "preview": "# translation of kdiff3 to Kinyarwanda.\n# Copyright (C) \n# This file is distributed under the same license as the kdiff3"
  },
  {
    "path": "po/sa/diff_ext.po",
    "chars": 3582,
    "preview": "# Sanskrit translations for kdiff3 package.\n# Copyright (C) 2024 This file is copyright:\n# This file is distributed unde"
  },
  {
    "path": "po/sa/kdiff3.po",
    "chars": 90283,
    "preview": "# Sanskrit translations for kdiff3 package.\n# Copyright (C) 2024 This file is copyright:\n# This file is distributed unde"
  },
  {
    "path": "po/sa/kdiff3fileitemactionplugin.po",
    "chars": 3523,
    "preview": "# Sanskrit translations for kdiff3 package.\n# Copyright (C) 2024 This file is copyright:\n# This file is distributed unde"
  },
  {
    "path": "po/sk/diff_ext.po",
    "chars": 3680,
    "preview": "# translation of diff_ext.po to Slovak\n# Roman Paholik <wizzardsk@gmail.com>, 2018, 2019, 2021.\nmsgid \"\"\nmsgstr \"\"\n\"Proj"
  },
  {
    "path": "po/sk/kdiff3.po",
    "chars": 104175,
    "preview": "# translation of kdiff3.po to Slovak\n# Richard Fric <Richard.Fric@kdemail.net>, 2006, 2009.\n# Roman Paholík <wizzardsk@g"
  },
  {
    "path": "po/sk/kdiff3fileitemactionplugin.po",
    "chars": 3452,
    "preview": "# translation of kdiff3fileitemactionplugin.po to Slovak\n# Richard Fric <Richard.Fric@kdemail.net>, 2011.\n# Roman Paholí"
  },
  {
    "path": "po/sl/diff_ext.po",
    "chars": 3807,
    "preview": "# Slovenian translation of KDiff3\n# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same"
  },
  {
    "path": "po/sl/docs/kdiff3/index.docbook",
    "chars": 124853,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/sl/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6825,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/sl/kdiff3.po",
    "chars": 94869,
    "preview": "# Copyright (C) 2023 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/sl/kdiff3fileitemactionplugin.po",
    "chars": 3601,
    "preview": "# Copyright (C) YEAR This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  },
  {
    "path": "po/sr/kdiff3.po",
    "chars": 106347,
    "preview": "# Translation of kdiff3.po into Serbian.\n# Slobodan Simic <slsimic@gmail.com>, 2009.\n# Chusslove Illich <caslav.ilic@gmx"
  },
  {
    "path": "po/sr/kdiff3fileitemactionplugin.po",
    "chars": 4621,
    "preview": "# Translation of kdiff3fileitemactionplugin.po into Serbian.\n# Chusslove Illich <caslav.ilic@gmx.net>, 2012, 2017.\nmsgid"
  },
  {
    "path": "po/sr@ijekavian/kdiff3.po",
    "chars": 106357,
    "preview": "# Translation of kdiff3.po into Serbian.\n# Slobodan Simic <slsimic@gmail.com>, 2009.\n# Chusslove Illich <caslav.ilic@gmx"
  },
  {
    "path": "po/sr@ijekavian/kdiff3fileitemactionplugin.po",
    "chars": 4631,
    "preview": "# Translation of kdiff3fileitemactionplugin.po into Serbian.\n# Chusslove Illich <caslav.ilic@gmx.net>, 2012, 2017.\nmsgid"
  },
  {
    "path": "po/sr@ijekavianlatin/kdiff3.po",
    "chars": 106686,
    "preview": "# Translation of kdiff3.po into Serbian.\n# Slobodan Simic <slsimic@gmail.com>, 2009.\n# Chusslove Illich <caslav.ilic@gmx"
  },
  {
    "path": "po/sr@ijekavianlatin/kdiff3fileitemactionplugin.po",
    "chars": 4651,
    "preview": "# Translation of kdiff3fileitemactionplugin.po into Serbian.\n# Chusslove Illich <caslav.ilic@gmx.net>, 2012, 2017.\nmsgid"
  },
  {
    "path": "po/sr@latin/kdiff3.po",
    "chars": 106677,
    "preview": "# Translation of kdiff3.po into Serbian.\n# Slobodan Simic <slsimic@gmail.com>, 2009.\n# Chusslove Illich <caslav.ilic@gmx"
  },
  {
    "path": "po/sr@latin/kdiff3fileitemactionplugin.po",
    "chars": 4642,
    "preview": "# Translation of kdiff3fileitemactionplugin.po into Serbian.\n# Chusslove Illich <caslav.ilic@gmx.net>, 2012, 2017.\nmsgid"
  },
  {
    "path": "po/sv/diff_ext.po",
    "chars": 3759,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/sv/docs/kdiff3/index.docbook",
    "chars": 127634,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!DOCTYPE book PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/"
  },
  {
    "path": "po/sv/docs/kdiff3/man-kdiff3.1.docbook",
    "chars": 6722,
    "preview": "<?xml version=\"1.0\" ?>\n<!DOCTYPE refentry PUBLIC \"-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN\" \"dtd/kdedbx45.dtd"
  },
  {
    "path": "po/sv/kdiff3.po",
    "chars": 104005,
    "preview": "# translation of kdiff3.po to Swedish\n# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,"
  },
  {
    "path": "po/sv/kdiff3fileitemactionplugin.po",
    "chars": 3577,
    "preview": "# Copyright (C) YEAR This_file_is_part_of_KDE\n# This file is distributed under the same license as the PACKAGE package.\n"
  },
  {
    "path": "po/ta/kdiff3.po",
    "chars": 106559,
    "preview": "# translation of kdiff3.po to\n# translation of kdiff3.po to\n# translation of kdiff3.po to\n# translation of kdiff3.po to "
  },
  {
    "path": "po/tg/kdiff3.po",
    "chars": 88170,
    "preview": "# translation of kdiff3.po to Tajik\n# Copyright (C) 2004, 2005 Free Software Foundation, Inc.\n# 2004, infoDev, a World B"
  },
  {
    "path": "po/tr/diff_ext.po",
    "chars": 3566,
    "preview": "# Copyright (C) 2024 This file is copyright:\n# This file is distributed under the same license as the kdiff3 package.\n#\n"
  }
]

// ... and 191 more files (download for full content)

About this extraction

This page contains the full source code of the KDE/kdiff3 GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 391 files (8.5 MB), approximately 2.2M tokens, and a symbol index with 483 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!