Merge lp:~jelmer/bzr-gtk/split-out-olive into lp:bzr-gtk/gtk2

Proposed by Jelmer Vernooij
Status: Merged
Merged at revision: 691
Proposed branch: lp:~jelmer/bzr-gtk/split-out-olive
Merge into: lp:bzr-gtk/gtk2
Diff against target: 4313 lines (+9/-4035)
27 files modified
AUTHORS (+0/-2)
MANIFEST.in (+0/-1)
__init__.py (+5/-9)
branchbox.py (+0/-5)
checkout.py (+0/-5)
cmenu.ui (+0/-32)
commands.py (+0/-13)
genpot.sh (+0/-43)
olive-gtk (+0/-94)
olive-gtk.1 (+0/-15)
olive-gtk.desktop (+0/-14)
olive/__init__.py (+0/-1407)
olive/add.py (+0/-95)
olive/bookmark.py (+0/-92)
olive/guifiles.py (+0/-49)
olive/info.py (+0/-287)
olive/info_helper.py (+0/-323)
olive/launch.py (+0/-54)
olive/menu.py (+0/-383)
olive/mkdir.py (+0/-92)
olive/move.py (+0/-115)
olive/remove.py (+0/-88)
olive/rename.py (+0/-104)
olive/window.py (+0/-575)
setup.py (+4/-46)
tests/__init__.py (+0/-1)
tests/test_preferences.py (+0/-91)
To merge this branch: bzr merge lp:~jelmer/bzr-gtk/split-out-olive
Reviewer Review Type Date Requested Status
Vincent Ladeuil Approve
Jasper Groenewegen (community) Approve
Szilveszter Farkas Pending
Review via email: mp+26376@code.launchpad.net

Description of the change

This splits olive out into a separate project again, per my email to the mailing list.

This makes olive a project with a relation to bzr-gtk that is similar to the relation between qbzr and bzr-explorer.

To post a comment you must log in.
Revision history for this message
Jasper Groenewegen (colbrac) wrote :

I think the visibility of Olive is improved when split out. As my focus was on Olive related development (you know, back in the day before I worked a fulltime job) I wouldn't mind receiving Olive related bugreports. Will the new olive project be maintained by the bzr-gtk maintainers group? I would hope so.

review: Approve
Revision history for this message
Jelmer Vernooij (jelmer) wrote :

Hey Jasper,

On Mon, 2010-05-31 at 21:10 +0000, Jasper Groenewegen wrote:
> Review: Approve I think the visibility of Olive is improved when split
> out. As my focus was on Olive related development (you know, back in
> the day before I worked a fulltime job) I wouldn't mind receiving
> Olive related bugreports. Will the new olive project be maintained by
> the bzr-gtk maintainers group? I would hope so.
Ah, I was wondering what had happened to you. :-) The same thing
happened to me, which is one of the reasons why I haven't had as much
time to spend on bzr-gtk as I used to.

I hope there will be some overlap between developers like there is
overlap between the qbzr and bzr-explorer developers, but it doesn't
necessarily have to be the same group of people.

Cheers,

Jelmer

Revision history for this message
Jasper Groenewegen (colbrac) wrote :

Losing the ability to help out properly is something most volunteers
encounter I think (at least the ones not moving on to a career in OS
development). I'm happy as it is that I'm able to use my python + numpy
dataprocessing abilities to sort through the more massive datasets I
have to work with now.
All the issues with bzr-gtk trying to stay near the bullseye with a fast
moving target like bzr or integration with other components such as
seahorse are harder to work on for people with less time. Adding polish
to Olive is more for me :) I really should get around to removing that
non-functioning and confusing history mode in Olive :/ Or figure out how
to call up old versions of documents as shown in the history file list.
:P (Who am I kidding, figuring out how LP works nowadays would be the
first hurdle :D).

Regards,
Jasper

On 31/05/10 23:45, Jelmer Vernooij wrote:
> Hey Jasper,
>
> On Mon, 2010-05-31 at 21:10 +0000, Jasper Groenewegen wrote:
>> Review: Approve I think the visibility of Olive is improved when split
>> out. As my focus was on Olive related development (you know, back in
>> the day before I worked a fulltime job) I wouldn't mind receiving
>> Olive related bugreports. Will the new olive project be maintained by
>> the bzr-gtk maintainers group? I would hope so.
> Ah, I was wondering what had happened to you. :-) The same thing
> happened to me, which is one of the reasons why I haven't had as much
> time to spend on bzr-gtk as I used to.
>
> I hope there will be some overlap between developers like there is
> overlap between the qbzr and bzr-explorer developers, but it doesn't
> necessarily have to be the same group of people.
>
> Cheers,
>
> Jelmer

Revision history for this message
Vincent Ladeuil (vila) wrote :

GO :)

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'AUTHORS'
2--- AUTHORS 2008-07-22 22:40:17 +0000
3+++ AUTHORS 2010-05-29 23:49:22 +0000
4@@ -13,8 +13,6 @@
5
6 nautilus-bzr was written by Jelmer Vernooij and Jeff Bailey.
7
8-Olive was written by Szilveszter Farkas <Szilveszter.Farkas@gmail.com>.
9-
10 The tag icon was created by Jakub Steiner.
11 The bug icon was created by Josef Vybíral.
12
13
14=== modified file 'MANIFEST.in'
15--- MANIFEST.in 2009-07-11 19:00:11 +0000
16+++ MANIFEST.in 2010-05-29 23:49:22 +0000
17@@ -6,7 +6,6 @@
18 include bzr-gtk.applications
19 include bzr-gtk.cfg
20 include credits.pickle
21-include olive-gtk.1
22 include preferences/TODO
23 include *.desktop
24 include *.ui
25
26=== modified file '__init__.py'
27--- __init__.py 2010-03-25 06:33:53 +0000
28+++ __init__.py 2010-05-29 23:49:22 +0000
29@@ -22,7 +22,6 @@
30 gconflicts GTK+ conflicts.
31 gdiff Show differences in working tree in a GTK+ Window.
32 ginit Initialise a new branch.
33-ginfo GTK+ branch info dialog
34 gloom GTK+ loom browse dialog
35 gmerge GTK+ merge dialog
36 gmissing GTK+ missing revisions dialog.
37@@ -135,7 +134,6 @@
38 "gconflicts": [],
39 "gdiff": [],
40 "ginit": [],
41- "ginfo": [],
42 "gmerge": [],
43 "gmissing": [],
44 "gpreferences": [],
45@@ -166,13 +164,6 @@
46 save_commit_messages,
47 "Saving commit messages for gcommit")
48
49-import gettext
50-gettext.install('olive-gtk')
51-
52-# Let's create a specialized alias to protect '_' from being erased by other
53-# uses of '_' as an anonymous variable (think pdb for one).
54-_i18n = gettext.gettext
55-
56 class NoDisplayError(errors.BzrCommandError):
57 """gtk could not find a proper display"""
58
59@@ -212,3 +203,8 @@
60 reload(sys)
61 sys.setdefaultencoding(default_encoding)
62 return basic_tests
63+
64+
65+def _i18n(text):
66+ # Stub until we support proper i18n
67+ return text
68
69=== modified file 'branchbox.py'
70--- branchbox.py 2009-03-05 16:50:39 +0000
71+++ branchbox.py 2010-05-29 23:49:22 +0000
72@@ -24,7 +24,6 @@
73 from bzrlib.config import GlobalConfig
74 import gtk
75 from history import UrlHistory
76-from olive import Preferences
77 import gobject
78
79 class BranchSelectionBox(gtk.HBox):
80@@ -58,10 +57,6 @@
81 for item in self._history.get_entries():
82 self._combo_model.append([ item ])
83
84- pref = Preferences()
85- for item in pref.get_bookmarks():
86- self._combo_model.append([ item ])
87-
88 self._combo.set_model(self._combo_model)
89 self._combo.set_text_column(0)
90
91
92=== modified file 'checkout.py'
93--- checkout.py 2009-12-22 22:35:52 +0000
94+++ checkout.py 2010-05-29 23:49:22 +0000
95@@ -33,7 +33,6 @@
96 from dialog import error_dialog
97
98 from history import UrlHistory
99-from olive import Preferences
100
101 class CheckoutDialog(gtk.Dialog):
102 """ New implementation of the Checkout dialog. """
103@@ -117,10 +116,6 @@
104 for item in self._history.get_entries():
105 self._combo_model.append([ item ])
106
107- pref = Preferences()
108- for item in pref.get_bookmarks():
109- self._combo_model.append([ item ])
110-
111 self._combo.set_model(self._combo_model)
112 self._combo.set_text_column(0)
113
114
115=== removed file 'cmenu.ui'
116--- cmenu.ui 2007-07-21 13:16:33 +0000
117+++ cmenu.ui 1970-01-01 00:00:00 +0000
118@@ -1,32 +0,0 @@
119-<ui>
120- <popup name="context_right">
121- <menuitem name="add" action="add" />
122- <menuitem name="remove" action="remove" />
123- <menuitem name="remove_and_delete" action="remove_and_delete" />
124- <menuitem name="rename" action="rename" />
125- <menuitem name="open" action="open" />
126- <separator />
127- <menuitem name="revert" action="revert" />
128- <menuitem name="commit" action="commit" />
129- <separator />
130- <menuitem name="annotate" action="annotate" />
131- <menuitem name="diff" action="diff" />
132- <separator />
133- <menuitem name="bookmark" action="bookmark" />
134- </popup>
135- <popup name="context_left">
136- <menuitem name="edit_bookmark" action="edit_bookmark" />
137- <menuitem name="remove_bookmark" action="remove_bookmark" />
138- <separator />
139- <menuitem name="open_folder" action="open_folder" />
140- </popup>
141- <popup name="toolbar_diff">
142- <menuitem name="diff_selected" action="diff_selected" />
143- <menuitem name="diff_all" action="diff_all" />
144- </popup>
145- <popup name="context_remote">
146- <menuitem name="view_remote" action="view_remote" />
147- <menuitem name="diff_remote" action="diff_remote" />
148- <menuitem name="revert_remote" action="revert_remote" />
149- </popup>
150-</ui>
151
152=== modified file 'commands.py'
153--- commands.py 2010-05-27 01:10:15 +0000
154+++ commands.py 2010-05-29 23:49:22 +0000
155@@ -375,19 +375,6 @@
156 dialog.run()
157
158
159-class cmd_ginfo(Command):
160- """ GTK+ info dialog
161-
162- """
163- def run(self):
164- from bzrlib import workingtree
165- from bzrlib.plugins.gtk.olive.info import InfoDialog
166- wt = workingtree.WorkingTree.open_containing('.')[0]
167- info = InfoDialog(wt.branch)
168- info.display()
169- info.window.run()
170-
171-
172 class cmd_gmerge(Command):
173 """ GTK+ merge dialog
174
175
176=== removed file 'genpot.sh'
177--- genpot.sh 2008-05-05 18:16:46 +0000
178+++ genpot.sh 1970-01-01 00:00:00 +0000
179@@ -1,43 +0,0 @@
180-#!/bin/sh
181-
182-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
183-#
184-# This program is free software; you can redistribute it and/or modify
185-# it under the terms of the GNU General Public License as published by
186-# the Free Software Foundation; either version 2 of the License, or
187-# (at your option) any later version.
188-#
189-# This program is distributed in the hope that it will be useful,
190-# but WITHOUT ANY WARRANTY; without even the implied warranty of
191-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
192-# GNU General Public License for more details.
193-#
194-# You should have received a copy of the GNU General Public License
195-# along with this program; if not, write to the Free Software
196-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
197-
198-# Generate translation template
199-
200-if [ "$1" = "" ]; then
201- POT=po/olive-gtk.pot
202-else
203- # Used for debugging
204- POT=$1
205-fi
206-
207-XGETTEXT="xgettext -o $POT"
208-PY_XGETTEXT="$XGETTEXT -L python --from-code=ASCII --keyword=_i18n"
209-
210-if [ -x $POT ]; then
211- rm $POT
212- touch $POT
213-else
214- touch $POT
215-fi
216-$PY_XGETTEXT olive-gtk
217-$XGETTEXT -j olive.glade
218-
219-for d in . annotate branchview olive preferences viz ;
220-do
221- $PY_XGETTEXT -j $d/*.py
222-done
223
224=== removed directory 'olive'
225=== removed file 'olive-gtk'
226--- olive-gtk 2008-08-04 18:51:44 +0000
227+++ olive-gtk 1970-01-01 00:00:00 +0000
228@@ -1,94 +0,0 @@
229-#!/usr/bin/python
230-
231-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
232-#
233-# This program is free software; you can redistribute it and/or modify
234-# it under the terms of the GNU General Public License as published by
235-# the Free Software Foundation; either version 2 of the License, or
236-# (at your option) any later version.
237-#
238-# This program is distributed in the hope that it will be useful,
239-# but WITHOUT ANY WARRANTY; without even the implied warranty of
240-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
241-# GNU General Public License for more details.
242-#
243-# You should have received a copy of the GNU General Public License
244-# along with this program; if not, write to the Free Software
245-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
246-
247-import os
248-import sys
249-import re
250-
251-try:
252- version_info = sys.version_info
253-except AttributeError:
254- version_info = 1, 5 # 1.5 or older
255-
256-REINVOKE = "__BZR_REINVOKE"
257-NEED_VERS = (2, 4)
258-KNOWN_PYTHONS = ('python2.4',)
259-
260-if version_info < NEED_VERS:
261- if not os.environ.has_key(REINVOKE):
262- # mutating os.environ doesn't work in old Pythons
263- os.putenv(REINVOKE, "1")
264- for python in KNOWN_PYTHONS:
265- try:
266- os.execvp(python, [python] + sys.argv)
267- except OSError:
268- pass
269- print >>sys.stderr, ('bzr: error: cannot find a suitable python interpreter'
270- ' (need %d.%d or later)'
271- ) % NEED_VERS
272- sys.exit(1)
273-
274-try:
275- import pygtk
276- pygtk.require("2.0")
277-except:
278- pass
279-
280-try:
281- import gtk
282-except:
283- print >>sys.stderr, ('You need to install pygtk2 (gtk2)'
284- ' or set your PYTHONPATH correctly.\n'
285- 'try: export PYTHONPATH=/usr/local/lib/python2.4/site-packages/'
286- )
287- sys.exit(1)
288-
289-# gettext support
290-import gettext
291-gettext.install('olive-gtk')
292-
293-
294-# make sure we could import bzrlib
295-try:
296- import bzrlib
297-except ImportError:
298- # try to find bzr if it exist in $PATH
299- p = os.popen('bzr version')
300- s = p.read()
301- r = p.close()
302- if r not in (None, 0):
303- print >>sys.stderr, "bzr not found"
304- sys.exit(1)
305- else:
306- bzrlib_match = re.compile(r"bzrlib: (.*)[/\\]bzrlib").search(s)
307- if bzrlib_match:
308- sys.path.append(bzrlib_match.group(1))
309- else:
310- print >>sys.stderr, "Can't find bzrlib location"
311- sys.exit(1)
312-
313-from bzrlib.plugin import load_plugins
314-load_plugins()
315-
316-import bzrlib.ui
317-import bzrlib.plugins.gtk.ui as ui
318-bzrlib.ui.ui_factory = ui.GtkUIFactory()
319-
320-from bzrlib.plugins.gtk.olive import OliveGtk
321-app = OliveGtk()
322-gtk.main()
323
324=== removed file 'olive-gtk.1'
325--- olive-gtk.1 2008-05-01 12:55:33 +0000
326+++ olive-gtk.1 1970-01-01 00:00:00 +0000
327@@ -1,15 +0,0 @@
328-.TH OLIVE-GTK 1 "April 24, 2007"
329-.SH NAME
330-olive-gtk \- GTK+ frontend for Bazaar
331-.SH SYNOPSIS
332-.B olive-gtk
333-.SH DESCRIPTION
334-Olive aims to be a full-featured graphical frontend for the Bazaar (bzr)
335-source code management tool.
336-.SH SEE ALSO
337-.BR bzr (1).
338-.SH AUTHOR
339-\fBolive-gtk\fP was written by Szilveszter Farkas <szilveszter.farkas@gmail.com>
340-.PP
341-This manual page was written by Chris Lamb <chris@chris-lamb.co.uk>,
342-for the Debian project (but may be used by others).
343
344=== removed file 'olive-gtk.desktop'
345--- olive-gtk.desktop 2008-08-06 14:25:18 +0000
346+++ olive-gtk.desktop 1970-01-01 00:00:00 +0000
347@@ -1,14 +0,0 @@
348-[Desktop Entry]
349-Type=Application
350-Version=1.0
351-Name=Olive Bazaar Branch Manager
352-Name[fr]=Gestionnaire de branche Bazaar Olive
353-GenericName=Version Control GUI
354-GenericName[pl]=Klient graficzny Bazaar
355-GenericName[fr]=Client graphique Bazaar
356-Comment=Graphical User Interface for the Bazaar Version Control System
357-Comment[pl]=Graficzny interfejs dla systemu kontroli wersji Bazaar
358-Comment[fr]=Interface graphique pour le gestionnaire de version Bazaar
359-Icon=olive-gtk
360-Exec=olive-gtk
361-Categories=Development;RevisionControl;
362
363=== removed file 'olive/__init__.py'
364--- olive/__init__.py 2009-05-27 09:19:42 +0000
365+++ olive/__init__.py 1970-01-01 00:00:00 +0000
366@@ -1,1407 +0,0 @@
367-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
368-#
369-# This program is free software; you can redistribute it and/or modify
370-# it under the terms of the GNU General Public License as published by
371-# the Free Software Foundation; either version 2 of the License, or
372-# (at your option) any later version.
373-#
374-# This program is distributed in the hope that it will be useful,
375-# but WITHOUT ANY WARRANTY; without even the implied warranty of
376-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
377-# GNU General Public License for more details.
378-#
379-# You should have received a copy of the GNU General Public License
380-# along with this program; if not, write to the Free Software
381-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
382-
383-import os
384-import sys
385-import time
386-import errno
387-
388-# gettext support
389-import gettext
390-gettext.install('olive-gtk')
391-
392-try:
393- import pygtk
394- pygtk.require("2.0")
395-except:
396- pass
397-
398-import gobject
399-import gtk
400-import gtk.gdk
401-
402-from bzrlib.branch import Branch
403-import bzrlib.errors as bzrerrors
404-from bzrlib.lazy_import import lazy_import
405-from bzrlib.ui import ui_factory
406-from bzrlib.workingtree import WorkingTree
407-
408-from bzrlib.plugins.gtk import _i18n
409-from bzrlib.plugins.gtk.dialog import error_dialog, info_dialog, warning_dialog
410-from bzrlib.plugins.gtk.errors import show_bzr_error
411-from bzrlib.plugins.gtk.olive.window import OliveGui
412-
413-from bzrlib.plugins.gtk.diff import DiffWindow
414-lazy_import(globals(), """
415-from bzrlib.plugins.gtk.viz import branchwin
416-""")
417-from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
418-from bzrlib.plugins.gtk.annotate.config import GAnnotateConfig
419-from bzrlib.plugins.gtk.commit import CommitDialog
420-from bzrlib.plugins.gtk.conflicts import ConflictsDialog
421-from bzrlib.plugins.gtk.initialize import InitDialog
422-from bzrlib.plugins.gtk.push import PushDialog
423-from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
424-
425-def about():
426- """ Display the AboutDialog. """
427- from bzrlib.plugins.gtk import __version__, icon_path
428-
429- dialog = gtk.AboutDialog()
430- dialog.set_name("Olive")
431- dialog.set_version(__version__)
432- dialog.set_copyright("Copyright (C) 2006-2008 Szilveszter Farkas (Phanatic)")
433- dialog.set_website("https://launchpad.net/bzr-gtk")
434- dialog.set_website_label("https://launchpad.net/bzr-gtk")
435- dialog.set_icon_from_file(icon_path("oliveicon2.png"))
436- dialog.set_logo(gtk.gdk.pixbuf_new_from_file(icon_path("oliveicon2.png")))
437- dialog.set_authors([ _i18n("Lead Developer:"),
438- "Szilveszter Farkas <szilveszter.farkas@gmail.com>",
439- _i18n("Contributors:"),
440- "Jelmer Vernooij <jelmer@samba.org>",
441- "Mateusz Korniak <mateusz.korniak@ant.gliwice.pl>",
442- "Gary van der Merwe <garyvdm@gmail.com>" ])
443- dialog.set_artists([ "Simon Pascal Klein <klepas@klepas.org>",
444- "Jakub Steiner <jimmac@novell.com>" ])
445-
446- dialog.run()
447- # Destroy the dialog
448- dialog.destroy()
449-
450-
451-class OliveGtk:
452- """ The main Olive GTK frontend class. This is called when launching the
453- program. """
454-
455- def __init__(self):
456- self.window = OliveGui(calling_app = self)
457-
458- self.pref = Preferences()
459- self.path = None
460-
461- # Initialize the statusbar
462- self.context_id = self.window.statusbar.get_context_id('olive')
463-
464- # Get the drive selector
465- self.combobox_drive = gtk.combo_box_new_text()
466- self.combobox_drive.connect("changed", self._refresh_drives)
467-
468- # Get the navigation widgets
469- self.hbox_location = self.window.locationbar
470- self.button_location_up = self.window.button_location_up
471- self.button_location_jump = self.window.button_location_jump
472- self.entry_location = self.window.entry_location
473-
474- # Get the History widgets
475- self.check_history = self.window.checkbutton_history
476- self.entry_history = self.window.entry_history_revno
477- self.button_history = self.window.button_history_browse
478-
479- self._just_started = True
480-
481- # Apply window size and position
482- width = self.pref.get_preference('window_width', 'int')
483- height = self.pref.get_preference('window_height', 'int')
484- self.window.resize(width, height)
485- x = self.pref.get_preference('window_x', 'int')
486- y = self.pref.get_preference('window_y', 'int')
487- self.window.move(x, y)
488- # Apply paned position
489- pos = self.pref.get_preference('paned_position', 'int')
490- self.window.hpaned_main.set_position(pos)
491-
492- # Now we can show the window
493- self.window.show()
494-
495- # Show drive selector if under Win32
496- if sys.platform == 'win32':
497- self.hbox_location.pack_start(self.combobox_drive, False, False, 0)
498- self.hbox_location.reorder_child(self.combobox_drive, 1)
499- self.combobox_drive.show()
500- self.gen_hard_selector()
501-
502- self.refresh_left()
503-
504- # Apply menu state
505- self.window.mb_view_showhidden.set_active(self.pref.get_preference('dotted_files', 'bool'))
506- self.window.mb_view_showignored.set_active(self.pref.get_preference('ignored_files', 'bool'))
507-
508- # We're starting local
509- self.remote = False
510- self.remote_branch = None
511- self.remote_path = None
512- self.remote_revision = None
513-
514- self.set_path(os.getcwd())
515- self.refresh_right()
516-
517- self._just_started = False
518-
519- def set_path(self, path, force_remote=False):
520- self.window.location_status.destroy()
521- self.notbranch = False
522-
523- if force_remote:
524- # Forcing remote mode (reading data from inventory)
525- self.window.set_location_status(gtk.STOCK_DISCONNECT)
526- try:
527- br = Branch.open_containing(path)[0]
528- except bzrerrors.NotBranchError:
529- self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
530- self.check_history.set_active(False)
531- self.check_history.set_sensitive(False)
532- return False
533- except bzrerrors.UnsupportedProtocol:
534- self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
535- self.check_history.set_active(False)
536- self.check_history.set_sensitive(False)
537- return False
538-
539- self.window.set_location_status(gtk.STOCK_CONNECT)
540-
541- self.remote = True
542-
543- # We're remote
544- self.remote_branch, self.remote_path = Branch.open_containing(path)
545-
546- if self.remote_revision is None:
547- self.remote_revision = self.remote_branch.last_revision()
548-
549- self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
550-
551- if len(self.remote_path) == 0:
552- self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
553- else:
554- for (name, type) in self.remote_entries:
555- if name == self.remote_path:
556- self.remote_parent = type.file_id
557- break
558-
559- if not path.endswith('/'):
560- path += '/'
561-
562- if self.remote_branch.base == path:
563- self.button_location_up.set_sensitive(False)
564- else:
565- self.button_location_up.set_sensitive(True)
566- else:
567- if os.path.isdir(path):
568- self.remote = False
569-
570- # We're local
571- try:
572- self.wt, self.wtpath = WorkingTree.open_containing(os.path.realpath(path))
573- except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
574- self.notbranch = True
575- except bzrerrors.PermissionDenied:
576- self.window.set_location_status(gtk.STOCK_DIALOG_WARNING, allowPopup=True)
577- self.window.location_status.connect_object('clicked', warning_dialog,
578- *(_i18n('Branch information unreadable'),
579- _i18n('The current folder is a branch but the .bzr folder is not readable')))
580- self.notbranch = True
581-
582- # If we're in the root, we cannot go up anymore
583- if sys.platform == 'win32':
584- drive, tail = os.path.splitdrive(path)
585- if tail in ('', '/', '\\'):
586- self.button_location_up.set_sensitive(False)
587- else:
588- self.button_location_up.set_sensitive(True)
589- else:
590- if self.path == '/':
591- self.button_location_up.set_sensitive(False)
592- else:
593- self.button_location_up.set_sensitive(True)
594- elif not os.path.isfile(path):
595- # Doesn't seem to be a file nor a directory, trying to open a
596- # remote location
597- self.window.set_location_status(gtk.STOCK_DISCONNECT)
598- try:
599- br = Branch.open_containing(path)[0]
600- except bzrerrors.NotBranchError:
601- self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
602- self.check_history.set_active(False)
603- self.check_history.set_sensitive(False)
604- return False
605- except bzrerrors.UnsupportedProtocol:
606- self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
607- self.check_history.set_active(False)
608- self.check_history.set_sensitive(False)
609- return False
610-
611- self.window.set_location_status(gtk.STOCK_CONNECT)
612-
613- self.remote = True
614-
615- # We're remote
616- self.remote_branch, self.remote_path = Branch.open_containing(path)
617-
618- if self.remote_revision is None:
619- self.remote_revision = self.remote_branch.last_revision()
620-
621- self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
622-
623- if len(self.remote_path) == 0:
624- self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
625- else:
626- for (name, type) in self.remote_entries:
627- if name == self.remote_path:
628- self.remote_parent = type.file_id
629- break
630-
631- if not path.endswith('/'):
632- path += '/'
633-
634- if self.remote_branch.base == path:
635- self.button_location_up.set_sensitive(False)
636- else:
637- self.button_location_up.set_sensitive(True)
638-
639- if self.notbranch:
640- self.check_history.set_active(False)
641- self.check_history.set_sensitive(False)
642- else:
643- self.check_history.set_sensitive(True)
644-
645- self.window.statusbar.push(self.context_id, path)
646- self.entry_location.set_text(path)
647- self.path = path
648- return True
649-
650- def get_path(self):
651- if not self.remote:
652- return self.path
653- else:
654- # Remote mode
655- if len(self.remote_path) > 0:
656- return self.remote_branch.base + self.remote_path + '/'
657- else:
658- return self.remote_branch.base
659-
660- def on_about_activate(self, widget):
661- about()
662-
663- def on_button_history_browse_clicked(self, widget):
664- """ Browse for revision button handler. """
665- if self.remote:
666- br = self.remote_branch
667- else:
668- br = self.wt.branch
669-
670- revb = RevisionBrowser(br, self.window)
671- response = revb.run()
672- if response != gtk.RESPONSE_NONE:
673- revb.hide()
674-
675- if response == gtk.RESPONSE_OK:
676- if revb.selected_revno is not None:
677- self.entry_history.set_text(revb.selected_revno)
678- self.on_entry_history_revno_activate()
679-
680- revb.destroy()
681-
682- def on_button_location_jump_clicked(self, widget):
683- """ Location Jump button handler. """
684- location = self.entry_location.get_text()
685-
686- if self.set_path(location):
687- self.refresh_right()
688-
689- def on_button_location_up_clicked(self, widget):
690- """ Location Up button handler. """
691- if not self.remote:
692- # Local mode
693- self.set_path(os.path.split(self.get_path())[0])
694- else:
695- # Remote mode
696- delim = '/'
697- newpath = delim.join(self.get_path().split(delim)[:-2])
698- newpath += '/'
699- self.set_path(newpath)
700-
701- self.refresh_right()
702-
703- def on_checkbutton_history_toggled(self, widget):
704- """ History Mode toggle handler. """
705- if self.check_history.get_active():
706- # History Mode activated
707- self.entry_history.set_sensitive(True)
708- self.button_history.set_sensitive(True)
709- if self.entry_history.get_text() != "":
710- self.on_entry_history_revno_activate()
711- else:
712- # History Mode deactivated
713- self.entry_history.set_sensitive(False)
714- self.button_history.set_sensitive(False)
715-
716- # Return right window to normal view by acting like we jump to it
717- self.on_button_location_jump_clicked(widget)
718-
719- @show_bzr_error
720- def on_entry_history_revno_activate(self, widget=None):
721- """ Key pressed handler for the history entry. """
722- path = self.get_path()
723- if not self.remote:
724- self.remote = True
725- self.remote_branch = self.wt.branch
726-
727- revno = int(self.entry_history.get_text())
728- self.remote_revision = self.remote_branch.get_rev_id(revno)
729- if self.set_path(path, True):
730- self.refresh_right()
731-
732- def on_menuitem_add_files_activate(self, widget):
733- """ Add file(s)... menu handler. """
734- from bzrlib.plugins.gtk.olive.add import AddDialog
735- add = AddDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
736- response = add.run()
737- add.destroy()
738- if response == gtk.RESPONSE_OK:
739- self.refresh_right()
740-
741- def on_menuitem_branch_get_activate(self, widget):
742- """ Branch/Get... menu handler. """
743- from bzrlib.plugins.gtk.branch import BranchDialog
744-
745- if self.remote:
746- branch = BranchDialog(os.getcwd(), self.window, self.remote_branch.base)
747- else:
748- branch = BranchDialog(self.get_path(), self.window)
749- response = branch.run()
750- if response != gtk.RESPONSE_NONE:
751- branch.hide()
752-
753- if response == gtk.RESPONSE_OK:
754- self.refresh_right()
755-
756- branch.destroy()
757-
758- def on_menuitem_branch_checkout_activate(self, widget):
759- """ Branch/Checkout... menu handler. """
760- from bzrlib.plugins.gtk.checkout import CheckoutDialog
761-
762- if self.remote:
763- checkout = CheckoutDialog(os.getcwd(), self.window, self.remote_branch.base)
764- else:
765- checkout = CheckoutDialog(self.get_path(), self.window)
766- response = checkout.run()
767- if response != gtk.RESPONSE_NONE:
768- checkout.hide()
769-
770- if response == gtk.RESPONSE_OK:
771- self.refresh_right()
772-
773- checkout.destroy()
774-
775- @show_bzr_error
776- def on_menuitem_branch_commit_activate(self, widget):
777- """ Branch/Commit... menu handler. """
778- selected = self.get_selected_right()
779- if selected:
780- selected = os.path.join(self.wtpath, selected)
781- commit = CommitDialog(wt=self.wt,
782- parent=self.window,
783- selected=selected,
784- )
785- response = commit.run()
786- if response != gtk.RESPONSE_NONE:
787- commit.hide()
788-
789- if response == gtk.RESPONSE_OK:
790- self.refresh_right()
791-
792- commit.destroy()
793-
794- def on_menuitem_branch_conflicts_activate(self, widget):
795- """ Branch/Conflicts... menu handler. """
796- conflicts = ConflictsDialog(self.wt, self.window)
797- response = conflicts.run()
798- if response != gtk.RESPONSE_NONE:
799- conflicts.destroy()
800-
801- def on_menuitem_branch_merge_activate(self, widget):
802- """ Branch/Merge... menu handler. """
803- from bzrlib.plugins.gtk.merge import MergeDialog
804-
805- if self.check_for_changes():
806- error_dialog(_i18n('There are local changes in the branch'),
807- _i18n('Please commit or revert the changes before merging.'))
808- else:
809- parent_branch_path = self.wt.branch.get_parent()
810- merge = MergeDialog(self.wt, self.wtpath, parent_branch_path, self.window)
811- response = merge.run()
812- merge.destroy()
813- if response == gtk.RESPONSE_OK:
814- self.refresh_right()
815-
816- @show_bzr_error
817- def on_menuitem_branch_missing_revisions_activate(self, widget):
818- """ Branch/Missing revisions menu handler. """
819-
820- from bzrlib.missing import find_unmerged, iter_log_revisions
821-
822- local_branch = self.wt.branch
823- parent_branch_path = local_branch.get_parent()
824- if parent_branch_path is None:
825- error_dialog(_i18n('Parent location is unknown'),
826- _i18n('Cannot determine missing revisions if no parent location is known.'))
827- return
828-
829- parent_branch = Branch.open(parent_branch_path)
830-
831- if parent_branch.base == local_branch.base:
832- parent_branch = local_branch
833-
834- local_extra, remote_extra = find_unmerged(local_branch,parent_branch)
835-
836- if local_extra or remote_extra:
837-
838- ## def log_revision_one_line_text(log_revision):
839- ## """ Generates one line description of log_revison ended with end of line."""
840- ## revision = log_revision.rev
841- ## txt = "- %s (%s)\n" % (revision.get_summary(), revision.committer, )
842- ## txt = txt.replace("<"," ") # Seems < > chars are expected to be xml tags ...
843- ## txt = txt.replace(">"," ")
844- ## return txt
845-
846- dlg_txt = ""
847- if local_extra:
848- dlg_txt += _i18n('%d local extra revision(s). \n') % (len(local_extra),)
849- ## NOTE: We do not want such ugly info about missing revisions
850- ## Revision Browser should be used there
851- ## max_revisions = 10
852- ## for log_revision in iter_log_revisions(local_extra, local_branch.repository, verbose=1):
853- ## dlg_txt += log_revision_one_line_text(log_revision)
854- ## if max_revisions <= 0:
855- ## dlg_txt += _i18n("more ... \n")
856- ## break
857- ## max_revisions -= 1
858- ## dlg_txt += "\n"
859- if remote_extra:
860- dlg_txt += _i18n('%d local missing revision(s).\n') % (len(remote_extra),)
861- ## max_revisions = 10
862- ## for log_revision in iter_log_revisions(remote_extra, parent_branch.repository, verbose=1):
863- ## dlg_txt += log_revision_one_line_text(log_revision)
864- ## if max_revisions <= 0:
865- ## dlg_txt += _i18n("more ... \n")
866- ## break
867- ## max_revisions -= 1
868-
869- info_dialog(_i18n('There are missing revisions'),
870- dlg_txt)
871- else:
872- info_dialog(_i18n('Local branch up to date'),
873- _i18n('There are no missing revisions.'))
874-
875- @show_bzr_error
876- def on_menuitem_branch_pull_activate(self, widget):
877- """ Branch/Pull menu handler. """
878- branch_to = self.wt.branch
879-
880- location = branch_to.get_parent()
881- if location is None:
882- error_dialog(_i18n('Parent location is unknown'),
883- _i18n('Pulling is not possible until there is a parent location.'))
884- return
885-
886- branch_from = Branch.open(location)
887-
888- if branch_to.get_parent() is None:
889- branch_to.set_parent(branch_from.base)
890-
891- ret = branch_to.pull(branch_from)
892-
893- info_dialog(_i18n('Pull successful'), _i18n('%d revision(s) pulled.') % ret)
894-
895- @show_bzr_error
896- def on_menuitem_branch_update_activate(self, widget):
897- """ Branch/checkout update menu handler. """
898-
899- ret = self.wt.update()
900- conflicts = self.wt.conflicts()
901- if conflicts:
902- info_dialog(_i18n('Update successful but conflicts generated'), _i18n('Number of conflicts generated: %d.') % (len(conflicts),) )
903- else:
904- info_dialog(_i18n('Update successful'), _i18n('No conflicts generated.') )
905- self.refresh_right()
906-
907- def on_menuitem_branch_push_activate(self, widget):
908- """ Branch/Push... menu handler. """
909- push = PushDialog(repository=None,revid=None,branch=self.wt.branch, parent=self.window)
910- response = push.run()
911- if response != gtk.RESPONSE_NONE:
912- push.destroy()
913-
914- @show_bzr_error
915- def on_menuitem_branch_revert_activate(self, widget):
916- """ Branch/Revert all changes menu handler. """
917- ret = self.wt.revert(None)
918- if ret:
919- warning_dialog(_i18n('Conflicts detected'),
920- _i18n('Please have a look at the working tree before continuing.'))
921- else:
922- info_dialog(_i18n('Revert successful'),
923- _i18n('All files reverted to last revision.'))
924- self.refresh_right()
925-
926- def on_menuitem_branch_status_activate(self, widget):
927- """ Branch/Status... menu handler. """
928- from bzrlib.plugins.gtk.status import StatusWindow
929- status = StatusWindow(self.wt, self.wtpath)
930- status.show()
931-
932- def on_menuitem_branch_initialize_activate(self, widget):
933- """ Initialize current directory. """
934- init = InitDialog(self.path, self.window)
935- response = init.run()
936- if response != gtk.RESPONSE_NONE:
937- init.hide()
938-
939- if response == gtk.RESPONSE_OK:
940- self.refresh_right()
941-
942- init.destroy()
943-
944- def on_menuitem_branch_tags_activate(self, widget):
945- """ Branch/Tags... menu handler. """
946- from bzrlib.plugins.gtk.tags import TagsWindow
947- if not self.remote:
948- window = TagsWindow(self.wt.branch, self.window)
949- else:
950- window = TagsWindow(self.remote_branch, self.window)
951- window.show()
952-
953- def on_menuitem_file_annotate_activate(self, widget):
954- """ File/Annotate... menu handler. """
955- if self.get_selected_right() is None:
956- error_dialog(_i18n('No file was selected'),
957- _i18n('Please select a file from the list.'))
958- return
959-
960- branch = self.wt.branch
961- file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
962-
963- window = GAnnotateWindow(all=False, plain=False, parent=self.window)
964- window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
965- config = GAnnotateConfig(window)
966- window.show()
967- branch.lock_read()
968- try:
969- window.annotate(self.wt, branch, file_id)
970- finally:
971- branch.unlock()
972-
973- def on_menuitem_file_bookmark_activate(self, widget):
974- """ File/Bookmark current directory menu handler. """
975- if self.pref.add_bookmark(self.path):
976- info_dialog(_i18n('Bookmark successfully added'),
977- _i18n('The current directory was bookmarked. You can reach\nit by selecting it from the left panel.'))
978- self.pref.write()
979- else:
980- warning_dialog(_i18n('Location already bookmarked'),
981- _i18n('The current directory is already bookmarked.\nSee the left panel for reference.'))
982-
983- self.refresh_left()
984-
985- def on_menuitem_file_make_directory_activate(self, widget):
986- """ File/Make directory... menu handler. """
987- from bzrlib.plugins.gtk.olive.mkdir import MkdirDialog
988- mkdir = MkdirDialog(self.wt, self.wtpath, self.window)
989- response = mkdir.run()
990- mkdir.destroy()
991- if response == gtk.RESPONSE_OK:
992- self.refresh_right()
993-
994- def on_menuitem_file_move_activate(self, widget):
995- """ File/Move... menu handler. """
996- from bzrlib.plugins.gtk.olive.move import MoveDialog
997- move = MoveDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
998- response = move.run()
999- move.destroy()
1000- if response == gtk.RESPONSE_OK:
1001- self.refresh_right()
1002-
1003- def on_menuitem_file_rename_activate(self, widget):
1004- """ File/Rename... menu handler. """
1005- from bzrlib.plugins.gtk.olive.rename import RenameDialog
1006- rename = RenameDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
1007- response = rename.run()
1008- rename.destroy()
1009- if response == gtk.RESPONSE_OK:
1010- self.refresh_right()
1011-
1012- def on_menuitem_remove_file_activate(self, widget):
1013- """ Remove (unversion) selected file. """
1014- from bzrlib.plugins.gtk.olive.remove import RemoveDialog
1015- remove = RemoveDialog(self.wt, self.wtpath,
1016- selected=self.get_selected_right(),
1017- parent=self.window)
1018- response = remove.run()
1019-
1020- if response != gtk.RESPONSE_NONE:
1021- remove.hide()
1022-
1023- if response == gtk.RESPONSE_OK:
1024- self.refresh_right()
1025-
1026- remove.destroy()
1027-
1028- def on_menuitem_stats_diff_activate(self, widget):
1029- """ Statistics/Differences... menu handler. """
1030- window = DiffWindow(parent=self.window)
1031- parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
1032- window.set_diff(self.wt.branch._get_nick(local=True), self.wt,
1033- parent_tree)
1034- window.show()
1035-
1036- def on_menuitem_stats_infos_activate(self, widget):
1037- """ Statistics/Informations... menu handler. """
1038- from bzrlib.plugins.gtk.olive.info import InfoDialog
1039- if self.remote:
1040- info = InfoDialog(self.remote_branch)
1041- else:
1042- info = InfoDialog(self.wt.branch)
1043- info.display()
1044-
1045- def on_menuitem_stats_log_activate(self, widget):
1046- """ Statistics/Log... menu handler. """
1047-
1048- if not self.remote:
1049- branch = self.wt.branch
1050- else:
1051- branch = self.remote_branch
1052-
1053- window = branchwin.BranchWindow(branch, [branch.last_revision()], None,
1054- parent=self.window)
1055- window.show()
1056-
1057- def on_menuitem_view_refresh_activate(self, widget):
1058- """ View/Refresh menu handler. """
1059- # Refresh the left pane
1060- self.refresh_left()
1061- # Refresh the right pane
1062- self.refresh_right()
1063-
1064- def on_menuitem_view_show_hidden_files_activate(self, widget):
1065- """ View/Show hidden files menu handler. """
1066- self.pref.set_preference('dotted_files', widget.get_active())
1067- self.pref.write()
1068- if self.path is not None:
1069- self.refresh_right()
1070-
1071- def on_menuitem_view_show_ignored_files_activate(self, widget):
1072- """ Hide/Show ignored files menu handler. """
1073- self.pref.set_preference('ignored_files', widget.get_active())
1074- self.pref.write()
1075- if self.path is not None:
1076- self.refresh_right()
1077-
1078- def on_treeview_left_button_press_event(self, widget, event):
1079- """ Occurs when somebody clicks in the bookmark list. """
1080- treepathpos = widget.get_path_at_pos(int(event.x), int(event.y))
1081- treeselection = widget.get_selection()
1082- if treepathpos is not None:
1083- treeselection.select_path(treepathpos[0])
1084- if event.button == 1:
1085- newdir = self.get_selected_left()
1086- if newdir == None:
1087- return
1088-
1089- if self.set_path(newdir):
1090- self.refresh_right()
1091- elif event.button == 3:
1092- # Don't show context with nothing selected
1093- if self.get_selected_left() == None:
1094- return
1095-
1096- # Create a menu
1097- from menu import OliveMenu
1098- menu = OliveMenu(path=self.get_path(),
1099- selected=self.get_selected_left(),
1100- app=self)
1101-
1102- menu.left_context_menu().popup(None, None, None, 0,
1103- event.time)
1104- else:
1105- if treeselection is not None:
1106- treeselection.unselect_all()
1107-
1108- def on_treeview_left_row_activated(self, treeview, path, view_column):
1109- """ Occurs when somebody double-clicks or enters an item in the
1110- bookmark list. """
1111-
1112- newdir = self.get_selected_left()
1113- if newdir == None:
1114- return
1115-
1116- if self.set_path(newdir):
1117- self.refresh_right()
1118-
1119- def on_treeview_right_button_press_event(self, widget, event):
1120- """ Occurs when somebody clicks in the file list. """
1121- treepathpos = widget.get_path_at_pos(int(event.x), int(event.y))
1122- if event.button == 1:
1123- if treepathpos is None and widget.get_selection is not None:
1124- treeselection = widget.get_selection()
1125- treeselection.unselect_all()
1126- elif event.button == 3:
1127- treeselection = widget.get_selection()
1128- if treepathpos is not None:
1129- treeselection.select_path(treepathpos[0])
1130- else:
1131- if treeselection is not None:
1132- treeselection.unselect_all()
1133- # Create a menu
1134- from menu import OliveMenu
1135- menu = OliveMenu(path=self.get_path(),
1136- selected=self.get_selected_right(),
1137- app=self)
1138- # get the menu items
1139- m_open = menu.ui.get_widget('/context_right/open')
1140- m_add = menu.ui.get_widget('/context_right/add')
1141- m_remove = menu.ui.get_widget('/context_right/remove')
1142- m_remove_and_delete = menu.ui.get_widget('/context_right/remove_and_delete')
1143- m_rename = menu.ui.get_widget('/context_right/rename')
1144- m_revert = menu.ui.get_widget('/context_right/revert')
1145- m_commit = menu.ui.get_widget('/context_right/commit')
1146- m_annotate = menu.ui.get_widget('/context_right/annotate')
1147- m_diff = menu.ui.get_widget('/context_right/diff')
1148- # check if we're in a branch
1149- try:
1150- from bzrlib.branch import Branch
1151- Branch.open_containing(self.get_path())
1152- if self.remote:
1153- m_open.set_sensitive(False)
1154- m_add.set_sensitive(False)
1155- m_remove.set_sensitive(False)
1156- m_remove_and_delete.set_sensitive(False)
1157- m_rename.set_sensitive(False)
1158- m_revert.set_sensitive(False)
1159- m_commit.set_sensitive(False)
1160- m_annotate.set_sensitive(False)
1161- m_diff.set_sensitive(False)
1162- else:
1163- if treepathpos is None:
1164- m_open.set_sensitive(False)
1165- m_add.set_sensitive(False)
1166- m_remove.set_sensitive(False)
1167- m_remove_and_delete.set_sensitive(False)
1168- m_rename.set_sensitive(False)
1169- m_annotate.set_sensitive(False)
1170- m_diff.set_sensitive(False)
1171- m_revert.set_sensitive(False)
1172- else:
1173- m_open.set_sensitive(True)
1174- m_add.set_sensitive(True)
1175- m_remove.set_sensitive(True)
1176- m_remove_and_delete.set_sensitive(True)
1177- m_rename.set_sensitive(True)
1178- m_annotate.set_sensitive(True)
1179- m_diff.set_sensitive(True)
1180- m_revert.set_sensitive(True)
1181- m_commit.set_sensitive(True)
1182- except bzrerrors.NotBranchError:
1183- if treepathpos is None:
1184- m_open.set_sensitive(False)
1185- else:
1186- m_open.set_sensitive(True)
1187- m_add.set_sensitive(False)
1188- m_remove.set_sensitive(False)
1189- m_remove_and_delete.set_sensitive(False)
1190- m_rename.set_sensitive(False)
1191- m_revert.set_sensitive(False)
1192- m_commit.set_sensitive(False)
1193- m_annotate.set_sensitive(False)
1194- m_diff.set_sensitive(False)
1195-
1196- if not self.remote:
1197- menu.right_context_menu().popup(None, None, None, 0,
1198- event.time)
1199- else:
1200- menu.remote_context_menu().popup(None, None, None, 0,
1201- event.time)
1202-
1203- def on_treeview_right_row_activated(self, treeview, path, view_column):
1204- """ Occurs when somebody double-clicks or enters an item in the
1205- file list. """
1206- from launch import launch
1207-
1208- newdir = self.get_selected_right()
1209-
1210- if not self.remote:
1211- # We're local
1212- if newdir == '..':
1213- self.set_path(os.path.split(self.get_path())[0])
1214- else:
1215- fullpath = os.path.join(self.get_path(), newdir)
1216- if os.path.isdir(fullpath):
1217- # selected item is an existant directory
1218- self.set_path(fullpath)
1219- else:
1220- launch(fullpath)
1221- else:
1222- # We're remote
1223- if self._is_remote_dir(self.get_path() + newdir):
1224- self.set_path(self.get_path() + newdir)
1225-
1226- self.refresh_right()
1227-
1228- def on_window_main_delete_event(self, widget, event=None):
1229- """ Do some stuff before exiting. """
1230- width, height = self.window.get_size()
1231- self.pref.set_preference('window_width', width)
1232- self.pref.set_preference('window_height', height)
1233- x, y = self.window.get_position()
1234- self.pref.set_preference('window_x', x)
1235- self.pref.set_preference('window_y', y)
1236- self.pref.set_preference('paned_position',
1237- self.window.hpaned_main.get_position())
1238-
1239- self.pref.write()
1240- self.window.destroy()
1241-
1242- def get_selected_fileid(self):
1243- """ Get the file_id of the selected file. """
1244- treeselection = self.window.treeview_right.get_selection()
1245- (model, iter) = treeselection.get_selected()
1246-
1247- if iter is None:
1248- return None
1249- else:
1250- return model.get_value(iter, 9)
1251-
1252- def get_selected_right(self):
1253- """ Get the selected filename. """
1254- treeselection = self.window.treeview_right.get_selection()
1255- (model, iter) = treeselection.get_selected()
1256-
1257- if iter is None:
1258- return None
1259- else:
1260- return model.get_value(iter, 2)
1261-
1262- def get_selected_left(self):
1263- """ Get the selected bookmark. """
1264- treeselection = self.window.treeview_left.get_selection()
1265- (model, iter) = treeselection.get_selected()
1266-
1267- if iter is None:
1268- return None
1269- else:
1270- return model.get_value(iter, 1)
1271-
1272- def set_statusbar(self, message):
1273- """ Set the statusbar message. """
1274- self.window.statusbar.push(self.context_id, message)
1275-
1276- def clear_statusbar(self):
1277- """ Clean the last message from the statusbar. """
1278- self.window.statusbar.pop(self.context_id)
1279-
1280- def set_sensitivity(self):
1281- """ Set menu and toolbar sensitivity. """
1282- if not self.remote:
1283- self.window.set_view_to_localbranch(self.notbranch)
1284- else:
1285- self.window.set_view_to_remotebranch()
1286-
1287- def refresh_left(self):
1288- """ Refresh the bookmark list. """
1289-
1290- # Get ListStore and clear it
1291- liststore = self.window.bookmarklist
1292- liststore.clear()
1293-
1294- # Re-read preferences
1295- self.pref.read()
1296-
1297- # Get bookmarks
1298- bookmarks = self.pref.get_bookmarks()
1299-
1300- # Get titles and sort by title
1301- bookmarks = [[self.pref.get_bookmark_title(item), item, gtk.STOCK_DIRECTORY] for item in bookmarks]
1302- bookmarks.sort()
1303- for title_item in bookmarks:
1304- liststore.append(title_item)
1305-
1306- # Add the ListStore to the TreeView and refresh column width
1307- self.window.treeview_left.set_model(liststore)
1308- self.window.treeview_left.columns_autosize()
1309-
1310- def refresh_right(self):
1311- """ Refresh the file list. """
1312- if not self.remote:
1313- # We're local
1314- from bzrlib.workingtree import WorkingTree
1315-
1316- path = self.get_path()
1317-
1318- # Get ListStore and clear it
1319- liststore = self.window.filelist
1320- liststore.clear()
1321-
1322- dirs = []
1323- files = []
1324-
1325- # Fill the appropriate lists
1326- dotted_files = self.pref.get_preference('dotted_files', 'bool')
1327- ignored_files = self.pref.get_preference('ignored_files', 'bool')
1328-
1329- for item in os.listdir(path):
1330- if not dotted_files and item[0] == '.':
1331- continue
1332- if os.path.isdir(os.path.join(path, item)):
1333- dirs.append(item)
1334- else:
1335- files.append(item)
1336-
1337- self.window.col_status.set_visible(False)
1338- if not self.notbranch:
1339- try:
1340- tree1 = WorkingTree.open_containing(os.path.realpath(path))[0]
1341- branch = tree1.branch
1342- tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
1343-
1344- delta = tree1.changes_from(tree2, want_unchanged=True)
1345-
1346- # Show Status column
1347- self.window.col_status.set_visible(True)
1348- except bzrerrors.LockContention:
1349- self.window.set_location_status(gtk.STOCK_DIALOG_ERROR, allowPopup=True)
1350- self.window.location_status.connect_object('clicked', error_dialog,
1351- *(_i18n('Branch is locked'),
1352- _i18n('The branch in the current folder is locked by another Bazaar program')))
1353- self.notbranch = True
1354- self.window.set_view_to_localbranch(False)
1355-
1356- # Add'em to the ListStore
1357- for item in dirs:
1358- status = ''
1359- st = ''
1360- fileid = ''
1361- if not self.notbranch:
1362- filename = tree1.relpath(os.path.join(os.path.realpath(path), item))
1363-
1364- st, status = self.statusmapper(filename, delta)
1365- if not ignored_files and status == 'ignored':
1366- continue
1367-
1368- statinfo = os.lstat(os.path.join(self.path, item))
1369- liststore.append([ gtk.STOCK_DIRECTORY,
1370- True,
1371- item,
1372- st,
1373- status,
1374- "<DIR>",
1375- "<DIR>",
1376- statinfo.st_mtime,
1377- self._format_date(statinfo.st_mtime),
1378- ''])
1379- for item in files:
1380- status = ''
1381- st = ''
1382- fileid = ''
1383- if not self.notbranch:
1384- filename = tree1.relpath(os.path.join(os.path.realpath(path), item))
1385-
1386- st, status = self.statusmapper(filename, delta)
1387- if not ignored_files and status == 'ignored':
1388- continue
1389-
1390- statinfo = os.lstat(os.path.join(self.path, item))
1391- liststore.append([gtk.STOCK_FILE,
1392- False,
1393- item,
1394- st,
1395- status,
1396- str(statinfo.st_size),
1397- self._format_size(statinfo.st_size),
1398- statinfo.st_mtime,
1399- self._format_date(statinfo.st_mtime),
1400- fileid])
1401- else:
1402- # We're remote
1403-
1404- # Get ListStore and clear it
1405- liststore = self.window.filelist
1406- liststore.clear()
1407-
1408- # Hide Status column
1409- self.window.col_status.set_visible(False)
1410-
1411- dirs = []
1412- files = []
1413-
1414- self.window.set_location_status(gtk.STOCK_REFRESH)
1415-
1416- for (name, type) in self.remote_entries:
1417- if type.kind == 'directory':
1418- dirs.append(type)
1419- elif type.kind == 'file':
1420- files.append(type)
1421-
1422- class HistoryCache:
1423- """ Cache based on revision history. """
1424- def __init__(self, history):
1425- self._history = history
1426-
1427- def _lookup_revision(self, revid):
1428- for r in self._history:
1429- if r.revision_id == revid:
1430- return r
1431- rev = repo.get_revision(revid)
1432- self._history.append(rev)
1433- return rev
1434-
1435- repo = self.remote_branch.repository
1436-
1437- revhistory = self.remote_branch.revision_history()
1438- try:
1439- revs = repo.get_revisions(revhistory)
1440- cache = HistoryCache(revs)
1441- except bzrerrors.InvalidHttpResponse:
1442- # Fallback to dummy algorithm, because of LP: #115209
1443- cache = HistoryCache([])
1444-
1445- for item in dirs:
1446- if item.parent_id == self.remote_parent:
1447- rev = cache._lookup_revision(item.revision)
1448- liststore.append([ gtk.STOCK_DIRECTORY,
1449- True,
1450- item.name,
1451- '',
1452- '',
1453- "<DIR>",
1454- "<DIR>",
1455- rev.timestamp,
1456- self._format_date(rev.timestamp),
1457- ''
1458- ])
1459- while gtk.events_pending():
1460- gtk.main_iteration()
1461-
1462- for item in files:
1463- if item.parent_id == self.remote_parent:
1464- rev = cache._lookup_revision(item.revision)
1465- liststore.append([ gtk.STOCK_FILE,
1466- False,
1467- item.name,
1468- '',
1469- '',
1470- str(item.text_size),
1471- self._format_size(item.text_size),
1472- rev.timestamp,
1473- self._format_date(rev.timestamp),
1474- item.file_id
1475- ])
1476- while gtk.events_pending():
1477- gtk.main_iteration()
1478-
1479- self.window.location_status.destroy()
1480-
1481- # Columns should auto-size
1482- self.window.treeview_right.columns_autosize()
1483-
1484- # Set sensitivity
1485- self.set_sensitivity()
1486-
1487- def statusmapper(self, filename, delta):
1488- status = 'unknown'
1489- try:
1490- self.wt.lock_read()
1491-
1492- for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1493- if rpathnew == filename:
1494- status = 'renamed'
1495- fileid = id
1496- for rpath, id, kind in delta.added:
1497- if rpath == filename:
1498- status = 'added'
1499- fileid = id
1500- for rpath, id, kind in delta.removed:
1501- if rpath == filename:
1502- status = 'removed'
1503- fileid = id
1504- for rpath, id, kind, text_modified, meta_modified in delta.modified:
1505- if rpath == filename:
1506- status = 'modified'
1507- fileid = id
1508- for rpath, id, kind in delta.unchanged:
1509- if rpath == filename:
1510- status = 'unchanged'
1511- fileid = id
1512- for rpath, file_class, kind, id, entry in self.wt.list_files():
1513- if rpath == filename and file_class == 'I':
1514- status = 'ignored'
1515- finally:
1516- self.wt.unlock()
1517-
1518- if status == 'renamed':
1519- st = _i18n('renamed')
1520- elif status == 'removed':
1521- st = _i18n('removed')
1522- elif status == 'added':
1523- st = _i18n('added')
1524- elif status == 'modified':
1525- st = _i18n('modified')
1526- elif status == 'unchanged':
1527- st = _i18n('unchanged')
1528- elif status == 'ignored':
1529- st = _i18n('ignored')
1530- else:
1531- st = _i18n('unknown')
1532- return st, status
1533-
1534- def _harddisks(self):
1535- """ Returns hard drive letters under Win32. """
1536- try:
1537- import win32file
1538- import string
1539- except ImportError:
1540- if sys.platform == 'win32':
1541- print "pyWin32 modules needed to run Olive on Win32."
1542- sys.exit(1)
1543-
1544- driveletters = []
1545- for drive in string.ascii_uppercase:
1546- if win32file.GetDriveType(drive+':') == win32file.DRIVE_FIXED or\
1547- win32file.GetDriveType(drive+':') == win32file.DRIVE_REMOTE or\
1548- win32file.GetDriveType(drive+':') == win32file.DRIVE_REMOVABLE:
1549- driveletters.append(drive+':')
1550- return driveletters
1551-
1552- def gen_hard_selector(self):
1553- """ Generate the hard drive selector under Win32. """
1554- drives = self._harddisks()
1555- for drive in drives:
1556- self.combobox_drive.append_text(drive)
1557- self.combobox_drive.set_active(drives.index(os.getcwd()[0:2]))
1558-
1559- def _refresh_drives(self, combobox):
1560- if self._just_started:
1561- return
1562- model = combobox.get_model()
1563- active = combobox.get_active()
1564- if active >= 0:
1565- drive = model[active][0]
1566- self.set_path(drive + '\\')
1567- self.refresh_right()
1568-
1569- def check_for_changes(self):
1570- """ Check whether there were changes in the current working tree. """
1571- old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
1572- delta = self.wt.changes_from(old_tree)
1573-
1574- changes = False
1575-
1576- if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
1577- changes = True
1578-
1579- return changes
1580-
1581- def _sort_filelist_callback(self, model, iter1, iter2, data):
1582- """ The sort callback for the file list, return values:
1583- -1: iter1 < iter2
1584- 0: iter1 = iter2
1585- 1: iter1 > iter2
1586- """
1587- name1 = model.get_value(iter1, 2)
1588- name2 = model.get_value(iter2, 2)
1589-
1590- if model.get_value(iter1, 1):
1591- # item1 is a directory
1592- if not model.get_value(iter2, 1):
1593- # item2 isn't
1594- return -1
1595- else:
1596- # both of them are directories, we compare their names
1597- if name1 < name2:
1598- return -1
1599- elif name1 == name2:
1600- return 0
1601- else:
1602- return 1
1603- else:
1604- # item1 is not a directory
1605- if model.get_value(iter2, 1):
1606- # item2 is
1607- return 1
1608- else:
1609- # both of them are files, compare them
1610- if name1 < name2:
1611- return -1
1612- elif name1 == name2:
1613- return 0
1614- else:
1615- return 1
1616-
1617- def _format_size(self, size):
1618- """ Format size to a human readable format. """
1619- if size < 1000:
1620- return "%d[B]" % (size,)
1621- size = size / 1000.0
1622-
1623- for metric in ["kB","MB","GB","TB"]:
1624- if size < 1000:
1625- break
1626- size = size / 1000.0
1627- return "%.1f[%s]" % (size,metric)
1628-
1629- def _format_date(self, timestamp):
1630- """ Format the time (given in secs) to a human readable format. """
1631- return time.ctime(timestamp)
1632-
1633- def _is_remote_dir(self, location):
1634- """ Determine whether the given location is a directory or not. """
1635- if not self.remote:
1636- # We're in local mode
1637- return False
1638- else:
1639- branch, path = Branch.open_containing(location)
1640- for (name, type) in self.remote_entries:
1641- if name == path and type.kind == 'directory':
1642- # We got it
1643- return True
1644- # Either it's not a directory or not in the inventory
1645- return False
1646-
1647-import ConfigParser
1648-
1649-class Preferences:
1650- """ A class which handles Olive's preferences. """
1651- def __init__(self, path=None):
1652- """ Initialize the Preferences class. """
1653- # Some default options
1654- self.defaults = { 'strict_commit' : False,
1655- 'dotted_files' : False,
1656- 'ignored_files' : True,
1657- 'window_width' : 700,
1658- 'window_height' : 400,
1659- 'window_x' : 40,
1660- 'window_y' : 40,
1661- 'paned_position': 200 }
1662-
1663- # Create a config parser object
1664- self.config = ConfigParser.RawConfigParser()
1665-
1666- # Set filename
1667- if path is None:
1668- if sys.platform == 'win32':
1669- # Windows - no dotted files
1670- self._filename = os.path.expanduser('~/olive.conf')
1671- else:
1672- self._filename = os.path.expanduser('~/.olive.conf')
1673- else:
1674- self._filename = path
1675-
1676- # Load the configuration
1677- self.read()
1678-
1679- def _get_default(self, option):
1680- """ Get the default option for a preference. """
1681- try:
1682- ret = self.defaults[option]
1683- except KeyError:
1684- return None
1685- else:
1686- return ret
1687-
1688- def refresh(self):
1689- """ Refresh the configuration. """
1690- # First write out the changes
1691- self.write()
1692- # Then load the configuration again
1693- self.read()
1694-
1695- def read(self):
1696- """ Just read the configuration. """
1697- # Re-initialize the config parser object to avoid some bugs
1698- self.config = ConfigParser.RawConfigParser()
1699- self.config.read([self._filename])
1700-
1701- def write(self):
1702- """ Write the configuration to the appropriate files. """
1703- fp = open(self._filename, 'w')
1704- self.config.write(fp)
1705- fp.close()
1706-
1707- def get_bookmarks(self):
1708- """ Return the list of bookmarks. """
1709- bookmarks = self.config.sections()
1710- if self.config.has_section('preferences'):
1711- bookmarks.remove('preferences')
1712- return bookmarks
1713-
1714- def add_bookmark(self, path):
1715- """ Add bookmark. """
1716- try:
1717- self.config.add_section(path)
1718- except ConfigParser.DuplicateSectionError:
1719- return False
1720- else:
1721- return True
1722-
1723- def get_bookmark_title(self, path):
1724- """ Get bookmark title. """
1725- try:
1726- ret = self.config.get(path, 'title')
1727- except ConfigParser.NoOptionError:
1728- ret = path
1729-
1730- return ret
1731-
1732- def set_bookmark_title(self, path, title):
1733- """ Set bookmark title. """
1734- # FIXME: What if path isn't listed yet?
1735- # FIXME: Canonicalize paths first?
1736- self.config.set(path, 'title', title)
1737-
1738- def remove_bookmark(self, path):
1739- """ Remove bookmark. """
1740- return self.config.remove_section(path)
1741-
1742- def set_preference(self, option, value):
1743- """ Set the value of the given option. """
1744- if value is True:
1745- value = 'yes'
1746- elif value is False:
1747- value = 'no'
1748-
1749- if self.config.has_section('preferences'):
1750- self.config.set('preferences', option, value)
1751- else:
1752- self.config.add_section('preferences')
1753- self.config.set('preferences', option, value)
1754-
1755- def get_preference(self, option, kind='str'):
1756- """ Get the value of the given option.
1757-
1758- :param kind: str/bool/int/float. default: str
1759- """
1760- if self.config.has_option('preferences', option):
1761- if kind == 'bool':
1762- return self.config.getboolean('preferences', option)
1763- elif kind == 'int':
1764- return self.config.getint('preferences', option)
1765- elif kind == 'float':
1766- return self.config.getfloat('preferences', option)
1767- else:
1768- return self.config.get('preferences', option)
1769- else:
1770- try:
1771- return self._get_default(option)
1772- except KeyError:
1773- return None
1774
1775=== removed file 'olive/add.py'
1776--- olive/add.py 2008-07-17 20:41:24 +0000
1777+++ olive/add.py 1970-01-01 00:00:00 +0000
1778@@ -1,95 +0,0 @@
1779-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
1780-#
1781-# This program is free software; you can redistribute it and/or modify
1782-# it under the terms of the GNU General Public License as published by
1783-# the Free Software Foundation; either version 2 of the License, or
1784-# (at your option) any later version.
1785-#
1786-# This program is distributed in the hope that it will be useful,
1787-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1788-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1789-# GNU General Public License for more details.
1790-#
1791-# You should have received a copy of the GNU General Public License
1792-# along with this program; if not, write to the Free Software
1793-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1794-
1795-import os
1796-
1797-try:
1798- import pygtk
1799- pygtk.require("2.0")
1800-except:
1801- pass
1802-
1803-import gtk
1804-
1805-import bzrlib.add
1806-import bzrlib.errors as errors
1807-
1808-from bzrlib.plugins.gtk import _i18n
1809-from bzrlib.plugins.gtk.dialog import error_dialog
1810-from bzrlib.plugins.gtk.errors import show_bzr_error
1811-
1812-
1813-class AddDialog(gtk.Dialog):
1814- """ Dialog for adding selected file or recursively all unknown files/folders in branch """
1815-
1816- def __init__(self, wt, wtpath, selected, parent=None):
1817- """ Initialize the Add dialog. """
1818- gtk.Dialog.__init__(self, title="Olive - Add file(s)",
1819- parent=parent,
1820- flags=0,
1821- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1822-
1823- # Get arguments
1824- self.wt = wt
1825- self.wtpath = wtpath
1826- self.selected = selected
1827-
1828- # Create widgets
1829- self._label_add_question = gtk.Label(_i18n("Which file(s) do you want to add?"))
1830- self._radiobutton_add_selected = gtk.RadioButton(None,_i18n("Selected: %s"%self.selected))
1831- self._radiobutton_add_unknown = gtk.RadioButton(self._radiobutton_add_selected,
1832- _i18n("All unknowns recursively"))
1833- self._button_add = gtk.Button(stock=gtk.STOCK_ADD)
1834-
1835- self._button_add.connect('clicked', self._on_add_clicked)
1836-
1837- # Add widgets to dialog window and decorate
1838- self.vbox.add(self._label_add_question)
1839- self.vbox.add(self._radiobutton_add_selected)
1840- self.vbox.add(self._radiobutton_add_unknown)
1841- self.vbox.set_spacing(3)
1842- self.action_area.pack_end(self._button_add)
1843-
1844- self.vbox.show_all()
1845-
1846- @show_bzr_error
1847- def _on_add_clicked(self, button):
1848- """ """
1849- if self._radiobutton_add_selected.get_active():
1850- # Add only the selected file
1851- filename = self.selected
1852-
1853- if filename is None:
1854- error_dialog(_i18n('No file was selected'),
1855- _i18n('Please select a file from the list,\nor choose the other option.'))
1856- return
1857-
1858- try:
1859- self.wt.add([filename])
1860- except errors.NotBranchError:
1861- error_dialog(_i18n('Directory is not a branch'),
1862- _i18n('You can perform this action only in a branch.'))
1863- return
1864- elif self._radiobutton_add_unknown.get_active():
1865- # Add unknown files recursively
1866- try:
1867- self.wt.add(self.wt.unknowns())
1868- except errors.NotBranchError:
1869- error_dialog(_i18n('Directory is not a branch'),
1870- _i18n('You can perform this action only in a branch.'))
1871- return
1872-
1873- self.response(gtk.RESPONSE_OK)
1874
1875=== removed file 'olive/bookmark.py'
1876--- olive/bookmark.py 2008-07-20 22:36:42 +0000
1877+++ olive/bookmark.py 1970-01-01 00:00:00 +0000
1878@@ -1,92 +0,0 @@
1879-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
1880-#
1881-# This program is free software; you can redistribute it and/or modify
1882-# it under the terms of the GNU General Public License as published by
1883-# the Free Software Foundation; either version 2 of the License, or
1884-# (at your option) any later version.
1885-#
1886-# This program is distributed in the hope that it will be useful,
1887-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1888-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1889-# GNU General Public License for more details.
1890-#
1891-# You should have received a copy of the GNU General Public License
1892-# along with this program; if not, write to the Free Software
1893-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1894-
1895-try:
1896- import pygtk
1897- pygtk.require("2.0")
1898-except:
1899- pass
1900-
1901-import gtk
1902-
1903-from bzrlib.plugins.gtk.olive import Preferences
1904-from bzrlib.plugins.gtk import _i18n
1905-from bzrlib.plugins.gtk.dialog import error_dialog
1906-
1907-
1908-class BookmarkDialog(gtk.Dialog):
1909- """ This class wraps the old Bookmark window into a gtk.Dialog. """
1910-
1911- def __init__(self, selected, parent=None):
1912- """ Initialize the Bookmark dialog. """
1913- gtk.Dialog.__init__(self, title="Bookmarks - Olive",
1914- parent=parent,
1915- flags=0,
1916- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
1917-
1918- self.pref = Preferences()
1919-
1920- # Get arguments
1921- self.selected = selected
1922-
1923- # Create widgets
1924- self._label_location = gtk.Label(_i18n("Location:"))
1925- self._label_title = gtk.Label(_i18n("Title:"))
1926- self._entry_location = gtk.Entry()
1927- self._entry_title = gtk.Entry()
1928- self._button_save = gtk.Button(stock=gtk.STOCK_SAVE)
1929-
1930- self._button_save.connect('clicked', self._on_save_clicked)
1931-
1932- # Set default values
1933- self._entry_location.set_text(self.selected)
1934- self._entry_location.set_sensitive(False)
1935- self._entry_title.set_text(self.pref.get_bookmark_title(self.selected))
1936- self._entry_title.set_flags(gtk.CAN_FOCUS | gtk.HAS_FOCUS)
1937-
1938- self._entry_title.connect('activate', self._on_save_clicked)
1939-
1940- # Create a table and put widgets into it
1941- self._table = gtk.Table(rows=2, columns=2)
1942- self._table.attach(self._label_location, 0, 1, 0, 1)
1943- self._table.attach(self._label_title, 0, 1, 1, 2)
1944- self._table.attach(self._entry_location, 1, 2, 0, 1)
1945- self._table.attach(self._entry_title, 1, 2, 1, 2)
1946-
1947- self._label_location.set_alignment(0, 0.5)
1948- self._label_title.set_alignment(0, 0.5)
1949- self._table.set_row_spacings(3)
1950- self._table.set_col_spacings(3)
1951- self.vbox.set_spacing(3)
1952-
1953- self.vbox.add(self._table)
1954-
1955- self.action_area.pack_end(self._button_save)
1956-
1957- self.vbox.show_all()
1958-
1959- def _on_save_clicked(self, button):
1960- """ Save button clicked handler. """
1961- if self._entry_title.get_text() == '':
1962- error_dialog(_i18n('No title given'),
1963- _i18n('Please specify a title to continue.'))
1964- return
1965-
1966- self.pref.set_bookmark_title(self._entry_location.get_text(),
1967- self._entry_title.get_text())
1968- self.pref.write()
1969-
1970- self.response(gtk.RESPONSE_OK)
1971
1972=== removed file 'olive/guifiles.py'
1973--- olive/guifiles.py 2008-07-22 08:01:14 +0000
1974+++ olive/guifiles.py 1970-01-01 00:00:00 +0000
1975@@ -1,49 +0,0 @@
1976-# This program is free software; you can redistribute it and/or modify
1977-# it under the terms of the GNU General Public License as published by
1978-# the Free Software Foundation; either version 2 of the License, or
1979-# (at your option) any later version.
1980-#
1981-# This program is distributed in the hope that it will be useful,
1982-# but WITHOUT ANY WARRANTY; without even the implied warranty of
1983-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1984-# GNU General Public License for more details.
1985-#
1986-# You should have received a copy of the GNU General Public License
1987-# along with this program; if not, write to the Free Software
1988-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1989-
1990-"""cmenu.ui path"""
1991-
1992-import os
1993-import sys
1994-
1995-from bzrlib.plugins.gtk import _i18n
1996-
1997-UIFILENAMES = ["/usr/share/olive/cmenu.ui",
1998- "/usr/local/share/olive/cmenu.ui",
1999- "/opt/share/olive/cmenu.ui",
2000- "/opt/local/share/olive/cmenu.ui",
2001- "~/share/olive/cmenu.ui",
2002- ]
2003-
2004-# Get the glade file name
2005-if sys.platform == 'win32':
2006- UIFILENAMES = [os.path.join(os.path.dirname(sys.executable),
2007- "share/olive/cmenu.ui")]
2008-
2009-dir_ = os.path.split(os.path.dirname(__file__))[0]
2010-# Check first if we are running from source
2011-UIFILENAMES.insert(0, os.path.join(dir_, "cmenu.ui"))
2012-
2013-UIFILENAME = None
2014-
2015-for path in UIFILENAMES:
2016- path = os.path.expanduser(path)
2017- if os.path.isfile(path):
2018- UIFILENAME = path
2019- break
2020-
2021-if UIFILENAME is None:
2022- # Fail
2023- print _i18n('Context menu file (cmenu.ui) cannot be found.')
2024- sys.exit(1)
2025
2026=== removed file 'olive/info.py'
2027--- olive/info.py 2008-08-04 21:39:55 +0000
2028+++ olive/info.py 1970-01-01 00:00:00 +0000
2029@@ -1,287 +0,0 @@
2030-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2031-#
2032-# This program is free software; you can redistribute it and/or modify
2033-# it under the terms of the GNU General Public License as published by
2034-# the Free Software Foundation; either version 2 of the License, or
2035-# (at your option) any later version.
2036-#
2037-# This program is distributed in the hope that it will be useful,
2038-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2039-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2040-# GNU General Public License for more details.
2041-#
2042-# You should have received a copy of the GNU General Public License
2043-# along with this program; if not, write to the Free Software
2044-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2045-
2046-import os
2047-
2048-try:
2049- import pygtk
2050- pygtk.require("2.0")
2051-except:
2052- pass
2053-
2054-import gtk
2055-
2056-import bzrlib.errors as errors
2057-
2058-from bzrlib.plugins.gtk import _i18n, icon_path
2059-from bzrlib.plugins.gtk.dialog import error_dialog
2060-
2061-
2062-def info(location):
2063- """ Get info about branch, working tree, and repository
2064-
2065- :param location: the location of the branch/working tree/repository
2066-
2067- :return: the information in dictionary format
2068-
2069- The following informations are delivered (if available):
2070- ret['location']['lightcoroot']: Light checkout root
2071- ret['location']['sharedrepo']: Shared repository
2072- ret['location']['repobranch']: Repository branch
2073- ret['location']['cobranch']: Checkout of branch
2074- ret['location']['repoco']: Repository checkout
2075- ret['location']['coroot']: Checkout root
2076- ret['location']['branchroot']: Branch root
2077- ret['related']['parentbranch']: Parent branch
2078- ret['related']['publishbranch']: Publish to branch
2079- ret['format']['control']: Control format
2080- ret['format']['workingtree']: Working tree format
2081- ret['format']['branch']: Branch format
2082- ret['format']['repository']: Repository format
2083- ret['locking']['workingtree']: Working tree lock status
2084- ret['locking']['branch']: Branch lock status
2085- ret['locking']['repository']: Repository lock status
2086- ret['missing']['branch']: Missing revisions in branch
2087- ret['missing']['workingtree']: Missing revisions in working tree
2088- ret['wtstats']['unchanged']: Unchanged files
2089- ret['wtstats']['modified']: Modified files
2090- ret['wtstats']['added']: Added files
2091- ret['wtstats']['removed']: Removed files
2092- ret['wtstats']['renamed']: Renamed files
2093- ret['wtstats']['unknown']: Unknown files
2094- ret['wtstats']['ignored']: Ingnored files
2095- ret['wtstats']['subdirs']: Versioned subdirectories
2096- ret['brstats']['revno']: Revisions in branch
2097- ret['brstats']['commiters']: Number of commiters
2098- ret['brstats']['age']: Age of branch in days
2099- ret['brstats']['firstrev']: Time of first revision
2100- ret['brstats']['lastrev']: Time of last revision
2101- ret['repstats']['revisions']: Revisions in repository
2102- ret['repstats']['size']: Size of repository in bytes
2103- """
2104- import bzrlib.bzrdir as bzrdir
2105-
2106- import info_helper
2107-
2108- ret = {}
2109- try:
2110- a_bzrdir = bzrdir.BzrDir.open_containing(location)[0]
2111- except errors.NotBranchError:
2112- raise errors.NotBranchError(location)
2113-
2114- try:
2115- working = a_bzrdir.open_workingtree()
2116- working.lock_read()
2117- try:
2118- branch = working.branch
2119- repository = branch.repository
2120- control = working.bzrdir
2121-
2122- ret['location'] = info_helper.get_location_info(repository, branch, working)
2123- ret['related'] = info_helper.get_related_info(branch)
2124- ret['format'] = info_helper.get_format_info(control, repository, branch, working)
2125- ret['locking'] = info_helper.get_locking_info(repository, branch, working)
2126- ret['missing'] = {}
2127- ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
2128- ret['missing']['workingtree'] = info_helper.get_missing_revisions_working(working)
2129- ret['wtstats'] = info_helper.get_working_stats(working)
2130- ret['brstats'] = info_helper.get_branch_stats(branch)
2131- ret['repstats'] = info_helper.get_repository_stats(repository)
2132- finally:
2133- working.unlock()
2134- return ret
2135- return
2136- except (errors.NoWorkingTree, errors.NotLocalUrl):
2137- pass
2138-
2139- try:
2140- branch = a_bzrdir.open_branch()
2141- repository = branch.repository
2142- control = a_bzrdir
2143- branch.lock_read()
2144- try:
2145- ret['location'] = info_helper.get_location_info(repository, branch)
2146- ret['related'] = info_helper.get_related_info(branch)
2147- ret['format'] = info_helper.get_format_info(control, repository, branch)
2148- ret['locking'] = info_helper.get_locking_info(repository, branch)
2149- ret['missing']['branch'] = info_helper.get_missing_revisions_branch(branch)
2150- ret['brstats'] = info_helper.get_branch_stats(branch)
2151- ret['repstats'] = info_helper.get_repository_stats(repository)
2152- finally:
2153- branch.unlock()
2154- return ret
2155- return
2156- except errors.NotBranchError:
2157- pass
2158-
2159- try:
2160- repository = a_bzrdir.open_repository()
2161- repository.lock_read()
2162- try:
2163- ret['location'] = info_helper.get_location_info(repository)
2164- ret['format'] = info_helper.get_format_info(control, repository)
2165- ret['locking'] = info_helper.get_locking_info(repository)
2166- ret['repstats'] = info_helper.get_repository_stats(repository)
2167- finally:
2168- repository.unlock()
2169- return ret
2170- except errors.NoRepositoryPresent:
2171- pass
2172-
2173-
2174-class InfoDialog(object):
2175- """ Display Informations window and perform the needed actions. """
2176-
2177- def __init__(self, branch):
2178- """ Initialize the Informations window. """
2179- # Check if current location is a branch
2180- self.notbranch = False
2181- try:
2182- self.ret = info(branch.base)
2183- except errors.NotBranchError:
2184- self.notbranch = True
2185- return
2186-
2187- # Create the window
2188- self.window = gtk.Dialog(title="Branch Information",
2189- parent = None,
2190- flags=0,
2191- buttons=None)
2192- self.window.set_icon_list(gtk.gdk.pixbuf_new_from_file(icon_path("oliveicon2.png")),
2193- gtk.gdk.pixbuf_new_from_file(icon_path("olive-gtk.png")))
2194- self.window.vbox.set_spacing(3)
2195- self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_NORMAL)
2196-
2197- infokeylist = ( ('location', _i18n("Location"), (
2198- ('lightcoroot', _i18n("Light checkout root")),
2199- ('sharedrepo', _i18n("Shared repository")),
2200- ('repobranch', _i18n("Repository branch")),
2201- ('cobranch', _i18n("Checkout of branch")),
2202- ('repoco', _i18n("Repository checkout")),
2203- ('coroot', _i18n("Checkout root")),
2204- ('branchroot', _i18n("Branch root")),
2205- )),
2206- ('related', _i18n("Related branches"), (
2207- ('parentbranch', _i18n("Parent branch")),
2208- ('publishbranch', _i18n("Publish to branch")),
2209- )),
2210- ('format', _i18n("Format"), (
2211- ('control', _i18n("Control format")),
2212- ('workingtree', _i18n("Working tree format")),
2213- ('branch', _i18n("Branch format")),
2214- ('repository', _i18n("Repository format")),
2215- )),
2216- ('locking', _i18n("Lock status"), (
2217- ('workingtree', _i18n("Working tree lock status")),
2218- ('branch', _i18n("Branch lock status")),
2219- ('repository', _i18n("Repository lock status")),
2220- )),
2221- #('missing', _i18n("Missing revisions"), (
2222- # ('branch', _i18n("Missing revisions in branch")),
2223- # ('workingtree', _i18n("Missing revisions in working tree")),
2224- # )), # Missing is 'temporary' disabled
2225- ('wtstats', _i18n("In the working tree"), (
2226- ('unchanged', _i18n("Unchanged files")),
2227- ('modified', _i18n("Modified files")),
2228- ('added', _i18n("Added files")),
2229- ('removed', _i18n("Removed files")),
2230- ('renamed', _i18n("Renamed files")),
2231- ('unknown', _i18n("Unknown files")),
2232- ('ignored', _i18n("Ignored files")),
2233- ('subdirs', _i18n("Versioned subdirectories")),
2234- )),
2235- ('brstats', _i18n("Branch history"), (
2236- ('revno', _i18n("Revisions in branch")),
2237- ('commiters', _i18n("Number of commiters")),
2238- ('age', _i18n("Age of branch in days")),
2239- ('firstrev', _i18n("Time of first revision")),
2240- ('lastrev', _i18n("Time of last revision")),
2241- )),
2242- ('repstats', _i18n("Revision store"), (
2243- ('revisions', _i18n("Revisions in repository")),
2244- ('size', _i18n("Size of repository in bytes")),
2245- )),
2246- )
2247-
2248- # Generate status output
2249- self._generate_info(infokeylist)
2250-
2251- button_close = gtk.Button(stock=gtk.STOCK_CLOSE)
2252- button_close.connect('clicked', self.close)
2253- self.window.action_area.pack_end(button_close)
2254- self.window.set_focus(button_close)
2255-
2256- def _generate_info(self, infokeylist):
2257- """ Generate 'bzr info' output. """
2258- expander={}
2259- alignment={}
2260- table={}
2261- label = {}
2262- description = {}
2263- for key, keystring, subkeylist in infokeylist:
2264- if self.ret.has_key(key):
2265- tablelength = 0
2266- for subkey, subkeystring in subkeylist:
2267- if self.ret[key].has_key(subkey):
2268- tablelength += 1
2269- if tablelength == 0:
2270- pass
2271- else:
2272- expander[key] = gtk.Expander(keystring)
2273- expander[key].set_use_markup(True)
2274- expander[key].connect('activate', self.activate)
2275-
2276- alignment[key]= gtk.Alignment()
2277- alignment[key].set_padding(0, 0, 24, 0)
2278- expander[key].add(alignment[key])
2279-
2280- table[key] = gtk.Table(tablelength, 2)
2281- table[key].set_col_spacings(12)
2282- alignment[key].add(table[key])
2283-
2284- label[key] = {}
2285- description[key] = {}
2286-
2287- tablepos = 0
2288- for subkey, subkeystring in subkeylist:
2289- if self.ret[key].has_key(subkey):
2290- label[key][subkey] = gtk.Label(subkeystring)
2291- table[key].attach(label[key][subkey], 0, 1, tablepos, tablepos + 1, gtk.FILL)
2292- label[key][subkey].set_alignment(0, 0.5)
2293-
2294- description[key][subkey] = gtk.Label(str(self.ret[key][subkey]))
2295- table[key].attach(description[key][subkey], 1, 2, tablepos, tablepos + 1, gtk.FILL)
2296- description[key][subkey].set_alignment(0, 0.5)
2297- tablepos += 1
2298- expander[key].set_expanded(True)
2299- self.window.vbox.pack_start(expander[key], False, True, 0)
2300-
2301- def activate(self, expander):
2302- """ Redraw the window. """
2303- self.window.resize(50, 50)
2304- self.window.queue_resize()
2305-
2306- def display(self):
2307- """ Display the Informations window. """
2308- if self.notbranch:
2309- error_dialog(_i18n('Directory is not a branch'),
2310- _i18n('You can perform this action only in a branch.'))
2311- self.close()
2312- else:
2313- self.window.show_all()
2314-
2315- def close(self, widget=None):
2316- self.window.destroy()
2317
2318=== removed file 'olive/info_helper.py'
2319--- olive/info_helper.py 2008-07-19 23:16:51 +0000
2320+++ olive/info_helper.py 1970-01-01 00:00:00 +0000
2321@@ -1,323 +0,0 @@
2322-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2323-# Some parts of the code are:
2324-# Copyright (C) 2005, 2006 by Canonical Ltd
2325-#
2326-# This program is free software; you can redistribute it and/or modify
2327-# it under the terms of the GNU General Public License as published by
2328-# the Free Software Foundation; either version 2 of the License, or
2329-# (at your option) any later version.
2330-#
2331-# This program is distributed in the hope that it will be useful,
2332-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2333-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2334-# GNU General Public License for more details.
2335-#
2336-# You should have received a copy of the GNU General Public License
2337-# along with this program; if not, write to the Free Software
2338-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2339-
2340-import time
2341-import sys
2342-
2343-import bzrlib
2344-
2345-from bzrlib import (
2346- bzrdir,
2347- diff,
2348- errors,
2349- osutils,
2350- urlutils,
2351- )
2352-
2353-from bzrlib.diff import show_diff_trees
2354-from bzrlib.missing import find_unmerged
2355-
2356-def _repo_rel_url(repo_url, inner_url):
2357- """Return path with common prefix of repository path removed.
2358-
2359- If path is not part of the repository, the original path is returned.
2360- If path is equal to the repository, the current directory marker '.' is
2361- returned.
2362- Otherwise, a relative path is returned, with trailing '/' stripped.
2363- """
2364- inner_url = urlutils.normalize_url(inner_url)
2365- repo_url = urlutils.normalize_url(repo_url)
2366- if inner_url == repo_url:
2367- return '.'
2368- result = urlutils.relative_url(repo_url, inner_url)
2369- if result != inner_url:
2370- result = result.rstrip('/')
2371- return result
2372-
2373-def get_location_info(repository, branch=None, working=None):
2374- """ Get known locations for working, branch and repository.
2375-
2376- :return: a dictionary containing the needed infos
2377- """
2378- ret = {}
2379- repository_path = repository.bzrdir.root_transport.base
2380- if working and branch:
2381- working_path = working.bzrdir.root_transport.base
2382- branch_path = branch.bzrdir.root_transport.base
2383- if working_path != branch_path:
2384- # lightweight checkout
2385- ret['lightcoroot'] = working_path
2386- if repository.is_shared():
2387- # lightweight checkout of branch in shared repository
2388- ret['sharedrepo'] = repository_path
2389- ret['repobranch'] = _repo_rel_url(repository_path, branch_path)
2390- else:
2391- # lightweight checkout of standalone branch
2392- ret['cobranch'] = branch_path
2393- elif repository.is_shared():
2394- # branch with tree inside shared repository
2395- ret['sharedrepo'] = repository_path
2396- ret['repoco'] = _repo_rel_url(repository_path, branch_path)
2397- elif branch.get_bound_location():
2398- # normal checkout
2399- ret['coroot'] = working_path
2400- ret['cobranch'] = branch.get_bound_location()
2401- else:
2402- # standalone
2403- ret['branchroot'] = working_path
2404- elif branch:
2405- branch_path = branch.bzrdir.root_transport.base
2406- if repository.is_shared():
2407- # branch is part of shared repository
2408- ret['sharedrepo'] = repository_path
2409- ret['repobranch'] = _repo_rel_url(repository_path, branch_path)
2410- else:
2411- # standalone branch
2412- ret['branchroot'] = branch_path
2413- else:
2414- # shared repository
2415- assert repository.is_shared()
2416- ret['sharedrepo'] = repository_path
2417-
2418- return ret
2419-
2420-def get_related_info(branch):
2421- """ Get parent and push location of branch.
2422-
2423- :return: a dictionary containing the needed infos
2424- """
2425- ret = {}
2426- if branch.get_parent() or branch.get_push_location():
2427- if branch.get_parent():
2428- ret['parentbranch'] = branch.get_parent()
2429- if branch.get_push_location():
2430- ret['publishbranch'] = branch.get_push_location()
2431-
2432- return ret
2433-
2434-
2435-def get_format_info(control=None, repository=None, branch=None, working=None):
2436- """ Get known formats for control, working, branch and repository.
2437-
2438- :return: a dictionary containing the needed infos
2439- """
2440- ret = {}
2441- if control:
2442- ret['control'] = control._format.get_format_description()
2443- if working:
2444- ret['workingtree'] = working._format.get_format_description()
2445- if branch:
2446- ret['branch'] = branch._format.get_format_description()
2447- if repository:
2448- ret['repository'] = repository._format.get_format_description()
2449-
2450- return ret
2451-
2452-
2453-def get_locking_info(repository, branch=None, working=None):
2454- """ Get locking status of working, branch and repository.
2455-
2456- :return: a dictionary containing the needed infos
2457- """
2458- ret = {}
2459- if (repository.get_physical_lock_status() or
2460- (branch and branch.get_physical_lock_status()) or
2461- (working and working.get_physical_lock_status())):
2462- if working:
2463- if working.get_physical_lock_status():
2464- status = 'locked'
2465- else:
2466- status = 'unlocked'
2467- ret['workingtree'] = status
2468- if branch:
2469- if branch.get_physical_lock_status():
2470- status = 'locked'
2471- else:
2472- status = 'unlocked'
2473- ret['branch'] = status
2474- if repository:
2475- if repository.get_physical_lock_status():
2476- status = 'locked'
2477- else:
2478- status = 'unlocked'
2479- ret['repository'] = status
2480-
2481- return ret
2482-
2483-def get_missing_revisions_branch(branch):
2484- """ Get missing master revisions in branch.
2485-
2486- :return: a dictionary containing the needed infos
2487- """
2488- ret = {}
2489- # Try with inaccessible branch ?
2490- master = branch.get_master_branch()
2491- if master:
2492- local_extra, remote_extra = find_unmerged(branch, master)
2493- if remote_extra:
2494- ret = len(remote_extra)
2495-
2496- return ret
2497-
2498-
2499-def get_missing_revisions_working(working):
2500- """ Get missing revisions in working tree.
2501-
2502- :return: a dictionary containing the needed infos
2503- """
2504- if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
2505- # function deprecated after 0.9
2506- from bzrlib.delta import compare_trees
2507-
2508- ret = {}
2509- branch = working.branch
2510- basis = working.basis_tree()
2511-
2512- if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
2513- delta = compare_trees(basis, working, want_unchanged=True)
2514- else:
2515- delta = working.changes_from(basis, want_unchanged=True)
2516-
2517- history = branch.revision_history()
2518- tree_last_id = working.last_revision()
2519-
2520- if len(history) and tree_last_id != history[-1]:
2521- tree_last_revno = branch.revision_id_to_revno(tree_last_id)
2522- missing_count = len(history) - tree_last_revno
2523- ret = missing_count
2524-
2525- return ret
2526-
2527-
2528-def get_working_stats(working):
2529- """ Get statistics about a working tree.
2530-
2531- :return: a dictionary containing the needed infos
2532- """
2533- if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
2534- # function deprecated after 0.9
2535- from bzrlib.delta import compare_trees
2536-
2537- ret = {}
2538- basis = working.basis_tree()
2539-
2540- if (bzrlib.version_info[0] == 0) and (bzrlib.version_info[1] < 9):
2541- delta = compare_trees(basis, working, want_unchanged=True)
2542- else:
2543- delta = working.changes_from(basis, want_unchanged=True)
2544-
2545- ret['unchanged'] = len(delta.unchanged)
2546- ret['modified'] = len(delta.modified)
2547- ret['added'] = len(delta.added)
2548- ret['removed'] = len(delta.removed)
2549- ret['renamed'] = len(delta.renamed)
2550-
2551- ignore_cnt = unknown_cnt = 0
2552- for path in working.extras():
2553- if working.is_ignored(path):
2554- ignore_cnt += 1
2555- else:
2556- unknown_cnt += 1
2557- ret['unknown'] = unknown_cnt
2558- ret['ignored'] = ignore_cnt
2559-
2560- dir_cnt = 0
2561- for path, ie in working.iter_entries_by_dir():
2562- if ie.kind == 'directory':
2563- dir_cnt += 1
2564- ret['subdirs'] = dir_cnt
2565-
2566- return ret
2567-
2568-def get_branch_stats(branch):
2569- """ Get statistics about a branch.
2570-
2571- :return: a dictionary containing the needed infos
2572- """
2573- ret = {}
2574- repository = branch.repository
2575- history = branch.revision_history()
2576-
2577- revno = len(history)
2578- ret['revno'] = revno
2579- committers = {}
2580- for rev in history:
2581- committers[repository.get_revision(rev).committer] = True
2582- ret['commiters'] = len(committers)
2583- if revno > 0:
2584- firstrev = repository.get_revision(history[0])
2585- age = int((time.time() - firstrev.timestamp) / 3600 / 24)
2586- ret['age'] = '%d days'%age
2587- ret['firstrev'] = osutils.format_date(firstrev.timestamp,
2588- firstrev.timezone)
2589-
2590- lastrev = repository.get_revision(history[-1])
2591- ret['lastrev'] = osutils.format_date(lastrev.timestamp,
2592- lastrev.timezone)
2593-
2594- return ret
2595-
2596-def get_repository_stats(repository):
2597- """ Get statistics about a repository.
2598-
2599- :return: a dictionary containing the needed infos
2600- """
2601- ret = {}
2602- if repository.bzrdir.root_transport.listable():
2603- c, t = repository._revision_store.total_size(repository.get_transaction())
2604- ret['revisions'] = c
2605- ret['size'] = '%d KiB'%t
2606-
2607- return ret
2608-
2609-def diff_helper(tree, specific_files, external_diff_options,
2610- old_revision_spec=None, new_revision_spec=None,
2611- old_label='a/', new_label='b/', output=None):
2612- """ Helper for diff.
2613-
2614- :param tree: a WorkingTree
2615-
2616- :param specific_files: the specific files to compare, or None
2617-
2618- :param external_diff_options: if non-None, run an external diff, and pass it these options
2619-
2620- :param old_revision_spec: if None, use basis tree as old revision, otherwise use the tree for the specified revision.
2621-
2622- :param new_revision_spec: if None, use working tree as new revision, otherwise use the tree for the specified revision.
2623- """
2624-
2625- if output == None:
2626- output = sys.stdout
2627-
2628- if old_revision_spec is None:
2629- old_tree = tree.basis_tree()
2630- else:
2631- old_tree = spec_tree(old_revision_spec)
2632-
2633- if new_revision_spec is None:
2634- new_tree = tree
2635- else:
2636- new_tree = spec_tree(new_revision_spec)
2637-
2638- return show_diff_trees(old_tree, new_tree, output, specific_files,
2639- external_diff_options,
2640- old_label=old_label, new_label=new_label)
2641-
2642-def spec_tree(spec):
2643- revision_id = spec.in_store(tree.branch).rev_id
2644- return tree.branch.repository.revision_tree(revision_id)
2645
2646=== removed file 'olive/launch.py'
2647--- olive/launch.py 2006-09-30 13:04:15 +0000
2648+++ olive/launch.py 1970-01-01 00:00:00 +0000
2649@@ -1,54 +0,0 @@
2650-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2651-#
2652-# This program is free software; you can redistribute it and/or modify
2653-# it under the terms of the GNU General Public License as published by
2654-# the Free Software Foundation; either version 2 of the License, or
2655-# (at your option) any later version.
2656-#
2657-# This program is distributed in the hope that it will be useful,
2658-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2659-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2660-# GNU General Public License for more details.
2661-#
2662-# You should have received a copy of the GNU General Public License
2663-# along with this program; if not, write to the Free Software
2664-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2665-
2666-import sys
2667-import os
2668-
2669-def launch(path):
2670- """ Launch program associated with path """
2671-
2672- # Normalize filepath
2673- normpath = os.path.normpath(path)
2674-
2675- if sys.platform == 'win32':
2676- # Windows is easy
2677- os.startfile(normpath)
2678- else:
2679- # Maybe Gnome?
2680- exe = search_exe('gnome-open')
2681- if exe != None:
2682- os.system("gnome-open %s" % normpath)
2683- return
2684- # Maybe KDE?
2685- exe = search_exe('kfmclient')
2686- if exe != None:
2687- os.system("kfmclient exec file:%s" % normpath)
2688- return
2689-
2690- # TODO: support other platforms
2691- print "DEBUG: file launch not supported on this platform."
2692-
2693-def search_exe(exe):
2694- """ Search for given executable. """
2695- found = 0
2696- paths = os.environ['PATH'].split(os.pathsep)
2697- for path in paths:
2698- if os.path.exists(os.path.join(path,exe)):
2699- found = 1
2700- break
2701- if found:
2702- return True
2703- return None
2704
2705=== removed file 'olive/menu.py'
2706--- olive/menu.py 2010-01-25 01:58:58 +0000
2707+++ olive/menu.py 1970-01-01 00:00:00 +0000
2708@@ -1,383 +0,0 @@
2709-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2710-#
2711-# This program is free software; you can redistribute it and/or modify
2712-# it under the terms of the GNU General Public License as published by
2713-# the Free Software Foundation; either version 2 of the License, or
2714-# (at your option) any later version.
2715-#
2716-# This program is distributed in the hope that it will be useful,
2717-# but WITHOUT ANY WARRANTY; without even the implied warranty of
2718-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2719-# GNU General Public License for more details.
2720-#
2721-# You should have received a copy of the GNU General Public License
2722-# along with this program; if not, write to the Free Software
2723-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2724-
2725-import os
2726-import os.path
2727-import shutil
2728-import sys
2729-
2730-try:
2731- import pygtk
2732- pygtk.require("2.0")
2733-except:
2734- pass
2735-
2736-import gtk
2737-
2738-import bzrlib.errors as errors
2739-from bzrlib.workingtree import WorkingTree
2740-
2741-from bzrlib.plugins.gtk import _i18n
2742-from bzrlib.plugins.gtk.dialog import error_dialog, info_dialog, question_dialog, warning_dialog
2743-from bzrlib.plugins.gtk.errors import show_bzr_error
2744-from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
2745-from bzrlib.plugins.gtk.annotate.config import GAnnotateConfig
2746-from bzrlib.plugins.gtk.diff import DiffWindow
2747-from bzrlib.plugins.gtk.olive import Preferences, launch
2748-
2749-class OliveMenu:
2750- """ This class is responsible for building the context menus. """
2751- def __init__(self, path, selected, app=None):
2752- # Load the UI file
2753- from guifiles import UIFILENAME
2754-
2755- self.uifile = UIFILENAME
2756-
2757- # Preferences handler
2758- self.pref = Preferences()
2759-
2760- # Set default values
2761- self.path = path
2762- self.selected = selected
2763- self.app = app
2764-
2765- # Create the file list context menu
2766- self.ui = gtk.UIManager()
2767-
2768- self.actiongroup = gtk.ActionGroup('context')
2769- self.actiongroup.add_actions([('add', gtk.STOCK_ADD,
2770- _i18n('Add'), None,
2771- _i18n('Add the selected file'),
2772- self.add_file),
2773- ('remove', gtk.STOCK_REMOVE,
2774- _i18n('Remove'), None,
2775- _i18n('Remove the selected file'),
2776- self.remove_file),
2777- ('remove_and_delete', gtk.STOCK_REMOVE,
2778- _i18n('Remove and delete'), None,
2779- _i18n('Remove the selected file/dir and delete from disk'),
2780- self.remove_and_delete_file),
2781- ('rename', None,
2782- _i18n('Rename'), None,
2783- _i18n('Rename the selected file'),
2784- self.rename_file),
2785- ('open', gtk.STOCK_OPEN,
2786- _i18n('Open'), None,
2787- _i18n('Open the selected file'),
2788- self.open_file),
2789- ('revert', None,
2790- _i18n('Revert'), None,
2791- _i18n('Revert the changes'),
2792- self.revert),
2793- ('commit', None,
2794- _i18n('Commit'), None,
2795- _i18n('Commit the changes'),
2796- self.commit),
2797- ('annotate', None,
2798- _i18n('Annotate'), None,
2799- _i18n('Annotate the selected file'),
2800- self.annotate),
2801- ('diff', None,
2802- _i18n('Diff'), None,
2803- _i18n('Show the diff of the file'),
2804- self.diff),
2805- ('bookmark', None,
2806- _i18n('Bookmark'), None,
2807- _i18n('Bookmark current location'),
2808- self.bookmark),
2809- ('edit_bookmark', gtk.STOCK_EDIT,
2810- _i18n('Edit'), None,
2811- _i18n('Edit the selected bookmark'),
2812- self.edit_bookmark),
2813- ('remove_bookmark', gtk.STOCK_REMOVE,
2814- _i18n('Remove'), None,
2815- _i18n('Remove the selected bookmark'),
2816- self.remove_bookmark),
2817- ('open_folder', gtk.STOCK_OPEN,
2818- _i18n('Open Folder'), None,
2819- _i18n('Open bookmark folder in Nautilus'),
2820- self.open_folder),
2821- ('diff_selected', None,
2822- _i18n('Selected...'), None,
2823- _i18n('Show the differences of the selected file'),
2824- self.diff_selected),
2825- ('diff_all', None,
2826- _i18n('All...'), None,
2827- _i18n('Show the differences of all files'),
2828- self.diff_all),
2829- ('view_remote', None,
2830- _i18n('View contents'), None,
2831- _i18n('View the contents of the file in a builtin viewer'),
2832- self.view_remote),
2833- ('diff_remote', None,
2834- _i18n('Show differences'), None,
2835- _i18n('Show the differences between two revisions of the file'),
2836- self.diff_remote),
2837- ('revert_remote', None,
2838- _i18n('Revert to this revision'), None,
2839- _i18n('Revert the selected file to the selected revision'),
2840- self.revert_remote)
2841- ])
2842-
2843- self.ui.insert_action_group(self.actiongroup, 0)
2844- self.ui.add_ui_from_file(self.uifile)
2845-
2846- self.cmenu_right = self.ui.get_widget('/context_right')
2847- self.cmenu_left = self.ui.get_widget('/context_left')
2848- self.toolbar_diff = self.ui.get_widget('/toolbar_diff')
2849- self.cmenu_remote = self.ui.get_widget('/context_remote')
2850-
2851- # Set icons
2852- # TODO: do it without using deprecated comm
2853- #commit_menu = self.ui.get_widget('/context_right/commit')
2854- #commit_image = self.comm.menuitem_branch_commit.get_image()
2855- #commit_pixbuf = commit_image.get_pixbuf()
2856- #commit_icon = gtk.Image()
2857- #commit_icon.set_from_pixbuf(commit_pixbuf)
2858- #commit_menu.set_image(commit_icon)
2859- #diff_menu = self.ui.get_widget('/context_right/diff')
2860- #diff_image = self.comm.menuitem_stats_diff.get_image()
2861- #diff_pixbuf = diff_image.get_pixbuf()
2862- #diff_icon = gtk.Image()
2863- #diff_icon.set_from_pixbuf(diff_pixbuf)
2864- #diff_menu.set_image(diff_icon)
2865-
2866- def right_context_menu(self):
2867- return self.cmenu_right
2868-
2869- def left_context_menu(self):
2870- return self.cmenu_left
2871-
2872- def remote_context_menu(self):
2873- return self.cmenu_remote
2874-
2875- @show_bzr_error
2876- def add_file(self, action):
2877- """ Right context menu -> Add """
2878- import bzrlib.add
2879-
2880- # Add only the selected file
2881- directory = self.path
2882- filename = self.selected
2883-
2884- if filename is None:
2885- error_dialog(_i18n('No file was selected'),
2886- _i18n('Please select a file from the list,\nor choose the other option.'))
2887- return
2888-
2889- wt, path = WorkingTree.open_containing(os.path.join(directory, filename))
2890- wt.add([path])
2891-
2892- self.app.refresh_right()
2893-
2894- @show_bzr_error
2895- def annotate(self, action):
2896- """ Right context menu -> Annotate """
2897- directory = self.path
2898- filename = self.selected
2899-
2900- if filename is None:
2901- error_dialog(_i18n('No file was selected'),
2902- _i18n('Please select a file from the list.'))
2903- return
2904-
2905- wt, path = WorkingTree.open_containing(os.path.join(directory, filename))
2906-
2907- branch = wt.branch
2908- file_id = wt.path2id(wt.relpath(os.path.join(directory, filename)))
2909- if file_id is None:
2910- raise errors.NotVersionedError(filename)
2911- window = GAnnotateWindow(all=False, plain=False, parent=self.app)
2912- window.set_title(os.path.join(directory, filename) + " - Annotate")
2913- config = GAnnotateConfig(window)
2914- window.show()
2915- branch.lock_read()
2916- try:
2917- window.annotate(wt, branch, file_id)
2918- finally:
2919- branch.unlock()
2920-
2921- @show_bzr_error
2922- def remove_file(self, action, delete_on_disk=False):
2923- """ Right context menu -> Remove """
2924- # Remove only the selected file
2925- directory = self.path
2926- filename = self.selected
2927-
2928- if filename is None:
2929- error_dialog(_i18n('No file was selected'),
2930- _i18n('Please select a file from the list,\nor choose the other option.'))
2931- return
2932-
2933- wt, path = WorkingTree.open_containing(os.path.join(directory, filename))
2934- wt.remove(path)
2935-
2936- if delete_on_disk:
2937- abs_filename = os.path.join(directory,filename)
2938- if os.path.isdir(abs_filename):
2939- response = question_dialog(_i18n('Delete directory with all directories below ?'), abs_filename )
2940- if response == gtk.RESPONSE_YES:
2941- shutil.rmtree(abs_filename)
2942- else:
2943- os.remove(abs_filename)
2944-
2945- self.app.set_path(self.path)
2946- self.app.refresh_right()
2947-
2948- def remove_and_delete_file(self, action):
2949- """ Right context menu -> Remove and delete"""
2950- self.remove_file(action, delete_on_disk=True)
2951-
2952- def rename_file(self, action):
2953- """ Right context menu -> Rename """
2954- from bzrlib.plugins.gtk.olive.rename import RenameDialog
2955- wt = WorkingTree.open_containing(os.path.join(self.path, self.selected))[0]
2956- rename = RenameDialog(wt, wt.relpath(self.path), self.selected)
2957- response = rename.run()
2958- rename.destroy()
2959- if response == gtk.RESPONSE_OK:
2960- self.app.refresh_right()
2961-
2962- def open_file(self, action):
2963- """ Right context menu -> Open """
2964- # Open only the selected file
2965- filename = self.selected
2966-
2967- if filename is None:
2968- error_dialog(_i18n('No file was selected'),
2969- _i18n('Please select a file from the list,\nor choose the other option.'))
2970- return
2971-
2972- if filename == '..':
2973- # TODO: how to enter a directory?
2974- return
2975- else:
2976- fullpath = os.path.join(self.path, filename)
2977- launch.launch(fullpath)
2978-
2979- def revert(self, action):
2980- """ Right context menu -> Revert """
2981- wt, path = WorkingTree.open_containing(self.path)
2982- ret = wt.revert([os.path.join(path, self.selected)])
2983- if ret:
2984- warning_dialog(_i18n('Conflicts detected'),
2985- _i18n('Please have a look at the working tree before continuing.'))
2986- else:
2987- info_dialog(_i18n('Revert successful'),
2988- _i18n('Selected file reverted to last revision.'))
2989- self.app.refresh_right()
2990-
2991- def commit(self, action):
2992- """ Right context menu -> Commit """
2993- from bzrlib.plugins.gtk.commit import CommitDialog
2994- branch = None
2995- try:
2996- wt, path = WorkingTree.open_containing(self.path)
2997- branch = wt.branch
2998- except NotBranchError, e:
2999- path = e.path
3000-
3001- if self.selected:
3002- selected = os.path.join(path, self.selected)
3003- else:
3004- selected = None
3005- commit = CommitDialog(wt=wt, selected=selected, parent=None)
3006- response = commit.run()
3007- if response != gtk.RESPONSE_NONE:
3008- commit.hide()
3009-
3010- if response == gtk.RESPONSE_OK:
3011- self.app.refresh_right()
3012-
3013- commit.destroy()
3014-
3015- @show_bzr_error
3016- def diff(self, action):
3017- """ Right context menu -> Diff """
3018- wt = WorkingTree.open_containing(self.path)[0]
3019- window = DiffWindow(self.app)
3020- parent_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
3021- window.set_diff(wt.branch._get_nick(local=True), wt, parent_tree)
3022- window.set_file(wt.relpath(self.path + os.sep + self.selected))
3023- window.show()
3024-
3025- def bookmark(self, action):
3026- """ Right context menu -> Bookmark """
3027- if self.pref.add_bookmark(self.path):
3028- info_dialog(_i18n('Bookmark successfully added'),
3029- _i18n('The current directory was bookmarked. You can reach\nit by selecting it from the left panel.'))
3030- self.pref.write()
3031- else:
3032- warning_dialog(_i18n('Location already bookmarked'),
3033- _i18n('The current directory is already bookmarked.\nSee the left panel for reference.'))
3034-
3035- self.app.refresh_left()
3036-
3037- def edit_bookmark(self, action):
3038- """ Left context menu -> Edit """
3039- from bookmark import BookmarkDialog
3040-
3041- if self.selected != None:
3042- bookmark = BookmarkDialog(self.selected, self.app.window)
3043- response = bookmark.run()
3044-
3045- if response != gtk.RESPONSE_NONE:
3046- bookmark.hide()
3047-
3048- if response == gtk.RESPONSE_OK:
3049- self.app.refresh_left()
3050-
3051- bookmark.destroy()
3052-
3053- def remove_bookmark(self, action):
3054- """ Left context menu -> Remove """
3055-
3056- if self.selected != None:
3057- self.pref.remove_bookmark(self.selected)
3058- self.pref.write()
3059-
3060- self.app.refresh_left()
3061-
3062- def open_folder(self, action):
3063- """ Left context menu -> Open Folder """
3064- path = self.selected
3065-
3066- if path != None:
3067- launch.launch(path)
3068-
3069- def diff_selected(self, action):
3070- """ Diff toolbutton -> Selected... """
3071- print "DEBUG: not implemented."
3072-
3073- def diff_all(self, action):
3074- """ Diff toolbutton -> All... """
3075- wt = WorkingTree.open_containing(self.path)[0]
3076- window = DiffWindow(self.app)
3077- parent_tree = wt.branch.repository.revision_tree(wt.branch.last_revision())
3078- window.set_diff(wt.branch._get_nick(local=True), wt, parent_tree)
3079- window.show()
3080-
3081- def view_remote(self, action):
3082- """ Remote context menu -> View contents """
3083- print "DEBUG: view contents."
3084-
3085- def diff_remote(self, action):
3086- """ Remote context menu -> Show differences """
3087- print "DEBUG: show differences."
3088-
3089- def revert_remote(self, action):
3090- """ Remote context menu -> Revert to this revision """
3091- print "DEBUG: revert to this revision."
3092
3093=== removed file 'olive/mkdir.py'
3094--- olive/mkdir.py 2008-07-17 21:10:05 +0000
3095+++ olive/mkdir.py 1970-01-01 00:00:00 +0000
3096@@ -1,92 +0,0 @@
3097-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
3098-#
3099-# This program is free software; you can redistribute it and/or modify
3100-# it under the terms of the GNU General Public License as published by
3101-# the Free Software Foundation; either version 2 of the License, or
3102-# (at your option) any later version.
3103-#
3104-# This program is distributed in the hope that it will be useful,
3105-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3106-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3107-# GNU General Public License for more details.
3108-#
3109-# You should have received a copy of the GNU General Public License
3110-# along with this program; if not, write to the Free Software
3111-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3112-
3113-import os
3114-
3115-try:
3116- import pygtk
3117- pygtk.require("2.0")
3118-except:
3119- pass
3120-
3121-import gtk
3122-
3123-import bzrlib.errors as errors
3124-
3125-from bzrlib.plugins.gtk import _i18n
3126-from bzrlib.plugins.gtk.dialog import error_dialog, warning_dialog
3127-from bzrlib.plugins.gtk.errors import show_bzr_error
3128-
3129-
3130-class MkdirDialog(gtk.Dialog):
3131- """ Display the Make directory dialog and perform the needed actions. """
3132-
3133- def __init__(self, wt, wtpath, parent=None):
3134- """ Initialize the Make directory dialog. """
3135- gtk.Dialog.__init__(self, title="Olive - Make directory",
3136- parent=parent,
3137- flags=0,
3138- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
3139-
3140- # Get arguments
3141- self.wt = wt
3142- self.wtpath = wtpath
3143-
3144- # Create widgets
3145- self._hbox = gtk.HBox()
3146- self._label_directory_name = gtk.Label(_i18n("Directory name"))
3147- self._entry = gtk.Entry()
3148- self._versioned = gtk.CheckButton(_i18n("_Versioned directory"), use_underline=True)
3149- self._button_mkdir = gtk.Button(_i18n("_Make directory"), use_underline=True)
3150- self._button_mkdir_icon = gtk.Image()
3151- self._button_mkdir_icon.set_from_stock(gtk.STOCK_ADD, gtk.ICON_SIZE_BUTTON)
3152- self._button_mkdir.set_image(self._button_mkdir_icon)
3153-
3154- self._entry.connect('activate', self._on_mkdir_clicked)
3155- self._button_mkdir.connect('clicked', self._on_mkdir_clicked)
3156-
3157- # Add widgets to dialog
3158- self.vbox.add(self._hbox)
3159- self._hbox.add(self._label_directory_name)
3160- self._hbox.add(self._entry)
3161- self._hbox.set_spacing(5)
3162- self.vbox.add(self._versioned)
3163- self.action_area.pack_end(self._button_mkdir)
3164-
3165- self.vbox.show_all()
3166-
3167- @show_bzr_error
3168- def _on_mkdir_clicked(self, widget):
3169- dirname = self._entry.get_text()
3170-
3171- if dirname == "":
3172- error_dialog(_i18n('No directory name given'),
3173- _i18n('Please specify a desired name for the new directory.'))
3174- return
3175-
3176- try:
3177- os.mkdir(os.path.join(self.wt.basedir, self.wtpath, dirname))
3178-
3179- if self._versioned.get_active():
3180- self.wt.add([os.path.join(self.wtpath, dirname)])
3181- except OSError, e:
3182- if e.errno == 17:
3183- error_dialog(_i18n('Directory already exists'),
3184- _i18n('Please specify another name to continue.'))
3185- else:
3186- raise
3187-
3188- self.response(gtk.RESPONSE_OK)
3189
3190=== removed file 'olive/move.py'
3191--- olive/move.py 2008-07-17 21:16:27 +0000
3192+++ olive/move.py 1970-01-01 00:00:00 +0000
3193@@ -1,115 +0,0 @@
3194-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
3195-#
3196-# This program is free software; you can redistribute it and/or modify
3197-# it under the terms of the GNU General Public License as published by
3198-# the Free Software Foundation; either version 2 of the License, or
3199-# (at your option) any later version.
3200-#
3201-# This program is distributed in the hope that it will be useful,
3202-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3203-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3204-# GNU General Public License for more details.
3205-#
3206-# You should have received a copy of the GNU General Public License
3207-# along with this program; if not, write to the Free Software
3208-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3209-
3210-import os
3211-
3212-try:
3213- import pygtk
3214- pygtk.require("2.0")
3215-except:
3216- pass
3217-
3218-import gtk
3219-
3220-import bzrlib.errors as errors
3221-from bzrlib.workingtree import WorkingTree
3222-
3223-from bzrlib.plugins.gtk import _i18n
3224-from bzrlib.plugins.gtk.dialog import error_dialog
3225-from bzrlib.plugins.gtk.errors import show_bzr_error
3226-
3227-
3228-class MoveDialog(gtk.Dialog):
3229- """ Display the Move dialog and perform the needed actions. """
3230-
3231- def __init__(self, wt, wtpath, selected, parent=None):
3232- """ Initialize the Move dialog. """
3233- gtk.Dialog.__init__(self, title="Olive - Move",
3234- parent=parent,
3235- flags=0,
3236- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
3237-
3238- # Get arguments
3239- self.wt = wt
3240- self.wtpath = wtpath
3241- self.selected = selected
3242-
3243- if self.selected is None:
3244- self.selected = ""
3245-
3246- if self.wtpath == "":
3247- directory = os.path.dirname(self.wt.abspath(self.selected))
3248- else:
3249- directory = os.path.dirname(self.wt.abspath(self.wtpath + os.sep + self.selected))
3250-
3251- # Create widgets
3252- self._hbox = gtk.HBox()
3253- self._label_move_to = gtk.Label(_i18n("Move to"))
3254- self._filechooser_dialog = gtk.FileChooserDialog(title="Please select a folder",
3255- parent=self.window,
3256- action=gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER,
3257- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
3258- gtk.STOCK_OPEN, gtk.RESPONSE_OK))
3259- self._filechooser_dialog.set_default_response(gtk.RESPONSE_OK)
3260- self.filechooser = gtk.FileChooserButton(self._filechooser_dialog)
3261- self._button_move = gtk.Button(_i18n("_Move"))
3262- self._button_move_icon = gtk.Image()
3263- self._button_move_icon.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
3264- self._button_move.set_image(self._button_move_icon)
3265-
3266- self._button_move.connect('clicked', self._on_move_clicked)
3267-
3268- # Set location
3269- self._filechooser_dialog.set_current_folder(directory)
3270-
3271- # Add widgets to dialog
3272- self.vbox.add(self._hbox)
3273- self._hbox.add(self._label_move_to)
3274- self._hbox.add(self.filechooser)
3275- self._hbox.set_spacing(5)
3276- self.action_area.pack_end(self._button_move)
3277-
3278- self.vbox.show_all()
3279-
3280- @show_bzr_error
3281- def _on_move_clicked(self, widget):
3282- destination = self.filechooser.get_filename()
3283-
3284- if destination == None:
3285- error_dialog(_i18n('No folder was selected'),
3286- _i18n('Please select a folder to move the selected file to'))
3287- return
3288-
3289- filename = self.selected
3290-
3291- if filename is None:
3292- error_dialog(_i18n('No file was selected'),
3293- _i18n('Please select a file from the list to proceed.'))
3294- return
3295-
3296- source = os.path.join(self.wtpath, filename)
3297-
3298- # Move the file to a directory
3299- wt1, path1 = WorkingTree.open_containing(self.wt.abspath(source))
3300- wt2, path2 = WorkingTree.open_containing(destination)
3301- if wt1.basedir != wt2.basedir:
3302- error_dialog(_i18n('Not the same branch'),
3303- _i18n('The destination is not in the same branch.'))
3304- return
3305-
3306- wt1.move([source], wt1.relpath(destination))
3307-
3308- self.response(gtk.RESPONSE_OK)
3309
3310=== removed file 'olive/remove.py'
3311--- olive/remove.py 2008-07-17 21:24:16 +0000
3312+++ olive/remove.py 1970-01-01 00:00:00 +0000
3313@@ -1,88 +0,0 @@
3314-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
3315-#
3316-# This program is free software; you can redistribute it and/or modify
3317-# it under the terms of the GNU General Public License as published by
3318-# the Free Software Foundation; either version 2 of the License, or
3319-# (at your option) any later version.
3320-#
3321-# This program is distributed in the hope that it will be useful,
3322-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3323-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3324-# GNU General Public License for more details.
3325-#
3326-# You should have received a copy of the GNU General Public License
3327-# along with this program; if not, write to the Free Software
3328-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3329-
3330-import os
3331-
3332-try:
3333- import pygtk
3334- pygtk.require("2.0")
3335-except:
3336- pass
3337-
3338-import gtk
3339-
3340-import bzrlib.errors as errors
3341-
3342-from bzrlib.plugins.gtk import _i18n
3343-from bzrlib.plugins.gtk.dialog import error_dialog, warning_dialog
3344-from bzrlib.plugins.gtk.errors import show_bzr_error
3345-
3346-
3347-class RemoveDialog(gtk.Dialog):
3348- """ This class wraps the old Remove window into a gtk.Dialog. """
3349-
3350- def __init__(self, wt, wtpath, selected='', parent=None):
3351- """ Initialize the Remove file(s) dialog. """
3352- gtk.Dialog.__init__(self, title="Olive - Remove files",
3353- parent=parent,
3354- flags=0,
3355- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
3356-
3357- # Get arguments
3358- self.wt = wt
3359- self.wtpath = wtpath
3360- self.selected = selected
3361-
3362- # Create widgets
3363- self._label = gtk.Label(_i18n("Which file(s) do you want to remove?"))
3364- self._radio_selected = gtk.RadioButton(None, _i18n("Selected: %s"%self.selected), False)
3365- self._radio_added = gtk.RadioButton(self._radio_selected, _i18n("All files with status 'added'"), False)
3366- self._button_remove = gtk.Button(stock=gtk.STOCK_REMOVE)
3367-
3368- self._button_remove.connect('clicked', self._on_remove_clicked)
3369-
3370- self.vbox.add(self._label)
3371- self.vbox.add(self._radio_selected)
3372- self.vbox.add(self._radio_added)
3373- self.vbox.set_spacing(3)
3374- self.action_area.pack_end(self._button_remove)
3375-
3376- self.vbox.show_all()
3377-
3378- @show_bzr_error
3379- def _on_remove_clicked(self, button):
3380- """ Remove button clicked handler. """
3381- if self._radio_selected.get_active():
3382- # Remove only the selected file
3383- filename = self.selected
3384-
3385- if filename is None:
3386- error_dialog(_i18n('No file was selected'),
3387- _i18n('Please select a file from the list,\nor choose the other option.'))
3388- return
3389-
3390- self.wt.remove(os.path.join(self.wtpath, filename))
3391- elif self._radio_added.get_active():
3392- # Remove added files recursively
3393- added = self.wt.changes_from(self.wt.basis_tree()).added
3394- file_list = sorted([f[0] for f in added], reverse=True)
3395- if len(file_list) == 0:
3396- warning_dialog(_i18n('No matching files'),
3397- _i18n('No added files were found in the working tree.'))
3398- return
3399- self.wt.remove(file_list)
3400-
3401- self.response(gtk.RESPONSE_OK)
3402
3403=== removed file 'olive/rename.py'
3404--- olive/rename.py 2008-07-18 10:39:25 +0000
3405+++ olive/rename.py 1970-01-01 00:00:00 +0000
3406@@ -1,104 +0,0 @@
3407-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
3408-#
3409-# This program is free software; you can redistribute it and/or modify
3410-# it under the terms of the GNU General Public License as published by
3411-# the Free Software Foundation; either version 2 of the License, or
3412-# (at your option) any later version.
3413-#
3414-# This program is distributed in the hope that it will be useful,
3415-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3416-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3417-# GNU General Public License for more details.
3418-#
3419-# You should have received a copy of the GNU General Public License
3420-# along with this program; if not, write to the Free Software
3421-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3422-
3423-import os
3424-
3425-try:
3426- import pygtk
3427- pygtk.require("2.0")
3428-except:
3429- pass
3430-
3431-import gtk
3432-
3433-import bzrlib.errors as errors
3434-from bzrlib.workingtree import WorkingTree
3435-
3436-from bzrlib.plugins.gtk import _i18n
3437-from bzrlib.plugins.gtk.dialog import error_dialog
3438-from bzrlib.plugins.gtk.errors import show_bzr_error
3439-
3440-
3441-class RenameDialog(gtk.Dialog):
3442- """ Display the Rename dialog and perform the needed actions. """
3443-
3444- def __init__(self, wt, wtpath, selected=None, parent=None):
3445- """ Initialize the Rename file dialog. """
3446- gtk.Dialog.__init__(self, title="Olive - Rename files",
3447- parent=parent,
3448- flags=0,
3449- buttons=(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL))
3450-
3451- # Get arguments
3452- self.wt = wt
3453- self.wtpath = wtpath
3454- self.selected = selected
3455-
3456- # Create widgets
3457- self._hbox = gtk.HBox()
3458- self._label_rename_to = gtk.Label(_i18n("Rename to"))
3459- self._entry = gtk.Entry()
3460- self._button_rename = gtk.Button(_i18n("_Rename"))
3461- self._button_rename_icon = gtk.Image()
3462- self._button_rename_icon.set_from_stock(gtk.STOCK_APPLY, gtk.ICON_SIZE_BUTTON)
3463- self._button_rename.set_image(self._button_rename_icon)
3464-
3465- self._entry.connect('activate', self._on_rename_clicked)
3466- self._button_rename.connect('clicked', self._on_rename_clicked)
3467-
3468- # Set text
3469- if self.selected is not None:
3470- self._entry.set_text(self.selected)
3471-
3472- # Add widgets to dialog
3473- self.vbox.add(self._hbox)
3474- self._hbox.add(self._label_rename_to)
3475- self._hbox.add(self._entry)
3476- self._hbox.set_spacing(5)
3477- self.action_area.pack_end(self._button_rename)
3478-
3479- self.vbox.show_all()
3480-
3481- @show_bzr_error
3482- def _on_rename_clicked(self, widget):
3483- # Get entry
3484- old_filename = self.selected
3485- new_filename = self._entry.get_text()
3486-
3487- if old_filename is None:
3488- error_dialog(_i18n('No file was selected'),
3489- _i18n('Please select a file from the list to proceed.'))
3490- return
3491-
3492- if new_filename == "":
3493- error_dialog(_i18n('Filename not given'),
3494- _i18n('Please specify a new name for the file.'))
3495- return
3496-
3497- source = os.path.join(self.wtpath, old_filename)
3498- destination = os.path.join(self.wtpath, new_filename)
3499-
3500- # Rename the file
3501- wt1, path1 = WorkingTree.open_containing(self.wt.abspath(source))
3502- wt2, path2 = WorkingTree.open_containing(self.wt.abspath(source))
3503-
3504- if wt1.basedir != wt2.basedir:
3505- error_dialog(_i18n('Not the same branch'),
3506- _i18n('The destination is not in the same branch.'))
3507- return
3508- wt1.rename_one(source, destination)
3509-
3510- self.response(gtk.RESPONSE_OK)
3511
3512=== removed file 'olive/window.py'
3513--- olive/window.py 2009-12-23 05:17:26 +0000
3514+++ olive/window.py 1970-01-01 00:00:00 +0000
3515@@ -1,575 +0,0 @@
3516-# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
3517-# Some parts of the code are:
3518-# Copyright (C) 2005, 2006 by Canonical Ltd
3519-#
3520-# This program is free software; you can redistribute it and/or modify
3521-# it under the terms of the GNU General Public License as published by
3522-# the Free Software Foundation; either version 2 of the License, or
3523-# (at your option) any later version.
3524-#
3525-# This program is distributed in the hope that it will be useful,
3526-# but WITHOUT ANY WARRANTY; without even the implied warranty of
3527-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3528-# GNU General Public License for more details.
3529-#
3530-# You should have received a copy of the GNU General Public License
3531-# along with this program; if not, write to the Free Software
3532-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
3533-
3534-import os
3535-import sys
3536-import gtk
3537-import gobject
3538-
3539-from bzrlib.plugins.gtk import _i18n, icon_path
3540-
3541-
3542-class OliveGui(gtk.Window):
3543- """ Olive main window """
3544-
3545- def __init__(self, calling_app):
3546- # Pointer to calling instance for signal connection
3547- self.signal = calling_app
3548-
3549- # Initialise window
3550- gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL)
3551- self.set_title(_i18n("Olive - Bazaar GUI"))
3552- self.set_icon_list(gtk.gdk.pixbuf_new_from_file(icon_path("oliveicon2.png")),
3553- gtk.gdk.pixbuf_new_from_file(icon_path("olive-gtk.png")),
3554- # Who has the svg version of the icon? Would be nice to include
3555- #gtk.gdk.pixbuf_new_from_file(icon_path("olive.svg"))
3556- )
3557- self.set_property("width-request", 700)
3558- self.set_property("height-request", 400)
3559-
3560- self.connect("destroy", self.destroy)
3561- self.connect("delete_event", self.signal.on_window_main_delete_event)
3562-
3563- # Accelerator group to Quit program
3564- accelgroup = gtk.AccelGroup()
3565- self.add_accel_group(accelgroup)
3566- self.quit_action = gtk.Action(_i18n("Quit"), None, None, gtk.STOCK_QUIT)
3567- self.quit_action.connect('activate', self.signal.on_window_main_delete_event)
3568- actiongroup = gtk.ActionGroup('QuitAction')
3569- actiongroup.add_action_with_accel(self.quit_action, None)
3570- self.quit_action.set_accel_group(accelgroup)
3571- self.quit_action.connect_accelerator()
3572-
3573- # High level build up of window
3574- self.vbox = gtk.VBox(False, 0)
3575- self.add(self.vbox)
3576-
3577- # Menu bar
3578- self._create_menubar()
3579- self.vbox.pack_start(self.mb, False, False, 0)
3580-
3581- # Toolbar
3582- self._create_toolbar()
3583- self.vbox.pack_start(self.tb, False, False, 0)
3584-
3585- # Locationbar
3586- self._create_locationbar()
3587- self.vbox.pack_start(self.locationbar, False, False, 0)
3588-
3589- # Main area
3590- self.hpaned_main = gtk.HPaned()
3591- self._create_bookmarklist()
3592- self.hpaned_main.add(self.scrolledwindow_left)
3593- self._create_filelist()
3594- self.hpaned_main.add(self.scrolledwindow_right)
3595- self.vbox.pack_start(self.hpaned_main, True, True, 0)
3596-
3597- # Statusbar
3598- self.statusbar = gtk.Statusbar()
3599- self.vbox.pack_end(self.statusbar, False, False, 0)
3600-
3601- def show(self):
3602- self.show_all()
3603-
3604- def destroy(self, widget=None, data=None):
3605- """ Ends the program """
3606- gtk.main_quit()
3607-
3608- def _create_menubar(self):
3609- self.mb = gtk.MenuBar()
3610-
3611- # File menu
3612- self.mb_file = gtk.MenuItem(_i18n("_File"))
3613- self.mb_file_menu = gtk.Menu()
3614-
3615- self.mb_file_add = gtk.ImageMenuItem(gtk.STOCK_ADD, _i18n("_Add file(s)"))
3616- self.mb_file_add.connect('activate', self.signal.on_menuitem_add_files_activate)
3617- self.mb_file_menu.append(self.mb_file_add)
3618-
3619- self.mb_file_remove = gtk.ImageMenuItem(gtk.STOCK_REMOVE, _i18n("_Remove file(s)"))
3620- self.mb_file_remove.connect('activate', self.signal.on_menuitem_remove_file_activate)
3621- self.mb_file_menu.append(self.mb_file_remove)
3622-
3623- self.mb_file_menu.append(gtk.SeparatorMenuItem())
3624-
3625- self.mb_file_bookmark = gtk.MenuItem(_i18n("_Bookmark current directory"))
3626- self.mb_file_bookmark.connect('activate', self.signal.on_menuitem_file_bookmark_activate)
3627- self.mb_file_menu.append(self.mb_file_bookmark)
3628-
3629- self.mb_file_mkdir = gtk.MenuItem(_i18n("_Make directory"))
3630- self.mb_file_mkdir.connect('activate', self.signal.on_menuitem_file_make_directory_activate)
3631- self.mb_file_menu.append(self.mb_file_mkdir)
3632-
3633- self.mb_file_menu.append(gtk.SeparatorMenuItem())
3634-
3635- self.mb_file_rename = gtk.MenuItem(_i18n("_Rename"))
3636- self.mb_file_rename.connect('activate', self.signal.on_menuitem_file_rename_activate)
3637- self.mb_file_menu.append(self.mb_file_rename)
3638-
3639- self.mb_file_move = gtk.MenuItem(_i18n("_Move"))
3640- self.mb_file_move.connect('activate', self.signal.on_menuitem_file_move_activate)
3641- self.mb_file_menu.append(self.mb_file_move)
3642-
3643- self.mb_file_annotate = gtk.MenuItem(_i18n("_Annotate"))
3644- self.mb_file_annotate.connect('activate', self.signal.on_menuitem_file_annotate_activate)
3645- self.mb_file_menu.append(self.mb_file_annotate)
3646-
3647- self.mb_file_menu.append(gtk.SeparatorMenuItem())
3648-
3649- self.mb_file_quit = self.quit_action.create_menu_item()
3650- self.mb_file_menu.append(self.mb_file_quit)
3651-
3652- self.mb_file.set_submenu(self.mb_file_menu)
3653- self.mb.append(self.mb_file)
3654-
3655- # View menu
3656- self.mb_view = gtk.MenuItem(_i18n("_View"))
3657- self.mb_view_menu = gtk.Menu()
3658-
3659- self.mb_view_showhidden = gtk.CheckMenuItem(_i18n("Show _hidden files"))
3660- self.mb_view_showhidden.connect('activate', self.signal.on_menuitem_view_show_hidden_files_activate)
3661- self.mb_view_menu.append(self.mb_view_showhidden)
3662-
3663- self.mb_view_showignored = gtk.CheckMenuItem(_i18n("Show _ignored files"))
3664- self.mb_view_showignored.connect('activate', self.signal.on_menuitem_view_show_ignored_files_activate)
3665- self.mb_view_menu.append(self.mb_view_showignored)
3666-
3667- self.mb_view_menu.append(gtk.SeparatorMenuItem())
3668-
3669- self.mb_view_refresh = gtk.ImageMenuItem(gtk.STOCK_REFRESH, _i18n("_Refresh"))
3670- self.mb_view_refresh.connect('activate', self.signal.on_menuitem_view_refresh_activate)
3671- self.mb_view_menu.append(self.mb_view_refresh)
3672-
3673- self.mb_view.set_submenu(self.mb_view_menu)
3674- self.mb.append(self.mb_view)
3675-
3676- # Branch menu
3677- self.mb_branch = gtk.MenuItem(_i18n("_Branch"))
3678- self.mb_branch_menu = gtk.Menu()
3679-
3680- self.mb_branch_initialize = gtk.MenuItem(_i18n("_Initialize"))
3681- self.mb_branch_initialize.connect('activate', self.signal.on_menuitem_branch_initialize_activate)
3682- self.mb_branch_menu.append(self.mb_branch_initialize)
3683-
3684- self.mb_branch_get = gtk.MenuItem(_i18n("_Get"))
3685- self.mb_branch_get.connect('activate', self.signal.on_menuitem_branch_get_activate)
3686- self.mb_branch_menu.append(self.mb_branch_get)
3687-
3688- self.mb_branch_checkout = gtk.MenuItem(_i18n("C_heckout"))
3689- self.mb_branch_checkout.connect('activate', self.signal.on_menuitem_branch_checkout_activate)
3690- self.mb_branch_menu.append(self.mb_branch_checkout)
3691-
3692- self.mb_branch_menu.append(gtk.SeparatorMenuItem())
3693-
3694- self.mb_branch_pull = gtk.ImageMenuItem(_i18n("Pu_ll"))
3695- pullimage = gtk.Image()
3696- pullimage.set_from_file(icon_path("pull16.png"))
3697- self.mb_branch_pull.set_image(pullimage)
3698- self.mb_branch_pull.connect('activate', self.signal.on_menuitem_branch_pull_activate)
3699- self.mb_branch_menu.append(self.mb_branch_pull)
3700-
3701- self.mb_branch_push = gtk.ImageMenuItem(_i18n("Pu_sh"))
3702- pushimage = gtk.Image()
3703- pushimage.set_from_file(icon_path("push16.png"))
3704- self.mb_branch_push.set_image(pushimage)
3705- self.mb_branch_push.connect('activate', self.signal.on_menuitem_branch_push_activate)
3706- self.mb_branch_menu.append(self.mb_branch_push)
3707-
3708- self.mb_branch_update = gtk.MenuItem(_i18n("_Update"))
3709- self.mb_branch_update.connect('activate', self.signal.on_menuitem_branch_update_activate)
3710- self.mb_branch_menu.append(self.mb_branch_update)
3711-
3712- self.mb_branch_menu.append(gtk.SeparatorMenuItem())
3713-
3714- self.mb_branch_revert = gtk.ImageMenuItem(_i18n("_Revert all changes"))
3715- revertimage = gtk.Image()
3716- revertimage.set_from_stock(gtk.STOCK_REVERT_TO_SAVED, gtk.ICON_SIZE_MENU)
3717- self.mb_branch_revert.set_image(revertimage)
3718- self.mb_branch_revert.connect('activate', self.signal.on_menuitem_branch_revert_activate)
3719- self.mb_branch_menu.append(self.mb_branch_revert)
3720-
3721- self.mb_branch_merge = gtk.MenuItem(_i18n("_Merge"))
3722- self.mb_branch_merge.connect('activate', self.signal.on_menuitem_branch_merge_activate)
3723- self.mb_branch_menu.append(self.mb_branch_merge)
3724-
3725- self.mb_branch_commit = gtk.ImageMenuItem(_i18n("_Commit"))
3726- commitimage = gtk.Image()
3727- commitimage.set_from_file(icon_path("commit16.png"))
3728- self.mb_branch_commit.set_image(commitimage)
3729- self.mb_branch_commit.connect('activate', self.signal.on_menuitem_branch_commit_activate)
3730- self.mb_branch_menu.append(self.mb_branch_commit)
3731-
3732- self.mb_branch_menu.append(gtk.SeparatorMenuItem())
3733-
3734- self.mb_branch_tags = gtk.ImageMenuItem(_i18n("Ta_gs"))
3735- tagsimage = gtk.Image()
3736- tagsimage.set_from_file(icon_path("tag-16.png"))
3737- self.mb_branch_tags.set_image(tagsimage)
3738- self.mb_branch_tags.connect('activate', self.signal.on_menuitem_branch_tags_activate)
3739- self.mb_branch_menu.append(self.mb_branch_tags)
3740-
3741- self.mb_branch_status = gtk.MenuItem(_i18n("S_tatus"))
3742- self.mb_branch_status.connect('activate', self.signal.on_menuitem_branch_status_activate)
3743- self.mb_branch_menu.append(self.mb_branch_status)
3744-
3745- self.mb_branch_missingrevisions = gtk.MenuItem(_i18n("Missing _revisions"))
3746- self.mb_branch_missingrevisions.connect('activate', self.signal.on_menuitem_branch_missing_revisions_activate)
3747- self.mb_branch_menu.append(self.mb_branch_missingrevisions)
3748-
3749- self.mb_branch_conflicts = gtk.MenuItem(_i18n("Con_flicts"))
3750- self.mb_branch_conflicts.connect('activate', self.signal.on_menuitem_branch_conflicts_activate)
3751- self.mb_branch_menu.append(self.mb_branch_conflicts)
3752-
3753- self.mb_branch.set_submenu(self.mb_branch_menu)
3754- self.mb.append(self.mb_branch)
3755-
3756- # Statistics menu
3757- self.mb_statistics = gtk.MenuItem(_i18n("_Statistics"))
3758- self.mb_statistics_menu = gtk.Menu()
3759-
3760- self.mb_statistics_differences = gtk.ImageMenuItem(_i18n("_Differences"))
3761- diffimage = gtk.Image()
3762- diffimage.set_from_file(icon_path("diff16.png"))
3763- self.mb_statistics_differences.set_image(diffimage)
3764- self.mb_statistics_differences.connect('activate', self.signal.on_menuitem_stats_diff_activate)
3765- self.mb_statistics_menu.append(self.mb_statistics_differences)
3766-
3767- self.mb_statistics_log = gtk.ImageMenuItem(_i18n("_Log"))
3768- logimage = gtk.Image()
3769- logimage.set_from_file(icon_path("log16.png"))
3770- self.mb_statistics_log.set_image(logimage)
3771- self.mb_statistics_log.connect('activate', self.signal.on_menuitem_stats_log_activate)
3772- self.mb_statistics_menu.append(self.mb_statistics_log)
3773-
3774- self.mb_statistics_information = gtk.MenuItem(_i18n("_Information"))
3775- self.mb_statistics_information.connect('activate', self.signal.on_menuitem_stats_infos_activate)
3776- self.mb_statistics_menu.append(self.mb_statistics_information)
3777-
3778- self.mb_statistics.set_submenu(self.mb_statistics_menu)
3779- self.mb.append(self.mb_statistics)
3780-
3781- # Help menu
3782- self.mb_help = gtk.MenuItem(_i18n("Help"))
3783- self.mb_help_menu = gtk.Menu()
3784-
3785- self.mb_help_about = gtk.ImageMenuItem(gtk.STOCK_ABOUT)
3786- self.mb_help_about.connect('activate', self.signal.on_about_activate)
3787- self.mb_help_menu.append(self.mb_help_about)
3788-
3789- self.mb_help.set_submenu(self.mb_help_menu)
3790- self.mb.append(self.mb_help)
3791-
3792- def _create_toolbar(self):
3793- self.tb = gtk.Toolbar()
3794-
3795- self.tb_refresh_icon = gtk.Image()
3796- self.tb_refresh_icon.set_from_file(icon_path("refresh.png"))
3797- self.tb_refresh = gtk.ToolButton(self.tb_refresh_icon, _i18n("Refresh"))
3798- self.tb_refresh.connect('clicked', self.signal.on_menuitem_view_refresh_activate)
3799- self.tb_refresh.set_tooltip_text(_i18n("Refresh the file list"))
3800- self.tb_refresh.set_is_important(True)
3801- self.tb.add(self.tb_refresh)
3802-
3803- self.tb_diff_icon = gtk.Image()
3804- self.tb_diff_icon.set_from_file(icon_path("diff.png"))
3805- self.tb_diff = gtk.ToolButton(self.tb_diff_icon, _i18n("Diff"))
3806- self.tb_diff.connect('clicked', self.signal.on_menuitem_stats_diff_activate)
3807- self.tb_diff.set_tooltip_text(_i18n("View changes since last commit"))
3808- self.tb.add(self.tb_diff)
3809-
3810- self.tb_log_icon = gtk.Image()
3811- self.tb_log_icon.set_from_file(icon_path("log.png"))
3812- self.tb_log = gtk.ToolButton(self.tb_log_icon, _i18n("Log"))
3813- self.tb_log.connect('clicked', self.signal.on_menuitem_stats_log_activate)
3814- self.tb_log.set_tooltip_text(_i18n("View the revision history"))
3815- self.tb.add(self.tb_log)
3816-
3817- self.tb.add(gtk.SeparatorToolItem())
3818-
3819- self.tb_commit_icon = gtk.Image()
3820- self.tb_commit_icon.set_from_file(icon_path("commit.png"))
3821- self.tb_commit = gtk.ToolButton(self.tb_commit_icon, _i18n("Commit"))
3822- self.tb_commit.connect('clicked', self.signal.on_menuitem_branch_commit_activate)
3823- self.tb_commit.set_tooltip_text(_i18n("Commit changes to the current branch"))
3824- self.tb_commit.set_is_important(True)
3825- self.tb.add(self.tb_commit)
3826-
3827- self.tb.add(gtk.SeparatorToolItem())
3828-
3829- self.tb_pull_icon = gtk.Image()
3830- self.tb_pull_icon.set_from_file(icon_path("pull.png"))
3831- self.tb_pull = gtk.ToolButton(self.tb_pull_icon, _i18n("Pull"))
3832- self.tb_pull.connect('clicked', self.signal.on_menuitem_branch_pull_activate)
3833- self.tb_pull.set_tooltip_text(_i18n("Pull changes from the parent branch"))
3834- self.tb.add(self.tb_pull)
3835-
3836- self.tb_push_icon = gtk.Image()
3837- self.tb_push_icon.set_from_file(icon_path("push.png"))
3838- self.tb_push = gtk.ToolButton(self.tb_push_icon, _i18n("Push"))
3839- self.tb_push.connect('clicked', self.signal.on_menuitem_branch_push_activate)
3840- self.tb_push.set_tooltip_text(_i18n("Push the branch to a remote location"))
3841- self.tb.add(self.tb_push)
3842-
3843- self.tb_update_icon = gtk.Image()
3844- self.tb_update_icon.set_from_file(icon_path("pull.png"))
3845- self.tb_update = gtk.ToolButton(self.tb_update_icon, _i18n("Update"))
3846- self.tb_update.connect('clicked', self.signal.on_menuitem_branch_update_activate)
3847- self.tb_update.set_tooltip_text(_i18n("Update the working tree"))
3848- self.tb.add(self.tb_update)
3849-
3850- def _create_locationbar(self):
3851- """ Creates the location bar, including the history widgets """
3852- self.locationbar = gtk.HBox()
3853-
3854- self.button_location_up = gtk.Button()
3855- self.button_location_up.set_relief(gtk.RELIEF_NONE)
3856- image_location_up = gtk.Image()
3857- image_location_up.set_from_stock(gtk.STOCK_GO_UP, gtk.ICON_SIZE_BUTTON)
3858- self.button_location_up.add(image_location_up)
3859- self.button_location_up.connect("clicked", self.signal.on_button_location_up_clicked)
3860- self.locationbar.pack_start(self.button_location_up, False, False, 0)
3861-
3862- self.entry_location = gtk.Entry()
3863- self.entry_location.connect("activate", self.signal.on_button_location_jump_clicked)
3864- self.locationbar.pack_start(self.entry_location, True, True, 0)
3865-
3866- self.location_status = gtk.Image()
3867- self.location_status.set_from_stock(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_BUTTON)
3868- self.locationbar.pack_start(self.location_status, False, False, 0)
3869-
3870- self.button_location_jump = gtk.Button(stock=gtk.STOCK_JUMP_TO)
3871- self.button_location_jump.set_relief(gtk.RELIEF_NONE)
3872- self.button_location_jump.connect("clicked", self.signal.on_button_location_jump_clicked)
3873- self.locationbar.pack_start(self.button_location_jump, False, False, 0)
3874-
3875- self.locationbar.pack_start(gtk.VSeparator(), False, False, 0)
3876-
3877- self.checkbutton_history = gtk.CheckButton(_i18n("H_istory Mode"))
3878- self.checkbutton_history.connect("toggled", self.signal.on_checkbutton_history_toggled)
3879- self.locationbar.pack_start(self.checkbutton_history, False, False, 0)
3880-
3881- self.entry_history_revno = gtk.Entry()
3882- self.entry_history_revno.set_property("width-request", 75)
3883- self.entry_history_revno.set_sensitive(False)
3884- self.entry_history_revno.connect("activate", self.signal.on_entry_history_revno_activate)
3885- self.locationbar.pack_start(self.entry_history_revno, False, False, 0)
3886-
3887- self.button_history_browse = gtk.Button()
3888- self.button_history_browse.set_sensitive(False)
3889- self.image_history_browse = gtk.Image()
3890- self.image_history_browse.set_from_stock(gtk.STOCK_OPEN, gtk.ICON_SIZE_BUTTON)
3891- self.button_history_browse.add(self.image_history_browse)
3892- self.button_history_browse.connect("clicked", self.signal.on_button_history_browse_clicked)
3893- self.locationbar.pack_start(self.button_history_browse, False, False, 0)
3894-
3895- def _create_bookmarklist(self):
3896- """ Creates the bookmark list (a ListStore in a TreeView in a ScrolledWindow)"""
3897- self.scrolledwindow_left = gtk.ScrolledWindow()
3898- self.scrolledwindow_left.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
3899-
3900- self.treeview_left = gtk.TreeView()
3901- self.treeview_left.connect("button-press-event", self.signal.on_treeview_left_button_press_event)
3902- self.treeview_left.connect("row-activated", self.signal.on_treeview_left_row_activated)
3903- self.scrolledwindow_left.add(self.treeview_left)
3904-
3905- self.bookmarklist = gtk.ListStore(gobject.TYPE_STRING,
3906- gobject.TYPE_STRING,
3907- gobject.TYPE_STRING)
3908- self.treeview_left.set_model(self.bookmarklist)
3909-
3910- icon = gtk.CellRendererPixbuf()
3911- cell = gtk.CellRendererText()
3912-
3913- col_bookmark = gtk.TreeViewColumn(_i18n('Bookmarks'))
3914- col_bookmark.pack_start(icon, False)
3915- col_bookmark.pack_start(cell, False)
3916- col_bookmark.set_attributes(icon, stock_id=2)
3917- col_bookmark.add_attribute(cell, 'text', 0)
3918- self.treeview_left.append_column(col_bookmark)
3919-
3920- def _create_filelist(self):
3921- """ Creates the file list (a ListStore in a TreeView in a ScrolledWindow)"""
3922- self.scrolledwindow_right = gtk.ScrolledWindow()
3923- self.scrolledwindow_right.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
3924-
3925- self.treeview_right = gtk.TreeView()
3926- self.treeview_right.connect("button-press-event", self.signal.on_treeview_right_button_press_event)
3927- self.treeview_right.connect("row-activated", self.signal.on_treeview_right_row_activated)
3928- self.scrolledwindow_right.add(self.treeview_right)
3929-
3930- # Model: [ icon, dir, name, status text, status, size (int), size (human), mtime (int), mtime (local), fileid ]
3931- self.filelist = gtk.ListStore(gobject.TYPE_STRING,
3932- gobject.TYPE_BOOLEAN,
3933- gobject.TYPE_STRING,
3934- gobject.TYPE_STRING,
3935- gobject.TYPE_STRING,
3936- gobject.TYPE_STRING,
3937- gobject.TYPE_STRING,
3938- gobject.TYPE_INT,
3939- gobject.TYPE_STRING,
3940- gobject.TYPE_STRING)
3941- self.treeview_right.set_model(self.filelist)
3942-
3943- # Set up the cells
3944- cellpb = gtk.CellRendererPixbuf()
3945- cell = gtk.CellRendererText()
3946- # For columns that get a different text color based on status (4)
3947- cellstatus = gtk.CellRendererText()
3948-
3949- self.col_filename = gtk.TreeViewColumn(_i18n('Filename'))
3950- self.col_filename.pack_start(cellpb, False)
3951- self.col_filename.pack_start(cell, True)
3952- self.col_filename.set_attributes(cellpb, stock_id=0)
3953- self.col_filename.add_attribute(cell, 'text', 2)
3954- self.col_filename.set_resizable(True)
3955- self.treeview_right.append_column(self.col_filename)
3956-
3957- self.col_status = gtk.TreeViewColumn(_i18n('Status'))
3958- self.col_status.pack_start(cellstatus, True)
3959- self.col_status.add_attribute(cellstatus, 'text', 3)
3960- self.col_status.set_cell_data_func(cellstatus, self._map_status_color)
3961- self.col_status.set_resizable(True)
3962- self.treeview_right.append_column(self.col_status)
3963-
3964- self.col_size = gtk.TreeViewColumn(_i18n('Size'))
3965- self.col_size.pack_start(cell, True)
3966- self.col_size.add_attribute(cell, 'text', 6)
3967- self.col_size.set_resizable(True)
3968- self.treeview_right.append_column(self.col_size)
3969-
3970- self.col_mtime = gtk.TreeViewColumn(_i18n('Last modified'))
3971- self.col_mtime.pack_start(cell, True)
3972- self.col_mtime.add_attribute(cell, 'text', 8)
3973- self.col_mtime.set_resizable(True)
3974- self.treeview_right.append_column(self.col_mtime)
3975-
3976- # Set up the properties of the TreeView
3977- self.treeview_right.set_headers_visible(True)
3978- self.treeview_right.set_headers_clickable(True)
3979- self.treeview_right.set_search_column(1)
3980-
3981- # Set up sorting
3982- self.filelist.set_sort_func(13, self.signal._sort_filelist_callback, None)
3983- self.filelist.set_sort_column_id(13, gtk.SORT_ASCENDING)
3984- self.col_filename.set_sort_column_id(13)
3985- self.col_status.set_sort_column_id(3)
3986- self.col_size.set_sort_column_id(5)
3987- self.col_mtime.set_sort_column_id(7)
3988-
3989- def _map_status_color(self, column, cell, model, iter):
3990- status = model.get_value(iter, 4)
3991- if status == 'unchanged':
3992- colorstatus = gtk.gdk.color_parse('black')
3993- weight = 400 # standard value
3994- elif status == 'removed':
3995- colorstatus = gtk.gdk.color_parse('red')
3996- weight = 800
3997- elif status == 'added':
3998- colorstatus = gtk.gdk.color_parse('green')
3999- weight = 800
4000- elif status == 'modified':
4001- colorstatus = gtk.gdk.color_parse("#FD00D3")
4002- weight = 800
4003- elif status == 'renamed':
4004- colorstatus = gtk.gdk.color_parse('blue')
4005- weight = 800
4006- elif status == 'ignored':
4007- colorstatus = gtk.gdk.color_parse('grey')
4008- weight = 600
4009- else: # status == unknown
4010- colorstatus = gtk.gdk.color_parse('orange')
4011- weight = 800
4012- cell.set_property('foreground-gdk', colorstatus)
4013- cell.set_property('weight', weight)
4014-
4015- def set_view_to_localbranch(self, notbranch=False):
4016- """ Change the sensitivity of gui items to reflect the fact that the path is a branch or not"""
4017- self.mb_branch_initialize.set_sensitive(notbranch)
4018- self.mb_branch_get.set_sensitive(notbranch)
4019- self.mb_branch_checkout.set_sensitive(notbranch)
4020- self.mb_branch_pull.set_sensitive(not notbranch)
4021- self.mb_branch_push.set_sensitive(not notbranch)
4022- self.mb_branch_update.set_sensitive(not notbranch)
4023- self.mb_branch_revert.set_sensitive(not notbranch)
4024- self.mb_branch_merge.set_sensitive(not notbranch)
4025- self.mb_branch_commit.set_sensitive(not notbranch)
4026- self.mb_branch_tags.set_sensitive(not notbranch)
4027- self.mb_branch_status.set_sensitive(not notbranch)
4028- self.mb_branch_missingrevisions.set_sensitive(not notbranch)
4029- self.mb_branch_conflicts.set_sensitive(not notbranch)
4030- self.mb_statistics.set_sensitive(not notbranch)
4031- self.mb_statistics_differences.set_sensitive(not notbranch)
4032- self.mb_file_add.set_sensitive(not notbranch)
4033- self.mb_file_remove.set_sensitive(not notbranch)
4034- self.mb_file_mkdir.set_sensitive(not notbranch)
4035- self.mb_file_rename.set_sensitive(not notbranch)
4036- self.mb_file_move.set_sensitive(not notbranch)
4037- self.mb_file_annotate.set_sensitive(not notbranch)
4038- self.tb_diff.set_sensitive(not notbranch)
4039- self.tb_log.set_sensitive(not notbranch)
4040- self.tb_commit.set_sensitive(not notbranch)
4041- self.tb_pull.set_sensitive(not notbranch)
4042- self.tb_push.set_sensitive(not notbranch)
4043- self.tb_update.set_sensitive(not notbranch)
4044-
4045- def set_view_to_remotebranch(self):
4046- """ Change the sensitivity of gui items to reflect the fact that the branch is remote"""
4047- self.mb_file_add.set_sensitive(False)
4048- self.mb_file_remove.set_sensitive(False)
4049- self.mb_file_mkdir.set_sensitive(False)
4050- self.mb_file_rename.set_sensitive(False)
4051- self.mb_file_move.set_sensitive(False)
4052- self.mb_file_annotate.set_sensitive(False)
4053- self.mb_branch_initialize.set_sensitive(False)
4054- self.mb_branch_get.set_sensitive(True)
4055- self.mb_branch_checkout.set_sensitive(True)
4056- self.mb_branch_pull.set_sensitive(False)
4057- self.mb_branch_push.set_sensitive(False)
4058- self.mb_branch_update.set_sensitive(False)
4059- self.mb_branch_revert.set_sensitive(False)
4060- self.mb_branch_merge.set_sensitive(False)
4061- self.mb_branch_commit.set_sensitive(False)
4062- self.mb_branch_tags.set_sensitive(True)
4063- self.mb_branch_status.set_sensitive(False)
4064- self.mb_branch_missingrevisions.set_sensitive(False)
4065- self.mb_branch_conflicts.set_sensitive(False)
4066- self.mb_statistics.set_sensitive(True)
4067- self.mb_statistics_differences.set_sensitive(False)
4068- self.tb_diff.set_sensitive(False)
4069- self.tb_log.set_sensitive(True)
4070- self.tb_commit.set_sensitive(False)
4071- self.tb_pull.set_sensitive(False)
4072- self.tb_push.set_sensitive(False)
4073- self.tb_update.set_sensitive(False)
4074-
4075- def set_location_status(self, stock_id, allowPopup=False):
4076- self.location_status.destroy()
4077- if allowPopup:
4078- self.location_status = gtk.Button()
4079- self.location_status.set_relief(gtk.RELIEF_NONE)
4080- image = gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_BUTTON)
4081- image.show()
4082- self.location_status.add(image)
4083- else:
4084- self.location_status = gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_BUTTON)
4085- self.locationbar.pack_start(self.location_status, False, False, 0)
4086- if sys.platform == 'win32':
4087- self.locationbar.reorder_child(self.location_status, 2)
4088- else:
4089- self.locationbar.reorder_child(self.location_status, 1)
4090- self.location_status.show()
4091
4092=== modified file 'setup.py'
4093--- setup.py 2010-03-01 08:48:46 +0000
4094+++ setup.py 2010-05-29 23:49:22 +0000
4095@@ -5,9 +5,6 @@
4096 from distutils.core import setup, Command
4097 from distutils.command.install_data import install_data
4098 from distutils.command.build import build
4099-from distutils.dep_util import newer
4100-from distutils.log import info
4101-import glob
4102 import os
4103 import sys
4104
4105@@ -83,7 +80,6 @@
4106
4107 def run(self):
4108 import subprocess
4109- self.data_files.extend(self._compile_po_files())
4110 self.data_files.extend(self._nautilus_plugin())
4111 install_data.run(self)
4112
4113@@ -93,36 +89,6 @@
4114 except OSError:
4115 pass
4116
4117- def _compile_po_files(self):
4118- data_files = []
4119-
4120- # Don't install language files on Win32
4121- if sys.platform == 'win32':
4122- return data_files
4123-
4124- PO_DIR = 'po'
4125- for po in glob.glob(os.path.join(PO_DIR,'*.po')):
4126- lang = os.path.basename(po[:-3])
4127- # It's necessary to compile in this directory (not in po_dir)
4128- # because install_data can't rename file
4129- mo = os.path.join('build', 'mo', lang, 'olive-gtk.mo')
4130-
4131- directory = os.path.dirname(mo)
4132- if not os.path.exists(directory):
4133- info('creating %s' % directory)
4134- os.makedirs(directory)
4135- if newer(po, mo):
4136- # True if mo doesn't exist
4137- cmd = 'msgfmt -o %s %s' % (mo, po)
4138- info('compiling %s -> %s' % (po, mo))
4139- if os.system(cmd) != 0:
4140- raise SystemExit('Error while running msgfmt')
4141- dest = os.path.dirname(
4142- os.path.join('share', 'locale', lang,
4143- 'LC_MESSAGES', 'olive-gtk.mo'))
4144- data_files.append((dest, [mo]))
4145- return data_files
4146-
4147 def _nautilus_plugin(self):
4148 files = []
4149 if sys.platform[:5] == 'linux':
4150@@ -144,13 +110,12 @@
4151 maintainer_email = "jelmer@samba.org",
4152 description = "GTK+ Frontends for various Bazaar commands",
4153 license = "GNU GPL v2 or later",
4154- scripts = ['olive-gtk', 'bzr-handle-patch', 'bzr-notify'],
4155+ scripts = ['bzr-handle-patch', 'bzr-notify'],
4156 url = "http://bazaar-vcs.org/BzrGtk",
4157 package_dir = {
4158 "bzrlib.plugins.gtk": ".",
4159 "bzrlib.plugins.gtk.viz": "viz",
4160 "bzrlib.plugins.gtk.annotate": "annotate",
4161- "bzrlib.plugins.gtk.olive": "olive",
4162 "bzrlib.plugins.gtk.tests": "tests",
4163 "bzrlib.plugins.gtk.branchview": "branchview",
4164 "bzrlib.plugins.gtk.preferences": "preferences",
4165@@ -159,14 +124,11 @@
4166 "bzrlib.plugins.gtk",
4167 "bzrlib.plugins.gtk.viz",
4168 "bzrlib.plugins.gtk.annotate",
4169- "bzrlib.plugins.gtk.olive",
4170 "bzrlib.plugins.gtk.tests",
4171 "bzrlib.plugins.gtk.branchview",
4172 "bzrlib.plugins.gtk.preferences",
4173 ],
4174- data_files=[('share/olive', ['cmenu.ui',
4175- ]),
4176- ('share/bzr-gtk', ['credits.pickle']),
4177+ data_files=[ ('share/bzr-gtk', ['credits.pickle']),
4178 ('share/bzr-gtk/icons', ['icons/commit.png',
4179 'icons/commit16.png',
4180 'icons/diff.png',
4181@@ -178,8 +140,6 @@
4182 'icons/push.png',
4183 'icons/push16.png',
4184 'icons/refresh.png',
4185- 'icons/olive-gtk.png',
4186- 'icons/oliveicon2.png',
4187 'icons/sign-bad.png',
4188 'icons/sign-ok.png',
4189 'icons/sign.png',
4190@@ -187,13 +147,11 @@
4191 'icons/tag-16.png',
4192 'icons/bug.png',
4193 'icons/bzr-icon-64.png']),
4194- ('share/applications', ['olive-gtk.desktop',
4195- 'bazaar-properties.desktop',
4196+ ('share/applications', ['bazaar-properties.desktop',
4197 'bzr-handle-patch.desktop',
4198 'bzr-notify.desktop']),
4199 ('share/application-registry', ['bzr-gtk.applications']),
4200- ('share/pixmaps', ['icons/olive-gtk.png',
4201- 'icons/bzr-icon-64.png']),
4202+ ('share/pixmaps', ['icons/bzr-icon-64.png']),
4203 ('share/icons/hicolor/scalable/emblems',
4204 ['icons/emblem-bzr-added.svg',
4205 'icons/emblem-bzr-conflict.svg',
4206
4207=== modified file 'tests/__init__.py'
4208--- tests/__init__.py 2009-05-07 09:54:50 +0000
4209+++ tests/__init__.py 2010-05-29 23:49:22 +0000
4210@@ -23,7 +23,6 @@
4211 'test_diff',
4212 'test_history',
4213 'test_linegraph',
4214- 'test_preferences',
4215 'test_revisionview',
4216 ]
4217
4218
4219=== removed file 'tests/test_preferences.py'
4220--- tests/test_preferences.py 2007-03-15 16:23:15 +0000
4221+++ tests/test_preferences.py 1970-01-01 00:00:00 +0000
4222@@ -1,91 +0,0 @@
4223-# Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
4224-#
4225-# This program is free software; you can redistribute it and/or modify
4226-# it under the terms of the GNU General Public License as published by
4227-# the Free Software Foundation; either version 2 of the License, or
4228-# (at your option) any later version.
4229-#
4230-# This program is distributed in the hope that it will be useful,
4231-# but WITHOUT ANY WARRANTY; without even the implied warranty of
4232-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4233-# GNU General Public License for more details.
4234-#
4235-# You should have received a copy of the GNU General Public License
4236-# along with this program; if not, write to the Free Software
4237-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
4238-
4239-from bzrlib.tests import TestCase, TestCaseInTempDir
4240-from bzrlib.plugins.gtk.olive import Preferences
4241-
4242-import os
4243-
4244-# FIXME: need to make sure that this also tests writing/reading.
4245-class TestPreferences(TestCaseInTempDir):
4246- def setUp(self):
4247- super(TestPreferences, self).setUp()
4248- self.prefs = Preferences(os.path.join(self.test_dir, 'prefs'))
4249-
4250- def test_create(self):
4251- Preferences()
4252-
4253- def test_add_bookmark(self):
4254- """make sure a bookmark can be added. This function is only supposed
4255- to store the location, not try to access it. """
4256- self.assertTrue(self.prefs.add_bookmark("file://foobar"))
4257- self.assertTrue("file://foobar" in self.prefs.get_bookmarks())
4258-
4259- def test_add_bookmark_twice(self):
4260- """Adding an already present bookmark will result in False being
4261- returned."""
4262- self.assertTrue(self.prefs.add_bookmark("file://foobar"))
4263- self.assertFalse(self.prefs.add_bookmark("file://foobar"))
4264-
4265- def test_set_bookmark_title(self):
4266- """Test setting a title for an existing bookmark."""
4267- self.prefs.add_bookmark("file://foobar")
4268- self.prefs.set_bookmark_title("file://foobar", "My Bookmark")
4269-
4270- def test_remove_bookmark(self):
4271- """Test removing a bookmark."""
4272- self.prefs.add_bookmark("http://example.com/branch")
4273- self.prefs.remove_bookmark("http://example.com/branch")
4274- self.assertFalse("http://example.com/branch" in self.prefs.get_bookmarks())
4275-
4276- def test_get_bookmarks_empty(self):
4277- """Test whether a new Preferences() object has an empty bookmarks
4278- list."""
4279- self.assertEqual([], self.prefs.get_bookmarks())
4280-
4281- def test_get_bookmark_title_set(self):
4282- """Test getting a title for an existing bookmark."""
4283- self.prefs.add_bookmark("file://foobar")
4284- self.prefs.set_bookmark_title("file://foobar", "My Bookmark")
4285- self.assertEqual("My Bookmark", self.prefs.get_bookmark_title("file://foobar"))
4286-
4287- def test_get_bookmark_title_implicit(self):
4288- """Test getting a bookmark title for a bookmark that doesn't
4289- have a title set."""
4290- self.prefs.add_bookmark("file://bla")
4291- self.assertEqual("file://bla", self.prefs.get_bookmark_title("file://bla"))
4292-
4293- def test_set_preference(self):
4294- """Check whether setting preferences works."""
4295- self.prefs.set_preference("foo", True)
4296- self.prefs.set_preference("foo", False)
4297- self.prefs.set_preference("foo", "bloe")
4298-
4299- def test_get_preference_bool(self):
4300- """Check whether a preference can be retrieved."""
4301- self.prefs.set_preference("foo", True)
4302- self.assertEqual(True, self.prefs.get_preference("foo", "bool"))
4303-
4304- def test_get_preference_str(self):
4305- """Check whether a string preference can be retrieved."""
4306- self.prefs.set_preference("bla", "bloe")
4307- self.assertEqual("bloe", self.prefs.get_preference("bla"))
4308-
4309- def test_get_preference_nonexistant(self):
4310- """Check whether get_preference returns None for nonexisting
4311- options."""
4312- self.assertEqual(None, self.prefs.get_preference("foo"))
4313-

Subscribers

People subscribed via source and target branches

to all changes: