Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi file tool support #535

Draft
wants to merge 33 commits into
base: master
Choose a base branch
from

Conversation

gh-devnull
Copy link
Contributor

Extend DiffTool, MergeTool, EditTool, and ShowTool to support one or more files in each tool.

Each of these tools is extended to handle multiple files as input, allowing the user to handle all the files in one instance of the external tool, if the external tools supports this. An example would be diffing multiple files, one per tab, in one session of meld (or other diff application that allows similar tab-like behavior).

gh-devnull and others added 7 commits April 6, 2023 16:45
Extend DiffTool, MergeTool, EditTool, and ShowTool to support
one or more files in each tool.
Avoid the inconvenience of having to close the drop-down list manually after checking out a branch.

...and format...
Using the workspace file as "merged" allows for the file to be edited in-place for the merge.
@Murmele Murmele self-requested a review April 28, 2023 08:09
src/tools/DiffTool.cpp Outdated Show resolved Hide resolved
src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
src/ui/FileContextMenu.cpp Outdated Show resolved Hide resolved
@Murmele
Copy link
Owner

Murmele commented May 7, 2023

@gh-devnull sorry for the late review

src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
src/tools/MergeTool.cpp Show resolved Hide resolved
src/tools/MergeTool.cpp Outdated Show resolved Hide resolved
Comment on lines 124 to 126
if (--numMergeFiles) {
deleteLater();
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't it be if (--numMergeFiles == 0) {}. Otherwise it will be called by every process you are creating.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Fixed.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this really needed? If you remove the "this" from the qprocess constructor and then deleting the process here might be less error prone?

Copy link
Contributor Author

@gh-devnull gh-devnull May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that makes sense. While the value of the processes created by start() may be diminished if gittyup exits before them, there appears to be no good reason to tie their lifetimes (and possibly stability) to gittyup's. I've removed "this" as a QProcess constructor parameter for MergeTool, DiffTool, and EditTool. ShowTool uses QProcess::startDetached() which has the same semantics in this regard so no change is required there.

src/tools/MergeTool.cpp Show resolved Hide resolved
@gh-devnull gh-devnull force-pushed the multi-file-tool-support branch from b82d934 to fb6218c Compare May 10, 2023 15:35
…r from the QProcess constructor for DiffTool.cpp, EditTool.cpp, and MergeTool.cpp so the external tool process lifetimes are not in anyway tied to gittup's lifetime. This simulates QProcess::startDetached() behavior.
…r from the QProcess constructor for DiffTool.cpp, EditTool.cpp, and MergeTool.cpp so the external tool process lifetimes are not in anyway tied to gittup's lifetime. This simulates QProcess::startDetached() behavior.
@gh-devnull
Copy link
Contributor Author

@Murmele - I have a subsequent patch to make on top of these. It resolves issues that occur when a multi-selection includes directories (from a tree view). Do you want me to add it here now or do you want to close out the changes so far?

@Murmele
Copy link
Owner

Murmele commented May 15, 2023

Hi @gh-devnull I would prefer creating a new mr for this, because they can be handled indipendently or? Sorry I am completely under right now. I hope I get to your mr soon

@gh-devnull
Copy link
Contributor Author

OK, I'll keep the new patch local until this one finishes.

…eration.

When a directory is selected, all files within it, recursively, are added to the list of 
files selected.  This is not really what the user intends (i.e. if the files are displayed 
as a tree and the user selects from the first to the last, the user really only wants to 
interact with the selected files, not all those in any selected directory).  

Introduce the AccumRepoFiles class to keep track of files actually selected by the user 
as well as those under any selected directory and provide a way to get either list 
individually or both file lists together.
Copy link
Owner

@Murmele Murmele left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not test yet, what do you think about this?


int numFiles = mFiles.size();
foreach (const QString &filePathAndName, mFiles) {
git::Blob filePathOld, filePathNew;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
git::Blob filePathOld, filePathNew;
QProcess *process = new QProcess();
git::Blob filePathOld, filePathNew;

}

// Destroy this after process finishes.
QProcess *process = new QProcess();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QProcess *process = new QProcess();

// Get the path to the file (either a full or relative path).
QString otherPathAndName = filePathAndName;
if (filePathOld.isValid()) {
otherPathAndName = makeBlobTempFullFilePath(filePathAndName, filePathOld);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
otherPathAndName = makeBlobTempFullFilePath(filePathAndName, filePathOld);
otherPathAndName = makeBlobTempFullFilePath(filePathAndName, filePathOld, process);

Comment on lines +70 to +72
if (--numFiles == 0) {
deleteLater();
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (--numFiles == 0) {
deleteLater();
}
delete process;

if (!process->waitForStarted()) {
qDebug() << "DiffTool starting failed";
return false;
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
}
}
deleteLater();

}

QString DiffTool::makeBlobTempFullFilePath(const QString &filePathAndName,
const git::Blob &fileBlob) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const git::Blob &fileBlob) {
const git::Blob &fileBlob, QObject* parent) {


QFileInfo fileInfo(filePathAndName);
QString templatePath = QDir::temp().filePath(fileInfo.fileName());
QTemporaryFile *temp = new QTemporaryFile(templatePath, this);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
QTemporaryFile *temp = new QTemporaryFile(templatePath, this);
QTemporaryFile *temp = new QTemporaryFile(templatePath, parent);

git::Blob &blob) const;

QString makeBlobTempFullFilePath(const QString &filePathAndName,
const git::Blob &fileBlob);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const git::Blob &fileBlob);
const git::Blob &fileBlob, QObject* parent);

process->start(git::Command::substitute(env, command));
} else {
emit error(BashNotFound);
return false;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return false;
delete process;
return false;

return false;
if (!process->waitForStarted()) {
qDebug() << "DiffTool starting failed";
return false;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
return false;
delete process;
return false;

@Murmele
Copy link
Owner

Murmele commented May 16, 2023

The idea is that QProcess will be detached and the QTemporaryFile will be deleted once the QProcess will be deleted. So the MergeTool/DiffTool Object can be deleted indipendently

@gh-devnull
Copy link
Contributor Author

Sure, that looks like it's an incremental improvement on the existing logic. You'd want similar logic changes for MergeTool and EditTool too.

editor.remove("\"");

// Destroy this after process finishes.
QProcess *process = new QProcess(this);
QProcess *process = new QProcess();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you have to be carefull here, because without parent, the process object has to be deleted manually.
If you pass a parent, the Destructor of the parent will delete all childs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, that accounts for the cryptic comment. 😉 I'll review this.

@Murmele
Copy link
Owner

Murmele commented May 16, 2023

Sure, that looks like it's an incremental improvement on the existing logic. You'd want similar logic changes for MergeTool and EditTool too.

Yes this would be nice.

Maybe you can move makeBlobTempFullFilePath into externalTools so it can be reused?

@gh-devnull
Copy link
Contributor Author

Yes, I was thinking there may be some refactoring that could be done for this too.

Is there anything else that you want to see before you accept this mr? I'm not against iterating further to improve code maintainability and readability but I'd also like to finish off at least the first round of this functionality particularly because I have a dependent change affecting user-visible functionality already waiting.

@Murmele
Copy link
Owner

Murmele commented May 16, 2023

Yes, I was thinking there may be some refactoring that could be done for this too.

Is there anything else that you want to see before you accept this mr? I'm not against iterating further to improve code maintainability and readability but I'd also like to finish off at least the first round of this functionality particularly because I have a dependent change affecting user-visible functionality already waiting.

No I think this is all. Moving this temp file function into external tools and then executing the process. So it is independent of the rest of the gui application.
Maybe you can check if the tools can be directly deleted outside of the object instead of using deleteLater then?

@gh-devnull
Copy link
Contributor Author

OK, I'll investigate tool/process lifetime dependencies and interactions.

@Murmele
Copy link
Owner

Murmele commented May 17, 2023

OK, I'll investigate tool/process lifetime dependencies and interactions.

Thank you. Refactoring is here just needed, because I don't like this counter counting down and it is not much more work to change.

@Murmele
Copy link
Owner

Murmele commented May 26, 2023

@gh-devnull can I help you somehow?

@gh-devnull
Copy link
Contributor Author

@Murmele - Sorry, I did spend some further time on this but the work is incomplete and I haven't had a chance to finish it yet.

@Murmele
Copy link
Owner

Murmele commented May 29, 2023

@gh-devnull don't rush. When it is finish, it is finish 😃 thanks for working on it!

gh-devnull and others added 9 commits June 8, 2023 18:46
3c92cc0 ("Adds "Hide Untracked Files" option to DoubleTreeWidget cogwheel context menu", 2023-07-02) pvacatel
a80ffed ("Fixes code format according to clang-format", 2023-07-03) pvacatel
b202f1a ("Reverts format changes to test/Settings.cpp", 2023-07-04) pablov
0a935f8 ("enable debug build by setting a settings Reason: so the debug possibility is always available and is by default off for performance reason", 2023-07-14) Martin Marmsoler
198fb7a ("Update src/app/Application.cpp", 2023-07-14) Martin Marmsoler
1e57e7d ("Spanish translation", 2023-06-17) José Miguel Manzano 
3c92cc0 ("Adds "Hide Untracked Files" option to DoubleTreeWidget cogwheel context menu", 2023-07-02) pvacatel
a80ffed ("Fixes code format according to clang-format", 2023-07-03) pvacatel
b202f1a ("Reverts format changes to test/Settings.cpp", 2023-07-04) pablov
0a935f8 ("enable debug build by setting a settings Reason: so the debug possibility is always available and is by default off for performance reason", 2023-07-14) Martin Marmsoler
198fb7a ("Update src/app/Application.cpp", 2023-07-14) Martin Marmsoler
…as a list in TreeViews. Resolves Dense layout issue Murmele#547
Conflicts:
	.gitignore
	src/ui/FileContextMenu.cpp
@Murmele Murmele marked this pull request as draft November 12, 2023 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants