Merge lp:~dorins/qbzr/qdiff-changes into lp:qbzr

Proposed by Dorin Scutarașu
Status: Merged
Merged at revision: 1368
Proposed branch: lp:~dorins/qbzr/qdiff-changes
Merge into: lp:qbzr
Diff against target: 1172 lines (+463/-206)
6 files modified
data/qbzr.qrc (+3/-1)
lib/commands.py (+50/-45)
lib/diff_arg.py (+40/-31)
lib/diffwindow.py (+210/-100)
lib/resources.py (+144/-28)
lib/util.py (+16/-1)
To merge this branch: bzr merge lp:~dorins/qbzr/qdiff-changes
Reviewer Review Type Date Requested Status
Alexander Belchenko Approve
Gary van der Merwe Pending
Review via email: mp+34710@code.launchpad.net

Description of the change

Implements the following changes on the qdiff window:

- Move actions from the bottom of the window on a toolbar, similar to the toolbar from the qannotate window
- Add a Find actions which toggles a find toolbar. Find action acts on the active panel - the panel that had focus last.
- Add shortcut keys for "Refresh", "Find" and "Toggle view mode" actions and show shortcut key hints on tooltips for these actions and also for "Find next", "Find previous" actions.
- Add an "Ignore whitespace changes" option.

To post a comment you must log in.
Revision history for this message
Alexander Belchenko (bialix) wrote :

Looks nice.

Although it's not very intuitive that clicking lowered Side-by-side button will give me unidiff view.

Revision history for this message
Alexander Belchenko (bialix) wrote :

Shortcut for switching between Side-by-Side and Unidiff is Crtl+| which means pressing Ctrl+Shift+\ on my keyboard. Is using Shift intended here? Maybe it worth to use something simler instead?

Revision history for this message
Alexander Belchenko (bialix) wrote :

I see you have added Ignore whitespace changes option. Does it related to this merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-whitespace/+merge/35921 ?

Revision history for this message
Alexander Belchenko (bialix) wrote :

Alexander Belchenko пишет:
> Shortcut for switching between Side-by-Side and Unidiff is Crtl+| which means pressing Ctrl+Shift+\ on my keyboard. Is using Shift intended here? Maybe it worth to use something simler instead?

I suggest using Ctrl+U.

Revision history for this message
Dorin Scutarașu (dorins) wrote :

> I see you have added Ignore whitespace changes option. Does it related to this
> merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
> whitespace/+merge/35921 ?

Yes. Looks like the other branch has similar changes except that the UI is different: I added a menu item to toggle whitespace changes, the other branch uses a command line parameter.

lp:~dorins/qbzr/qdiff-changes updated
1317. By Dorin Scutarașu

* Replaced "Side by side" toolbar button with "Unidiff" button to reflect default view mode.
* Changed shortcut key for toggling view mode to "Ctrl-U".

Revision history for this message
Dorin Scutarașu (dorins) wrote :

> Although it's not very intuitive that clicking lowered Side-by-side button
> will give me unidiff view.

I replaced the "Side by side" button with a "Unidiff" button which makes more sense since side by side is the default. Also, I changed the shortcut key to "Ctrl-U". Thanks for the feedback.

Revision history for this message
Alexander Belchenko (bialix) wrote :

I like new variant. I have some doubts about using 3-panel icon for Unidiff button now, but I have no good suggestions.

Also I found that External Diff button does not work. Have you tested it?

Revision history for this message
Alexander Belchenko (bialix) wrote :

Dorin Scutarașu пишет:
>> I see you have added Ignore whitespace changes option. Does it related to this
>> merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
>> whitespace/+merge/35921 ?
>
> Yes. Looks like the other branch has similar changes except that the UI is different: I added a menu item to toggle whitespace changes, the other branch uses a command line parameter.

@Dorin, can you merge the changes from the other branch, so I can land
both branches soon? Or I can land the other branch first and you will
update your patch later?

@Glen, can you help Dorin to merge your patches, or do you prefer to
land your patch first?

Maybe you guys can collaborate on this feature?

Revision history for this message
Glen Mailer (glenjamin) wrote :

I think the best approach will be to merge my command line changes stuff into this branch - I can have a go at that this weekend.

Interestingly my first approach to whitespace removal was the regular expression substitution, but I replaced it with string.whitespace and string.translate after seeing Dorin's approach - meanwhile Dorin appears to have started with string.whitespace and moved to regular expression substitution.

Any ideas which is preferrable?

Revision history for this message
Dorin Scutarașu (dorins) wrote :

On 7 octombrie 2010, 13:43, Glen Mailer <email address hidden> wrote:
> I think the best approach will be to merge my command line changes stuff into this branch - I can have a go at that this weekend.
>

Sounds like a plan.

> Interestingly my first approach to whitespace removal was the regular expression substitution, but I replaced it with string.whitespace and string.translate after seeing Dorin's approach - meanwhile Dorin appears to have started with string.whitespace and moved to regular expression substitution.
>
> Any ideas which is preferrable?
> --
> https://code.launchpad.net/~dorins/qbzr/qdiff-changes/+merge/34710
> You are the owner of lp:~dorins/qbzr/qdiff-changes.
>

I made some tests and it looks like string.translate is fastest. I
switched to using regular expresion substitution because I had some
problems with string.translate:

* python >= 2.6 accepts None as the first parameter, but older python
  versions don't.

* string.translate delegates to either str.translate(s, table,
  delchars=None) or unicode.translate(s, table), so it crashes for unicode
  strings when passing delchars argument.

I switched to regular expressions at the time thinking that I'll get back
to it and figure out how to use 'translate' safely, but I didn't manage to
do that so far.

lp:~dorins/qbzr/qdiff-changes updated
1318. By Dorin Scutarașu

Fixed "External Diff" toolbar button.

1319. By Dorin Scutarașu

Add shortcut keys: Alt+V pops up the view menu, Alt+E pops up the "External Diff" menu.

The shortcut keys are appended to the respective tool tips.
Also, "Complete" action is now accessible using "Alt+V,C" and "Ignore Whitespace changes" is accessible using "Alt+V,I".

1320. By Dorin Scutarașu

Merge with lp:~glenjamin/qbzr/qdiff-ignore-whitespace.
Adds --ignore-whitespace option in qdiff.

1321. By Dorin Scutarașu

Merge trunk.

Revision history for this message
Dorin Scutarașu (dorins) wrote :

> Also I found that External Diff button does not work. Have you tested it?

I missed that somehow. Anyway, I fixed it today.

> Dorin Scutarașu пишет:
> > > I see you have added Ignore whitespace changes option. Does it related to this
> > > merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
> > > whitespace/+merge/35921 ?
> >
> > Yes. Looks like the other branch has similar changes except that the
> > UI is different: I added a menu item to toggle whitespace changes,
> > the other branch uses a command line parameter.

> @Dorin, can you merge the changes from the other branch, so I can land
> both branches soon? Or I can land the other branch first and you will
> update your patch later?

I just merged the changes from this merge proposal:
https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-whitespace/+merge/35921
, which exposes an --ignore-whitespace option to qdiff.

lp:~dorins/qbzr/qdiff-changes updated
1322. By Dorin Scutarașu

Cleanup.

Revision history for this message
Glen Mailer (glenjamin) wrote :

> > Also I found that External Diff button does not work. Have you tested it?
>
> I missed that somehow. Anyway, I fixed it today.
>
> > Dorin Scutarașu пишет:
> > > > I see you have added Ignore whitespace changes option. Does it related
> to this
> > > > merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
> > > > whitespace/+merge/35921 ?
> > >
> > > Yes. Looks like the other branch has similar changes except that the
> > > UI is different: I added a menu item to toggle whitespace changes,
> > > the other branch uses a command line parameter.
>
> > @Dorin, can you merge the changes from the other branch, so I can land
> > both branches soon? Or I can land the other branch first and you will
> > update your patch later?
>
> I just merged the changes from this merge proposal:
> https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
> whitespace/+merge/35921
> , which exposes an --ignore-whitespace option to qdiff.

Excellent! I was just about to take a look at this :)

Revision history for this message
Alexander Belchenko (bialix) wrote :

Glen Mailer пишет:
>>> Also I found that External Diff button does not work. Have you tested it?
>> I missed that somehow. Anyway, I fixed it today.
>>
>>> Dorin Scutarașu пишет:
>>>>> I see you have added Ignore whitespace changes option. Does it related
>> to this
>>>>> merge proposal: https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
>>>>> whitespace/+merge/35921 ?
>>>> Yes. Looks like the other branch has similar changes except that the
>>>> UI is different: I added a menu item to toggle whitespace changes,
>>>> the other branch uses a command line parameter.
>>> @Dorin, can you merge the changes from the other branch, so I can land
>>> both branches soon? Or I can land the other branch first and you will
>>> update your patch later?
>> I just merged the changes from this merge proposal:
>> https://code.launchpad.net/~glenjamin/qbzr/qdiff-ignore-
>> whitespace/+merge/35921
>> , which exposes an --ignore-whitespace option to qdiff.
>
> Excellent! I was just about to take a look at this :)

Thank you, guys! I will review it ASAP and I hope to land it soon.

--
All the dude wanted was his rug back

Revision history for this message
Dorin Scutarașu (dorins) wrote :

Could someone review this please? Is there anything I can do to speed things up?

Revision history for this message
Alexander Belchenko (bialix) wrote :

Dorin Scutarașu пишет:
> Could someone review this please? Is there anything I can do to speed things up?

I'm very very very sorry, but it seems your patch misses our deadline
for 0.20 final to be in sync with bzr 2.3.
We will merge it as soon as 0.20 will be ready.

Sorry for the delay :-/

--
All the dude wanted was his rug back

Revision history for this message
Dorin Scutarașu (dorins) wrote :

> Sorry for the delay :-/

No problem. I was just curious as to what's holding this up. I was thinking about adding line numbers and "go to line" function, and wanted to work on top of this. I guess I need to figure out how the pipeline plug-in works.

Revision history for this message
Alexander Belchenko (bialix) wrote :

I was very busy last months, sorry. I'm going to merge it now. I think there is nothing we need to change or improve, and just need merge it, right?

Gary, are you have any comments on this patch?

review: Needs Information
Revision history for this message
Dorin Scutarașu (dorins) wrote :

> I was very busy last months, sorry. I'm going to merge it now. I think there
> is nothing we need to change or improve, and just need merge it, right?

Yes, as far as I know.

Revision history for this message
Alexander Belchenko (bialix) wrote :

Dorin, can you merge the trunk into your branch and resolve conflicts, please? There are some conflicted changes that look trivial, but I'm not quite sure about them. That will help me to do final review.

Revision history for this message
Alexander Belchenko (bialix) wrote :

> Dorin, can you merge the trunk into your branch and resolve conflicts, please?
> There are some conflicted changes that look trivial, but I'm not quite sure
> about them. That will help me to do final review.

I did it.

Revision history for this message
Alexander Belchenko (bialix) wrote :

Find is not intuitive because it search only on the left pane, I have to click on right pane to force it search there. I'd rather expect it searches both panes

Revision history for this message
Alexander Belchenko (bialix) wrote :

I've tested new qdiff but I haven't inspected every single line of your changes.

In the future please avoid unnecessary whitespace-only changes in contribution to QBzr. It breaks annotations and makes the review (without qdiff -w) much harder.

Also I wonder if we want to save state of "Ignore whitespace" knob in some config file (maybe in qbzr.conf or branch.conf) but I'm not sure yet. If you have any opinion on this we can discuss it in our google group ML.

Resume: many thanks for great work to you and Glenjamin. I'm going to land it to trunk and will release 0.21 beta1 soon so many people will have a chance to test it in the action.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== added file 'data/22x22/system-run.png'
0Binary files data/22x22/system-run.png 1970-01-01 00:00:00 +0000 and data/22x22/system-run.png 2010-10-16 08:18:41 +0000 differ0Binary files data/22x22/system-run.png 1970-01-01 00:00:00 +0000 and data/22x22/system-run.png 2010-10-16 08:18:41 +0000 differ
=== added file 'data/22x22/view-split-left-right.png'
1Binary files data/22x22/view-split-left-right.png 1970-01-01 00:00:00 +0000 and data/22x22/view-split-left-right.png 2010-10-16 08:18:41 +0000 differ1Binary files data/22x22/view-split-left-right.png 1970-01-01 00:00:00 +0000 and data/22x22/view-split-left-right.png 2010-10-16 08:18:41 +0000 differ
=== modified file 'data/qbzr.qrc'
--- data/qbzr.qrc 2009-12-22 22:04:05 +0000
+++ data/qbzr.qrc 2010-10-16 08:18:41 +0000
@@ -32,6 +32,8 @@
32 <file>22x22/go-jump.png</file>32 <file>22x22/go-jump.png</file>
33 <file>22x22/go-next.png</file>33 <file>22x22/go-next.png</file>
34 <file>22x22/go-previous.png</file>34 <file>22x22/go-previous.png</file>
35 <file>22x22/view-split-left-right.png</file>
36 <file>22x22/system-run.png</file>
3537
36</qresource>38</qresource>
37</RCC>
38\ No newline at end of file39\ No newline at end of file
40</RCC>
3941
=== modified file 'lib/commands.py'
--- lib/commands.py 2010-10-11 13:05:30 +0000
+++ lib/commands.py 2010-10-16 08:18:41 +0000
@@ -144,7 +144,7 @@
144 self.main_window should be instance of QBzrWindow or QBzrDialog144 self.main_window should be instance of QBzrWindow or QBzrDialog
145 with attribute "return_code" set to 0 or 1.145 with attribute "return_code" set to 0 or 1.
146 """146 """
147 147
148 @install_gettext148 @install_gettext
149 @report_missing_pyqt149 @report_missing_pyqt
150 def run(self, *args, **kwargs):150 def run(self, *args, **kwargs):
@@ -156,11 +156,11 @@
156 std_ui_factory = ui.ui_factory156 std_ui_factory = ui.ui_factory
157 try:157 try:
158 ui.ui_factory = QUIFactory()158 ui.ui_factory = QUIFactory()
159 159
160 # Set up global exception handling.160 # Set up global exception handling.
161 from bzrlib.plugins.qbzr.lib.trace import excepthook161 from bzrlib.plugins.qbzr.lib.trace import excepthook
162 sys.excepthook = excepthook162 sys.excepthook = excepthook
163 163
164 try:164 try:
165 try:165 try:
166 ret_code = self._qbzr_run(*args, **kwargs)166 ret_code = self._qbzr_run(*args, **kwargs)
@@ -251,7 +251,7 @@
251 else:251 else:
252 tree = branch.repository.revision_tree(252 tree = branch.repository.revision_tree(
253 revision_id = revision[0].in_history(branch).rev_id)253 revision_id = revision[0].in_history(branch).rev_id)
254 254
255 file_id = tree.path2id(relpath)255 file_id = tree.path2id(relpath)
256 if file_id is None:256 if file_id is None:
257 raise errors.NotVersionedError(filename)257 raise errors.NotVersionedError(filename)
@@ -288,7 +288,7 @@
288 """GUI for adding files or directories."""288 """GUI for adding files or directories."""
289 takes_args = ['selected*']289 takes_args = ['selected*']
290 takes_options = [ui_mode_option]290 takes_options = [ui_mode_option]
291 291
292 def _qbzr_run(self, selected_list=None, ui_mode=False):292 def _qbzr_run(self, selected_list=None, ui_mode=False):
293 tree, selected_list = builtins.tree_files(selected_list)293 tree, selected_list = builtins.tree_files(selected_list)
294 if selected_list == ['']:294 if selected_list == ['']:
@@ -387,6 +387,8 @@
387 Option('modified', short_name='M',387 Option('modified', short_name='M',
388 help='Show diff for modified files.'),388 help='Show diff for modified files.'),
389 Option('renamed', short_name='R', help='Show diff for renamed files.'),389 Option('renamed', short_name='R', help='Show diff for renamed files.'),
390 Option('ignore-whitespace', short_name='w',
391 help="Ignore whitespace when finding differences"),
390 bzr_option('diff', 'old'),392 bzr_option('diff', 'old'),
391 bzr_option('diff', 'new'),393 bzr_option('diff', 'new'),
392 ]394 ]
@@ -395,24 +397,26 @@
395 aliases = ['qdi']397 aliases = ['qdi']
396398
397 def get_diff_window_args(self, processEvents, add_cleanup):399 def get_diff_window_args(self, processEvents, add_cleanup):
400 args = {}
398 try:401 try:
399 from bzrlib.diff import get_trees_and_branches_to_diff_locked402 from bzrlib.diff import get_trees_and_branches_to_diff_locked
400 except ImportError:403 except ImportError:
401 from bzrlib.diff import get_trees_and_branches_to_diff404 from bzrlib.diff import get_trees_and_branches_to_diff
402 (old_tree, new_tree,405 (args["old_tree"], args["new_tree"],
403 old_branch, new_branch,406 args["old_branch"], args["new_branch"],
404 specific_files, extra_trees) = \407 args["specific_files"], _) = \
405 get_trees_and_branches_to_diff(408 get_trees_and_branches_to_diff(
406 self.file_list, self.revision, self.old, self.new)409 self.file_list, self.revision, self.old, self.new)
407 else:410 else:
408 (old_tree, new_tree,411 (args["old_tree"], args["new_tree"],
409 old_branch, new_branch,412 args["old_branch"], args["new_branch"],
410 specific_files, extra_trees) = \413 args["specific_files"], _) = \
411 get_trees_and_branches_to_diff_locked(414 get_trees_and_branches_to_diff_locked(
412 self.file_list, self.revision, self.old, self.new,415 self.file_list, self.revision, self.old, self.new,
413 add_cleanup)416 add_cleanup)
414 return old_tree, new_tree, old_branch, new_branch, specific_files417 args["ignore_whitespace"] = self.ignore_whitespace
415 418 return args
419
416 def get_ext_diff_args(self, processEvents):420 def get_ext_diff_args(self, processEvents):
417 args = []421 args = []
418 if self.revision and len(self.revision) == 1:422 if self.revision and len(self.revision) == 1:
@@ -425,14 +429,14 @@
425 args.append("--new=%s" % self.new)429 args.append("--new=%s" % self.new)
426 if self.old and not self.old == CUR_DIR:430 if self.old and not self.old == CUR_DIR:
427 args.append("--old=%s" % self.old)431 args.append("--old=%s" % self.old)
428 432
429 if self.file_list:433 if self.file_list:
430 args.extend(self.file_list)434 args.extend(self.file_list)
431 435
432 return None, args 436 return None, args
433437
434 def _qbzr_run(self, revision=None, file_list=None, complete=False,438 def _qbzr_run(self, revision=None, file_list=None, complete=False,
435 encoding=None,439 encoding=None, ignore_whitespace=False,
436 added=None, deleted=None, modified=None, renamed=None,440 added=None, deleted=None, modified=None, renamed=None,
437 old=None, new=None, ui_mode=False):441 old=None, new=None, ui_mode=False):
438442
@@ -445,11 +449,12 @@
445 if not (added or deleted or modified or renamed):449 if not (added or deleted or modified or renamed):
446 # if no filter option used then turn all on450 # if no filter option used then turn all on
447 filter_options.all_enable()451 filter_options.all_enable()
448 452
449 self.revision = revision453 self.revision = revision
450 self.file_list = file_list454 self.file_list = file_list
451 self.old = old455 self.old = old
452 self.new = new456 self.new = new
457 self.ignore_whitespace = ignore_whitespace
453458
454 window = DiffWindow(self,459 window = DiffWindow(self,
455 complete=complete,460 complete=complete,
@@ -464,7 +469,7 @@
464 """Show log of a repository, branch, file, or directory in a Qt window.469 """Show log of a repository, branch, file, or directory in a Qt window.
465470
466 By default show the log of the branch containing the working directory.471 By default show the log of the branch containing the working directory.
467 472
468 If multiple files are speciffied, they must be from the same branch.473 If multiple files are speciffied, they must be from the same branch.
469474
470 :Examples:475 :Examples:
@@ -618,7 +623,7 @@
618623
619 if directory is None:624 if directory is None:
620 directory = CUR_DIR625 directory = CUR_DIR
621 626
622 try:627 try:
623 tree_to = WorkingTree.open_containing(directory)[0]628 tree_to = WorkingTree.open_containing(directory)[0]
624 branch_to = tree_to.branch629 branch_to = tree_to.branch
@@ -705,7 +710,7 @@
705 tree_merger = self.merger.make_merger()710 tree_merger = self.merger.make_merger()
706 self.tt = tree_merger.make_preview_transform()711 self.tt = tree_merger.make_preview_transform()
707 result_tree = self.tt.get_preview_tree()712 result_tree = self.tt.get_preview_tree()
708 return self.merger.this_tree, result_tree, None, None, None713 return {"old_tree": self.merger.this_tree, "new_tree": result_tree}
709714
710 @install_gettext715 @install_gettext
711 @report_missing_pyqt716 @report_missing_pyqt
@@ -713,7 +718,7 @@
713 # Set up global execption handeling.718 # Set up global execption handeling.
714 from bzrlib.plugins.qbzr.lib.trace import excepthook719 from bzrlib.plugins.qbzr.lib.trace import excepthook
715 sys.excepthook = excepthook720 sys.excepthook = excepthook
716 721
717 self.merger = merger722 self.merger = merger
718 try:723 try:
719 window = DiffWindow(self, encoding=self._encoding)724 window = DiffWindow(self, encoding=self._encoding)
@@ -761,12 +766,12 @@
761# bzr qannotate commands.py -r1117766# bzr qannotate commands.py -r1117
762767
763class cmd_qsubprocess(Command):768class cmd_qsubprocess(Command):
764 """Run some bzr command as subprocess. 769 """Run some bzr command as subprocess.
765 Used with most of subprocess-based dialogs of QBzr.770 Used with most of subprocess-based dialogs of QBzr.
766 771
767 If CMD argument starts with @ characters then it used as name of file with772 If CMD argument starts with @ characters then it used as name of file with
768 actual cmd string (in utf-8).773 actual cmd string (in utf-8).
769 774
770 With --bencode option cmd string interpreted as bencoded list of utf-8775 With --bencode option cmd string interpreted as bencoded list of utf-8
771 strings. This is the recommended way to launch qsubprocess.776 strings. This is the recommended way to launch qsubprocess.
772 """777 """
@@ -929,7 +934,7 @@
929934
930 takes_args = ['submit_branch?', 'public_branch?']935 takes_args = ['submit_branch?', 'public_branch?']
931 takes_options = [ui_mode_option]936 takes_options = [ui_mode_option]
932 937
933 def _qbzr_run(self, submit_branch=CUR_DIR, public_branch=None, ui_mode=False):938 def _qbzr_run(self, submit_branch=CUR_DIR, public_branch=None, ui_mode=False):
934 branch = Branch.open_containing(submit_branch)[0]939 branch = Branch.open_containing(submit_branch)[0]
935 window = SendWindow(branch, ui_mode)940 window = SendWindow(branch, ui_mode)
@@ -939,74 +944,74 @@
939944
940class cmd_qswitch(QBzrCommand):945class cmd_qswitch(QBzrCommand):
941 """Set the branch of a checkout and update."""946 """Set the branch of a checkout and update."""
942 947
943 takes_args = ['location?']948 takes_args = ['location?']
944 takes_options = [ui_mode_option]949 takes_options = [ui_mode_option]
945 950
946 def _qbzr_run(self, location=None, ui_mode=False):951 def _qbzr_run(self, location=None, ui_mode=False):
947 from bzrlib.plugins.qbzr.lib.switch import QBzrSwitchWindow952 from bzrlib.plugins.qbzr.lib.switch import QBzrSwitchWindow
948 953
949 branch = Branch.open_containing(CUR_DIR)[0]954 branch = Branch.open_containing(CUR_DIR)[0]
950 bzrdir = BzrDir.open_containing(CUR_DIR)[0]955 bzrdir = BzrDir.open_containing(CUR_DIR)[0]
951 self.main_window = QBzrSwitchWindow(branch, bzrdir, location, ui_mode)956 self.main_window = QBzrSwitchWindow(branch, bzrdir, location, ui_mode)
952 self.main_window.show()957 self.main_window.show()
953 self._application.exec_() 958 self._application.exec_()
954959
955960
956class cmd_qunbind(QBzrCommand):961class cmd_qunbind(QBzrCommand):
957 """Convert the current checkout into a regular branch."""962 """Convert the current checkout into a regular branch."""
958 takes_options = [ui_mode_option, execute_option]963 takes_options = [ui_mode_option, execute_option]
959 964
960 def _qbzr_run(self, ui_mode=False, execute=False):965 def _qbzr_run(self, ui_mode=False, execute=False):
961 from bzrlib.plugins.qbzr.lib.unbind import QBzrUnbindDialog966 from bzrlib.plugins.qbzr.lib.unbind import QBzrUnbindDialog
962 967
963 branch = Branch.open_containing(CUR_DIR)[0]968 branch = Branch.open_containing(CUR_DIR)[0]
964 if branch.get_bound_location() == None:969 if branch.get_bound_location() == None:
965 raise errors.BzrCommandError("This branch is not bound.")970 raise errors.BzrCommandError("This branch is not bound.")
966 971
967 self.main_window = QBzrUnbindDialog(branch, ui_mode, execute)972 self.main_window = QBzrUnbindDialog(branch, ui_mode, execute)
968 self.main_window.show()973 self.main_window.show()
969 self._application.exec_() 974 self._application.exec_()
970975
971976
972class cmd_qexport(QBzrCommand):977class cmd_qexport(QBzrCommand):
973 """Export current or past revision to a destination directory or archive.978 """Export current or past revision to a destination directory or archive.
974 979
975 DEST is the destination file or dir where the branch will be exported.980 DEST is the destination file or dir where the branch will be exported.
976 If BRANCH_OR_SUBDIR is omitted then the branch containing the current working981 If BRANCH_OR_SUBDIR is omitted then the branch containing the current working
977 directory will be used.982 directory will be used.
978 """983 """
979 984
980 takes_args = ['dest?','branch_or_subdir?']985 takes_args = ['dest?','branch_or_subdir?']
981 takes_options = [ui_mode_option]986 takes_options = [ui_mode_option]
982 987
983 def _qbzr_run(self, dest=None, branch_or_subdir=None, ui_mode=False):988 def _qbzr_run(self, dest=None, branch_or_subdir=None, ui_mode=False):
984 from bzrlib.plugins.qbzr.lib.export import QBzrExportDialog989 from bzrlib.plugins.qbzr.lib.export import QBzrExportDialog
985 990
986 if branch_or_subdir == None:991 if branch_or_subdir == None:
987 branch = Branch.open_containing(CUR_DIR)[0]992 branch = Branch.open_containing(CUR_DIR)[0]
988 else:993 else:
989 branch = Branch.open_containing(branch_or_subdir)[0]994 branch = Branch.open_containing(branch_or_subdir)[0]
990 995
991 window = QBzrExportDialog(dest, branch, ui_mode)996 window = QBzrExportDialog(dest, branch, ui_mode)
992 window.show()997 window.show()
993 self._application.exec_() 998 self._application.exec_()
994999
9951000
996class cmd_qbind(QBzrCommand):1001class cmd_qbind(QBzrCommand):
997 """Convert the current branch into a checkout of the supplied branch.1002 """Convert the current branch into a checkout of the supplied branch.
998 1003
999 LOCATION is the branch where you want to bind your current branch.1004 LOCATION is the branch where you want to bind your current branch.
1000 """1005 """
1001 1006
1002 takes_args = ['location?']1007 takes_args = ['location?']
1003 takes_options = [ui_mode_option]1008 takes_options = [ui_mode_option]
1004 1009
1005 def _qbzr_run(self, location=None, ui_mode=False):1010 def _qbzr_run(self, location=None, ui_mode=False):
1006 from bzrlib.plugins.qbzr.lib.bind import QBzrBindDialog1011 from bzrlib.plugins.qbzr.lib.bind import QBzrBindDialog
1007 1012
1008 branch = Branch.open_containing(CUR_DIR)[0]1013 branch = Branch.open_containing(CUR_DIR)[0]
1009 1014
1010 self.main_window = QBzrBindDialog(branch, location, ui_mode)1015 self.main_window = QBzrBindDialog(branch, location, ui_mode)
1011 self.main_window.show()1016 self.main_window.show()
1012 self._application.exec_()1017 self._application.exec_()
10131018
=== modified file 'lib/diff_arg.py'
--- lib/diff_arg.py 2010-05-05 12:40:43 +0000
+++ lib/diff_arg.py 2010-10-16 08:18:41 +0000
@@ -27,25 +27,30 @@
27class DiffArgProvider (object):27class DiffArgProvider (object):
28 """Contract class to pass arguments to either builtin diff window, or28 """Contract class to pass arguments to either builtin diff window, or
29 external diffs"""29 external diffs"""
30 30
31 def get_diff_window_args(self, processEvents, add_cleanup):31 def get_diff_window_args(self, processEvents, add_cleanup):
32 """Returns the arguments for the builtin diff window.32 """Returns the arguments for the builtin diff window.
33 33
34 :return: (tree1, tree2, branch1, branch2, specific_files)34 :return: {"old_tree": old_tree,
35 "new_tree": new_tree,
36 "old_branch": old_branch, (optional)
37 "new_branch": new_branch, (optional)
38 "specific_files": specific_files, (optional)
39 "ignore_whitespace": True or False} (optional)
35 """40 """
36 raise NotImplementedError()41 raise NotImplementedError()
37 42
38 def get_ext_diff_args(self, processEvents):43 def get_ext_diff_args(self, processEvents):
39 """Returns the command line arguments for running an ext diff window.44 """Returns the command line arguments for running an ext diff window.
40 45
41 :return: (dir, List of command line arguments).46 :return: (dir, List of command line arguments).
42 """ 47 """
43 raise NotImplementedError()48 raise NotImplementedError()
4449
4550
46class InternalDiffArgProvider(DiffArgProvider):51class InternalDiffArgProvider(DiffArgProvider):
47 """Use for passing arguments from internal source."""52 """Use for passing arguments from internal source."""
48 53
49 def __init__(self, old_revid, new_revid, old_branch, new_branch,54 def __init__(self, old_revid, new_revid, old_branch, new_branch,
50 specific_files=None, specific_file_ids=None):55 specific_files=None, specific_file_ids=None):
51 self.old_revid = old_revid56 self.old_revid = old_revid
@@ -57,21 +62,21 @@
5762
58 self.old_tree = None63 self.old_tree = None
59 self.new_tree = None64 self.new_tree = None
60 65
61 def need_to_load_paths(self):66 def need_to_load_paths(self):
62 return self.specific_file_ids is not None \67 return self.specific_file_ids is not None \
63 and self.specific_files is None68 and self.specific_files is None
64 69
65 def load_old_tree(self):70 def load_old_tree(self):
66 if not self.old_tree:71 if not self.old_tree:
67 self.old_tree = \72 self.old_tree = \
68 self.old_branch.repository.revision_tree(self.old_revid)73 self.old_branch.repository.revision_tree(self.old_revid)
69 74
70 def load_new_tree_and_paths(self):75 def load_new_tree_and_paths(self):
71 if not self.new_tree:76 if not self.new_tree:
72 self.new_tree = \77 self.new_tree = \
73 self.new_branch.repository.revision_tree(self.new_revid)78 self.new_branch.repository.revision_tree(self.new_revid)
74 79
75 if self.need_to_load_paths():80 if self.need_to_load_paths():
76 self.new_tree.lock_read()81 self.new_tree.lock_read()
77 try:82 try:
@@ -85,14 +90,16 @@
85 processEvents()90 processEvents()
86 self.load_new_tree_and_paths()91 self.load_new_tree_and_paths()
87 processEvents()92 processEvents()
88 93
89 return (self.old_tree, self.new_tree,94 return {"old_tree": self.old_tree,
90 self.old_branch, self.new_branch,95 "new_tree": self.new_tree,
91 self.specific_files)96 "old_branch": self.old_branch,
92 97 "new_branch": self.new_branch,
98 "specific_files": self.specific_files}
99
93 def get_revspec(self):100 def get_revspec(self):
94 return "-rrevid:%s..revid:%s" % (self.old_revid, self.new_revid)101 return "-rrevid:%s..revid:%s" % (self.old_revid, self.new_revid)
95 102
96 def get_ext_diff_args(self, processEvents):103 def get_ext_diff_args(self, processEvents):
97 from bzrlib import urlutils104 from bzrlib import urlutils
98 from bzrlib import errors105 from bzrlib import errors
@@ -101,46 +108,46 @@
101 revspec = self.get_revspec()108 revspec = self.get_revspec()
102 if revspec:109 if revspec:
103 args.append(revspec)110 args.append(revspec)
104 111
105 from bzrlib.workingtree import WorkingTree112 from bzrlib.workingtree import WorkingTree
106 def get_base(branch, tree):113 def get_base(branch, tree):
107 if tree and isinstance(tree, WorkingTree):114 if tree and isinstance(tree, WorkingTree):
108 return urlutils.local_path_to_url(tree.basedir)115 return urlutils.local_path_to_url(tree.basedir)
109 return branch.base116 return branch.base
110 117
111 old_base = get_base(self.old_branch, self.old_tree)118 old_base = get_base(self.old_branch, self.old_tree)
112 new_base = get_base(self.new_branch, self.new_tree)119 new_base = get_base(self.new_branch, self.new_tree)
113 120
114 # We need to avoid using --new and --old because diff tools121 # We need to avoid using --new and --old because diff tools
115 # does not support it. There are however some cases where122 # does not support it. There are however some cases where
116 # this is not possilble.123 # this is not possilble.
117 need_old = False124 need_old = False
118 if not self.old_branch.base == self.new_branch.base:125 if not self.old_branch.base == self.new_branch.base:
119 need_old = True126 need_old = True
120 127
121 try:128 try:
122 dir = urlutils.local_path_from_url(new_base)129 dir = urlutils.local_path_from_url(new_base)
123 except errors.InvalidURL:130 except errors.InvalidURL:
124 dir = ""131 dir = ""
125 args.append("--new=%s" % new_base)132 args.append("--new=%s" % new_base)
126 need_old = True133 need_old = True
127 134
128 if need_old:135 if need_old:
129 args.append("--old=%s" % old_base)136 args.append("--old=%s" % old_base)
130 137
131 if self.need_to_load_paths():138 if self.need_to_load_paths():
132 self.load_new_tree_and_paths()139 self.load_new_tree_and_paths()
133 processEvents()140 processEvents()
134 if self.specific_files:141 if self.specific_files:
135 args.extend(self.specific_files)142 args.extend(self.specific_files)
136 143
137 return dir, args144 return dir, args
138145
139146
140class InternalWTDiffArgProvider(InternalDiffArgProvider):147class InternalWTDiffArgProvider(InternalDiffArgProvider):
141 """Use for passing arguments from internal source where the new tree is148 """Use for passing arguments from internal source where the new tree is
142 the working tree."""149 the working tree."""
143 150
144 def __init__(self, old_revid, new_tree, old_branch, new_branch,151 def __init__(self, old_revid, new_tree, old_branch, new_branch,
145 specific_files=None):152 specific_files=None):
146 self.old_revid = old_revid153 self.old_revid = old_revid
@@ -148,7 +155,7 @@
148 self.old_branch = old_branch155 self.old_branch = old_branch
149 self.new_branch = new_branch156 self.new_branch = new_branch
150 self.specific_files = specific_files157 self.specific_files = specific_files
151 158
152 self.old_tree = None159 self.old_tree = None
153160
154 def load_old_tree(self):161 def load_old_tree(self):
@@ -161,16 +168,18 @@
161 def get_diff_window_args(self, processEvents, add_cleanup):168 def get_diff_window_args(self, processEvents, add_cleanup):
162 self.load_old_tree()169 self.load_old_tree()
163 processEvents()170 processEvents()
164 171
165 return (self.old_tree, self.new_tree,172 return {"old_tree": self.old_tree,
166 self.old_branch, self.new_branch,173 "new_tree": self.new_tree,
167 self.specific_files)174 "old_branch": self.old_branch,
175 "new_branch": self.new_branch,
176 "specific_files": self.specific_files}
168177
169 def get_revspec(self):178 def get_revspec(self):
170 if self.old_revid is not None:179 if self.old_revid is not None:
171 return "-rrevid:%s" % (self.old_revid,)180 return "-rrevid:%s" % (self.old_revid,)
172 else:181 else:
173 return None182 return None
174 183
175 def need_to_load_paths(self):184 def need_to_load_paths(self):
176 return False185 return False
177186
=== modified file 'lib/diffwindow.py'
--- lib/diffwindow.py 2010-05-05 12:40:43 +0000
+++ lib/diffwindow.py 2010-10-16 08:18:41 +0000
@@ -22,6 +22,7 @@
2222
23import errno23import errno
24import time24import time
25import string
2526
26from PyQt4 import QtCore, QtGui27from PyQt4 import QtCore, QtGui
2728
@@ -47,19 +48,20 @@
4748
48from bzrlib.plugins.qbzr.lib.i18n import gettext, ngettext, N_49from bzrlib.plugins.qbzr.lib.i18n import gettext, ngettext, N_
49from bzrlib.plugins.qbzr.lib.util import (50from bzrlib.plugins.qbzr.lib.util import (
50 BTN_CLOSE, BTN_REFRESH,
51 FilterOptions,51 FilterOptions,
52 QBzrWindow,52 QBzrWindow,
53 ThrobberWidget,53 ToolBarThrobberWidget,
54 StandardButton,
55 get_set_encoding,54 get_set_encoding,
56 is_binary_content,55 is_binary_content,
57 run_in_loading_queue,56 run_in_loading_queue,
58 runs_in_loading_queue57 runs_in_loading_queue,
58 FindToolbar,
59 get_icon,
60 show_shortcut_hint
59 )61 )
60from bzrlib.plugins.qbzr.lib.uifactory import ui_current_widget62from bzrlib.plugins.qbzr.lib.uifactory import ui_current_widget
61from bzrlib.plugins.qbzr.lib.trace import reports_exception63from bzrlib.plugins.qbzr.lib.trace import reports_exception
62from bzrlib.plugins.qbzr.lib.encoding_selector import EncodingSelector64from bzrlib.plugins.qbzr.lib.encoding_selector import EncodingMenuSelector
6365
64try:66try:
65 from bzrlib.errors import FileTimestampUnavailable67 from bzrlib.errors import FileTimestampUnavailable
@@ -81,13 +83,13 @@
81 branch_title = ""83 branch_title = ""
82 if None not in (branch, other_branch) and branch.base != other_branch.base:84 if None not in (branch, other_branch) and branch.base != other_branch.base:
83 branch_title = branch.nick85 branch_title = branch.nick
84 86
85 if isinstance(tree, WorkingTree):87 if isinstance(tree, WorkingTree):
86 if branch_title:88 if branch_title:
87 return gettext("Working Tree for %s") % branch_title89 return gettext("Working Tree for %s") % branch_title
88 else:90 else:
89 return gettext("Working Tree")91 return gettext("Working Tree")
90 92
91 elif isinstance(tree, (RevisionTree, DirStateRevisionTree)):93 elif isinstance(tree, (RevisionTree, DirStateRevisionTree)):
92 # revision_id_to_revno is faster, but only works on mainline rev94 # revision_id_to_revno is faster, but only works on mainline rev
93 revid = tree.get_revision_id()95 revid = tree.get_revision_id()
@@ -117,7 +119,7 @@
117 elif isinstance(tree, _PreviewTree):119 elif isinstance(tree, _PreviewTree):
118 return gettext('Merge Preview')120 return gettext('Merge Preview')
119121
120 # XXX I don't know what other cases we need to handle 122 # XXX I don't know what other cases we need to handle
121 return 'Unknown tree'123 return 'Unknown tree'
122124
123125
@@ -138,9 +140,9 @@
138 if filter_options is None:140 if filter_options is None:
139 self.filter_options = FilterOptions(all_enable=True)141 self.filter_options = FilterOptions(all_enable=True)
140 self.complete = complete142 self.complete = complete
143 self.ignore_whitespace = False
144 self.delayed_signal_connections = []
141145
142 self.throbber = ThrobberWidget(self)
143
144 self.diffview = SidebySideDiffView(self)146 self.diffview = SidebySideDiffView(self)
145 self.sdiffview = SimpleDiffView(self)147 self.sdiffview = SimpleDiffView(self)
146 self.views = (self.diffview, self.sdiffview)148 self.views = (self.diffview, self.sdiffview)
@@ -148,74 +150,163 @@
148 self.stack = QtGui.QStackedWidget(self.centralwidget)150 self.stack = QtGui.QStackedWidget(self.centralwidget)
149 self.stack.addWidget(self.diffview)151 self.stack.addWidget(self.diffview)
150 self.stack.addWidget(self.sdiffview)152 self.stack.addWidget(self.sdiffview)
151
152 vbox = QtGui.QVBoxLayout(self.centralwidget)153 vbox = QtGui.QVBoxLayout(self.centralwidget)
153 vbox.addWidget(self.throbber)
154 vbox.addWidget(self.stack)154 vbox.addWidget(self.stack)
155155
156 diffsidebyside = QtGui.QRadioButton(gettext("Side by side"),156 for browser in self.diffview.browsers:
157 self.centralwidget)157 browser.installEventFilter(self)
158 self.connect(diffsidebyside,158
159 QtCore.SIGNAL("clicked(bool)"),159 self.create_main_toolbar()
160 self.click_diffsidebyside)160 self.addToolBarBreak()
161 diffsidebyside.setChecked(True);161 self.find_toolbar = FindToolbar(self, self.diffview.browsers[0],
162162 self.show_find)
163 unidiff = QtGui.QRadioButton(gettext("Unidiff"), self.centralwidget)163 self.find_toolbar.hide()
164 self.connect(unidiff,164 self.addToolBar(self.find_toolbar)
165 QtCore.SIGNAL("clicked(bool)"),165
166 self.click_unidiff)166 def connect_later(self, *args, **kwargs):
167 """Schedules a signal to be connected after loading CLI arguments.
168
169 Accepts the same arguments as QObject.connect method.
170 """
171 self.delayed_signal_connections.append((args, kwargs))
172
173 def process_delayed_connections(self):
174 for (args, kwargs) in self.delayed_signal_connections:
175 self.connect(*args, **kwargs)
176
177 def create_main_toolbar(self):
178 toolbar = self.addToolBar(gettext("Diff"))
179 toolbar.setMovable (False)
180 toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)
181
182 self.show_find = self.create_find_action()
183 toolbar.addAction(self.show_find)
184 toolbar.addAction(self.create_toggle_view_mode())
185 self.view_refresh = self.create_refresh_action()
186 toolbar.addAction(self.view_refresh)
187
188 if has_ext_diff():
189 show_ext_diff_menu = self.create_ext_diff_action()
190 toolbar.addAction(show_ext_diff_menu)
191 widget = toolbar.widgetForAction(show_ext_diff_menu)
192 widget.setPopupMode(QtGui.QToolButton.InstantPopup)
193 widget.setShortcut("Alt+E")
194 show_shortcut_hint(widget)
195
196 show_view_menu = self.create_view_menu()
197 toolbar.addAction(show_view_menu)
198 widget = toolbar.widgetForAction(show_view_menu)
199 widget.setPopupMode(QtGui.QToolButton.InstantPopup)
200 widget.setShortcut("Alt+V")
201 show_shortcut_hint(widget)
202
203 spacer = QtGui.QWidget()
204 spacer.setSizePolicy(QtGui.QSizePolicy.Expanding,
205 QtGui.QSizePolicy.Expanding)
206 toolbar.addWidget(spacer)
207
208 self.throbber = ToolBarThrobberWidget(self)
209 toolbar.addWidget(self.throbber)
210 return toolbar
211
212 def create_find_action(self):
213 action = QtGui.QAction(get_icon("edit-find"),
214 gettext("&Find"), self)
215 action.setShortcut(QtGui.QKeySequence.Find)
216 action.setToolTip(gettext("Find on active panel"))
217 show_shortcut_hint(action)
218 action.setCheckable(True)
219 return action
220
221 def create_toggle_view_mode(self):
222 action = QtGui.QAction(get_icon("view-split-left-right"),
223 gettext("Unidiff"), self)
224 action.setToolTip(
225 gettext("Toggle between Side by side and Unidiff view modes"))
226 action.setShortcut("Ctrl+U")
227 show_shortcut_hint(action)
228 action.setCheckable(True)
229 action.setChecked(False);
230 self.connect(action,
231 QtCore.SIGNAL("toggled (bool)"),
232 self.click_toggle_view_mode)
233 return action
234
235 def create_refresh_action(self):
236 action = QtGui.QAction(get_icon("view-refresh"),
237 gettext("&Refresh"), self)
238 action.setShortcut("Ctrl+R")
239 show_shortcut_hint(action)
240 self.connect(action,
241 QtCore.SIGNAL("triggered (bool)"),
242 self.click_refresh)
243 return action
244
245 def create_ext_diff_action(self):
246 action = QtGui.QAction(get_icon("system-run"),
247 gettext("&External Diff"), self)
248 action.setToolTip(
249 gettext("Launch an external diff application"))
250 ext_diff_menu = ExtDiffMenu(parent=self, include_builtin = False)
251 action.setMenu(ext_diff_menu)
252 self.connect(ext_diff_menu,
253 QtCore.SIGNAL("triggered(QString)"),
254 self.ext_diff_triggered)
255 return action
256
257
258 def create_view_menu(self):
259 show_view_menu = QtGui.QAction(get_icon("document-properties"), gettext("&View Options"), self)
260 view_menu = QtGui.QMenu(gettext('View Options'), self)
261 show_view_menu.setMenu(view_menu)
262
263 view_complete = QtGui.QAction(gettext("&Complete"), self)
264 view_complete.setCheckable(True)
265 self.connect(view_complete,
266 QtCore.SIGNAL("toggled (bool)"),
267 self.click_complete)
268 view_menu.addAction(view_complete)
269
270 self.ignore_whitespace_action = self.create_ignore_ws_action()
271 view_menu.addAction(self.ignore_whitespace_action)
167272
168 def on_left_encoding_changed(encoding):273 def on_left_encoding_changed(encoding):
169 if self.branches:274 if self.branches:
170 get_set_encoding(encoding, self.branches[0])275 get_set_encoding(encoding, self.branches[0])
171 self.click_refresh()276 self.click_refresh()
172 self.encoding_selector_left = EncodingSelector(encoding,277
173 gettext("Left side encoding:"),278 self.encoding_selector_left = EncodingMenuSelector(self.encoding,
174 on_left_encoding_changed)279 gettext("Left side encoding"),
280 on_left_encoding_changed)
281 view_menu.addMenu(self.encoding_selector_left)
175282
176 def on_right_encoding_changed(encoding):283 def on_right_encoding_changed(encoding):
177 if self.branches:284 if self.branches:
178 get_set_encoding(encoding, self.branches[1])285 get_set_encoding(encoding, self.branches[1])
179 self.click_refresh()286 self.click_refresh()
180 self.encoding_selector_right = EncodingSelector(encoding,287
181 gettext("Right side encoding:"),288 self.encoding_selector_right = EncodingMenuSelector(self.encoding,
182 on_right_encoding_changed)289 gettext("Right side encoding"),
183290 on_right_encoding_changed)
184291 view_menu.addMenu(self.encoding_selector_right)
185 complete = QtGui.QCheckBox (gettext("Complete"),292 return show_view_menu
186 self.centralwidget)293
187 self.connect(complete,294 def create_ignore_ws_action(self):
188 QtCore.SIGNAL("clicked(bool)"),295 action = QtGui.QAction(gettext("&Ignore whitespace changes"), self)
189 self.click_complete)296 action.setCheckable(True)
190 complete.setChecked(self.complete);297 action.setChecked(self.ignore_whitespace);
191 298 self.connect_later(action,
192 if has_ext_diff():299 QtCore.SIGNAL("toggled (bool)"),
193 self.menu = ExtDiffMenu(include_builtin = False)300 self.click_ignore_whitespace)
194 ext_diff_button = QtGui.QPushButton(gettext('Using'), self)301 return action
195 ext_diff_button.setMenu(self.menu)302
196 self.connect(self.menu, QtCore.SIGNAL("triggered(QString)"),303 def eventFilter(self, object, event):
197 self.ext_diff_triggered)304 if event.type() == QtCore.QEvent.FocusIn:
198305 if object in self.diffview.browsers:
199 buttonbox = self.create_button_box(BTN_CLOSE)306 self.find_toolbar.text_edit = object
200307 return QBzrWindow.eventFilter(self, object, event)
201 refresh = StandardButton(BTN_REFRESH)308 # Why doesn't this work?
202 refresh.setEnabled(self.can_refresh())309 #return super(DiffWindow, self).eventFilter(object, event)
203 buttonbox.addButton(refresh, QtGui.QDialogButtonBox.ActionRole)
204 self.connect(refresh,
205 QtCore.SIGNAL("clicked()"),
206 self.click_refresh)
207 self.refresh_button = refresh
208
209 hbox = QtGui.QHBoxLayout()
210 hbox.addWidget(diffsidebyside)
211 hbox.addWidget(unidiff)
212 hbox.addWidget(complete)
213 if has_ext_diff():
214 hbox.addWidget(ext_diff_button)
215 hbox.addWidget(self.encoding_selector_left)
216 hbox.addWidget(self.encoding_selector_right)
217 hbox.addWidget(buttonbox)
218 vbox.addLayout(hbox)
219310
220 def show(self):311 def show(self):
221 QBzrWindow.show(self)312 QBzrWindow.show(self)
@@ -233,33 +324,33 @@
233 self.throbber.show()324 self.throbber.show()
234 op.add_cleanup(self.throbber.hide)325 op.add_cleanup(self.throbber.hide)
235 op.run()326 op.run()
236 327
237 def _initial_load(self, op):328 def _initial_load(self, op):
238 (tree1, tree2,329 args = self.arg_provider.get_diff_window_args(self.processEvents, op.add_cleanup)
239 branch1, branch2,330
240 specific_files) = self.arg_provider.get_diff_window_args(331 self.trees = (args["old_tree"], args["new_tree"])
241 self.processEvents, op.add_cleanup)332 self.branches = (args.get("old_branch", None), args.get("new_branch",None))
242 333 self.specific_files = args.get("specific_files", None)
243 self.trees = (tree1, tree2)334 self.ignore_whitespace = args.get("ignore_whitespace", False)
244 self.branches = (branch1, branch2)335 self.ignore_whitespace_action.setChecked(self.ignore_whitespace)
245 self.specific_files = specific_files336
246 337 self.process_delayed_connections()
247 self.load_branch_info()338 self.load_branch_info()
248 self.load_diff()339 self.load_diff()
249 340
250 def load_branch_info(self):341 def load_branch_info(self):
251 self.set_diff_title()342 self.set_diff_title()
252 343
253 self.encoding_selector_left.encoding = get_set_encoding(self.encoding, self.branches[0])344 self.encoding_selector_left.encoding = get_set_encoding(self.encoding, self.branches[0])
254 self.encoding_selector_right.encoding = get_set_encoding(self.encoding, self.branches[1])345 self.encoding_selector_right.encoding = get_set_encoding(self.encoding, self.branches[1])
255 self.processEvents()346 self.processEvents()
256 347
257 def set_diff_title(self):348 def set_diff_title(self):
258 rev1_title = get_title_for_tree(self.trees[0], self.branches[0],349 rev1_title = get_title_for_tree(self.trees[0], self.branches[0],
259 self.branches[1])350 self.branches[1])
260 rev2_title = get_title_for_tree(self.trees[1], self.branches[1],351 rev2_title = get_title_for_tree(self.trees[1], self.branches[1],
261 self.branches[0])352 self.branches[0])
262 353
263 title = [gettext("Diff"), "%s..%s" % (rev1_title, rev2_title)]354 title = [gettext("Diff"), "%s..%s" % (rev1_title, rev2_title)]
264355
265 if self.specific_files:356 if self.specific_files:
@@ -277,7 +368,7 @@
277 self.processEvents()368 self.processEvents()
278369
279 def load_diff(self):370 def load_diff(self):
280 self.refresh_button.setEnabled(False)371 self.view_refresh.setEnabled(False)
281 for tree in self.trees: tree.lock_read()372 for tree in self.trees: tree.lock_read()
282 self.processEvents()373 self.processEvents()
283 try:374 try:
@@ -337,7 +428,7 @@
337 # ghosts around us (see Bug #513096)428 # ghosts around us (see Bug #513096)
338 dates[ix] = 0 # using 1970/1/1 instead429 dates[ix] = 0 # using 1970/1/1 instead
339430
340 properties_changed = [] 431 properties_changed = []
341 if bool(executable[0]) != bool(executable[1]):432 if bool(executable[0]) != bool(executable[1]):
342 descr = {True: "+x", False: "-x", None: None}433 descr = {True: "+x", False: "-x", None: None}
343 properties_changed.append((descr[executable[0]],434 properties_changed.append((descr[executable[0]],
@@ -374,12 +465,7 @@
374 elif versioned == (False, True):465 elif versioned == (False, True):
375 groups = [[('insert', 0, 0, 0, len(lines[1]))]]466 groups = [[('insert', 0, 0, 0, len(lines[1]))]]
376 else:467 else:
377 matcher = SequenceMatcher(None, lines[0], lines[1])468 groups = self.difference_groups(lines[0], lines[1])
378 self.processEvents()
379 if self.complete:
380 groups = list([matcher.get_opcodes()])
381 else:
382 groups = list(matcher.get_grouped_opcodes())
383 ulines = []469 ulines = []
384 for l, encoding in zip(lines, [self.encoding_selector_left.encoding,470 for l, encoding in zip(lines, [self.encoding_selector_left.encoding,
385 self.encoding_selector_right.encoding]):471 self.encoding_selector_right.encoding]):
@@ -416,18 +502,34 @@
416 QtGui.QMessageBox.information(self, gettext('Diff'),502 QtGui.QMessageBox.information(self, gettext('Diff'),
417 gettext('No changes found.'),503 gettext('No changes found.'),
418 gettext('&OK'))504 gettext('&OK'))
419 self.refresh_button.setEnabled(self.can_refresh())505 self.view_refresh.setEnabled(self.can_refresh())
420506
421 def click_unidiff(self, checked):507 def difference_groups(self, left, right):
422 if checked:508 if self.ignore_whitespace:
423 self.sdiffview.rewind()509 table = string.maketrans("", "")
424 self.stack.setCurrentIndex(1)510 strip = lambda l : l.translate(table, string.whitespace)
425511 left = (line.translate(table, string.whitespace) for line in left)
426 def click_diffsidebyside(self, checked):512 right = (line.translate(table, string.whitespace) for line in right)
427 if checked:513 matcher = SequenceMatcher(None, left, right)
428 self.diffview.rewind()514 self.processEvents()
429 self.stack.setCurrentIndex(0)515 if self.complete:
430 516 groups = list([matcher.get_opcodes()])
517 else:
518 groups = list(matcher.get_grouped_opcodes())
519
520 return groups
521
522 def click_toggle_view_mode(self, checked):
523 if checked:
524 view = self.sdiffview
525 self.find_toolbar.text_edit = view
526 else:
527 view = self.diffview
528 self.find_toolbar.text_edit = view.browsers[0]
529 view.rewind()
530 index = self.stack.indexOf(view)
531 self.stack.setCurrentIndex(index)
532
431 def click_complete(self, checked ):533 def click_complete(self, checked ):
432 self.complete = checked534 self.complete = checked
433 #Has the side effect of refreshing...535 #Has the side effect of refreshing...
@@ -448,7 +550,15 @@
448 if isinstance(tree1, MutableTree) or isinstance(tree2, MutableTree):550 if isinstance(tree1, MutableTree) or isinstance(tree2, MutableTree):
449 return True551 return True
450 return False552 return False
451 553
452 def ext_diff_triggered(self, ext_diff):554 def ext_diff_triggered(self, ext_diff):
453 """@param ext_diff: path to external diff executable."""555 """@param ext_diff: path to external diff executable."""
454 show_diff(self.arg_provider, ext_diff=ext_diff, parent_window = self)556 show_diff(self.arg_provider, ext_diff=ext_diff, parent_window = self)
557
558 def click_ignore_whitespace(self, checked ):
559 self.ignore_whitespace = checked
560 #Has the side effect of refreshing...
561 self.diffview.clear()
562 self.sdiffview.clear()
563 run_in_loading_queue(self.load_diff)
564
455565
=== modified file 'lib/resources.py'
--- lib/resources.py 2009-12-22 22:04:05 +0000
+++ lib/resources.py 2010-10-16 08:18:41 +0000
@@ -2,8 +2,8 @@
22
3# Resource object code3# Resource object code
4#4#
5# Created: Fri Dec 18 15:04:38 20095# Created: Ma aug. 31 02:22:47 2010
6# by: The Resource Compiler for PyQt (Qt v4.5.2)6# by: The Resource Compiler for PyQt (Qt v4.7.0)
7#7#
8# WARNING! All changes made in this file will be lost!8# WARNING! All changes made in this file will be lost!
99
@@ -323,6 +323,111 @@
323\x62\x92\x6e\xdf\x1c\xb8\x35\x76\xd9\x24\xeb\x89\x72\x63\xe8\xfd\323\x62\x92\x6e\xdf\x1c\xb8\x35\x76\xd9\x24\xeb\x89\x72\x63\xe8\xfd\
324\xc4\xfa\x07\x16\xd6\x69\xc5\x45\xde\xc7\x7f\x00\x00\x00\x00\x49\324\xc4\xfa\x07\x16\xd6\x69\xc5\x45\xde\xc7\x7f\x00\x00\x00\x00\x49\
325\x45\x4e\x44\xae\x42\x60\x82\325\x45\x4e\x44\xae\x42\x60\x82\
326\x00\x00\x05\x0c\
327\x89\
328\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
329\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\
330\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
331\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x1b\xaf\x00\x00\
332\x1b\xaf\x01\x5e\x1a\x91\x1c\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
333\xd7\x0c\x1c\x0b\x31\x3b\x67\xd3\x82\x66\x00\x00\x04\x99\x49\x44\
334\x41\x54\x78\xda\xa5\x55\x5d\x48\x64\x65\x18\x7e\xe6\xcc\x9f\xff\
335\x4e\x88\xbf\xad\x4e\xce\xe8\xec\x68\xe9\x62\x20\x76\xb1\x26\x95\
336\xe0\xb6\x5d\x2d\x6d\xc4\xae\x17\xe1\x55\x14\xe6\x85\x8a\x46\x17\
337\xe2\x7a\x25\x4a\x48\x17\x11\x0a\x09\x11\x11\xc4\x8a\x11\x2b\xe5\
338\x4f\xcb\x6a\x8b\xcb\x48\x6a\xd6\xd8\x34\xea\xe8\x8e\xab\xe3\xff\
339\xfc\xff\x9e\x99\x39\xa7\xf7\x3b\x71\x16\xd4\xc2\xa2\x07\x1e\xe6\
340\xcc\xf9\xbe\x79\xbf\xf7\x7d\xde\xe7\x7b\x47\x81\x7f\x81\xf1\xf1\
341\xf1\xb7\xd2\xd3\xd3\xcb\x95\x4a\x25\xf6\xf7\xf7\xd7\x9a\x9b\x9b\
342\xef\xe2\xff\xa2\xba\xba\x5a\x65\xb1\x58\x62\xa1\x50\x48\x64\x5c\
343\x58\x58\x88\xd5\xd6\xd6\xaa\x70\x01\x38\x9c\x41\x4f\x4f\x4f\xfd\
344\xd0\xd0\x50\x93\xfc\xbd\xb0\xb0\xb0\x88\xb2\x55\xb3\x6c\x19\xd3\
345\xd2\xd2\xd4\x45\x04\x79\x7d\x72\x72\xf2\xda\xe8\xe8\x68\x3d\xce\
346\xe0\x94\x14\x7d\x7d\x7d\xb7\x08\x5f\xa8\x54\x2a\x6e\x6c\x6c\xec\
347\x4e\x59\x59\x59\xa5\xc9\x64\xba\x51\x52\x52\xa2\x05\x41\x14\x45\
348\x89\xbb\xbb\xbb\x31\x87\xc3\x31\xae\xd1\x68\x6c\x54\x51\x4f\x22\
349\x91\x10\xa6\xa7\xa7\xdf\x69\x69\x69\xf9\x1a\x67\xd1\xde\xde\x5e\
350\xbf\xba\xba\xca\xfb\x7c\x3e\x51\x2e\x3b\x1c\x0e\x4b\x9f\xc1\x60\
351\x50\x0c\x04\x02\xa2\xdf\xef\x17\xbd\x5e\xaf\xe8\xf1\x78\x44\xb7\
352\xdb\x2d\x9e\x9c\x9c\x88\xc7\xc7\xc7\x22\xe9\x2e\xda\xed\x76\xbe\
353\xbb\xbb\xfb\xaa\x1c\xef\xa9\x56\x54\x6e\x1a\x65\xc3\x45\x22\x11\
354\x64\x64\x64\x80\xb2\x06\x43\x38\x1c\x81\xc3\xe9\x82\x3f\x18\x41\
355\x32\x29\x20\x3d\x55\x03\xfd\xb3\xb9\xd0\x68\xd4\x2c\x7b\x7a\x97\
356\x04\xcf\xf3\xa0\x24\x38\x42\x86\x1c\x4f\x29\x3f\xcc\xcd\xcd\x39\
357\x8c\x46\x23\xca\xcb\xcb\x5f\x11\x04\x01\xa9\xa9\xa9\xb0\x3b\xb6\
358\x61\x59\x71\x20\x29\x72\x10\x88\x7c\x42\xc0\x89\x37\x8c\xe5\xdf\
359\xb7\xc0\x21\x89\x67\xb2\x33\x10\x8b\xc5\x58\x50\x4c\x4c\x4c\xdc\
360\xe9\xed\xed\xfd\xfc\x5c\xc6\x0c\x59\x59\x59\x2f\x50\x50\x69\xf3\
361\xe2\x8a\x0d\x6b\xce\x13\x6a\x56\x0a\x3c\xbe\x20\xe2\x89\xa4\x44\
362\x9e\x4f\xd0\x01\x22\xee\x2f\x6c\x20\xc6\xc7\x71\x29\x5f\xc7\xf6\
363\xb3\x2a\xcd\x90\x21\x67\x5c\x57\x57\xa7\x22\x16\x37\x36\x36\x7e\
364\x9a\x9d\x9d\xad\x64\x25\xff\x68\xb1\xb3\xde\x4a\x52\x94\x17\xeb\
365\x00\x21\x86\x9d\x7d\x2f\x42\x31\x01\x5e\x7f\x08\xc1\x50\x04\x36\
366\x87\x0b\x95\x86\x5c\x30\x68\xb5\x5a\x33\xf5\xe7\x4b\x9d\x4e\x17\
367\xa4\xe6\x0a\x8a\xe1\xe1\xe1\x9b\x55\x55\x55\x5f\x69\x48\x34\x5a\
368\x54\x30\x6d\x1f\xbb\xdc\x78\xb8\xb4\x05\x25\x3d\xd7\x3c\x6f\xc4\
369\xeb\x2f\x57\x81\x9a\x08\xb7\xc7\x83\x9f\x7f\xdd\x80\xc5\xea\xc2\
370\x91\x3b\x80\x60\x30\x84\xdb\xd7\x6b\x70\xd9\x50\x28\x59\x31\x1a\
371\x8d\x8a\xe4\x90\x38\x79\xbd\x99\xa3\xee\x9a\x48\x74\x0d\x4b\x8f\
372\x35\x82\xf1\xf1\xce\x31\xf6\x0e\x3d\xf0\xf8\xa3\x88\x0b\xdc\xd3\
373\x26\x69\x35\x1a\xbc\x76\xf5\x45\xbc\x7f\xfb\x55\x7a\xaf\x80\xeb\
374\xd0\x0d\xdb\xd6\x01\x0b\x2a\xad\x2b\xfe\x82\x86\x1c\x64\xe2\x98\
375\x3e\xf1\x78\x1c\x74\x12\xa3\xb4\xe1\xe0\xd8\x8b\xbb\xdf\x3f\xc2\
376\xdc\xd2\x26\x5c\x27\x61\xc8\x20\xfd\xa5\x75\x97\x3b\x86\x95\xb5\
377\x3d\xd8\x37\x5d\x14\x8c\x63\xef\xe5\xdf\xb3\x58\x8c\x0a\x15\x95\
378\xe8\x20\x2f\xc6\xc9\x6e\xaa\xcc\xcc\x4c\x05\x08\xa6\xd2\x02\x29\
379\xcb\x48\x94\x47\x30\x92\x80\x0c\x7f\x8c\xc3\xec\xe2\x21\x7e\x98\
380\xfb\x4d\xd2\x9f\xb6\xe0\x32\xed\x95\x03\x32\xaf\x53\xbc\x04\xf9\
381\x7e\x43\x35\x38\x38\xf8\x4d\x4e\x4e\xce\x77\x15\x15\x15\x97\x3a\
382\x3b\x3b\xad\xf9\xf9\xf9\x1a\xf3\x73\xb9\x30\x96\xe4\xe1\xd0\xe7\
383\xc3\x4f\xcb\x5b\x28\x2b\x2d\x86\x36\x2d\x0b\xf6\x9d\x04\x9c\x4f\
384\xfc\xa4\x65\x04\xa1\x80\x0f\x65\xfa\x3c\x98\xf4\xb9\xe4\x94\x18\
385\x0e\x0e\x0e\xf8\xfe\xfe\xfe\x6a\x9b\xcd\xf6\x84\x9a\x18\x91\x5c\
386\x41\x97\x22\xb1\xbd\xbd\xed\x6e\x68\x68\xb8\x92\x97\x97\x57\x09\
387\xc2\x15\xb3\x1e\xf7\xee\x2f\x92\x2b\xa2\xd8\xf7\x09\xf0\x47\x15\
388\xf0\xf9\x03\x70\x3a\x9d\xd8\x5c\xb7\x21\x1a\xf2\xe2\xe3\x0f\x6f\
389\x21\x3d\x85\x93\x32\x5e\x5f\x5f\x1f\x1f\x19\x19\xf9\x8c\xa4\x8d\
390\x9f\xf3\x31\x5d\x51\x2b\x2d\xdc\x64\x37\x29\x37\x5b\x8d\x4f\x3e\
391\x7a\x1b\x83\xa3\x53\x78\x34\x37\x03\xeb\x2f\x3a\x30\x04\xfc\x3e\
392\xe8\x0b\xb3\x31\x3c\xf4\x01\xcc\x86\x02\x96\xa9\x14\x98\xe4\xb4\
393\xfe\xed\x10\xa2\xd3\x9a\xe8\xd6\x4d\xa8\xd5\x6a\x25\x81\x5d\x69\
394\x89\x6a\x72\xc2\x1f\x9b\xfb\x58\x77\x1e\x82\x53\x28\x60\x36\x16\
395\x51\x35\x25\xcc\x01\x60\x60\x49\xd0\xfc\x00\xe9\x9a\x5c\x5a\x5a\
396\x7a\xa3\xa3\xa3\x63\xf2\x54\xc6\x54\x4a\xc2\x60\x30\x88\x34\x16\
397\x21\x8f\x48\xb2\x21\x44\xea\xb8\xb9\x34\x9f\x91\x05\x63\x64\xd2\
398\x9d\x72\x0a\x25\xc3\xdc\x22\xba\x5c\xae\xc4\xb9\x59\x31\x3f\x3f\
399\xbf\x45\xe3\xd1\xa5\xd7\xeb\xaf\xd3\x66\x91\x66\xc7\x20\x35\x61\
400\x2f\x25\x25\xc5\x48\x73\x43\xc5\x02\xca\x81\x8e\x8e\x8e\xa2\x56\
401\xab\xf5\xdb\xe5\xe5\xe5\x7b\xd4\x93\x97\xe8\x20\x61\x66\x66\xe6\
402\xbd\x81\x81\x81\x31\xfc\x13\xda\xda\xda\x9a\xba\xba\xba\x6e\x30\
403\x99\x18\x6b\x6a\x6a\x4c\xb3\xb3\xb3\x02\x8d\x54\x91\xf1\xc1\x83\
404\x07\x02\x7b\x27\xaf\x53\xe9\x6f\xb6\xb6\xb6\x5e\xc3\x7f\x45\x41\
405\x41\x81\x76\x6a\x6a\x8a\x27\x1b\x89\x8c\xf4\x8f\xc1\xd3\x1f\x88\
406\x16\x17\x40\x85\x0b\x40\x43\x9c\xa7\x8c\xdf\xa5\x60\x26\x10\x48\
407\xc7\x35\x22\x8f\x0b\xf0\x27\x9b\x2f\xb2\xa4\xb3\x87\x63\xc7\x00\
408\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
409\x00\x00\x01\x3c\
410\x89\
411\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
412\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\
413\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
414\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\xa7\x93\x00\
415\x00\x00\x09\x70\x48\x59\x73\x00\x00\x06\xec\x00\x00\x06\xec\x01\
416\x1e\x75\x38\x35\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x0c\x1c\
417\x14\x18\x23\xd6\xd5\xd3\x43\x00\x00\x00\xbc\x49\x44\x41\x54\x38\
418\xcb\xed\x95\xc1\x0a\x82\x40\x14\x45\xcf\xe8\xe4\x62\x92\x90\x96\
419\x05\xf5\x0b\xd1\xb7\x4b\xbf\xd1\x1f\x08\xba\x6a\x6d\xe5\x62\xe6\
420\x4d\xb6\x28\xb4\x85\x88\x81\x42\x90\x77\x75\x07\xce\x3b\x0c\xbc\
421\xc5\x53\xbc\xa2\x18\x37\xb5\x02\x56\xc0\x1e\x58\x8c\x24\x75\x40\
422\xae\x81\x5d\x55\x55\xe7\xc7\xa3\x0e\xc7\xb0\x06\x81\xf2\xc6\x98\
423\x83\x06\xa2\xb2\xbc\x86\x5a\x6b\x00\x6e\xb7\x7b\xef\x60\x1c\x2f\
424\x1b\xae\xab\x8b\x48\x08\x44\xfa\xfd\xa0\x28\x72\x00\x92\x64\xdd\
425\x2b\xce\xb2\x4b\xc3\x75\xf5\xcd\x66\x0b\x80\x06\x70\x4e\x30\x26\
426\x06\xc0\x5a\xdb\x2b\xfe\xe4\xba\xba\x73\xd2\x8a\xbd\x17\x44\x64\
427\x94\xcd\x79\xdf\x7a\x8e\xf5\xc0\xa4\xe9\x69\x10\x07\x1c\x83\xef\
428\x36\x3e\x1c\x9f\xc5\xb3\xf8\x0f\xc5\xfc\xc6\x8f\xed\x04\x62\x3b\
429\xd9\x69\x52\x53\x1d\xd3\x27\xd3\xf0\x95\x3a\x8b\x52\x56\x44\x00\
430\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
326\x00\x00\x02\x90\431\x00\x00\x02\x90\
327\x89\432\x89\
328\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\433\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
@@ -1714,6 +1819,15 @@
1714\x00\x68\x15\xe7\1819\x00\x68\x15\xe7\
1715\x00\x62\1820\x00\x62\
1716\x00\x7a\x00\x72\x00\x2d\x00\x33\x00\x32\x00\x2e\x00\x70\x00\x6e\x00\x67\1821\x00\x7a\x00\x72\x00\x2d\x00\x33\x00\x32\x00\x2e\x00\x70\x00\x6e\x00\x67\
1822\x00\x0e\
1823\x09\x14\x31\x07\
1824\x00\x73\
1825\x00\x79\x00\x73\x00\x74\x00\x65\x00\x6d\x00\x2d\x00\x72\x00\x75\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
1826\x00\x19\
1827\x01\x7d\x34\xe7\
1828\x00\x76\
1829\x00\x69\x00\x65\x00\x77\x00\x2d\x00\x73\x00\x70\x00\x6c\x00\x69\x00\x74\x00\x2d\x00\x6c\x00\x65\x00\x66\x00\x74\x00\x2d\x00\x72\
1830\x00\x69\x00\x67\x00\x68\x00\x74\x00\x2e\x00\x70\x00\x6e\x00\x67\
1717\x00\x11\1831\x00\x11\
1718\x01\x82\x9d\x27\1832\x01\x82\x9d\x27\
1719\x00\x69\1833\x00\x69\
@@ -1824,36 +1938,38 @@
18241938
1825qt_resource_struct = "\1939qt_resource_struct = "\
1826\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\1940\x00\x00\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x01\
1827\x00\x00\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x0f\1941\x00\x00\x00\x00\x00\x02\x00\x00\x00\x10\x00\x00\x00\x11\
1828\x00\x00\x00\x10\x00\x02\x00\x00\x00\x09\x00\x00\x00\x06\1942\x00\x00\x00\x10\x00\x02\x00\x00\x00\x0b\x00\x00\x00\x06\
1829\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x09\xe9\1943\x00\x00\x00\x3a\x00\x00\x00\x00\x00\x01\x00\x00\x09\xe9\
1830\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x79\1944\x00\x00\x00\x54\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x79\
1831\x00\x00\x00\x20\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\1945\x00\x00\x00\x20\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
1946\x00\x00\x00\x90\x00\x00\x00\x00\x00\x01\x00\x00\x18\x35\
1947\x00\x00\x00\xc8\x00\x00\x00\x00\x00\x01\x00\x00\x19\x75\
1948\x00\x00\x01\x10\x00\x00\x00\x00\x00\x01\x00\x00\x20\x4f\
1949\x00\x00\x01\xca\x00\x00\x00\x00\x00\x01\x00\x00\x36\x18\
1950\x00\x00\x01\x84\x00\x00\x00\x00\x00\x01\x00\x00\x2a\x68\
1951\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x30\xc0\
1832\x00\x00\x00\x6e\x00\x00\x00\x00\x00\x01\x00\x00\x13\x25\1952\x00\x00\x00\x6e\x00\x00\x00\x00\x00\x01\x00\x00\x13\x25\
1833\x00\x00\x00\xb6\x00\x00\x00\x00\x00\x01\x00\x00\x19\xff\1953\x00\x00\x00\xf0\x00\x00\x00\x00\x00\x01\x00\x00\x1c\x09\
1834\x00\x00\x01\x70\x00\x00\x00\x00\x00\x01\x00\x00\x2f\xc8\1954\x00\x00\x01\x68\x00\x00\x00\x00\x00\x01\x00\x00\x26\xc2\
1835\x00\x00\x01\x2a\x00\x00\x00\x00\x00\x01\x00\x00\x24\x18\1955\x00\x00\x01\xea\x00\x00\x00\x00\x00\x01\x00\x00\x3c\x7f\
1836\x00\x00\x01\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x2a\x70\1956\x00\x00\x01\x44\x00\x00\x00\x00\x00\x01\x00\x00\x23\x03\
1837\x00\x00\x00\x96\x00\x00\x00\x00\x00\x01\x00\x00\x15\xb9\1957\x00\x00\x02\x5a\x00\x00\x00\x00\x00\x01\x00\x00\x49\x32\
1838\x00\x00\x01\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x20\x72\1958\x00\x00\x04\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x69\x88\
1839\x00\x00\x01\x90\x00\x00\x00\x00\x00\x01\x00\x00\x36\x2f\1959\x00\x00\x02\x32\x00\x00\x00\x00\x00\x01\x00\x00\x46\xb6\
1840\x00\x00\x00\xea\x00\x00\x00\x00\x00\x01\x00\x00\x1c\xb3\1960\x00\x00\x03\x78\x00\x00\x00\x00\x00\x01\x00\x00\x5c\x24\
1841\x00\x00\x02\x00\x00\x00\x00\x00\x00\x01\x00\x00\x42\xe2\1961\x00\x00\x02\x06\x00\x00\x00\x00\x00\x01\x00\x00\x40\xa1\
1842\x00\x00\x03\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x63\x38\1962\x00\x00\x03\xc2\x00\x00\x00\x00\x00\x01\x00\x00\x61\x64\
1843\x00\x00\x01\xd8\x00\x00\x00\x00\x00\x01\x00\x00\x40\x66\1963\x00\x00\x01\xa4\x00\x00\x00\x00\x00\x01\x00\x00\x63\x23\
1844\x00\x00\x03\x1e\x00\x00\x00\x00\x00\x01\x00\x00\x55\xd4\1964\x00\x00\x02\xe6\x00\x00\x00\x00\x00\x01\x00\x00\x52\x7b\
1845\x00\x00\x01\xac\x00\x00\x00\x00\x00\x01\x00\x00\x3a\x51\1965\x00\x00\x03\x96\x00\x00\x00\x00\x00\x01\x00\x00\x5e\x90\
1846\x00\x00\x03\x68\x00\x00\x00\x00\x00\x01\x00\x00\x5b\x14\1966\x00\x00\x03\x38\x00\x00\x00\x00\x00\x01\x00\x00\x57\x5a\
1847\x00\x00\x01\x4a\x00\x00\x00\x00\x00\x01\x00\x00\x5c\xd3\1967\x00\x00\x02\xc4\x00\x00\x00\x00\x00\x01\x00\x00\x4f\xfc\
1848\x00\x00\x02\x8c\x00\x00\x00\x00\x00\x01\x00\x00\x4c\x2b\1968\x00\x00\x02\x70\x00\x00\x00\x00\x00\x01\x00\x00\x4a\x9f\
1849\x00\x00\x03\x3c\x00\x00\x00\x00\x00\x01\x00\x00\x58\x40\1969\x00\x00\x02\x9c\x00\x00\x00\x00\x00\x01\x00\x00\x4d\x5a\
1850\x00\x00\x02\xde\x00\x00\x00\x00\x00\x01\x00\x00\x51\x0a\1970\x00\x00\x03\xe0\x00\x00\x00\x00\x00\x01\x00\x00\x66\xb7\
1851\x00\x00\x02\x6a\x00\x00\x00\x00\x00\x01\x00\x00\x49\xac\1971\x00\x00\x03\x0e\x00\x00\x00\x00\x00\x01\x00\x00\x54\xd9\
1852\x00\x00\x02\x16\x00\x00\x00\x00\x00\x01\x00\x00\x44\x4f\1972\x00\x00\x03\x52\x00\x00\x00\x00\x00\x01\x00\x00\x59\x50\
1853\x00\x00\x02\x42\x00\x00\x00\x00\x00\x01\x00\x00\x47\x0a\
1854\x00\x00\x03\x86\x00\x00\x00\x00\x00\x01\x00\x00\x60\x67\
1855\x00\x00\x02\xb4\x00\x00\x00\x00\x00\x01\x00\x00\x4e\x89\
1856\x00\x00\x02\xf8\x00\x00\x00\x00\x00\x01\x00\x00\x53\x00\
1857"1973"
18581974
1859def qInitResources():1975def qInitResources():
18601976
=== modified file 'lib/util.py'
--- lib/util.py 2010-09-06 09:13:15 +0000
+++ lib/util.py 2010-10-16 08:18:41 +0000
@@ -745,6 +745,15 @@
745 done.add(item)745 done.add(item)
746 combo.addItem(item)746 combo.addItem(item)
747747
748def show_shortcut_hint(action):
749 """Show this action's shortcut, if any, as part of the tooltip.
750
751 Make sure to set the shortcut and tooltip *before* calling this.
752 """
753 shortcut = action.shortcut()
754 if shortcut and shortcut.toString():
755 toolTip = action.toolTip()
756 action.setToolTip("%s (%s)" % (toolTip, shortcut.toString()))
748757
749def iter_saved_pull_locations():758def iter_saved_pull_locations():
750 """ Iterate the 'pull' locations we have previously saved for the user.759 """ Iterate the 'pull' locations we have previously saved for the user.
@@ -1022,9 +1031,11 @@
1022 1031
1023 prev = self.addAction(get_icon("go-previous"), gettext("Previous"))1032 prev = self.addAction(get_icon("go-previous"), gettext("Previous"))
1024 prev.setShortcut(QtGui.QKeySequence.FindPrevious)1033 prev.setShortcut(QtGui.QKeySequence.FindPrevious)
1034 show_shortcut_hint(prev)
1025 1035
1026 next = self.addAction(get_icon("go-next"), gettext("Next"))1036 next = self.addAction(get_icon("go-next"), gettext("Next"))
1027 next.setShortcut(QtGui.QKeySequence.FindNext)1037 next.setShortcut(QtGui.QKeySequence.FindNext)
1038 show_shortcut_hint(next)
1028 1039
1029 self.case_sensitive = QtGui.QCheckBox(gettext("Case sensitive"), self)1040 self.case_sensitive = QtGui.QCheckBox(gettext("Case sensitive"), self)
1030 self.addWidget(self.case_sensitive)1041 self.addWidget(self.case_sensitive)
@@ -1088,7 +1099,7 @@
1088 self.find(self.text_edit.textCursor().selectionStart(), 0,1099 self.find(self.text_edit.textCursor().selectionStart(), 0,
1089 self.find_get_flags())1100 self.find_get_flags())
1090 1101
1091 def find_next(self, state):1102 def find_next(self):
1092 self.find(self.text_edit.textCursor().selectionEnd(), 0,1103 self.find(self.text_edit.textCursor().selectionEnd(), 0,
1093 self.find_get_flags())1104 self.find_get_flags())
1094 1105
@@ -1112,6 +1123,10 @@
1112 else:1123 else:
1113 self.text_edit.setTextCursor(cursor)1124 self.text_edit.setTextCursor(cursor)
11141125
1126 def set_text_edit(self, new_text_edit):
1127 if self.text_edit:
1128 self.text_edit.setTextCursor(QtGui.QTextCursor())
1129 self.text_edit = new_text_edit
11151130
1116class InfoWidget(QtGui.QFrame):1131class InfoWidget(QtGui.QFrame):
1117 def __init__(self, parent=None):1132 def __init__(self, parent=None):

Subscribers

People subscribed via source and target branches