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

Grey out files that have been Ctrl-X'ed #88

Merged
merged 1 commit into from
Sep 15, 2017
Merged

Grey out files that have been Ctrl-X'ed #88

merged 1 commit into from
Sep 15, 2017

Conversation

vc-01
Copy link
Contributor

@vc-01 vc-01 commented May 21, 2017

Add visual feedback for files that have been 'cut' to clipboard.

Hello. Referring to issue #503.

I was looking on that and made some working draft. But before more work to be put into this I'd like to know if you think this is good way at all and if you are interested in it.

I put more details in source comments temporarily.

I can answer design decisions but mostly they were influenced by speed requirements (to the point I understood them as such).

This solution is based mostly on weak pointers serving as "observers" to current cut selection, and if present - adjusting icons transparency (icons/thumbnails view only now)

In this approach, two lines of code are necessary to add to pcmanfm-qt because actual CTRL-X key shortcut is defined and processed there - test it with mouse context menu -> "cut" for now.

If you see something very mysterious there, that's possible, this is my first meet with all this, smart pointers etc.

This is not a ready to commit PR yet but a designing proposal.

@tsujan
Copy link
Member

tsujan commented May 22, 2017

It's great that you work on it! I'll read your code as soos as I find some free time. Thanks!

@vc-01
Copy link
Contributor Author

vc-01 commented May 22, 2017

I use pcmanfm-qt, I do it for myself and everyone else. It's hobby. But also please be patient when waiting for my responses and changes, could take some time too.

I'm not that content with this work but I couldn't find better solution actually.
Maybe I summarize it..

  1. Cutting files, pasting files (pasting not implemented yet but easy) - very fast, good
  2. Making another cut selection when one was already present - quite ok, fast (invalidating weak pointers)
  3. Reloading folder with cut files - more problematic, looking cut files through std::set of file path hashes for every file (and restricted to max. 450)

More detailed discussion when ready..
(and open to any hints and critics)

case FileIsCutRole:
bool isCut = false;
if (folder_ && folder_->hasCutFiles()) { // most of the time false
isCut = item->isCut() || item->info->isCut(); // then dynamic evaluation
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why is spread twice (in FileInfo and in FolderModelItem)? Because of const-ness of FileInfo. Could be casted away but should be?

@vc-01
Copy link
Contributor Author

vc-01 commented May 25, 2017

Anyway, I finished it the way it was started.

I forced pushed it as a full new patch but nothing has changed from before (if you started to review already), things were only added.

If settled and approved, I'll make another small PR in pcmanfm-qt repo to finalize it and make actual CTRL-X to work.

(Surely as mentioned before, this was not that straightforward as it may have seemed)

@tsujan
Copy link
Member

tsujan commented May 26, 2017

If settled and approved, I'll make another small PR in pcmanfm-qt repo to finalize it

You could do so now for people to be able to test your idea. In your pcmanfm-qt PR's comment, you could add "follows #88" or "based on ...".

@tsujan
Copy link
Member

tsujan commented May 26, 2017

BTW, sorry that I still haven't had time to read this! It needs to be read carefully because you've changed sensitive parts of the code. I'll find some time soon.

@tsujan
Copy link
Member

tsujan commented May 26, 2017

Before going to bed (it's past midnight here), I took a look at the code and hoped that it could be made simpler. However, graying out cut files isn't as easy as it might seem and you've done a great job here.

Including folderview.h in filemenu.h may not be a good option but I don't know of a better way either. in my (updated) patch for inline renaming (not PR'ed yet), I needed to include QAbstractItemView in filemenu.cpp to make it aware of views. So, perhaps this is inevitable -- I can't say yet.

Anyhow, there's a serious issue, IMHO. In your code, I couldn't find a mechanism for removing the grayed-out state when another file is copied. So, I compiled your branch and saw the problem. Since the grayed-out state is for the user to know which file will be cut and pasted the next time, if that state isn't removed after copying another file, it'll be misleading. I don't mean that the implementation of this property is easy but it's necessary.

Please keep up the good work! Thanks!

@tsujan
Copy link
Member

tsujan commented May 26, 2017

Oh! More importantly, we need a mechanism to watch the clipboard! Once something is copied/cut anywhere, the grayed-out state should be removed. Whether we need another approach or this one could be modified, I don't know yet.

@tsujan
Copy link
Member

tsujan commented May 27, 2017

Your last commit isn't enough. The grayed-out state should be removed on copying anywhere -- copying a text inside a text editor, for example.

@vc-01
Copy link
Contributor Author

vc-01 commented May 27, 2017

Yes, now I understand the problem. I can only hope I find a solution which wouldn't touch the core of the lib too much. Until now it was mostly about adding things. But this needs to be figured out, UI cannot mislead about its states, that would be a bug anyway.

(PR in pcmanfm-qt has to wait, this is not test ready yet again)

@tsujan
Copy link
Member

tsujan commented May 27, 2017

PR in pcmanfm-qt has to wait,

I agree. I hope you'll find a solution for copy/cut in other apps.

@palinek
Copy link
Contributor

palinek commented May 29, 2017

My poor 2 cents.... I think we should listen to to QClipboard changes and do something like in the Fm::pasteFilesFromClipboard & co. https://github.com/lxde/libfm-qt/blob/master/src/utilities.cpp#L69 . (maybe keep a global list of Fm::FolderModels to set the isCut flag for items..)

@vc-01
Copy link
Contributor Author

vc-01 commented May 29, 2017

@palinek

I think we should listen to QClipboard changes ...

Yes, this is the way I think, same approach is implemented in Dolphin file manager. I think I can come up with something but need some time.

maybe keep a global list of Fm::FolderModels to set the isCut flag for items

To avoid adding isCut state to FileInfo and then also to DirListJob? But FolderModelItems are re-created every chdir (https://github.com/lxde/libfm-qt/blob/master/src/foldermodel.cpp#L80). Maybe I didn't get your point, then need more explanation here.

@tsujan
Copy link
Member

tsujan commented May 29, 2017

To avoid adding isCut state to FileInfo and then also to DirListJob?

I don't think @palinek meant that. Keeping track of files that are cut is at the core of your approach and since the directory may change, it seems necessary.

We all agree that QClipboard should be watched.

@tsujan
Copy link
Member

tsujan commented May 29, 2017

@vc-01 I'm still suspicious about graying out files on such a deep level as that of FileInfo because we can't cut files from different directories but please complete your method! Even if it's too generalized for graying out, its structure might be used for other purposes in future.

@vc-01
Copy link
Contributor Author

vc-01 commented May 31, 2017

Two small bits to review first (bug-fixes).

Then the main patch, it's done with the least possible changes to the lib. In the next iteration, maybe I'd like a new global Clipboard (singleton) class which will wrap utilities' clipboard functions and save parsed data. But since this touches the core of the lib a lot, I left it to some subsequent PR.

Anyway, cut files are processed differently (aka more locally) for in-app made clipboard changes - same approach as already presented was kept.

I kept it, because I somehow believe in how was it done, because dealing directly with selections is fast. More general approach of listening to clipboard, signalling changes, and processing its data by saving and refreshing found folder items, may be cleaner design but slower (speed optimized code is always less readable and understandable).

Some slow method FolderModel::findItemByPath is used (but only for externally set cut files), I can provide refinement of this method by adding unordered map of FilePaths -> FolderModelItems, if you want. But this part of code won't be run very often.

Last thing, when pcmanfm-qt is started it doesn't process clipboard data (so doesn't possibly show cut files) because according to QClipboard documentation it is recommended that the contents of the clipboard are stored or retrieved in direct response to user-input events. Dolphin does this is on startup, but here I'm not sure what is correct.

(tested with Dolphin file manager)

(I can do commits squashing for cleaner history at the end before merge)

@tsujan
Copy link
Member

tsujan commented Jun 1, 2017

Requested @PCMan's review.

if(hasCutFiles && cutFilesHashSet_->count(fileInfo->path().hash()))
fileInfo->bindCutFiles(cutFilesHashSet_);

auto fileInfoConst = std::const_pointer_cast<const FileInfo>(fileInfo);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see now, maybe I should have created shared_ptr only here, then const_pointer_cast can be ommited - Can fix..

auto fileInfoConst = std::const_pointer_cast<const FileInfo>(fileInfo);

results_.push_back(fileInfoConst);
Q_EMIT gotInfo(path, fileInfoConst);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just to point out. Signal gotInfo is never used in the project.

@vc-01
Copy link
Contributor Author

vc-01 commented Jul 24, 2017

I'm thinking about what is best for this pull request now, after this new merge conflict appeared.

History of this branch is getting harder to follow and it's not merged yet, so now I think it's good time to tidy up this - do rebase and squash, which will though invalidate comment history.

I will still keep two bugfixes made as separate commits because they are separate things, only they were found during the development of this feature.

Stop me if not to do this or if it's better to close this pull request, do rebase + squash, and re-open it as a new one (still learning the github and opensource way).

@tsujan
Copy link
Member

tsujan commented Jul 24, 2017

@vc-01
I've had PRs which should have been rebased a few times, were marginalized by more important changes many times, or were removed and remade by me after several months. Such things often happen because of jumps in development, priorities or lack of manpower but they usually aren't about the PRs in question. So, it's up to the contributor to keep his/her idea up-to-date. The branch history isn't important -- if the code is clean, there will no need to a specific branch history.

@tsujan
Copy link
Member

tsujan commented Aug 1, 2017

I'll try to focus on this starting from tomorrow if no important bug is found.

@tsujan tsujan self-requested a review August 1, 2017 14:22
@tsujan
Copy link
Member

tsujan commented Aug 1, 2017

@vc-01 I was impressed by seeing that if I cut a file in Dolphin, it'll be grayed out in pcmanfm-qt too and conversely but there's a (small) problem:

When a cut file is grayed out in pcmanfm-qt, if something is copied elsewhere, the grayed-out state won't be removed until the cursor goes over the view or the pcmanfm-qt window is focused. This doesn't happen with Dolphin and is an issue. Could you fix it, please?

@tsujan
Copy link
Member

tsujan commented Aug 1, 2017

The problem only happens when desktop is shown (in the desktop mode).

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 3, 2017

@palinek I'm rethinking variables naming. I think it's not an issue if user in some less common way cut files - like in search results and then files aren't grayed out when browsing back directories. Especially when they aren't gray out in search result.

Confusing may be variable naming, because it looks like it's some low level cut files stuff - but it's not, it's used only for visual purposes, sometimes even skipped (hashes search for more than 450 cut files).

But if agreed upon, multi directory support is doable (will pollute the code a bit though).

EDIT: meant source code variable naming

@tsujan
Copy link
Member

tsujan commented Aug 3, 2017

But if agreed upon, multi directory support is doable

Could you explain how it might be possible to do multi-dir cut in pcmanfm-qt (since we don't gray out files when the cut is done by another app or in the search view)?

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 3, 2017

Could you explain how it might be possible to do multi-dir cut in pcmanfm-qt

e.g. if you have files testdir1/a1.test and testdir2/a2.test and you search with "Search in sub directories" option from the upper dir for *a* pattern and cut the result.

@tsujan
Copy link
Member

tsujan commented Aug 3, 2017

e.g. if you have files testdir1/a1.test and testdir2/a2.test and you search...

I know (and had edited my last comment) but we don't gray out files when they're cut n the search view.

@tsujan
Copy link
Member

tsujan commented Aug 3, 2017

Actually, the search view has several problems because searching is somehow "enforced". If, at some point, it's fixed, we could think about multi-dir gray-out. And as you said, it's possible,

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 3, 2017

I know (and had edited my last comment)

I see now edited comments are only visible after F5 / Refresh. As I said above I don't see this as a problem, because (1) if it's working - which means file are cut in clipboard, (2) if they aren't grayed out in search result, this shouldn't appear as bug to user - or at least it wouldn't to me.

@tsujan
Copy link
Member

tsujan commented Aug 3, 2017

OK. BTW, an explanation about hadCutFiles():
It wasn't needed to correctly set cut files but without it, all indexes in all open views would be refreshed on copying anything anywhere. At first, that didn't seem to be a problem but when I opened a few windows with folders containing many files, using Ctrl+C multiple times and consecutively in a text editor caused a tangible CPU usage. So, I saw the need for finding the folder that contained the previous cut file(s) to update only its indexes and only once.

@@ -62,6 +63,12 @@ void DirListJob::exec() {
false
};
if(enu) {
bool bindCutFiles = false;
if(cutFilesHashSet_
&& cutFilesHashSet_->size() < 450 /* give up if more than 450 cut files */) {
Copy link
Member

Choose a reason for hiding this comment

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

@vc-01 Could you please remove the condition about 450 files here and at FileInfoJob::exec()? It isn't needed anymore (there's no problem with thousands of files); moreover, it's confusing to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It looks like it's OK to remove it, it's fast for >1000 files, but be aware it's very different code path when selecting & cutting files inside a directory and go to a directory with already selected & cut files - hash set search is done only in the latter case.

Copy link
Member

Choose a reason for hiding this comment

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

but be aware it's very different code path when selecting & cutting files inside a directory and go to a directory with already selected & cut files

I know but don't see any extra CPU usage in the latter case with ~4000 cut files. Do you see any?

Copy link
Member

@tsujan tsujan Aug 3, 2017

Choose a reason for hiding this comment

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

By the way, what about adding !cutFilesHashSet_->empty()? Is it needed?

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, corrected it ;)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't see any extra CPU usage in the latter case

I searched for what's the best implementation for this particular case and std::set was a winner, probably it's very capable with even much bigger numbers - but not tested. I will remove the condition.

what about adding !cutFilesHashSet_->empty()? Is it needed?

It's tested already in folder.cpp:693 and folder.cpp:258 with Folder::hasCutFiles()

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 3, 2017

explanation about hadCutFiles()

hadCutFiles() is harder to understand in looking in the source, maybe some source comment will be helpful (for the future).

@tsujan
Copy link
Member

tsujan commented Aug 3, 2017

hadCutFiles() is harder to understand in looking in the source, maybe some source comment will be helpful (for the future).

I agree. It's simple and, at the same time, tricky, and especially this part in Folder::setCutFiles is really needed but the reason may not be clear:

    if(cutFilesHashSet_ && !cutFilesHashSet_->empty()) {
        oldCutFilesDirPath_ = cutFilesDirPath_;
    }

@tsujan
Copy link
Member

tsujan commented Aug 4, 2017

Yes, lastCutFilesDirPath_ is a better name for that variable.

Unimportant suggestions:

hadCutFilesInvalidate and hadCutFilesUnset sound a little weird to me.

This comment may also need to be changed:

// Add current pid to skip processing own data

To something like this:

// Add current pid to trace cut/copy operations to current app

@tsujan
Copy link
Member

tsujan commented Aug 4, 2017

I haven't encountered any problem in 2 days. Tomorrow, I'll test with remote files.

Copy link
Member

@tsujan tsujan left a comment

Choose a reason for hiding this comment

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

Was able to do the last test. My conclusion:

On the one hand, this patch adds a nice feature to libfm-qt/pcmanfm-qt, is fast/light, correctly shows files that are cut by the current app, and doesn't interfere with anything. On the other hand, I couldn't find a better way of doing the same thing. If also a fast way is found for graying out files the are cut by other apps, we could improve it later. So,

GTM.

@agaida Would you please also test and merge it?

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 4, 2017

hadCutFilesInvalidate and hadCutFilesUnset sound a little weird to me

I've encountered with such naming when functions do something more which should be mentioned in their names. As you can see I've had problem with this name too, cause I changed it twice.

hadCutFiles is not the best name IMO, because it does something more - invalidates / unsets the flag. I think functions like isSet etc. shouldn't change states unless mentioned - do you have a suggestion for the name? I don't have a problem to rename it.

// Add current pid to trace cut/copy operations to current app

Will change.

GTM

Please let me do the squashing first, this branch history is unneeded to keep IMO.

@tsujan
Copy link
Member

tsujan commented Aug 4, 2017

@vc-01 When it comes to names, tastes differ. That was the reason why I said those suggestions were unimportant.

Please let me do the squashing first, this branch history is unneeded to keep IMO.

Do so if you see it better in that way but I don't think it's important either. To me, the important thing is the nice job you've done here and it works without problem as far as I tested/used it.

@vc-01
Copy link
Contributor Author

vc-01 commented Aug 4, 2017

@tsujan I change function names a lot during development and I'm not "sure" with its names often, that's why I'm very open to change it to whatever name. Only its first name confused me a bit when tried to understand its behavior.

Squashing: First commit message went a bit obsolete and it's unnecessary for anyone to follow development path of this branch in the future IMO.

@tsujan
Copy link
Member

tsujan commented Aug 4, 2017

that's why I'm very open to change it to whatever name.

Frankly, no good name came to my mind because it checks something and invalidates it if found. If I hear of a better name in my dreams, I'll tell you ;) Fortunately, a name can't be an obstacle.

@tsujan
Copy link
Member

tsujan commented Aug 8, 2017

Just for the record:

This or #112, whichever is merged first, the other one might need a rebase.

tsujan referenced this pull request Aug 21, 2017
Used `QFileInfo::exists()` instead of `ProxyFolderModel::indexFromPath()` in one case.

Also removed the condition about text entry having focus because it wasn't reliable.
@tsujan
Copy link
Member

tsujan commented Aug 26, 2017

@vc-01 proxyfoldermodel.cpp has a conflict because of the file dialog commits; please rebase!

* Made with big help from Tsu Jan *

Add visual feedback for files that have been 'cut'
to clipboard.

This solution is based mostly on weak pointers
serving as "observers" to current cut selection.

Watching for clipboard changes to set or discard
set of cut files.

Without support for graying out multi-directory cut
selections or files cut in external applications.
@agaida
Copy link
Member

agaida commented Sep 14, 2017

@tsujan: Good to merge?

@tsujan
Copy link
Member

tsujan commented Sep 15, 2017

@agaida Yes, it's good. Please merge it!

@tsujan tsujan merged commit 17e3e9f into lxqt:master Sep 15, 2017
@tsujan
Copy link
Member

tsujan commented Sep 15, 2017

Did it myself.

@vc-01 Thanks again for the good work!

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.

4 participants