Merge lp:~craighewetson-deactivatedaccount/bzr-explorer/shorten-refresh-time into lp:bzr-explorer
- shorten-refresh-time
- Merge into trunk
Status: | Rejected |
---|---|
Rejected by: | Alexander Belchenko |
Proposed branch: | lp:~craighewetson-deactivatedaccount/bzr-explorer/shorten-refresh-time |
Merge into: | lp:bzr-explorer |
Diff against target: |
127 lines (+57/-4) 3 files modified
lib/custom_dialogs.py (+10/-0) lib/explorer.py (+41/-4) lib/explorer_preferences.py (+6/-0) |
To merge this branch: | bzr merge lp:~craighewetson-deactivatedaccount/bzr-explorer/shorten-refresh-time |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alexander Belchenko | Needs Information | ||
Craig Hewetson (community) | Needs Resubmitting | ||
Review via email: mp+18822@code.launchpad.net |
Commit message
Description of the change
After every action in bzr explorer the working tree gets refreshed and for large trees this makes the ui rather unresponsive. So instead of initiating a refresh of the working tree
after the user closes an action's dialog. The refresh will take place once the action has completed. If this is done the time between the user realizing that the action has completed
and when user closes the dialog can now be used for refreshing the working tree.
This means the user will effectively have to wait less for refreshes of the working tree and hence the app will feel more responsive for working larger trees.
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
My only problem i have is that i would like to call self.do_refresh() from a separate Thread. Because the dialog now takes longer to "complete" since its holding the ui to do the refresh work.
I'm not a python pro so is there any way to call the do_refresh() method from a Thread so that the ui does not get held up.
I've tried but I get all sorts of errors.
(QObject: Cannot create children for a parent that is in a different thread.
(Parent is QTextDocument(
In java I'll easily be able to do this, but thats just because I know java better.
Alexander Belchenko (bialix) wrote : | # |
Craig Hewetson пишет:
> My only problem i have is that i would like to call self.do_refresh() from a separate Thread. Because the dialog now takes longer to "complete" since its holding the ui to do the refresh work.
In PyQt you should not call methods directly but instead you should send
a signal to do what you need. Signals are asynchronous, and it won't
block your dialog.
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
>
>
> In PyQt you should not call methods directly but instead you should send
> a signal to do what you need. Signals are asynchronous, and it won't
> block your dialog.
>
>
It seems the bzr explorer already listeners to the finished() signal when
showing the dialog. The following code snippet comes from explorer.py line
1388 to 1396:
for
finisher.
I assume from this that the finisher method gets called when the
"finished()" signal is sent. But the dialog seems to get blocked i.e the OK
and Cancel buttons take a while before they get replaced with the "Close"
button.
Its very likely that I'm missing something here...
Alexander Belchenko (bialix) wrote : | # |
> This feature comes from the email discussion on how to reduce the time taken
> from when a qbzr dialog is closed to when the working tree is refreshed.
>
> email subject:
> Bzr-Explorer: Embedding status output after executing qbzr dialogs.
The discussion is here: http://
Alexander Belchenko (bialix) wrote : | # |
What is the status of this merge proposal today?
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
This branch isn't ready yet, I would have to find some time to look at it
again. I think i had an issue with the "finished()" signal... it was being
called too late
On Tue, Aug 24, 2010 at 7:57 PM, Alexander Belchenko <email address hidden> wrote:
> Review: Needs Information
> What is the status of this merge proposal today?
> --
>
> https:/
> You are the owner of lp:~craighewetson/bzr-explorer/shorten-refresh-time.
>
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
I've found a problem and it has to do with qbzr.
The SubProcessWindo
The problem is that when I connect with the "finished()" from bzr-explorer to run a refresh of the working tree. But I want the "close" button to show BEFORE my refresh work takes place. Currently it only gets shown AFTER the refresh has completed thus the dialog stays open while the working tree gets refreshed and this defeats the purpose of my feature.
I found a workaround to this and it requires me to change the do_finish method in SubProcessWindo
def on_finished(self):
if hasattr(self, 'setResult'):
if not self.ui_mode:
else: # This is where the change happens
NOTE: I explicitly change the state of the buttons while not solely relying on the "subprocessFini
This does feel like a hack so if there is a better suggestion please let me know ...
Alexander Belchenko (bialix) wrote : | # |
See related proposal where Simon did similar changes (okButton => self.okButton) https:/
Alexander Belchenko (bialix) wrote : | # |
> This does feel like a hack so if there is a better suggestion please let me know ...
What do you mean by "this"?
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
The idea of directly hiding and showing buttons and allowing the signal to
be emitted to do the same thing.
BUT, based on the comments on Simon's merge proposal and with me rethinking
my comment, I think its probably not a hack.
So I'll make the change and propose a merge...
Thanks
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
This patch will still will perform better when the code changes from this branch:
lp:~craighewetson/qbzr/subprocess_buttons_statechange
is merged into the qbzr project.
Note these changes can still be merged into bzr-explorer without the qbzr changes, because it will only result in the user having to wait for the subprocess dialog's close button getting enabled while the working tree is refreshed.
Once the qbzr change is merged the dialog can be closed as soon as the subprocess is finished and even while the refresh is taking place.
Alexander Belchenko (bialix) wrote : | # |
Craig, why you voted "Resubmit"? In Launchpad terms it means you asking yourself to rework the patch. Instead you should change status of proposal from "Work In Progress" to "Needs Review".
Anyway, I need something to put into NEWS file about this improvement.
Also, your changes for QBzr will be merged into QBzr 0.20. If it helps you can check the version of QBzr and don't block it if QBzr version < 0.20?
Another question: while Close button is not active user should still be able to close the dialog with Alt+F4 or Close icon in the dialog title. Can you check that it still works?
Alexander Belchenko (bialix) wrote : | # |
Craig, I think I know how to not block Close button.
You should not execute self.do_refresh() immediately, instead you should send additional signal to yourself with
QtCore.
The timer will start refresh once all other signals will be processed, as I understand. So buttons should be activated and won't blocked by refresh.
Craig, please test this change and say if it works as expected without patching QBzr.
Alexander Belchenko (bialix) wrote : | # |
@Craig, we need to decide something about this patch.
Craig Hewetson (craighewetson-deactivatedaccount) wrote : | # |
Hi Alexander
The problem is that none of the solutions actually freed up the UI thread enough to allow the user to close the dialog while the refresh is taking place. So to do the refresh after the dialog closes (currently happens in released version) is probably better than doing the refresh before its closed (this is what currently happens in this branch).
I don't think we can use this patch now. Until we can get bzr-explorer to call "refresh" (access bzrlib) from another thread other than the UI Thread.
Alexander Belchenko (bialix) wrote : | # |
I'm marking this merge proposal as Rejected for now, in hope we invent better solution later.
Unmerged revisions
- 486. By Craig Hewetson
-
Refresh the bzr-explorer working tree once the "custom" qbzr dialogs have completed their specific operations.
Preview Diff
1 | === modified file 'lib/custom_dialogs.py' | |||
2 | --- lib/custom_dialogs.py 2010-02-04 08:55:56 +0000 | |||
3 | +++ lib/custom_dialogs.py 2010-09-03 21:53:39 +0000 | |||
4 | @@ -36,6 +36,11 @@ | |||
5 | 36 | import workspace_dialogs | 36 | import workspace_dialogs |
6 | 37 | import checkout_dialog | 37 | import checkout_dialog |
7 | 38 | import switch_dialog | 38 | import switch_dialog |
8 | 39 | from bzrlib.plugins.qbzr.lib.update import QBzrUpdateWindow | ||
9 | 40 | from bzrlib.plugins.qbzr.lib.add import AddWindow | ||
10 | 41 | from bzrlib.plugins.qbzr.lib.commit import CommitWindow | ||
11 | 42 | from bzrlib.plugins.qbzr.lib.revert import RevertWindow | ||
12 | 43 | from bzrlib.plugins.qbzr.lib.uncommit import QBzrUncommitWindow | ||
13 | 39 | 44 | ||
14 | 40 | class CustomDialogRegistry(registry.Registry): | 45 | class CustomDialogRegistry(registry.Registry): |
15 | 41 | """Registry for custom dialogs. | 46 | """Registry for custom dialogs. |
16 | @@ -54,3 +59,8 @@ | |||
17 | 54 | checkout_dialog.QCheckoutExplorerStyleDialog) | 59 | checkout_dialog.QCheckoutExplorerStyleDialog) |
18 | 55 | custom_dialog_registry.register('switch', | 60 | custom_dialog_registry.register('switch', |
19 | 56 | switch_dialog.QSwitchExplorerStyleDialog) | 61 | switch_dialog.QSwitchExplorerStyleDialog) |
20 | 62 | custom_dialog_registry.register('update', QBzrUpdateWindow) | ||
21 | 63 | custom_dialog_registry.register('add', AddWindow) | ||
22 | 64 | custom_dialog_registry.register('commit', CommitWindow) | ||
23 | 65 | custom_dialog_registry.register('revert', RevertWindow) | ||
24 | 66 | custom_dialog_registry.register('uncommit', QBzrUncommitWindow) | ||
25 | 57 | 67 | ||
26 | === modified file 'lib/explorer.py' | |||
27 | --- lib/explorer.py 2010-08-24 17:34:38 +0000 | |||
28 | +++ lib/explorer.py 2010-09-03 21:53:39 +0000 | |||
29 | @@ -26,6 +26,7 @@ | |||
30 | 26 | trace, | 26 | trace, |
31 | 27 | urlutils, | 27 | urlutils, |
32 | 28 | ) | 28 | ) |
33 | 29 | from bzrlib.workingtree import WorkingTree | ||
34 | 29 | from bzrlib.commands import shlex_split_unicode | 30 | from bzrlib.commands import shlex_split_unicode |
35 | 30 | from bzrlib.plugins import explorer | 31 | from bzrlib.plugins import explorer |
36 | 31 | from bzrlib.plugins.explorer.lib import ( | 32 | from bzrlib.plugins.explorer.lib import ( |
37 | @@ -94,12 +95,11 @@ | |||
38 | 94 | 95 | ||
39 | 95 | # Actions that should automatically refresh the page on successful completion | 96 | # Actions that should automatically refresh the page on successful completion |
40 | 96 | _AUTO_REFRESH_CMDS = [ | 97 | _AUTO_REFRESH_CMDS = [ |
45 | 97 | 'add', 'commit', | 98 | 'send', 'bind', 'unbind', 'conflicts', 'pull', 'merge', 'push', |
46 | 98 | 'pull', 'merge', 'update', 'push', 'send', | 99 | # These really ought to be handled by a custom dialog so that the new |
43 | 99 | 'conflicts', 'switch', 'bind', 'unbind', 'revert', 'uncommit', | ||
44 | 100 | # This one really ought to be handled by a custom dialog so that the new | ||
47 | 101 | # location can be opened. Refreshing the current page (often the | 100 | # location can be opened. Refreshing the current page (often the |
48 | 102 | # repository view) is better than nothing though. | 101 | # repository view) is better than nothing though. |
49 | 102 | 'add', 'commit', 'switch', 'update', 'revert', 'uncommit', | ||
50 | 103 | 'branch', | 103 | 'branch', |
51 | 104 | ] | 104 | ] |
52 | 105 | 105 | ||
53 | @@ -1430,6 +1430,11 @@ | |||
54 | 1430 | 'branch': (self._start_branch, False, self._finish_branch), | 1430 | 'branch': (self._start_branch, False, self._finish_branch), |
55 | 1431 | 'checkout': (self._start_checkout, False, self._finish_checkout), | 1431 | 'checkout': (self._start_checkout, False, self._finish_checkout), |
56 | 1432 | 'switch': (self._start_switch, False, self._finish_switch), | 1432 | 'switch': (self._start_switch, False, self._finish_switch), |
57 | 1433 | 'update': (self._start_update, False, self._finish_do_refresh), | ||
58 | 1434 | 'add': (self._start_add, False, self._finish_do_refresh), | ||
59 | 1435 | 'commit': (self._start_commit, False, self._finish_do_refresh), | ||
60 | 1436 | 'revert': (self._start_revert, False, self._finish_do_refresh), | ||
61 | 1437 | 'uncommit': (self._start_uncommit, False, self._finish_do_refresh), | ||
62 | 1433 | } | 1438 | } |
63 | 1434 | if cmd_id in internal_handlers and cmd_id in custom_dialog_registry: | 1439 | if cmd_id in internal_handlers and cmd_id in custom_dialog_registry: |
64 | 1435 | if self.dry_run: | 1440 | if self.dry_run: |
65 | @@ -1497,6 +1502,38 @@ | |||
66 | 1497 | new_location = osutils.abspath(to_location) | 1502 | new_location = osutils.abspath(to_location) |
67 | 1498 | self.open_location(new_location) | 1503 | self.open_location(new_location) |
68 | 1499 | 1504 | ||
69 | 1505 | def _start_update(self, context=None): | ||
70 | 1506 | location = context.get('branch_root') | ||
71 | 1507 | tree = WorkingTree.open_containing(location)[0] | ||
72 | 1508 | dialog = custom_dialog_registry.get('update') | ||
73 | 1509 | return dialog(tree, parent=self) | ||
74 | 1510 | |||
75 | 1511 | def _start_add(self, context=None): | ||
76 | 1512 | location = context.get('branch_root') | ||
77 | 1513 | tree = WorkingTree.open_containing(location)[0] | ||
78 | 1514 | dialog = custom_dialog_registry.get('add') | ||
79 | 1515 | return dialog(tree, None, parent=self) | ||
80 | 1516 | |||
81 | 1517 | def _start_commit(self, context=None): | ||
82 | 1518 | location = context.get('branch_root') | ||
83 | 1519 | tree = WorkingTree.open_containing(location)[0] | ||
84 | 1520 | dialog = custom_dialog_registry.get('commit') | ||
85 | 1521 | return dialog(tree, None, parent=self) | ||
86 | 1522 | |||
87 | 1523 | def _start_revert(self, context=None): | ||
88 | 1524 | location = context.get('branch_root') | ||
89 | 1525 | tree = WorkingTree.open_containing(location)[0] | ||
90 | 1526 | dialog = custom_dialog_registry.get('revert') | ||
91 | 1527 | return dialog(tree, None, parent=self) | ||
92 | 1528 | |||
93 | 1529 | def _start_uncommit(self, context=None): | ||
94 | 1530 | location = context.get('branch_root') | ||
95 | 1531 | dialog = custom_dialog_registry.get('uncommit') | ||
96 | 1532 | return dialog(location, parent=self) | ||
97 | 1533 | |||
98 | 1534 | def _finish_do_refresh(self): | ||
99 | 1535 | self.do_refresh() | ||
100 | 1536 | |||
101 | 1500 | def _start_checkout(self, context=None): | 1537 | def _start_checkout(self, context=None): |
102 | 1501 | return custom_dialog_registry.get('checkout')(parent=self) | 1538 | return custom_dialog_registry.get('checkout')(parent=self) |
103 | 1502 | 1539 | ||
104 | 1503 | 1540 | ||
105 | === modified file 'lib/explorer_preferences.py' | |||
106 | --- lib/explorer_preferences.py 2010-08-06 15:08:29 +0000 | |||
107 | +++ lib/explorer_preferences.py 2010-09-03 21:53:39 +0000 | |||
108 | @@ -43,6 +43,11 @@ | |||
109 | 43 | "custom-dialog-branch": True, | 43 | "custom-dialog-branch": True, |
110 | 44 | "custom-dialog-checkout": True, | 44 | "custom-dialog-checkout": True, |
111 | 45 | "custom-dialog-switch": True, | 45 | "custom-dialog-switch": True, |
112 | 46 | "custom-dialog-update": True, | ||
113 | 47 | "custom-dialog-add": True, | ||
114 | 48 | "custom-dialog-commit": True, | ||
115 | 49 | "custom-dialog-revert": True, | ||
116 | 50 | "custom-dialog-uncommit": True, | ||
117 | 46 | "advanced-commands-terminal": False, | 51 | "advanced-commands-terminal": False, |
118 | 47 | "workingtree-style": "qbrowse", | 52 | "workingtree-style": "qbrowse", |
119 | 48 | "workspace-model": "feature-branches", | 53 | "workspace-model": "feature-branches", |
120 | @@ -65,6 +70,7 @@ | |||
121 | 65 | "custom-dialog-branch", | 70 | "custom-dialog-branch", |
122 | 66 | "custom-dialog-checkout", | 71 | "custom-dialog-checkout", |
123 | 67 | "custom-dialog-switch", | 72 | "custom-dialog-switch", |
124 | 73 | "custom-dialog-update", | ||
125 | 68 | "advanced-commands-terminal", | 74 | "advanced-commands-terminal", |
126 | 69 | "bind-branches-by-default", | 75 | "bind-branches-by-default", |
127 | 70 | "toolbox-on-status-view", | 76 | "toolbox-on-status-view", |
This feature comes from the email discussion on how to reduce the time taken from when a qbzr dialog is closed to when the working tree is refreshed.
email subject:
Bzr-Explorer: Embedding status output after executing qbzr dialogs.
The only dialogs I didn't do is:
qconflicts, pull, push and merge.