/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import os
18
import sys
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
19
import time
531.2.2 by Jasper Groenewegen
Replace fix by solution suggested by Scott Scriven
20
import errno
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
21
89 by Jelmer Vernooij
Rename OliveBranch -> BranchDialog.
22
# gettext support
23
import gettext
24
gettext.install('olive-gtk')
25
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
26
try:
27
    import pygtk
28
    pygtk.require("2.0")
29
except:
30
    pass
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
31
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
32
import gobject
0.13.11 by Jelmer Vernooij
Bunch of small fixes, cleanups and simplifications.
33
import gtk
34
import gtk.gdk
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
35
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
36
from bzrlib.branch import Branch
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
37
import bzrlib.errors as bzrerrors
157.1.6 by Aaron Bentley
Defer importing branchwin to avoid cairo import errors
38
from bzrlib.lazy_import import lazy_import
195.1.10 by Szilveszter Farkas (Phanatic)
Showing progress of loading remote branch.
39
from bzrlib.ui import ui_factory
0.13.13 by Jelmer Vernooij
Update TODO
40
from bzrlib.workingtree import WorkingTree
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
41
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
42
from bzrlib.plugins.gtk import _i18n
151 by Jelmer Vernooij
Move dialog to top-level directory.
43
from bzrlib.plugins.gtk.dialog import error_dialog, info_dialog, warning_dialog
44
from bzrlib.plugins.gtk.errors import show_bzr_error
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
45
from bzrlib.plugins.gtk.olive.window import OliveGui
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
46
151 by Jelmer Vernooij
Move dialog to top-level directory.
47
from bzrlib.plugins.gtk.diff import DiffWindow
157.1.6 by Aaron Bentley
Defer importing branchwin to avoid cairo import errors
48
lazy_import(globals(), """
49
from bzrlib.plugins.gtk.viz import branchwin
50
""")
149 by Jelmer Vernooij
Move diff to top-level directory as well.
51
from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
52
from bzrlib.plugins.gtk.annotate.config import GAnnotateConfig
53
from bzrlib.plugins.gtk.commit import CommitDialog
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
54
from bzrlib.plugins.gtk.conflicts import ConflictsDialog
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
55
from bzrlib.plugins.gtk.initialize import InitDialog
149 by Jelmer Vernooij
Move diff to top-level directory as well.
56
from bzrlib.plugins.gtk.push import PushDialog
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
57
from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
58
218 by Jelmer Vernooij
Move olive about dialog into olive.
59
def about():
60
    """ Display the AboutDialog. """
533.3.1 by Jasper Groenewegen
Replace about dialog with gtk.Dialog version
61
    from bzrlib.plugins.gtk import __version__, icon_path
62
    
63
    dialog = gtk.AboutDialog()
64
    dialog.set_name("Olive")
218 by Jelmer Vernooij
Move olive about dialog into olive.
65
    dialog.set_version(__version__)
597.2.1 by Jelmer Vernooij
Fix Olive homepage URL.
66
    dialog.set_copyright("Copyright (C) 2006-2008 Szilveszter Farkas (Phanatic)")
67
    dialog.set_website("https://launchpad.net/bzr-gtk")
68
    dialog.set_website_label("https://launchpad.net/bzr-gtk")
69
    dialog.set_icon_from_file(icon_path("oliveicon2.png"))
70
    dialog.set_logo(gtk.gdk.pixbuf_new_from_file(icon_path("oliveicon2.png")))
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
71
    dialog.set_authors([ _i18n("Lead Developer:"),
423.1.16 by Daniel Schierbeck
Reverted change to Olive's credits list.
72
			 "Szilveszter Farkas <szilveszter.farkas@gmail.com>",
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
73
			 _i18n("Contributors:"),
423.1.16 by Daniel Schierbeck
Reverted change to Olive's credits list.
74
			 "Jelmer Vernooij <jelmer@samba.org>",
75
			 "Mateusz Korniak <mateusz.korniak@ant.gliwice.pl>",
76
			 "Gary van der Merwe <garyvdm@gmail.com>" ])
205.1.5 by Szilveszter Farkas (Phanatic)
Added proper Credits.
77
    dialog.set_artists([ "Simon Pascal Klein <klepas@klepas.org>",
423.1.16 by Daniel Schierbeck
Reverted change to Olive's credits list.
78
			 "Jakub Steiner <jimmac@novell.com>" ])
218 by Jelmer Vernooij
Move olive about dialog into olive.
79
80
    dialog.run()
81
    # Destroy the dialog
82
    dialog.destroy()
83
597.2.1 by Jelmer Vernooij
Fix Olive homepage URL.
84
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
85
class OliveGtk:
86
    """ The main Olive GTK frontend class. This is called when launching the
87
    program. """
88
    
89
    def __init__(self):
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
90
        self.window = OliveGui(calling_app = self)
91
        
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
92
        self.pref = Preferences()
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
93
        self.path = None
0.13.13 by Jelmer Vernooij
Update TODO
94
95
        # Initialize the statusbar
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
96
        self.context_id = self.window.statusbar.get_context_id('olive')
97
        
0.13.13 by Jelmer Vernooij
Update TODO
98
        # Get the drive selector
99
        self.combobox_drive = gtk.combo_box_new_text()
100
        self.combobox_drive.connect("changed", self._refresh_drives)
101
        
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
102
        # Get the navigation widgets
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
103
        self.hbox_location = self.window.locationbar
104
        self.button_location_up = self.window.button_location_up
105
        self.button_location_jump = self.window.button_location_jump
106
        self.entry_location = self.window.entry_location
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
107
        
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
108
        # Get the History widgets
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
109
        self.check_history = self.window.checkbutton_history
110
        self.entry_history = self.window.entry_history_revno
111
        self.button_history = self.window.button_history_browse
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
112
        
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
113
        self._just_started = True
114
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
115
        # Apply window size and position
116
        width = self.pref.get_preference('window_width', 'int')
117
        height = self.pref.get_preference('window_height', 'int')
118
        self.window.resize(width, height)
119
        x = self.pref.get_preference('window_x', 'int')
120
        y = self.pref.get_preference('window_y', 'int')
121
        self.window.move(x, y)
122
        # Apply paned position
123
        pos = self.pref.get_preference('paned_position', 'int')
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
124
        self.window.hpaned_main.set_position(pos)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
125
        
126
        # Now we can show the window
127
        self.window.show()
128
        
129
        # Show drive selector if under Win32
130
        if sys.platform == 'win32':
195.6.4 by Szilveszter Farkas (Phanatic)
The Windows drive selector was moved to the location bar.
131
            self.hbox_location.pack_start(self.combobox_drive, False, False, 0)
132
            self.hbox_location.reorder_child(self.combobox_drive, 1)
0.13.13 by Jelmer Vernooij
Update TODO
133
            self.combobox_drive.show()
134
            self.gen_hard_selector()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
135
        
560.11.1 by Jasper Groenewegen
Replace Bookmarks tree with list + folder icons
136
        self.refresh_left()
0.13.13 by Jelmer Vernooij
Update TODO
137
138
        # Apply menu state
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
139
        self.window.mb_view_showhidden.set_active(self.pref.get_preference('dotted_files', 'bool'))
140
        self.window.mb_view_showignored.set_active(self.pref.get_preference('ignored_files', 'bool'))
0.13.13 by Jelmer Vernooij
Update TODO
141
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
142
        # We're starting local
143
        self.remote = False
144
        self.remote_branch = None
145
        self.remote_path = None
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
146
        self.remote_revision = None
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
147
        
0.13.13 by Jelmer Vernooij
Update TODO
148
        self.set_path(os.getcwd())
560.10.1 by Jasper Groenewegen
File list changes
149
        self.refresh_right()
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
150
        
151
        self._just_started = False
0.13.13 by Jelmer Vernooij
Update TODO
152
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
153
    def set_path(self, path, force_remote=False):
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
154
        self.window.location_status.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
155
        self.notbranch = False
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
156
        
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
157
        if force_remote:
158
            # Forcing remote mode (reading data from inventory)
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
159
            self.window.set_location_status(gtk.STOCK_DISCONNECT)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
160
            try:
161
                br = Branch.open_containing(path)[0]
162
            except bzrerrors.NotBranchError:
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
163
                self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
164
                self.check_history.set_active(False)
165
                self.check_history.set_sensitive(False)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
166
                return False
167
            except bzrerrors.UnsupportedProtocol:
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
168
                self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
169
                self.check_history.set_active(False)
170
                self.check_history.set_sensitive(False)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
171
                return False
172
            
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
173
            self.window.set_location_status(gtk.STOCK_CONNECT)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
174
            
175
            self.remote = True
176
           
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
177
            # We're remote
178
            self.remote_branch, self.remote_path = Branch.open_containing(path)
179
            
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
180
            if self.remote_revision is None:
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
181
                self.remote_revision = self.remote_branch.last_revision()
182
            
183
            self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
184
            
185
            if len(self.remote_path) == 0:
195.1.14 by Szilveszter Farkas (Phanatic)
Fixed the determination of tree root.
186
                self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
187
            else:
188
                for (name, type) in self.remote_entries:
189
                    if name == self.remote_path:
190
                        self.remote_parent = type.file_id
191
                        break
192
            
193
            if not path.endswith('/'):
194
                path += '/'
195
            
196
            if self.remote_branch.base == path:
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
197
                self.button_location_up.set_sensitive(False)
198
            else:
199
                self.button_location_up.set_sensitive(True)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
200
        else:
201
            if os.path.isdir(path):
202
                self.remote = False
203
                
204
                # We're local
205
                try:
560.10.1 by Jasper Groenewegen
File list changes
206
                    self.wt, self.wtpath = WorkingTree.open_containing(os.path.realpath(path))
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
207
                except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
208
                    self.notbranch = True
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
209
                except bzrerrors.PermissionDenied:
210
                    self.window.set_location_status(gtk.STOCK_DIALOG_WARNING, allowPopup=True)
211
                    self.window.location_status.connect_object('clicked', warning_dialog, 
212
                                       *(_i18n('Branch information unreadable'),
213
                                		_i18n('The current folder is a branch but the .bzr folder is not readable')))
214
                    self.notbranch = True
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
215
                
216
                # If we're in the root, we cannot go up anymore
217
                if sys.platform == 'win32':
218
                    drive, tail = os.path.splitdrive(path)
219
                    if tail in ('', '/', '\\'):
220
                        self.button_location_up.set_sensitive(False)
221
                    else:
222
                        self.button_location_up.set_sensitive(True)
223
                else:
224
                    if self.path == '/':
225
                        self.button_location_up.set_sensitive(False)
226
                    else:
227
                        self.button_location_up.set_sensitive(True)
228
            elif not os.path.isfile(path):
229
                # Doesn't seem to be a file nor a directory, trying to open a
230
                # remote location
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
231
                self.window.set_location_status(gtk.STOCK_DISCONNECT)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
232
                try:
233
                    br = Branch.open_containing(path)[0]
234
                except bzrerrors.NotBranchError:
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
235
                    self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
236
                    self.check_history.set_active(False)
237
                    self.check_history.set_sensitive(False)
238
                    return False
239
                except bzrerrors.UnsupportedProtocol:
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
240
                    self.window.set_location_status(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
241
                    self.check_history.set_active(False)
242
                    self.check_history.set_sensitive(False)
243
                    return False
244
                
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
245
                self.window.set_location_status(gtk.STOCK_CONNECT)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
246
                
247
                self.remote = True
248
               
249
                # We're remote
250
                self.remote_branch, self.remote_path = Branch.open_containing(path)
251
                
252
                if self.remote_revision is None:
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
253
                    self.remote_revision = self.remote_branch.last_revision()
254
                
255
                self.remote_entries = self.remote_branch.repository.get_inventory(self.remote_revision).entries()
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
256
                
257
                if len(self.remote_path) == 0:
258
                    self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
259
                else:
260
                    for (name, type) in self.remote_entries:
261
                        if name == self.remote_path:
262
                            self.remote_parent = type.file_id
263
                            break
264
                
265
                if not path.endswith('/'):
266
                    path += '/'
267
                
268
                if self.remote_branch.base == path:
269
                    self.button_location_up.set_sensitive(False)
270
                else:
271
                    self.button_location_up.set_sensitive(True)
272
        
273
        if self.notbranch:
274
            self.check_history.set_active(False)
275
            self.check_history.set_sensitive(False)
276
        else:
277
            self.check_history.set_sensitive(True)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
278
        
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
279
        self.window.statusbar.push(self.context_id, path)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
280
        self.entry_location.set_text(path)
281
        self.path = path
282
        return True
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
283
0.13.13 by Jelmer Vernooij
Update TODO
284
    def get_path(self):
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
285
        if not self.remote:
286
            return self.path
287
        else:
288
            # Remote mode
289
            if len(self.remote_path) > 0:
290
                return self.remote_branch.base + self.remote_path + '/'
291
            else:
292
                return self.remote_branch.base
0.13.13 by Jelmer Vernooij
Update TODO
293
   
294
    def on_about_activate(self, widget):
295
        about()
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
296
    
297
    def on_button_history_browse_clicked(self, widget):
298
        """ Browse for revision button handler. """
299
        if self.remote:
300
            br = self.remote_branch
301
        else:
302
            br = self.wt.branch
303
            
304
        revb = RevisionBrowser(br, self.window)
305
        response = revb.run()
306
        if response != gtk.RESPONSE_NONE:
307
            revb.hide()
308
        
309
            if response == gtk.RESPONSE_OK:
310
                if revb.selected_revno is not None:
311
                    self.entry_history.set_text(revb.selected_revno)
560.3.1 by Jasper Groenewegen
Change locationbar bits (event signals, handling)
312
                    self.on_entry_history_revno_activate()
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
313
            
314
            revb.destroy()
315
    
316
    def on_button_location_jump_clicked(self, widget):
317
        """ Location Jump button handler. """
318
        location = self.entry_location.get_text()
319
        
320
        if self.set_path(location):
321
            self.refresh_right()
322
    
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
323
    def on_button_location_up_clicked(self, widget):
324
        """ Location Up button handler. """
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
325
        if not self.remote:
326
            # Local mode
327
            self.set_path(os.path.split(self.get_path())[0])
328
        else:
329
            # Remote mode
330
            delim = '/'
331
            newpath = delim.join(self.get_path().split(delim)[:-2])
332
            newpath += '/'
333
            self.set_path(newpath)
334
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
335
        self.refresh_right()
336
    
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
337
    def on_checkbutton_history_toggled(self, widget):
338
        """ History Mode toggle handler. """
339
        if self.check_history.get_active():
340
            # History Mode activated
341
            self.entry_history.set_sensitive(True)
342
            self.button_history.set_sensitive(True)
560.3.1 by Jasper Groenewegen
Change locationbar bits (event signals, handling)
343
            if self.entry_history.get_text() != "":
344
                self.on_entry_history_revno_activate()
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
345
        else:
346
            # History Mode deactivated
347
            self.entry_history.set_sensitive(False)
348
            self.button_history.set_sensitive(False)
504.2.1 by Jasper Groenewegen
Fix for LP144962
349
            
350
            # Return right window to normal view by acting like we jump to it
351
            self.on_button_location_jump_clicked(widget)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
352
    
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
353
    @show_bzr_error
560.3.1 by Jasper Groenewegen
Change locationbar bits (event signals, handling)
354
    def on_entry_history_revno_activate(self, widget=None):
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
355
        """ Key pressed handler for the history entry. """
560.3.1 by Jasper Groenewegen
Change locationbar bits (event signals, handling)
356
        path = self.get_path()
357
        if not self.remote:
358
            self.remote = True
359
            self.remote_branch = self.wt.branch
360
        
361
        revno = int(self.entry_history.get_text())
362
        self.remote_revision = self.remote_branch.get_rev_id(revno)
363
        if self.set_path(path, True):
364
            self.refresh_right()
365
0.13.13 by Jelmer Vernooij
Update TODO
366
    def on_menuitem_add_files_activate(self, widget):
367
        """ Add file(s)... menu handler. """
533.8.1 by Jasper Groenewegen
Replace OliveAdd glade add dialog with AddDialog
368
        from bzrlib.plugins.gtk.olive.add import AddDialog
369
        add = AddDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
370
        response = add.run()
371
        add.destroy()
372
        if response == gtk.RESPONSE_OK:
373
            self.refresh_right()
374
0.13.13 by Jelmer Vernooij
Update TODO
375
    def on_menuitem_branch_get_activate(self, widget):
376
        """ Branch/Get... menu handler. """
154 by Jelmer Vernooij
Add trivial generic class for storing URL history.
377
        from bzrlib.plugins.gtk.branch import BranchDialog
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
378
        
379
        if self.remote:
380
            branch = BranchDialog(os.getcwd(), self.window, self.remote_branch.base)
381
        else:
382
            branch = BranchDialog(self.get_path(), self.window)
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
383
        response = branch.run()
384
        if response != gtk.RESPONSE_NONE:
385
            branch.hide()
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
386
            
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
387
            if response == gtk.RESPONSE_OK:
388
                self.refresh_right()
389
            
390
            branch.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
391
    
392
    def on_menuitem_branch_checkout_activate(self, widget):
393
        """ Branch/Checkout... menu handler. """
154 by Jelmer Vernooij
Add trivial generic class for storing URL history.
394
        from bzrlib.plugins.gtk.checkout import CheckoutDialog
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
395
        
396
        if self.remote:
397
            checkout = CheckoutDialog(os.getcwd(), self.window, self.remote_branch.base)
398
        else:
399
            checkout = CheckoutDialog(self.get_path(), self.window)
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
400
        response = checkout.run()
401
        if response != gtk.RESPONSE_NONE:
402
            checkout.hide()
403
        
404
            if response == gtk.RESPONSE_OK:
405
                self.refresh_right()
406
            
407
            checkout.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
408
    
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
409
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
410
    def on_menuitem_branch_commit_activate(self, widget):
411
        """ Branch/Commit... menu handler. """
278.1.35 by John Arbash Meinel
Make use of the 'selected' parameter to CommitDialog.
412
        selected = self.get_selected_right()
413
        if selected:
414
            selected = os.path.join(self.wtpath, selected)
415
        commit = CommitDialog(wt=self.wt,
416
                              parent=self.window,
417
                              selected=selected,
418
                             )
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
419
        response = commit.run()
420
        if response != gtk.RESPONSE_NONE:
421
            commit.hide()
422
        
423
            if response == gtk.RESPONSE_OK:
424
                self.refresh_right()
425
            
426
            commit.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
427
    
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
428
    def on_menuitem_branch_conflicts_activate(self, widget):
429
        """ Branch/Conflicts... menu handler. """
430
        conflicts = ConflictsDialog(self.wt, self.window)
431
        response = conflicts.run()
432
        if response != gtk.RESPONSE_NONE:
433
            conflicts.destroy()
434
    
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
435
    def on_menuitem_branch_merge_activate(self, widget):
436
        """ Branch/Merge... menu handler. """
533.2.3 by Jasper Groenewegen
MergeDialog: Point to right location again.
437
        from bzrlib.plugins.gtk.merge import MergeDialog
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
438
        
439
        if self.check_for_changes():
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
440
            error_dialog(_i18n('There are local changes in the branch'),
441
                         _i18n('Please commit or revert the changes before merging.'))
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
442
        else:
533.2.4 by Jasper Groenewegen
Fix what is broken
443
            parent_branch_path = self.wt.branch.get_parent()
533.1.1 by Jasper Groenewegen
Replace MergeDialog with glade-less version.
444
            merge = MergeDialog(self.wt, self.wtpath, parent_branch_path, self.window)
445
            response = merge.run()
446
            merge.destroy()
447
            if response == gtk.RESPONSE_OK:
448
                self.refresh_right()
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
449
155 by Jelmer Vernooij
Fix a couple of smaller bugs.
450
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
451
    def on_menuitem_branch_missing_revisions_activate(self, widget):
452
        """ Branch/Missing revisions menu handler. """
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
453
        
454
        from bzrlib.missing import find_unmerged, iter_log_revisions
455
        
0.13.13 by Jelmer Vernooij
Update TODO
456
        local_branch = self.wt.branch
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
457
        parent_branch_path = local_branch.get_parent()
458
        if parent_branch_path is None:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
459
            error_dialog(_i18n('Parent location is unknown'),
460
                         _i18n('Cannot determine missing revisions if no parent location is known.'))
0.13.13 by Jelmer Vernooij
Update TODO
461
            return
462
        
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
463
        parent_branch = Branch.open(parent_branch_path)
464
        
465
        if parent_branch.base == local_branch.base:
466
            parent_branch = local_branch
467
        
468
        local_extra, remote_extra = find_unmerged(local_branch,parent_branch)
469
470
        if local_extra or remote_extra:
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
471
            
472
            ## def log_revision_one_line_text(log_revision):
473
            ##    """ Generates one line description of log_revison ended with end of line."""
474
            ##    revision = log_revision.rev
475
            ##    txt =  "- %s (%s)\n" % (revision.get_summary(), revision.committer, )
476
            ##    txt = txt.replace("<"," ") # Seems < > chars are expected to be xml tags ...
477
            ##    txt = txt.replace(">"," ")
478
            ##    return txt
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
479
            
480
            dlg_txt = ""
481
            if local_extra:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
482
                dlg_txt += _i18n('%d local extra revision(s). \n') % (len(local_extra),) 
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
483
                ## NOTE: We do not want such ugly info about missing revisions
484
                ##       Revision Browser should be used there
485
                ## max_revisions = 10
486
                ## for log_revision in iter_log_revisions(local_extra, local_branch.repository, verbose=1):
487
                ##    dlg_txt += log_revision_one_line_text(log_revision)
488
                ##    if max_revisions <= 0:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
489
                ##        dlg_txt += _i18n("more ... \n")
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
490
                ##        break
491
                ## max_revisions -= 1
492
            ## dlg_txt += "\n"
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
493
            if remote_extra:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
494
                dlg_txt += _i18n('%d local missing revision(s).\n') % (len(remote_extra),) 
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
495
                ## max_revisions = 10
496
                ## for log_revision in iter_log_revisions(remote_extra, parent_branch.repository, verbose=1):
497
                ##    dlg_txt += log_revision_one_line_text(log_revision)
498
                ##    if max_revisions <= 0:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
499
                ##        dlg_txt += _i18n("more ... \n")
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
500
                ##        break
501
                ##    max_revisions -= 1
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
502
                
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
503
            info_dialog(_i18n('There are missing revisions'),
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
504
                        dlg_txt)
0.13.13 by Jelmer Vernooij
Update TODO
505
        else:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
506
            info_dialog(_i18n('Local branch up to date'),
507
                        _i18n('There are no missing revisions.'))
0.13.13 by Jelmer Vernooij
Update TODO
508
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
509
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
510
    def on_menuitem_branch_pull_activate(self, widget):
511
        """ Branch/Pull menu handler. """
512
        branch_to = self.wt.branch
513
514
        location = branch_to.get_parent()
515
        if location is None:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
516
            error_dialog(_i18n('Parent location is unknown'),
517
                                     _i18n('Pulling is not possible until there is a parent location.'))
0.13.13 by Jelmer Vernooij
Update TODO
518
            return
519
132 by Jelmer Vernooij
Use decorator for catching and showing bzr-gtk errors graphically. Eventually, this should go away and should be handled by the ui factory.
520
        branch_from = Branch.open(location)
0.13.13 by Jelmer Vernooij
Update TODO
521
522
        if branch_to.get_parent() is None:
523
            branch_to.set_parent(branch_from.base)
524
0.14.14 by Alexander Belchenko
get number of pulled revision: it's return value of branch.pull() method
525
        ret = branch_to.pull(branch_from)
0.13.13 by Jelmer Vernooij
Update TODO
526
        
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
527
        info_dialog(_i18n('Pull successful'), _i18n('%d revision(s) pulled.') % ret)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
528
        
529
    @show_bzr_error
530
    def on_menuitem_branch_update_activate(self, widget):
592.1.1 by Jasper Groenewegen
Update Olive file list after update
531
        """ Branch/checkout update menu handler. """
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
532
        
533
        ret = self.wt.update()
534
        conflicts = self.wt.conflicts()
535
        if conflicts:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
536
            info_dialog(_i18n('Update successful but conflicts generated'), _i18n('Number of conflicts generated: %d.') % (len(conflicts),) )
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
537
        else:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
538
            info_dialog(_i18n('Update successful'), _i18n('No conflicts generated.') )
592.1.1 by Jasper Groenewegen
Update Olive file list after update
539
        self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
540
    
541
    def on_menuitem_branch_push_activate(self, widget):
542
        """ Branch/Push... menu handler. """
266.1.1 by Mateusz Korniak
Fixed interface to push.PushDialog
543
        push = PushDialog(repository=None,revid=None,branch=self.wt.branch, parent=self.window)
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
544
        response = push.run()
545
        if response != gtk.RESPONSE_NONE:
546
            push.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
547
    
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
548
    @show_bzr_error
549
    def on_menuitem_branch_revert_activate(self, widget):
550
        """ Branch/Revert all changes menu handler. """
552.1.1 by Jasper Groenewegen
Tweaks to olive/__init__.py:
551
        ret = self.wt.revert(None)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
552
        if ret:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
553
            warning_dialog(_i18n('Conflicts detected'),
554
                           _i18n('Please have a look at the working tree before continuing.'))
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
555
        else:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
556
            info_dialog(_i18n('Revert successful'),
557
                        _i18n('All files reverted to last revision.'))
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
558
        self.refresh_right()
559
    
0.13.13 by Jelmer Vernooij
Update TODO
560
    def on_menuitem_branch_status_activate(self, widget):
561
        """ Branch/Status... menu handler. """
625.8.1 by Jasper Groenewegen
Fix opening Status window in Olive
562
        from bzrlib.plugins.gtk.status import StatusWindow
563
        status = StatusWindow(self.wt, self.wtpath)
564
        status.show()
0.13.13 by Jelmer Vernooij
Update TODO
565
    
566
    def on_menuitem_branch_initialize_activate(self, widget):
567
        """ Initialize current directory. """
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
568
        init = InitDialog(self.path, self.window)
569
        response = init.run()
570
        if response != gtk.RESPONSE_NONE:
571
            init.hide()
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
572
        
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
573
            if response == gtk.RESPONSE_OK:
574
                self.refresh_right()
575
            
576
            init.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
577
        
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
578
    def on_menuitem_branch_tags_activate(self, widget):
579
        """ Branch/Tags... menu handler. """
580
        from bzrlib.plugins.gtk.tags import TagsWindow
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
581
        if not self.remote:
582
            window = TagsWindow(self.wt.branch, self.window)
583
        else:
584
            window = TagsWindow(self.remote_branch, self.window)
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
585
        window.show()
586
    
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
587
    def on_menuitem_file_annotate_activate(self, widget):
588
        """ File/Annotate... menu handler. """
589
        if self.get_selected_right() is None:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
590
            error_dialog(_i18n('No file was selected'),
591
                         _i18n('Please select a file from the list.'))
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
592
            return
593
        
594
        branch = self.wt.branch
595
        file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
596
        
275.1.6 by Daniel Schierbeck
Made Ctrl-W call gtk.main_quit if the window has no parent.
597
        window = GAnnotateWindow(all=False, plain=False, parent=self.window)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
598
        window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
599
        config = GAnnotateConfig(window)
600
        window.show()
601
        branch.lock_read()
602
        try:
66.2.17 by Aaron Bentley
Update olive to use current bzr.dev API. Used _repo_relpath. Bad phanatic!
603
            window.annotate(self.wt, branch, file_id)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
604
        finally:
605
            branch.unlock()
606
    
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
607
    def on_menuitem_file_bookmark_activate(self, widget):
608
        """ File/Bookmark current directory menu handler. """
609
        if self.pref.add_bookmark(self.path):
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
610
            info_dialog(_i18n('Bookmark successfully added'),
611
                        _i18n('The current directory was bookmarked. You can reach\nit by selecting it from the left panel.'))
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
612
            self.pref.write()
613
        else:
475.1.2 by Vincent Ladeuil
Fix bug #187283 fix replacing _() by _i18n().
614
            warning_dialog(_i18n('Location already bookmarked'),
615
                           _i18n('The current directory is already bookmarked.\nSee the left panel for reference.'))
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
616
        
617
        self.refresh_left()
618
    
0.13.13 by Jelmer Vernooij
Update TODO
619
    def on_menuitem_file_make_directory_activate(self, widget):
620
        """ File/Make directory... menu handler. """
533.7.1 by Jasper Groenewegen
Replace glade OliveMkdir dialog with MkdirDialog
621
        from bzrlib.plugins.gtk.olive.mkdir import MkdirDialog
622
        mkdir = MkdirDialog(self.wt, self.wtpath, self.window)
623
        response = mkdir.run()
624
        mkdir.destroy()
625
        if response == gtk.RESPONSE_OK:
626
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
627
    
628
    def on_menuitem_file_move_activate(self, widget):
629
        """ File/Move... menu handler. """
533.6.1 by Jasper Groenewegen
Replace glade OliveMove with MoveDialog
630
        from bzrlib.plugins.gtk.olive.move import MoveDialog
631
        move = MoveDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
632
        response = move.run()
633
        move.destroy()
634
        if response == gtk.RESPONSE_OK:
635
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
636
    
637
    def on_menuitem_file_rename_activate(self, widget):
638
        """ File/Rename... menu handler. """
533.4.1 by Jasper Groenewegen
Replace glade OliveRename dialog with RenameDialog
639
        from bzrlib.plugins.gtk.olive.rename import RenameDialog
640
        rename = RenameDialog(self.wt, self.wtpath, self.get_selected_right(), self.window)
641
        response = rename.run()
642
        rename.destroy()
643
        if response == gtk.RESPONSE_OK:
644
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
645
646
    def on_menuitem_remove_file_activate(self, widget):
647
        """ Remove (unversion) selected file. """
533.5.1 by Jasper Groenewegen
Remove glade bits of OliveRemove, tweak existing (Olive)RemoveDialog
648
        from bzrlib.plugins.gtk.olive.remove import RemoveDialog
649
        remove = RemoveDialog(self.wt, self.wtpath,
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
650
                                   selected=self.get_selected_right(),
121 by Szilveszter Farkas (Phanatic)
Use OliveBookmarkDialog instead of OliveBookmark.
651
                                   parent=self.window)
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
652
        response = remove.run()
653
        
654
        if response != gtk.RESPONSE_NONE:
655
            remove.hide()
656
        
657
            if response == gtk.RESPONSE_OK:
658
                self.refresh_right()
659
            
660
            remove.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
661
    
662
    def on_menuitem_stats_diff_activate(self, widget):
663
        """ Statistics/Differences... menu handler. """
298.2.1 by Daniel Schierbeck
Refactored the GTK window code, creating a single base window class that handles keyboard events.
664
        window = DiffWindow(parent=self.window)
0.13.13 by Jelmer Vernooij
Update TODO
665
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
630 by Jelmer Vernooij
Use _get_nick(local=True) rather than .nick to get at a branches' nick, since
666
        window.set_diff(self.wt.branch._get_nick(local=True), self.wt, 
667
                        parent_tree)
0.13.13 by Jelmer Vernooij
Update TODO
668
        window.show()
669
    
670
    def on_menuitem_stats_infos_activate(self, widget):
671
        """ Statistics/Informations... menu handler. """
554.1.1 by Jasper Groenewegen
Replace OliveInfo with gladeless InfoDialog
672
        from bzrlib.plugins.gtk.olive.info import InfoDialog
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
673
        if self.remote:
554.1.1 by Jasper Groenewegen
Replace OliveInfo with gladeless InfoDialog
674
            info = InfoDialog(self.remote_branch)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
675
        else:
554.1.1 by Jasper Groenewegen
Replace OliveInfo with gladeless InfoDialog
676
            info = InfoDialog(self.wt.branch)
0.13.13 by Jelmer Vernooij
Update TODO
677
        info.display()
678
    
679
    def on_menuitem_stats_log_activate(self, widget):
680
        """ Statistics/Log... menu handler. """
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
681
195.1.20 by Szilveszter Farkas (Phanatic)
Make bzrk working with remote branches.
682
        if not self.remote:
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
683
            branch = self.wt.branch
195.1.20 by Szilveszter Farkas (Phanatic)
Make bzrk working with remote branches.
684
        else:
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
685
            branch = self.remote_branch
686
523 by Jelmer Vernooij
Fix starting "bzr viz" from olive.
687
        window = branchwin.BranchWindow(branch, [branch.last_revision()], None, 
688
                                        parent=self.window)
0.13.13 by Jelmer Vernooij
Update TODO
689
        window.show()
690
    
691
    def on_menuitem_view_refresh_activate(self, widget):
692
        """ View/Refresh menu handler. """
693
        # Refresh the left pane
694
        self.refresh_left()
695
        # Refresh the right pane
696
        self.refresh_right()
697
   
698
    def on_menuitem_view_show_hidden_files_activate(self, widget):
699
        """ View/Show hidden files menu handler. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
700
        self.pref.set_preference('dotted_files', widget.get_active())
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
701
        self.pref.write()
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
702
        if self.path is not None:
703
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
704
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
705
    def on_menuitem_view_show_ignored_files_activate(self, widget):
706
        """ Hide/Show ignored files menu handler. """
707
        self.pref.set_preference('ignored_files', widget.get_active())
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
708
        self.pref.write()
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
709
        if self.path is not None:
710
            self.refresh_right()
711
            
0.13.13 by Jelmer Vernooij
Update TODO
712
    def on_treeview_left_button_press_event(self, widget, event):
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
713
        """ Occurs when somebody clicks in the bookmark list. """
714
        treepathpos = widget.get_path_at_pos(int(event.x), int(event.y))
715
        treeselection = widget.get_selection()
716
        if treepathpos is not None:
717
            treeselection.select_path(treepathpos[0])
718
            if event.button == 1:
719
                newdir = self.get_selected_left()
720
                if newdir == None:
721
                    return
722
723
                if self.set_path(newdir):
724
                    self.refresh_right()
725
            elif event.button == 3:
726
                # Don't show context with nothing selected
727
                if self.get_selected_left() == None:
728
                    return
729
730
                # Create a menu
731
                from menu import OliveMenu
732
                menu = OliveMenu(path=self.get_path(),
733
                                 selected=self.get_selected_left(),
734
                                 app=self)
735
                
736
                menu.left_context_menu().popup(None, None, None, 0,
737
                                               event.time)
738
        else:
739
            if treeselection is not None:
740
                treeselection.unselect_all()
435.3.1 by Farkas Szilveszter
Allow opening bookmarks with a single click (#151824).
741
0.13.13 by Jelmer Vernooij
Update TODO
742
    def on_treeview_left_row_activated(self, treeview, path, view_column):
743
        """ Occurs when somebody double-clicks or enters an item in the
744
        bookmark list. """
745
746
        newdir = self.get_selected_left()
747
        if newdir == None:
748
            return
749
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
750
        if self.set_path(newdir):
751
            self.refresh_right()
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
752
0.13.13 by Jelmer Vernooij
Update TODO
753
    def on_treeview_right_button_press_event(self, widget, event):
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
754
        """ Occurs when somebody clicks in the file list. """
755
        treepathpos = widget.get_path_at_pos(int(event.x), int(event.y))
756
        if event.button == 1:
757
            if treepathpos is None and widget.get_selection is not None:
758
                treeselection = widget.get_selection()
759
                treeselection.unselect_all()
760
        elif event.button == 3:
761
            treeselection = widget.get_selection()
762
            if treepathpos is not None:
763
                treeselection.select_path(treepathpos[0])
764
            else:
765
                if treeselection is not None:
766
                    treeselection.unselect_all()
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
767
            # Create a menu
768
            from menu import OliveMenu
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
769
            menu = OliveMenu(path=self.get_path(),
770
                             selected=self.get_selected_right(),
771
                             app=self)
0.13.13 by Jelmer Vernooij
Update TODO
772
            # get the menu items
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
773
            m_open = menu.ui.get_widget('/context_right/open')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
774
            m_add = menu.ui.get_widget('/context_right/add')
775
            m_remove = menu.ui.get_widget('/context_right/remove')
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
776
            m_remove_and_delete = menu.ui.get_widget('/context_right/remove_and_delete')
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
777
            m_rename = menu.ui.get_widget('/context_right/rename')
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
778
            m_revert = menu.ui.get_widget('/context_right/revert')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
779
            m_commit = menu.ui.get_widget('/context_right/commit')
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
780
            m_annotate = menu.ui.get_widget('/context_right/annotate')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
781
            m_diff = menu.ui.get_widget('/context_right/diff')
0.13.13 by Jelmer Vernooij
Update TODO
782
            # check if we're in a branch
783
            try:
784
                from bzrlib.branch import Branch
785
                Branch.open_containing(self.get_path())
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
786
                if self.remote:
787
                    m_open.set_sensitive(False)
788
                    m_add.set_sensitive(False)
789
                    m_remove.set_sensitive(False)
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
790
                    m_remove_and_delete.set_sensitive(False)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
791
                    m_rename.set_sensitive(False)
792
                    m_revert.set_sensitive(False)
793
                    m_commit.set_sensitive(False)
794
                    m_annotate.set_sensitive(False)
795
                    m_diff.set_sensitive(False)
796
                else:
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
797
                    if treepathpos is None:
798
                        m_open.set_sensitive(False)
799
                        m_add.set_sensitive(False)
800
                        m_remove.set_sensitive(False)
801
                        m_remove_and_delete.set_sensitive(False)
802
                        m_rename.set_sensitive(False)
803
                        m_annotate.set_sensitive(False)
804
                        m_diff.set_sensitive(False)
805
                        m_revert.set_sensitive(False)
806
                    else:
807
                        m_open.set_sensitive(True)
808
                        m_add.set_sensitive(True)
809
                        m_remove.set_sensitive(True)
810
                        m_remove_and_delete.set_sensitive(True)
811
                        m_rename.set_sensitive(True)
812
                        m_annotate.set_sensitive(True)
813
                        m_diff.set_sensitive(True)
814
                        m_revert.set_sensitive(True)
815
                    m_commit.set_sensitive(True)
816
            except bzrerrors.NotBranchError:
817
                if treepathpos is None:
818
                    m_open.set_sensitive(False)
819
                else:
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
820
                    m_open.set_sensitive(True)
0.13.13 by Jelmer Vernooij
Update TODO
821
                m_add.set_sensitive(False)
822
                m_remove.set_sensitive(False)
554.2.1 by klight at walkertechnical
This patch fixes the right click functionality for the bookmark and file panes (take 3).
823
                m_remove_and_delete.set_sensitive(False)
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
824
                m_rename.set_sensitive(False)
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
825
                m_revert.set_sensitive(False)
0.13.13 by Jelmer Vernooij
Update TODO
826
                m_commit.set_sensitive(False)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
827
                m_annotate.set_sensitive(False)
0.13.13 by Jelmer Vernooij
Update TODO
828
                m_diff.set_sensitive(False)
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
829
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
830
            if not self.remote:
831
                menu.right_context_menu().popup(None, None, None, 0,
832
                                                event.time)
833
            else:
834
                menu.remote_context_menu().popup(None, None, None, 0,
835
                                                 event.time)
0.13.13 by Jelmer Vernooij
Update TODO
836
        
837
    def on_treeview_right_row_activated(self, treeview, path, view_column):
838
        """ Occurs when somebody double-clicks or enters an item in the
839
        file list. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
840
        from launch import launch
841
        
0.13.13 by Jelmer Vernooij
Update TODO
842
        newdir = self.get_selected_right()
843
        
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
844
        if not self.remote:
845
            # We're local
846
            if newdir == '..':
847
                self.set_path(os.path.split(self.get_path())[0])
848
            else:
849
                fullpath = os.path.join(self.get_path(), newdir)
850
                if os.path.isdir(fullpath):
851
                    # selected item is an existant directory
852
                    self.set_path(fullpath)
853
                else:
854
                    launch(fullpath)
0.13.13 by Jelmer Vernooij
Update TODO
855
        else:
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
856
            # We're remote
857
            if self._is_remote_dir(self.get_path() + newdir):
858
                self.set_path(self.get_path() + newdir)
0.13.13 by Jelmer Vernooij
Update TODO
859
        
860
        self.refresh_right()
861
    
862
    def on_window_main_delete_event(self, widget, event=None):
863
        """ Do some stuff before exiting. """
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
864
        width, height = self.window.get_size()
0.13.13 by Jelmer Vernooij
Update TODO
865
        self.pref.set_preference('window_width', width)
866
        self.pref.set_preference('window_height', height)
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
867
        x, y = self.window.get_position()
0.13.13 by Jelmer Vernooij
Update TODO
868
        self.pref.set_preference('window_x', x)
869
        self.pref.set_preference('window_y', y)
870
        self.pref.set_preference('paned_position',
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
871
                                 self.window.hpaned_main.get_position())
0.13.13 by Jelmer Vernooij
Update TODO
872
        
873
        self.pref.write()
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
874
        self.window.destroy()
580.3.2 by Gediminas Paulauskas
Merge trunk.
875
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
876
    def get_selected_fileid(self):
877
        """ Get the file_id of the selected file. """
560.10.2 by Jasper Groenewegen
Forgot three treeview_right -> window.treeview_right
878
        treeselection = self.window.treeview_right.get_selection()
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
879
        (model, iter) = treeselection.get_selected()
880
        
881
        if iter is None:
882
            return None
883
        else:
884
            return model.get_value(iter, 9)
885
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
886
    def get_selected_right(self):
887
        """ Get the selected filename. """
560.10.2 by Jasper Groenewegen
Forgot three treeview_right -> window.treeview_right
888
        treeselection = self.window.treeview_right.get_selection()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
889
        (model, iter) = treeselection.get_selected()
890
        
891
        if iter is None:
892
            return None
893
        else:
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
894
            return model.get_value(iter, 2)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
895
    
896
    def get_selected_left(self):
897
        """ Get the selected bookmark. """
560.11.2 by Jasper Groenewegen
treeview_left -> window.treeview_left
898
        treeselection = self.window.treeview_left.get_selection()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
899
        (model, iter) = treeselection.get_selected()
900
        
901
        if iter is None:
902
            return None
903
        else:
904
            return model.get_value(iter, 1)
905
906
    def set_statusbar(self, message):
907
        """ Set the statusbar message. """
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
908
        self.window.statusbar.push(self.context_id, message)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
909
    
910
    def clear_statusbar(self):
911
        """ Clean the last message from the statusbar. """
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
912
        self.window.statusbar.pop(self.context_id)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
913
    
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
914
    def set_sensitivity(self):
915
        """ Set menu and toolbar sensitivity. """
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
916
        if not self.remote:
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
917
            self.window.set_view_to_localbranch(self.notbranch)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
918
        else:
533.12.1 by Jasper Groenewegen
Replace glade window_main with OliveGui
919
            self.window.set_view_to_remotebranch()
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
920
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
921
    def refresh_left(self):
922
        """ Refresh the bookmark list. """
923
        
560.11.1 by Jasper Groenewegen
Replace Bookmarks tree with list + folder icons
924
        # Get ListStore and clear it
925
        liststore = self.window.bookmarklist
926
        liststore.clear()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
927
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
928
        # Re-read preferences
929
        self.pref.read()
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
930
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
931
        # Get bookmarks
932
        bookmarks = self.pref.get_bookmarks()
933
531.8.2 by Jasper Groenewegen
And also for refresh_left method
934
        # Get titles and sort by title
560.11.1 by Jasper Groenewegen
Replace Bookmarks tree with list + folder icons
935
        bookmarks = [[self.pref.get_bookmark_title(item), item, gtk.STOCK_DIRECTORY] for item in bookmarks]
531.8.2 by Jasper Groenewegen
And also for refresh_left method
936
        bookmarks.sort()
937
        for title_item in bookmarks:
560.11.1 by Jasper Groenewegen
Replace Bookmarks tree with list + folder icons
938
            liststore.append(title_item)
531.8.2 by Jasper Groenewegen
And also for refresh_left method
939
        
592.3.1 by Jasper Groenewegen
Tweak: Resize column width after bookmark change
940
        # Add the ListStore to the TreeView and refresh column width
560.11.1 by Jasper Groenewegen
Replace Bookmarks tree with list + folder icons
941
        self.window.treeview_left.set_model(liststore)
592.3.1 by Jasper Groenewegen
Tweak: Resize column width after bookmark change
942
        self.window.treeview_left.columns_autosize()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
943
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
944
    def refresh_right(self):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
945
        """ Refresh the file list. """
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
946
        if not self.remote:
947
            # We're local
948
            from bzrlib.workingtree import WorkingTree
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
949
            
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
950
            path = self.get_path()
951
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
952
            # Get ListStore and clear it
560.10.1 by Jasper Groenewegen
File list changes
953
            liststore = self.window.filelist
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
954
            liststore.clear()
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
955
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
956
            dirs = []
957
            files = []
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
958
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
959
            # Fill the appropriate lists
960
            dotted_files = self.pref.get_preference('dotted_files', 'bool')
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
961
            ignored_files = self.pref.get_preference('ignored_files', 'bool')
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
962
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
963
            for item in os.listdir(path):
964
                if not dotted_files and item[0] == '.':
965
                    continue
437.2.1 by Gediminas Paulauskas
Use os.path.join
966
                if os.path.isdir(os.path.join(path, item)):
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
967
                    dirs.append(item)
968
                else:
969
                    files.append(item)
970
            
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
971
            self.window.col_status.set_visible(False)
972
            if not self.notbranch:
973
                try:
974
                    tree1 = WorkingTree.open_containing(os.path.realpath(path))[0]
975
                    branch = tree1.branch
976
                    tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
599.1.1 by Jasper Groenewegen
Showing hidden/ignored files were not properly saved since the self.pref Preferences object gets overwritten everytime refresh/refresh_left() is performed.
977
                    
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
978
                    delta = tree1.changes_from(tree2, want_unchanged=True)
979
                    
980
                    # Show Status column
981
                    self.window.col_status.set_visible(True)
982
                except bzrerrors.LockContention:
983
                    self.window.set_location_status(gtk.STOCK_DIALOG_ERROR, allowPopup=True)
984
                    self.window.location_status.connect_object('clicked', error_dialog, 
985
                                       *(_i18n('Branch is locked'),
986
                                		_i18n('The branch in the current folder is locked by another Bazaar program')))
987
                    self.notbranch = True
988
                    self.window.set_view_to_localbranch(False) 
989
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
990
            # Add'em to the ListStore
991
            for item in dirs:
560.10.1 by Jasper Groenewegen
File list changes
992
                status = ''
993
                st = ''
994
                fileid = ''
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
995
                if not self.notbranch:
560.10.1 by Jasper Groenewegen
File list changes
996
                    filename = tree1.relpath(os.path.join(os.path.realpath(path), item))
997
                    
998
                    st, status = self.statusmapper(filename, delta)
999
                    if not ignored_files and status == 'ignored':
1000
                        continue
1001
                
437.2.3 by Gediminas Paulauskas
Remove workaround for infinite loops, doesn't happen with lstat
1002
                statinfo = os.lstat(os.path.join(self.path, item))
560.10.1 by Jasper Groenewegen
File list changes
1003
                liststore.append([ gtk.STOCK_DIRECTORY,
1004
                                   True,
1005
                                   item,
1006
                                   st,
1007
                                   status,
1008
                                   "<DIR>",
1009
                                   "<DIR>",
1010
                                   statinfo.st_mtime,
1011
                                   self._format_date(statinfo.st_mtime),
1012
                                   ''])
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1013
            for item in files:
560.10.1 by Jasper Groenewegen
File list changes
1014
                status = ''
1015
                st = ''
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1016
                fileid = ''
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
1017
                if not self.notbranch:
560.10.1 by Jasper Groenewegen
File list changes
1018
                    filename = tree1.relpath(os.path.join(os.path.realpath(path), item))
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1019
                    
560.10.1 by Jasper Groenewegen
File list changes
1020
                    st, status = self.statusmapper(filename, delta)
1021
                    if not ignored_files and status == 'ignored':
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
1022
                        continue
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1023
                
437.2.3 by Gediminas Paulauskas
Remove workaround for infinite loops, doesn't happen with lstat
1024
                statinfo = os.lstat(os.path.join(self.path, item))
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1025
                liststore.append([gtk.STOCK_FILE,
1026
                                  False,
1027
                                  item,
1028
                                  st,
1029
                                  status,
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1030
                                  str(statinfo.st_size),
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1031
                                  self._format_size(statinfo.st_size),
1032
                                  statinfo.st_mtime,
1033
                                  self._format_date(statinfo.st_mtime),
1034
                                  fileid])
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1035
        else:
1036
            # We're remote
1037
            
1038
            # Get ListStore and clear it
560.10.1 by Jasper Groenewegen
File list changes
1039
            liststore = self.window.filelist
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1040
            liststore.clear()
1041
            
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1042
            # Hide Status column
560.10.1 by Jasper Groenewegen
File list changes
1043
            self.window.col_status.set_visible(False)
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1044
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1045
            dirs = []
1046
            files = []
1047
            
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
1048
            self.window.set_location_status(gtk.STOCK_REFRESH)
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1049
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1050
            for (name, type) in self.remote_entries:
1051
                if type.kind == 'directory':
1052
                    dirs.append(type)
1053
                elif type.kind == 'file':
1054
                    files.append(type)
1055
            
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1056
            class HistoryCache:
1057
                """ Cache based on revision history. """
1058
                def __init__(self, history):
1059
                    self._history = history
1060
                
1061
                def _lookup_revision(self, revid):
1062
                    for r in self._history:
1063
                        if r.revision_id == revid:
1064
                            return r
1065
                    rev = repo.get_revision(revid)
1066
                    self._history.append(rev)
1067
                    return rev
1068
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1069
            repo = self.remote_branch.repository
1070
            
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1071
            revhistory = self.remote_branch.revision_history()
1072
            try:
1073
                revs = repo.get_revisions(revhistory)
1074
                cache = HistoryCache(revs)
1075
            except bzrerrors.InvalidHttpResponse:
1076
                # Fallback to dummy algorithm, because of LP: #115209
1077
                cache = HistoryCache([])
1078
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1079
            for item in dirs:
1080
                if item.parent_id == self.remote_parent:
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1081
                    rev = cache._lookup_revision(item.revision)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1082
                    liststore.append([ gtk.STOCK_DIRECTORY,
1083
                                       True,
1084
                                       item.name,
1085
                                       '',
1086
                                       '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1087
                                       "<DIR>",
1088
                                       "<DIR>",
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1089
                                       rev.timestamp,
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1090
                                       self._format_date(rev.timestamp),
1091
                                       ''
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1092
                                   ])
195.1.11 by Szilveszter Farkas (Phanatic)
No progess bars, they suck. Use manual gtk loop iteration instead. Also added fancy connection icons to the location bar.
1093
                while gtk.events_pending():
1094
                    gtk.main_iteration()
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1095
            
1096
            for item in files:
1097
                if item.parent_id == self.remote_parent:
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1098
                    rev = cache._lookup_revision(item.revision)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1099
                    liststore.append([ gtk.STOCK_FILE,
1100
                                       False,
1101
                                       item.name,
1102
                                       '',
1103
                                       '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1104
                                       str(item.text_size),
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1105
                                       self._format_size(item.text_size),
1106
                                       rev.timestamp,
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1107
                                       self._format_date(rev.timestamp),
1108
                                       item.file_id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1109
                                   ])
195.1.11 by Szilveszter Farkas (Phanatic)
No progess bars, they suck. Use manual gtk loop iteration instead. Also added fancy connection icons to the location bar.
1110
                while gtk.events_pending():
1111
                    gtk.main_iteration()
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1112
            
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
1113
            self.window.location_status.destroy()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1114
195.1.11 by Szilveszter Farkas (Phanatic)
No progess bars, they suck. Use manual gtk loop iteration instead. Also added fancy connection icons to the location bar.
1115
        # Columns should auto-size
560.10.2 by Jasper Groenewegen
Forgot three treeview_right -> window.treeview_right
1116
        self.window.treeview_right.columns_autosize()
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
1117
        
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
1118
        # Set sensitivity
1119
        self.set_sensitivity()
560.10.1 by Jasper Groenewegen
File list changes
1120
    
1121
    def statusmapper(self, filename, delta):
1122
        status = 'unknown'
1123
        try:
1124
            self.wt.lock_read()
1125
            
1126
            for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1127
                if rpathnew == filename:
1128
                    status = 'renamed'
1129
                    fileid = id
1130
            for rpath, id, kind in delta.added:
1131
                if rpath == filename:
1132
                    status = 'added'
1133
                    fileid = id
1134
            for rpath, id, kind in delta.removed:
1135
                if rpath == filename:
1136
                    status = 'removed'
1137
                    fileid = id
1138
            for rpath, id, kind, text_modified, meta_modified in delta.modified:
1139
                if rpath == filename:
1140
                    status = 'modified'
1141
                    fileid = id
1142
            for rpath, id, kind in delta.unchanged:
1143
                if rpath == filename:
1144
                    status = 'unchanged'
1145
                    fileid = id
1146
            for rpath, file_class, kind, id, entry in self.wt.list_files():
1147
                if rpath == filename and file_class == 'I':
1148
                    status = 'ignored'
1149
        finally:
1150
            self.wt.unlock()
1151
    
1152
        if status == 'renamed':
1153
            st = _i18n('renamed')
1154
        elif status == 'removed':
1155
            st = _i18n('removed')
1156
        elif status == 'added':
1157
            st = _i18n('added')
1158
        elif status == 'modified':
1159
            st = _i18n('modified')
1160
        elif status == 'unchanged':
1161
            st = _i18n('unchanged')
1162
        elif status == 'ignored':
1163
            st = _i18n('ignored')
1164
        else:
1165
            st = _i18n('unknown')
1166
        return st, status
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1167
1168
    def _harddisks(self):
1169
        """ Returns hard drive letters under Win32. """
1170
        try:
1171
            import win32file
1172
            import string
1173
        except ImportError:
1174
            if sys.platform == 'win32':
1175
                print "pyWin32 modules needed to run Olive on Win32."
1176
                sys.exit(1)
1177
        
1178
        driveletters = []
1179
        for drive in string.ascii_uppercase:
531 by Kevin Light
Fix network drives listing in olive-gtk.
1180
            if win32file.GetDriveType(drive+':') == win32file.DRIVE_FIXED or\
583 by Dennis Miller
Extension of fix from bug 244308 to cover removable drives - bug 250804
1181
                win32file.GetDriveType(drive+':') == win32file.DRIVE_REMOTE or\
1182
                win32file.GetDriveType(drive+':') == win32file.DRIVE_REMOVABLE:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1183
                driveletters.append(drive+':')
1184
        return driveletters
1185
    
1186
    def gen_hard_selector(self):
1187
        """ Generate the hard drive selector under Win32. """
1188
        drives = self._harddisks()
1189
        for drive in drives:
1190
            self.combobox_drive.append_text(drive)
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
1191
        self.combobox_drive.set_active(drives.index(os.getcwd()[0:2]))
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1192
    
1193
    def _refresh_drives(self, combobox):
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
1194
        if self._just_started:
1195
            return
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1196
        model = combobox.get_model()
1197
        active = combobox.get_active()
1198
        if active >= 0:
1199
            drive = model[active][0]
0.14.11 by Alexander Belchenko
Make change of drive letter on win32 is actually workable
1200
            self.set_path(drive + '\\')
585.1.1 by Jasper Groenewegen
Improvements to path changes in Olive
1201
            self.refresh_right()
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
1202
    
1203
    def check_for_changes(self):
1204
        """ Check whether there were changes in the current working tree. """
1205
        old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
1206
        delta = self.wt.changes_from(old_tree)
1207
1208
        changes = False
1209
        
1210
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
1211
            changes = True
1212
        
1213
        return changes
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1214
    
1215
    def _sort_filelist_callback(self, model, iter1, iter2, data):
1216
        """ The sort callback for the file list, return values:
1217
        -1: iter1 < iter2
1218
        0: iter1 = iter2
1219
        1: iter1 > iter2
1220
        """
1221
        name1 = model.get_value(iter1, 2)
1222
        name2 = model.get_value(iter2, 2)
1223
        
1224
        if model.get_value(iter1, 1):
1225
            # item1 is a directory
1226
            if not model.get_value(iter2, 1):
1227
                # item2 isn't
1228
                return -1
1229
            else:
1230
                # both of them are directories, we compare their names
1231
                if name1 < name2:
1232
                    return -1
1233
                elif name1 == name2:
1234
                    return 0
1235
                else:
1236
                    return 1
1237
        else:
1238
            # item1 is not a directory
1239
            if model.get_value(iter2, 1):
1240
                # item2 is
1241
                return 1
1242
            else:
1243
                # both of them are files, compare them
1244
                if name1 < name2:
1245
                    return -1
1246
                elif name1 == name2:
1247
                    return 0
1248
                else:
1249
                    return 1
1250
    
1251
    def _format_size(self, size):
1252
        """ Format size to a human readable format. """
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1253
        if size < 1000:
1254
            return "%d[B]" % (size,)
1255
        size = size / 1000.0
1256
        
1257
        for metric in ["kB","MB","GB","TB"]:
1258
            if size < 1000:
1259
                break
1260
            size = size / 1000.0
1261
        return "%.1f[%s]" % (size,metric) 
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1262
    
1263
    def _format_date(self, timestamp):
1264
        """ Format the time (given in secs) to a human readable format. """
1265
        return time.ctime(timestamp)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1266
    
1267
    def _is_remote_dir(self, location):
1268
        """ Determine whether the given location is a directory or not. """
1269
        if not self.remote:
1270
            # We're in local mode
1271
            return False
1272
        else:
1273
            branch, path = Branch.open_containing(location)
1274
            for (name, type) in self.remote_entries:
1275
                if name == path and type.kind == 'directory':
1276
                    # We got it
1277
                    return True
1278
            # Either it's not a directory or not in the inventory
1279
            return False
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1280
0.13.13 by Jelmer Vernooij
Update TODO
1281
import ConfigParser
1282
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
1283
class Preferences:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1284
    """ A class which handles Olive's preferences. """
170 by Jelmer Vernooij
Add test argument to Preferences().
1285
    def __init__(self, path=None):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1286
        """ Initialize the Preferences class. """
1287
        # Some default options
1288
        self.defaults = { 'strict_commit' : False,
1289
                          'dotted_files'  : False,
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
1290
                          'ignored_files' : True,
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1291
                          'window_width'  : 700,
1292
                          'window_height' : 400,
1293
                          'window_x'      : 40,
1294
                          'window_y'      : 40,
1295
                          'paned_position': 200 }
1296
1297
        # Create a config parser object
1298
        self.config = ConfigParser.RawConfigParser()
170 by Jelmer Vernooij
Add test argument to Preferences().
1299
1300
        # Set filename
1301
        if path is None:
1302
            if sys.platform == 'win32':
1303
                # Windows - no dotted files
1304
                self._filename = os.path.expanduser('~/olive.conf')
1305
            else:
1306
                self._filename = os.path.expanduser('~/.olive.conf')
1307
        else:
1308
            self._filename = path
126.1.35 by Szilveszter Farkas (Phanatic)
Make test suite not fail if Olive was run before.
1309
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1310
        # Load the configuration
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1311
        self.read()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1312
        
1313
    def _get_default(self, option):
1314
        """ Get the default option for a preference. """
1315
        try:
1316
            ret = self.defaults[option]
1317
        except KeyError:
1318
            return None
1319
        else:
1320
            return ret
1321
1322
    def refresh(self):
1323
        """ Refresh the configuration. """
1324
        # First write out the changes
1325
        self.write()
1326
        # Then load the configuration again
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1327
        self.read()
1328
1329
    def read(self):
1330
        """ Just read the configuration. """
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
1331
        # Re-initialize the config parser object to avoid some bugs
1332
        self.config = ConfigParser.RawConfigParser()
170 by Jelmer Vernooij
Add test argument to Preferences().
1333
        self.config.read([self._filename])
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1334
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1335
    def write(self):
1336
        """ Write the configuration to the appropriate files. """
170 by Jelmer Vernooij
Add test argument to Preferences().
1337
        fp = open(self._filename, 'w')
1338
        self.config.write(fp)
1339
        fp.close()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1340
1341
    def get_bookmarks(self):
1342
        """ Return the list of bookmarks. """
1343
        bookmarks = self.config.sections()
1344
        if self.config.has_section('preferences'):
1345
            bookmarks.remove('preferences')
1346
        return bookmarks
1347
1348
    def add_bookmark(self, path):
1349
        """ Add bookmark. """
1350
        try:
1351
            self.config.add_section(path)
1352
        except ConfigParser.DuplicateSectionError:
1353
            return False
1354
        else:
1355
            return True
1356
1357
    def get_bookmark_title(self, path):
1358
        """ Get bookmark title. """
1359
        try:
1360
            ret = self.config.get(path, 'title')
1361
        except ConfigParser.NoOptionError:
1362
            ret = path
1363
        
1364
        return ret
1365
    
1366
    def set_bookmark_title(self, path, title):
1367
        """ Set bookmark title. """
143 by Jelmer Vernooij
More preference tests.
1368
        # FIXME: What if path isn't listed yet?
1369
        # FIXME: Canonicalize paths first?
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1370
        self.config.set(path, 'title', title)
1371
    
1372
    def remove_bookmark(self, path):
1373
        """ Remove bookmark. """
1374
        return self.config.remove_section(path)
0.13.13 by Jelmer Vernooij
Update TODO
1375
1376
    def set_preference(self, option, value):
1377
        """ Set the value of the given option. """
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1378
        if value is True:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1379
            value = 'yes'
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1380
        elif value is False:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1381
            value = 'no'
1382
        
0.13.13 by Jelmer Vernooij
Update TODO
1383
        if self.config.has_section('preferences'):
1384
            self.config.set('preferences', option, value)
1385
        else:
1386
            self.config.add_section('preferences')
1387
            self.config.set('preferences', option, value)
1388
1389
    def get_preference(self, option, kind='str'):
1390
        """ Get the value of the given option.
1391
        
1392
        :param kind: str/bool/int/float. default: str
1393
        """
1394
        if self.config.has_option('preferences', option):
1395
            if kind == 'bool':
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1396
                return self.config.getboolean('preferences', option)
0.13.13 by Jelmer Vernooij
Update TODO
1397
            elif kind == 'int':
1398
                return self.config.getint('preferences', option)
1399
            elif kind == 'float':
1400
                return self.config.getfloat('preferences', option)
1401
            else:
1402
                return self.config.get('preferences', option)
1403
        else:
1404
            try:
1405
                return self._get_default(option)
1406
            except KeyError:
1407
                return None