File indexing completed on 2025-05-04 05:17:22
0001 /* 0002 SPDX-FileCopyrightText: 2021 Hamed Masafi <hamed.masfi@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-3.0-or-later 0005 */ 0006 0007 #include "diffwindow.h" 0008 0009 #include <KActionCollection> 0010 #include <KLocalizedString> 0011 0012 #include <QDebug> 0013 #include <QDockWidget> 0014 #include <QTreeView> 0015 0016 #include <core/editactionsmapper.h> 0017 #include <dialogs/diffopendialog.h> 0018 #include <entities/branch.h> 0019 #include <entities/tag.h> 0020 #include <entities/tree.h> 0021 #include <gitmanager.h> 0022 #include <models/difftreemodel.h> 0023 #include <models/filesmodel.h> 0024 #include <widgets/difftreeview.h> 0025 #include <widgets/diffwidget.h> 0026 0027 DiffWindow::DiffWindow() 0028 : AppMainWindow() 0029 { 0030 init(true); 0031 } 0032 0033 DiffWindow::DiffWindow(Git::Manager *git) 0034 : AppMainWindow() 0035 , mGit(git) 0036 { 0037 init(true); 0038 0039 mOldBranch = git->currentBranch(); 0040 const auto diffs = git->diffBranch(mOldBranch); 0041 0042 for (const auto &f : diffs) { 0043 mDiffModel->addFile(f); 0044 mFilesModel->append(f.name()); 0045 } 0046 0047 mLeftStorage.setGitManager(git); 0048 mRightStorage.setPath(git->path()); 0049 mDiffModel->sortItems(); 0050 } 0051 0052 DiffWindow::DiffWindow(QSharedPointer<Git::File> oldFile, QSharedPointer<Git::File> newFile) 0053 : AppMainWindow() 0054 , mOldFile(oldFile) 0055 , mNewFile(newFile) 0056 { 0057 init(false); 0058 0059 mDiffWidget->setOldFile(oldFile); 0060 mDiffWidget->setNewFile(newFile); 0061 mDiffWidget->compare(); 0062 } 0063 0064 DiffWindow::DiffWindow(Git::Manager *git, const QString &oldBranch, const QString &newBranch) 0065 : AppMainWindow() 0066 , mGit(git) 0067 , mOldBranch(oldBranch) 0068 , mNewBranch(newBranch) 0069 { 0070 init(true); 0071 0072 const auto diffs = git->diffBranches(oldBranch, newBranch); 0073 0074 for (auto &f : diffs) { 0075 mDiffModel->addFile(f); 0076 // qCDebug(KOMMIT_LOG) << f.name() << f.status(); 0077 mFilesModel->append(f.name()); 0078 } 0079 // mLeftStorage.set = mRightStorage = Git; 0080 mDiffModel->sortItems(); 0081 } 0082 0083 DiffWindow::DiffWindow(Git::Manager *git, QSharedPointer<Git::Tag> tag) 0084 : AppMainWindow() 0085 , mOldBranch(tag->name()) 0086 , mNewBranch("Working dir") 0087 { 0088 init(true); 0089 0090 auto tree = tag->commit()->tree(); 0091 const auto diffs = git->diff(tree); 0092 0093 for (auto &f : diffs) { 0094 mDiffModel->addFile(f); 0095 // qCDebug(KOMMIT_LOG) << f.name() << f.status(); 0096 mFilesModel->append(f.newFile()); 0097 } 0098 mLeftStorage.setTree(tree); 0099 mRightStorage.setPath(git->path()); 0100 mDiffModel->sortItems(); 0101 } 0102 0103 DiffWindow::DiffWindow(Git::Branch *oldBranch, Git::Branch *newBranch) 0104 { 0105 mLeftStorage.setTree(oldBranch->tree()); 0106 mRightStorage.setTree(newBranch->tree()); 0107 } 0108 0109 DiffWindow::DiffWindow(Git::Manager *git, QSharedPointer<Git::Tree> leftTree) 0110 { 0111 init(true); 0112 mLeftStorage.setTree(leftTree); 0113 mRightStorage.setPath(git->path()); 0114 0115 const auto diffs = git->diff(leftTree); 0116 0117 for (auto &f : diffs) { 0118 mDiffModel->addFile(f); 0119 // qCDebug(KOMMIT_LOG) << f.name() << f.status(); 0120 mFilesModel->append(f.newFile()); 0121 } 0122 0123 mDiffModel->sortItems(); 0124 } 0125 0126 DiffWindow::DiffWindow(const QString &oldDir, const QString &newDir) 0127 { 0128 init(true); 0129 0130 mLeftDir = oldDir; 0131 mRightDir = newDir; 0132 compareDirs(); 0133 0134 mLeftStorage.setPath(oldDir); 0135 mRightStorage.setPath(newDir); 0136 } 0137 0138 void DiffWindow::init(bool showSideBar) 0139 { 0140 auto mapper = new EditActionsMapper(this); 0141 mDiffWidget = new DiffWidget(this); 0142 mDiffWidget->showSameSize(true); 0143 0144 mapper->init(actionCollection()); 0145 0146 setCentralWidget(mDiffWidget); 0147 0148 mapper->addTextEdit(mDiffWidget->oldCodeEditor()); 0149 mapper->addTextEdit(mDiffWidget->newCodeEditor()); 0150 setWindowTitle(i18nc("@title:window", "Kommit Diff[*]")); 0151 0152 mDock = new QDockWidget(this); 0153 mDock->setWindowTitle(i18nc("@title:window", "Tree")); 0154 mDock->setObjectName(QStringLiteral("treeViewDock")); 0155 0156 mTreeView = new DiffTreeView(this); 0157 connect(mTreeView, &DiffTreeView::fileSelected, this, &DiffWindow::slotTreeViewFileSelected); 0158 mDock->setWidget(mTreeView); 0159 mDock->setAllowedAreas(Qt::AllDockWidgetAreas); 0160 addDockWidget(Qt::LeftDockWidgetArea, mDock); 0161 0162 mFilesModel = new FilesModel(this); 0163 mDiffModel = new DiffTreeModel(this); 0164 mDiffModel->setShowRoot(true); 0165 //_treeView->setDiffModel(_diffModel, _filesModel); 0166 0167 initActions(); 0168 setupGUI(StandardWindowOption::Default, QStringLiteral("kommitdiffui.rc")); 0169 0170 mDock->setVisible(showSideBar); 0171 0172 mTreeView->setModels(mDiffModel, mFilesModel); 0173 } 0174 0175 void DiffWindow::initActions() 0176 { 0177 auto actionCollection = this->actionCollection(); 0178 0179 auto viewHiddenCharsAction = actionCollection->addAction(QStringLiteral("view_hidden_chars")); 0180 viewHiddenCharsAction->setText(i18n("View hidden chars...")); 0181 viewHiddenCharsAction->setCheckable(true); 0182 connect(viewHiddenCharsAction, &QAction::triggered, mDiffWidget, &DiffWidget::showHiddenChars); 0183 0184 auto viewSameSizeBlocksAction = actionCollection->addAction(QStringLiteral("view_same_size_blocks"), mDiffWidget, &DiffWidget::showSameSize); 0185 viewSameSizeBlocksAction->setText(i18n("Same size blocks")); 0186 viewSameSizeBlocksAction->setCheckable(true); 0187 viewSameSizeBlocksAction->setChecked(true); 0188 0189 auto viewFilesInfo = actionCollection->addAction(QStringLiteral("view_files_info"), mDiffWidget, &DiffWidget::showFilesInfo); 0190 viewFilesInfo->setText(i18n("Show files names")); 0191 viewFilesInfo->setCheckable(true); 0192 viewFilesInfo->setChecked(true); 0193 0194 auto showTreeDockAction = mDock->toggleViewAction(); 0195 actionCollection->addAction(QStringLiteral("show_tree_dock"), showTreeDockAction); 0196 showTreeDockAction->setText(i18n("Show Tree")); 0197 0198 auto reloadAction = actionCollection->addAction(QStringLiteral("file_reload"), mDiffWidget, &DiffWidget::compare); 0199 reloadAction->setText(i18n("Reload")); 0200 0201 KStandardAction::quit(this, &QWidget::close, actionCollection); 0202 KStandardAction::open(this, &DiffWindow::fileOpen, actionCollection); 0203 0204 #ifdef UNDEF 0205 auto settingsManager = new SettingsManager(mGit, this); 0206 KStandardAction::preferences(settingsManager, &SettingsManager::show, actionCollection); 0207 #endif 0208 } 0209 0210 void DiffWindow::fileOpen() 0211 { 0212 DiffOpenDialog d(this); 0213 if (d.exec() != QDialog::Accepted) 0214 return; 0215 0216 if (d.mode() == DiffOpenDialog::Dirs) { 0217 mLeftStorage.setPath(d.oldDir()); 0218 mRightStorage.setPath(d.newDir()); 0219 compareDirs(); 0220 } else { 0221 mDiffWidget->setOldFile(QSharedPointer<Git::File>{new Git::File{d.oldFile()}}); 0222 mDiffWidget->setNewFile(QSharedPointer<Git::File>{new Git::File{d.newFile()}}); 0223 mDiffWidget->compare(); 0224 } 0225 } 0226 0227 void DiffWindow::slotTreeViewFileSelected(const QString &file) 0228 { 0229 // switch (mLeftStorage) { 0230 // case FileSystem: 0231 // mDiffWidget->setOldFile(Git::File{mLeftDir + QLatin1Char('/') + file}); 0232 // break; 0233 // case Git: 0234 // mDiffWidget->setOldFile({mGit, mOldBranch, file}); 0235 // break; 0236 // case NoStorage: 0237 // return; 0238 // } 0239 // switch (mRightStorage) { 0240 // case FileSystem: 0241 // mDiffWidget->setNewFile(Git::File{mRightDir + QLatin1Char('/') + file}); 0242 // break; 0243 // case Git: 0244 // mDiffWidget->setNewFile({mGit, mNewBranch, file}); 0245 // break; 0246 // case NoStorage: 0247 // return; 0248 // } 0249 0250 mDiffWidget->setOldFile(mLeftStorage.file(file)); 0251 mDiffWidget->setNewFile(mRightStorage.file(file)); 0252 0253 mDiffWidget->compare(); 0254 } 0255 0256 QString diffTypeText(const Diff::DiffType type) 0257 { 0258 switch (type) { 0259 case Diff::DiffType::Unchanged: 0260 return i18n("Unchanged"); 0261 case Diff::DiffType::Added: 0262 return i18n("Added"); 0263 case Diff::DiffType::Removed: 0264 return i18n("Removed"); 0265 case Diff::DiffType::Modified: 0266 return i18n("Modified"); 0267 } 0268 return {}; 0269 } 0270 0271 void DiffWindow::compareDirs() 0272 { 0273 auto map = Diff::diffDirs(mLeftDir, mRightDir); 0274 for (auto i = map.begin(); i != map.end(); ++i) { 0275 mDiffModel->addFile(i.key(), i.value()); 0276 } 0277 mDiffModel->sortItems(); 0278 0279 mDock->show(); 0280 } 0281 0282 QSharedPointer<Git::File> DiffWindow::Storage::file(const QString &path) const 0283 { 0284 switch (mMode) { 0285 case Mode::NoStorage: 0286 break; 0287 case Mode::FileSystem: 0288 return QSharedPointer<Git::File>{new Git::File{mPath + path}}; 0289 case Mode::Git: 0290 return QSharedPointer<Git::File>{new Git::File{mManager, "mNewBranch", path}}; 0291 case Mode::Tree: 0292 return mTree->file(path); 0293 } 0294 0295 return {}; 0296 } 0297 0298 void DiffWindow::Storage::setGitManager(Git::Manager *manager) 0299 { 0300 mMode = Mode::Git; 0301 mManager = manager; 0302 } 0303 0304 void DiffWindow::Storage::setPath(const QString &path) 0305 { 0306 mPath = path; 0307 if (!mPath.endsWith("/")) 0308 mPath += "/"; 0309 mMode = Mode::FileSystem; 0310 } 0311 0312 void DiffWindow::Storage::setTree(QSharedPointer<Git::Tree> tree) 0313 { 0314 mTree = tree; 0315 mMode = Mode::Tree; 0316 } 0317 #include "moc_diffwindow.cpp"