/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
423.11.1 by Gary van der Merwe
Add encoding header to olive/__init__.py as it now has non ASCII chars.
1
#!/usr/bin/python
2
# -*- coding: UTF-8 -*-
3
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
4
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful,
12
# but WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
# GNU General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
20
import os
21
import sys
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
22
import time
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
23
89 by Jelmer Vernooij
Rename OliveBranch -> BranchDialog.
24
# gettext support
25
import gettext
26
gettext.install('olive-gtk')
27
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
28
try:
29
    import pygtk
30
    pygtk.require("2.0")
31
except:
32
    pass
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
33
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
34
import gobject
0.13.11 by Jelmer Vernooij
Bunch of small fixes, cleanups and simplifications.
35
import gtk
36
import gtk.gdk
37
import gtk.glade
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
38
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
39
from bzrlib.branch import Branch
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
40
import bzrlib.errors as bzrerrors
157.1.6 by Aaron Bentley
Defer importing branchwin to avoid cairo import errors
41
from bzrlib.lazy_import import lazy_import
195.1.10 by Szilveszter Farkas (Phanatic)
Showing progress of loading remote branch.
42
from bzrlib.ui import ui_factory
0.13.13 by Jelmer Vernooij
Update TODO
43
from bzrlib.workingtree import WorkingTree
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
44
151 by Jelmer Vernooij
Move dialog to top-level directory.
45
from bzrlib.plugins.gtk.dialog import error_dialog, info_dialog, warning_dialog
46
from bzrlib.plugins.gtk.errors import show_bzr_error
93.1.12 by Alexander Belchenko
Names XML files with GUI resources obtained via olive/guifiles.py
47
from guifiles import GLADEFILENAME
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
48
151 by Jelmer Vernooij
Move dialog to top-level directory.
49
from bzrlib.plugins.gtk.diff import DiffWindow
157.1.6 by Aaron Bentley
Defer importing branchwin to avoid cairo import errors
50
lazy_import(globals(), """
51
from bzrlib.plugins.gtk.viz import branchwin
52
""")
149 by Jelmer Vernooij
Move diff to top-level directory as well.
53
from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
54
from bzrlib.plugins.gtk.annotate.config import GAnnotateConfig
55
from bzrlib.plugins.gtk.commit import CommitDialog
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
56
from bzrlib.plugins.gtk.conflicts import ConflictsDialog
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
57
from bzrlib.plugins.gtk.initialize import InitDialog
149 by Jelmer Vernooij
Move diff to top-level directory as well.
58
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.
59
from bzrlib.plugins.gtk.revbrowser import RevisionBrowser
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
60
218 by Jelmer Vernooij
Move olive about dialog into olive.
61
def about():
62
    """ Display the AboutDialog. """
63
    from bzrlib.plugins.gtk import __version__
64
    from bzrlib.plugins.gtk.olive.guifiles import GLADEFILENAME
65
66
    # Load AboutDialog description
67
    dglade = gtk.glade.XML(GLADEFILENAME, 'aboutdialog')
68
    dialog = dglade.get_widget('aboutdialog')
69
70
    # Set version
71
    dialog.set_version(__version__)
205.1.5 by Szilveszter Farkas (Phanatic)
Added proper Credits.
72
    dialog.set_authors([ _("Lead Developer:"),
423.1.16 by Daniel Schierbeck
Reverted change to Olive's credits list.
73
			 "Szilveszter Farkas <szilveszter.farkas@gmail.com>",
74
			 _("Contributors:"),
75
			 "Jelmer Vernooij <jelmer@samba.org>",
76
			 "Mateusz Korniak <mateusz.korniak@ant.gliwice.pl>",
77
			 "Gary van der Merwe <garyvdm@gmail.com>" ])
205.1.5 by Szilveszter Farkas (Phanatic)
Added proper Credits.
78
    dialog.set_artists([ "Simon Pascal Klein <klepas@klepas.org>",
423.1.16 by Daniel Schierbeck
Reverted change to Olive's credits list.
79
			 "Jakub Steiner <jimmac@novell.com>" ])
218 by Jelmer Vernooij
Move olive about dialog into olive.
80
81
    dialog.run()
82
    # Destroy the dialog
83
    dialog.destroy()
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):
93.1.6 by Alexander Belchenko
detecting name of glade file doing in separate module (olive.gladefile)
90
        self.toplevel = gtk.glade.XML(GLADEFILENAME, 'window_main', 'olive-gtk')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
91
        self.window = self.toplevel.get_widget('window_main')
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
96
        self.statusbar = self.toplevel.get_widget('statusbar')
97
        self.context_id = self.statusbar.get_context_id('olive')
98
        
99
        # Get the main window
100
        self.window_main = self.toplevel.get_widget('window_main')
101
        # Get the HPaned
102
        self.hpaned_main = self.toplevel.get_widget('hpaned_main')
103
        # Get the TreeViews
104
        self.treeview_left = self.toplevel.get_widget('treeview_left')
105
        self.treeview_right = self.toplevel.get_widget('treeview_right')
106
        # Get some important menu items
107
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
108
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
109
        self.menuitem_file_bookmark = self.toplevel.get_widget('menuitem_file_bookmark')
0.13.13 by Jelmer Vernooij
Update TODO
110
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
111
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
112
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
113
        self.menuitem_file_annotate = self.toplevel.get_widget('menuitem_file_annotate')
0.13.13 by Jelmer Vernooij
Update TODO
114
        self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
115
        self.menuitem_view_show_ignored_files = self.toplevel.get_widget('menuitem_view_show_ignored_files')
0.13.13 by Jelmer Vernooij
Update TODO
116
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
117
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
118
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
119
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
120
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
121
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
122
        self.menuitem_branch_update = self.toplevel.get_widget('menuitem_branch_update')
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
123
        self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
124
        self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
0.13.13 by Jelmer Vernooij
Update TODO
125
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
126
        self.menuitem_branch_tags = self.toplevel.get_widget('menuitem_branch_tags')
0.13.13 by Jelmer Vernooij
Update TODO
127
        self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
128
        self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
129
        self.menuitem_branch_conflicts = self.toplevel.get_widget('menuitem_branch_conflicts')
0.13.13 by Jelmer Vernooij
Update TODO
130
        self.menuitem_stats = self.toplevel.get_widget('menuitem_stats')
131
        self.menuitem_stats_diff = self.toplevel.get_widget('menuitem_stats_diff')
132
        self.menuitem_stats_log = self.toplevel.get_widget('menuitem_stats_log')
133
        # Get some toolbuttons
134
        #self.menutoolbutton_diff = self.toplevel.get_widget('menutoolbutton_diff')
135
        self.toolbutton_diff = self.toplevel.get_widget('toolbutton_diff')
136
        self.toolbutton_log = self.toplevel.get_widget('toolbutton_log')
137
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
138
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
139
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
140
        self.toolbutton_update = self.toplevel.get_widget('toolbutton_update')
0.13.13 by Jelmer Vernooij
Update TODO
141
        # Get the drive selector
142
        self.combobox_drive = gtk.combo_box_new_text()
143
        self.combobox_drive.connect("changed", self._refresh_drives)
144
        
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
145
        # Get the navigation widgets
195.6.4 by Szilveszter Farkas (Phanatic)
The Windows drive selector was moved to the location bar.
146
        self.hbox_location = self.toplevel.get_widget('hbox_location')
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
147
        self.button_location_up = self.toplevel.get_widget('button_location_up')
148
        self.button_location_jump = self.toplevel.get_widget('button_location_jump')
149
        self.entry_location = self.toplevel.get_widget('entry_location')
150
        self.image_location_error = self.toplevel.get_widget('image_location_error')
151
        
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
152
        # Get the History widgets
153
        self.check_history = self.toplevel.get_widget('checkbutton_history')
154
        self.entry_history = self.toplevel.get_widget('entry_history_revno')
155
        self.button_history = self.toplevel.get_widget('button_history_browse')
156
        
0.13.13 by Jelmer Vernooij
Update TODO
157
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
158
        
159
        # Dictionary for signal_autoconnect
160
        dic = { "on_window_main_destroy": gtk.main_quit,
0.13.13 by Jelmer Vernooij
Update TODO
161
                "on_window_main_delete_event": self.on_window_main_delete_event,
162
                "on_quit_activate": self.on_window_main_delete_event,
163
                "on_about_activate": self.on_about_activate,
164
                "on_menuitem_add_files_activate": self.on_menuitem_add_files_activate,
165
                "on_menuitem_remove_file_activate": self.on_menuitem_remove_file_activate,
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
166
                "on_menuitem_file_bookmark_activate": self.on_menuitem_file_bookmark_activate,
0.13.13 by Jelmer Vernooij
Update TODO
167
                "on_menuitem_file_make_directory_activate": self.on_menuitem_file_make_directory_activate,
168
                "on_menuitem_file_move_activate": self.on_menuitem_file_move_activate,
169
                "on_menuitem_file_rename_activate": self.on_menuitem_file_rename_activate,
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
170
                "on_menuitem_file_annotate_activate": self.on_menuitem_file_annotate_activate,
0.13.13 by Jelmer Vernooij
Update TODO
171
                "on_menuitem_view_show_hidden_files_activate": self.on_menuitem_view_show_hidden_files_activate,
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
172
                "on_menuitem_view_show_ignored_files_activate": self.on_menuitem_view_show_ignored_files_activate,
0.13.13 by Jelmer Vernooij
Update TODO
173
                "on_menuitem_view_refresh_activate": self.on_menuitem_view_refresh_activate,
174
                "on_menuitem_branch_initialize_activate": self.on_menuitem_branch_initialize_activate,
175
                "on_menuitem_branch_get_activate": self.on_menuitem_branch_get_activate,
176
                "on_menuitem_branch_checkout_activate": self.on_menuitem_branch_checkout_activate,
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
177
                "on_menuitem_branch_revert_activate": self.on_menuitem_branch_revert_activate,
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
178
                "on_menuitem_branch_merge_activate": self.on_menuitem_branch_merge_activate,
0.13.13 by Jelmer Vernooij
Update TODO
179
                "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
180
                "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
181
                "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
182
                "on_menuitem_branch_update_activate": self.on_menuitem_branch_update_activate,                
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
183
                "on_menuitem_branch_tags_activate": self.on_menuitem_branch_tags_activate,
0.13.13 by Jelmer Vernooij
Update TODO
184
                "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
185
                "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
186
                "on_menuitem_branch_conflicts_activate": self.on_menuitem_branch_conflicts_activate,
0.13.13 by Jelmer Vernooij
Update TODO
187
                "on_menuitem_stats_diff_activate": self.on_menuitem_stats_diff_activate,
188
                "on_menuitem_stats_log_activate": self.on_menuitem_stats_log_activate,
189
                "on_menuitem_stats_infos_activate": self.on_menuitem_stats_infos_activate,
190
                "on_toolbutton_refresh_clicked": self.on_menuitem_view_refresh_activate,
191
                "on_toolbutton_log_clicked": self.on_menuitem_stats_log_activate,
192
                #"on_menutoolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
193
                "on_toolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
194
                "on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
195
                "on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
196
                "on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
197
                "on_toolbutton_update_clicked": self.on_menuitem_branch_update_activate,
0.13.13 by Jelmer Vernooij
Update TODO
198
                "on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
199
                "on_treeview_right_row_activated": self.on_treeview_right_row_activated,
200
                "on_treeview_left_button_press_event": self.on_treeview_left_button_press_event,
435.3.1 by Farkas Szilveszter
Allow opening bookmarks with a single click (#151824).
201
                "on_treeview_left_button_release_event": self.on_treeview_left_button_release_event,
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
202
                "on_treeview_left_row_activated": self.on_treeview_left_row_activated,
203
                "on_button_location_up_clicked": self.on_button_location_up_clicked,
204
                "on_button_location_jump_clicked": self.on_button_location_jump_clicked,
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
205
                "on_entry_location_key_press_event": self.on_entry_location_key_press_event,
206
                "on_checkbutton_history_toggled": self.on_checkbutton_history_toggled,
207
                "on_entry_history_revno_key_press_event": self.on_entry_history_revno_key_press_event,
208
                "on_button_history_browse_clicked": self.on_button_history_browse_clicked
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
209
            }
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
210
        
211
        # Connect the signals to the handlers
212
        self.toplevel.signal_autoconnect(dic)
213
        
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
214
        self._just_started = True
215
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
216
        # Apply window size and position
217
        width = self.pref.get_preference('window_width', 'int')
218
        height = self.pref.get_preference('window_height', 'int')
219
        self.window.resize(width, height)
220
        x = self.pref.get_preference('window_x', 'int')
221
        y = self.pref.get_preference('window_y', 'int')
222
        self.window.move(x, y)
223
        # Apply paned position
224
        pos = self.pref.get_preference('paned_position', 'int')
0.13.13 by Jelmer Vernooij
Update TODO
225
        self.hpaned_main.set_position(pos)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
226
        
227
        # Apply menu to the toolbutton
228
        #menubutton = self.toplevel.get_widget('menutoolbutton_diff')
229
        #menubutton.set_menu(handler.menu.toolbar_diff)
230
        
231
        # Now we can show the window
232
        self.window.show()
233
        
234
        # Show drive selector if under Win32
235
        if sys.platform == 'win32':
195.6.4 by Szilveszter Farkas (Phanatic)
The Windows drive selector was moved to the location bar.
236
            self.hbox_location.pack_start(self.combobox_drive, False, False, 0)
237
            self.hbox_location.reorder_child(self.combobox_drive, 1)
0.13.13 by Jelmer Vernooij
Update TODO
238
            self.combobox_drive.show()
239
            self.gen_hard_selector()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
240
        
241
        self._load_left()
0.13.13 by Jelmer Vernooij
Update TODO
242
243
        # Apply menu state
244
        self.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
245
        self.menuitem_view_show_ignored_files.set_active(self.pref.get_preference('ignored_files', 'bool'))
0.13.13 by Jelmer Vernooij
Update TODO
246
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
247
        # We're starting local
248
        self.remote = False
249
        self.remote_branch = None
250
        self.remote_path = None
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
251
        self.remote_revision = None
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
252
        
0.13.13 by Jelmer Vernooij
Update TODO
253
        self.set_path(os.getcwd())
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
254
        self._load_right()
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
255
        
256
        self._just_started = False
0.13.13 by Jelmer Vernooij
Update TODO
257
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
258
    def set_path(self, path, force_remote=False):
0.13.13 by Jelmer Vernooij
Update TODO
259
        self.notbranch = False
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
260
        
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
261
        if force_remote:
262
            # Forcing remote mode (reading data from inventory)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
263
            self._show_stock_image(gtk.STOCK_DISCONNECT)
264
            try:
265
                br = Branch.open_containing(path)[0]
266
            except bzrerrors.NotBranchError:
267
                self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
268
                self.check_history.set_active(False)
269
                self.check_history.set_sensitive(False)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
270
                return False
271
            except bzrerrors.UnsupportedProtocol:
272
                self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
273
                self.check_history.set_active(False)
274
                self.check_history.set_sensitive(False)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
275
                return False
276
            
277
            self._show_stock_image(gtk.STOCK_CONNECT)
278
            
279
            self.remote = True
280
           
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
281
            # We're remote
282
            self.remote_branch, self.remote_path = Branch.open_containing(path)
283
            
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
284
            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.
285
                self.remote_revision = self.remote_branch.last_revision()
286
            
287
            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.
288
            
289
            if len(self.remote_path) == 0:
195.1.14 by Szilveszter Farkas (Phanatic)
Fixed the determination of tree root.
290
                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.
291
            else:
292
                for (name, type) in self.remote_entries:
293
                    if name == self.remote_path:
294
                        self.remote_parent = type.file_id
295
                        break
296
            
297
            if not path.endswith('/'):
298
                path += '/'
299
            
300
            if self.remote_branch.base == path:
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
301
                self.button_location_up.set_sensitive(False)
302
            else:
303
                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.
304
        else:
305
            if os.path.isdir(path):
306
                self.image_location_error.destroy()
307
                self.remote = False
308
                
309
                # We're local
310
                try:
311
                    self.wt, self.wtpath = WorkingTree.open_containing(path)
312
                except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
313
                    self.notbranch = True
314
                
315
                # If we're in the root, we cannot go up anymore
316
                if sys.platform == 'win32':
317
                    drive, tail = os.path.splitdrive(path)
318
                    if tail in ('', '/', '\\'):
319
                        self.button_location_up.set_sensitive(False)
320
                    else:
321
                        self.button_location_up.set_sensitive(True)
322
                else:
323
                    if self.path == '/':
324
                        self.button_location_up.set_sensitive(False)
325
                    else:
326
                        self.button_location_up.set_sensitive(True)
327
            elif not os.path.isfile(path):
328
                # Doesn't seem to be a file nor a directory, trying to open a
329
                # remote location
330
                self._show_stock_image(gtk.STOCK_DISCONNECT)
331
                try:
332
                    br = Branch.open_containing(path)[0]
333
                except bzrerrors.NotBranchError:
334
                    self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
335
                    self.check_history.set_active(False)
336
                    self.check_history.set_sensitive(False)
337
                    return False
338
                except bzrerrors.UnsupportedProtocol:
339
                    self._show_stock_image(gtk.STOCK_DIALOG_ERROR)
340
                    self.check_history.set_active(False)
341
                    self.check_history.set_sensitive(False)
342
                    return False
343
                
344
                self._show_stock_image(gtk.STOCK_CONNECT)
345
                
346
                self.remote = True
347
               
348
                # We're remote
349
                self.remote_branch, self.remote_path = Branch.open_containing(path)
350
                
351
                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.
352
                    self.remote_revision = self.remote_branch.last_revision()
353
                
354
                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.
355
                
356
                if len(self.remote_path) == 0:
357
                    self.remote_parent = self.remote_branch.repository.get_inventory(self.remote_branch.last_revision()).iter_entries_by_dir().next()[1].file_id
358
                else:
359
                    for (name, type) in self.remote_entries:
360
                        if name == self.remote_path:
361
                            self.remote_parent = type.file_id
362
                            break
363
                
364
                if not path.endswith('/'):
365
                    path += '/'
366
                
367
                if self.remote_branch.base == path:
368
                    self.button_location_up.set_sensitive(False)
369
                else:
370
                    self.button_location_up.set_sensitive(True)
371
        
372
        if self.notbranch:
373
            self.check_history.set_active(False)
374
            self.check_history.set_sensitive(False)
375
        else:
376
            self.check_history.set_sensitive(True)
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
377
        
378
        self.statusbar.push(self.context_id, path)
379
        self.entry_location.set_text(path)
380
        self.path = path
381
        return True
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
382
0.13.13 by Jelmer Vernooij
Update TODO
383
    def get_path(self):
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
384
        if not self.remote:
385
            return self.path
386
        else:
387
            # Remote mode
388
            if len(self.remote_path) > 0:
389
                return self.remote_branch.base + self.remote_path + '/'
390
            else:
391
                return self.remote_branch.base
0.13.13 by Jelmer Vernooij
Update TODO
392
   
393
    def on_about_activate(self, widget):
394
        about()
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
395
    
396
    def on_button_history_browse_clicked(self, widget):
397
        """ Browse for revision button handler. """
398
        if self.remote:
399
            br = self.remote_branch
400
        else:
401
            br = self.wt.branch
402
            
403
        revb = RevisionBrowser(br, self.window)
404
        response = revb.run()
405
        if response != gtk.RESPONSE_NONE:
406
            revb.hide()
407
        
408
            if response == gtk.RESPONSE_OK:
409
                if revb.selected_revno is not None:
410
                    self.entry_history.set_text(revb.selected_revno)
411
            
412
            revb.destroy()
413
    
414
    def on_button_location_jump_clicked(self, widget):
415
        """ Location Jump button handler. """
416
        location = self.entry_location.get_text()
417
        
418
        if self.set_path(location):
419
            self.refresh_right()
420
    
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
421
    def on_button_location_up_clicked(self, widget):
422
        """ Location Up button handler. """
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
423
        if not self.remote:
424
            # Local mode
425
            self.set_path(os.path.split(self.get_path())[0])
426
        else:
427
            # Remote mode
428
            delim = '/'
429
            newpath = delim.join(self.get_path().split(delim)[:-2])
430
            newpath += '/'
431
            self.set_path(newpath)
432
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
433
        self.refresh_right()
434
    
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
435
    def on_checkbutton_history_toggled(self, widget):
436
        """ History Mode toggle handler. """
437
        if self.check_history.get_active():
438
            # History Mode activated
439
            self.entry_history.set_sensitive(True)
440
            self.button_history.set_sensitive(True)
441
        else:
442
            # History Mode deactivated
443
            self.entry_history.set_sensitive(False)
444
            self.button_history.set_sensitive(False)
445
    
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
446
    @show_bzr_error
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
447
    def on_entry_history_revno_key_press_event(self, widget, event):
448
        """ Key pressed handler for the history entry. """
449
        if event.keyval == 65293:
450
            # Return was hit, so we have to load that specific revision
451
            # Emulate being remote, so inventory should be used
452
            path = self.get_path()
453
            if not self.remote:
454
                self.remote = True
455
                self.remote_branch = self.wt.branch
456
            
457
            revno = int(self.entry_history.get_text())
458
            self.remote_revision = self.remote_branch.get_rev_id(revno)
459
            if self.set_path(path, True):
460
                self.refresh_right()
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
461
    
462
    def on_entry_location_key_press_event(self, widget, event):
463
        """ Key pressed handler for the location entry. """
464
        if event.keyval == 65293:
465
            # Return was hit, so we have to jump
466
            self.on_button_location_jump_clicked(widget)
467
    
0.13.13 by Jelmer Vernooij
Update TODO
468
    def on_menuitem_add_files_activate(self, widget):
469
        """ Add file(s)... menu handler. """
470
        from add import OliveAdd
471
        add = OliveAdd(self.wt, self.wtpath, self.get_selected_right())
472
        add.display()
473
    
474
    def on_menuitem_branch_get_activate(self, widget):
475
        """ Branch/Get... menu handler. """
154 by Jelmer Vernooij
Add trivial generic class for storing URL history.
476
        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.
477
        
478
        if self.remote:
479
            branch = BranchDialog(os.getcwd(), self.window, self.remote_branch.base)
480
        else:
481
            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.
482
        response = branch.run()
483
        if response != gtk.RESPONSE_NONE:
484
            branch.hide()
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
485
            
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
486
            if response == gtk.RESPONSE_OK:
487
                self.refresh_right()
488
            
489
            branch.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
490
    
491
    def on_menuitem_branch_checkout_activate(self, widget):
492
        """ Branch/Checkout... menu handler. """
154 by Jelmer Vernooij
Add trivial generic class for storing URL history.
493
        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.
494
        
495
        if self.remote:
496
            checkout = CheckoutDialog(os.getcwd(), self.window, self.remote_branch.base)
497
        else:
498
            checkout = CheckoutDialog(self.get_path(), self.window)
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
499
        response = checkout.run()
500
        if response != gtk.RESPONSE_NONE:
501
            checkout.hide()
502
        
503
            if response == gtk.RESPONSE_OK:
504
                self.refresh_right()
505
            
506
            checkout.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
507
    
147 by Jelmer Vernooij
Remove a bunch of duplicate functionality.
508
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
509
    def on_menuitem_branch_commit_activate(self, widget):
510
        """ Branch/Commit... menu handler. """
278.1.35 by John Arbash Meinel
Make use of the 'selected' parameter to CommitDialog.
511
#     def __init__(self, wt, wtpath, notbranch, selected=None, parent=None):
512
        selected = self.get_selected_right()
513
        if selected:
514
            selected = os.path.join(self.wtpath, selected)
515
        commit = CommitDialog(wt=self.wt,
516
                              parent=self.window,
517
                              selected=selected,
518
                             )
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
519
        response = commit.run()
520
        if response != gtk.RESPONSE_NONE:
521
            commit.hide()
522
        
523
            if response == gtk.RESPONSE_OK:
524
                self.refresh_right()
525
            
526
            commit.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
527
    
126.1.26 by Szilveszter Farkas (Phanatic)
Added Conflicts entry to the Branch menu.
528
    def on_menuitem_branch_conflicts_activate(self, widget):
529
        """ Branch/Conflicts... menu handler. """
530
        conflicts = ConflictsDialog(self.wt, self.window)
531
        response = conflicts.run()
532
        if response != gtk.RESPONSE_NONE:
533
            conflicts.destroy()
534
    
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
535
    def on_menuitem_branch_merge_activate(self, widget):
536
        """ Branch/Merge... menu handler. """
154 by Jelmer Vernooij
Add trivial generic class for storing URL history.
537
        from bzrlib.plugins.gtk.merge import MergeDialog
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
538
        
539
        if self.check_for_changes():
540
            error_dialog(_('There are local changes in the branch'),
541
                         _('Please commit or revert the changes before merging.'))
542
        else:
274.1.2 by Mateusz Korniak
Add default_branch_path to MergeDialog and use it from olive-gtk
543
            parent_branch_path = self.wt.branch.get_parent()
544
            merge = MergeDialog(self.wt, self.wtpath,default_branch_path=parent_branch_path )
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
545
            merge.display()
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
546
155 by Jelmer Vernooij
Fix a couple of smaller bugs.
547
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
548
    def on_menuitem_branch_missing_revisions_activate(self, widget):
549
        """ Branch/Missing revisions menu handler. """
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
550
        
551
        from bzrlib.missing import find_unmerged, iter_log_revisions
552
        
0.13.13 by Jelmer Vernooij
Update TODO
553
        local_branch = self.wt.branch
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
554
        parent_branch_path = local_branch.get_parent()
555
        if parent_branch_path is None:
0.13.13 by Jelmer Vernooij
Update TODO
556
            error_dialog(_('Parent location is unknown'),
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
557
                         _('Cannot determine missing revisions if no parent location is known.'))
0.13.13 by Jelmer Vernooij
Update TODO
558
            return
559
        
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
560
        parent_branch = Branch.open(parent_branch_path)
561
        
562
        if parent_branch.base == local_branch.base:
563
            parent_branch = local_branch
564
        
565
        local_extra, remote_extra = find_unmerged(local_branch,parent_branch)
566
567
        if local_extra or remote_extra:
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
568
            
569
            ## def log_revision_one_line_text(log_revision):
570
            ##    """ Generates one line description of log_revison ended with end of line."""
571
            ##    revision = log_revision.rev
572
            ##    txt =  "- %s (%s)\n" % (revision.get_summary(), revision.committer, )
573
            ##    txt = txt.replace("<"," ") # Seems < > chars are expected to be xml tags ...
574
            ##    txt = txt.replace(">"," ")
575
            ##    return txt
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
576
            
577
            dlg_txt = ""
578
            if local_extra:
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
579
                dlg_txt += _('%d local extra revision(s). \n') % (len(local_extra),) 
580
                ## NOTE: We do not want such ugly info about missing revisions
581
                ##       Revision Browser should be used there
582
                ## max_revisions = 10
583
                ## for log_revision in iter_log_revisions(local_extra, local_branch.repository, verbose=1):
584
                ##    dlg_txt += log_revision_one_line_text(log_revision)
585
                ##    if max_revisions <= 0:
586
                ##        dlg_txt += _("more ... \n")
587
                ##        break
588
                ## max_revisions -= 1
589
            ## dlg_txt += "\n"
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
590
            if remote_extra:
274.1.4 by Mateusz Korniak
Commented out one line description of log_revison in dialogs.
591
                dlg_txt += _('%d local missing revision(s).\n') % (len(remote_extra),) 
592
                ## max_revisions = 10
593
                ## for log_revision in iter_log_revisions(remote_extra, parent_branch.repository, verbose=1):
594
                ##    dlg_txt += log_revision_one_line_text(log_revision)
595
                ##    if max_revisions <= 0:
596
                ##        dlg_txt += _("more ... \n")
597
                ##        break
598
                ##    max_revisions -= 1
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
599
                
0.13.13 by Jelmer Vernooij
Update TODO
600
            info_dialog(_('There are missing revisions'),
274.1.1 by Mateusz Korniak
Use find_unmerged() instead of branch.missing_revisions().
601
                        dlg_txt)
0.13.13 by Jelmer Vernooij
Update TODO
602
        else:
603
            info_dialog(_('Local branch up to date'),
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
604
                        _('There are no missing revisions.'))
0.13.13 by Jelmer Vernooij
Update TODO
605
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.
606
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
607
    def on_menuitem_branch_pull_activate(self, widget):
608
        """ Branch/Pull menu handler. """
609
        branch_to = self.wt.branch
610
611
        location = branch_to.get_parent()
612
        if location is None:
613
            error_dialog(_('Parent location is unknown'),
614
                                     _('Pulling is not possible until there is a parent location.'))
615
            return
616
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.
617
        branch_from = Branch.open(location)
0.13.13 by Jelmer Vernooij
Update TODO
618
619
        if branch_to.get_parent() is None:
620
            branch_to.set_parent(branch_from.base)
621
0.14.14 by Alexander Belchenko
get number of pulled revision: it's return value of branch.pull() method
622
        ret = branch_to.pull(branch_from)
0.13.13 by Jelmer Vernooij
Update TODO
623
        
624
        info_dialog(_('Pull successful'), _('%d revision(s) pulled.') % ret)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
625
        
626
    @show_bzr_error
627
    def on_menuitem_branch_update_activate(self, widget):
628
        """ Brranch/checkout update menu handler. """
629
        
630
        ret = self.wt.update()
631
        conflicts = self.wt.conflicts()
632
        if conflicts:
633
            info_dialog(_('Update successful but conflicts generated'), _('Number of conflicts generated: %d.') % (len(conflicts),) )
634
        else:
635
            info_dialog(_('Update successful'), _('No conflicts generated.') )
0.13.13 by Jelmer Vernooij
Update TODO
636
    
637
    def on_menuitem_branch_push_activate(self, widget):
638
        """ Branch/Push... menu handler. """
266.1.1 by Mateusz Korniak
Fixed interface to push.PushDialog
639
        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.
640
        response = push.run()
641
        if response != gtk.RESPONSE_NONE:
642
            push.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
643
    
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
644
    @show_bzr_error
645
    def on_menuitem_branch_revert_activate(self, widget):
646
        """ Branch/Revert all changes menu handler. """
647
        ret = self.wt.revert([])
648
        if ret:
649
            warning_dialog(_('Conflicts detected'),
650
                           _('Please have a look at the working tree before continuing.'))
651
        else:
652
            info_dialog(_('Revert successful'),
653
                        _('All files reverted to last revision.'))
654
        self.refresh_right()
655
    
0.13.13 by Jelmer Vernooij
Update TODO
656
    def on_menuitem_branch_status_activate(self, widget):
657
        """ Branch/Status... menu handler. """
156 by Jelmer Vernooij
Move status to the top-level, remove its use of glade and allow double-clicking on entries to get at the diff for a file.
658
        from bzrlib.plugins.gtk.status import StatusDialog
659
        status = StatusDialog(self.wt, self.wtpath)
195.3.1 by Szilveszter Farkas (Phanatic)
Fixed Branch -> Status in Olive (no more traceback).
660
        response = status.run()
661
        if response != gtk.RESPONSE_NONE:
662
            status.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
663
    
664
    def on_menuitem_branch_initialize_activate(self, widget):
665
        """ Initialize current directory. """
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
666
        init = InitDialog(self.path, self.window)
667
        response = init.run()
668
        if response != gtk.RESPONSE_NONE:
669
            init.hide()
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
670
        
188.1.3 by Szilveszter Farkas (Phanatic)
Added the new Initialize dialog to Olive.
671
            if response == gtk.RESPONSE_OK:
672
                self.refresh_right()
673
            
674
            init.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
675
        
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
676
    def on_menuitem_branch_tags_activate(self, widget):
677
        """ Branch/Tags... menu handler. """
678
        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.
679
        if not self.remote:
680
            window = TagsWindow(self.wt.branch, self.window)
681
        else:
682
            window = TagsWindow(self.remote_branch, self.window)
190.1.8 by Szilveszter Farkas (Phanatic)
Added Tags entry to the Branch menu in Olive.
683
        window.show()
684
    
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
685
    def on_menuitem_file_annotate_activate(self, widget):
686
        """ File/Annotate... menu handler. """
687
        if self.get_selected_right() is None:
688
            error_dialog(_('No file was selected'),
689
                         _('Please select a file from the list.'))
690
            return
691
        
692
        branch = self.wt.branch
693
        file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
694
        
275.1.6 by Daniel Schierbeck
Made Ctrl-W call gtk.main_quit if the window has no parent.
695
        window = GAnnotateWindow(all=False, plain=False, parent=self.window)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
696
        window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
697
        config = GAnnotateConfig(window)
698
        window.show()
699
        branch.lock_read()
700
        try:
66.2.17 by Aaron Bentley
Update olive to use current bzr.dev API. Used _repo_relpath. Bad phanatic!
701
            window.annotate(self.wt, branch, file_id)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
702
        finally:
703
            branch.unlock()
704
    
435.2.1 by Szilveszter Farkas (Phanatic)
Added a Bookmark current directory to the File menu (#130245).
705
    def on_menuitem_file_bookmark_activate(self, widget):
706
        """ File/Bookmark current directory menu handler. """
707
        if self.pref.add_bookmark(self.path):
708
            info_dialog(_('Bookmark successfully added'),
709
                        _('The current directory was bookmarked. You can reach\nit by selecting it from the left panel.'))
710
            self.pref.write()
711
        else:
712
            warning_dialog(_('Location already bookmarked'),
713
                           _('The current directory is already bookmarked.\nSee the left panel for reference.'))
714
        
715
        self.refresh_left()
716
    
0.13.13 by Jelmer Vernooij
Update TODO
717
    def on_menuitem_file_make_directory_activate(self, widget):
718
        """ File/Make directory... menu handler. """
719
        from mkdir import OliveMkdir
720
        mkdir = OliveMkdir(self.wt, self.wtpath)
721
        mkdir.display()
722
    
723
    def on_menuitem_file_move_activate(self, widget):
724
        """ File/Move... menu handler. """
725
        from move import OliveMove
726
        move = OliveMove(self.wt, self.wtpath, self.get_selected_right())
727
        move.display()
728
    
729
    def on_menuitem_file_rename_activate(self, widget):
730
        """ File/Rename... menu handler. """
731
        from rename import OliveRename
732
        rename = OliveRename(self.wt, self.wtpath, self.get_selected_right())
733
        rename.display()
734
735
    def on_menuitem_remove_file_activate(self, widget):
736
        """ Remove (unversion) selected file. """
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
737
        from remove import OliveRemoveDialog
738
        remove = OliveRemoveDialog(self.wt, self.wtpath,
739
                                   selected=self.get_selected_right(),
121 by Szilveszter Farkas (Phanatic)
Use OliveBookmarkDialog instead of OliveBookmark.
740
                                   parent=self.window)
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
741
        response = remove.run()
742
        
743
        if response != gtk.RESPONSE_NONE:
744
            remove.hide()
745
        
746
            if response == gtk.RESPONSE_OK:
747
                self.set_path(self.path)
748
                self.refresh_right()
749
            
750
            remove.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
751
    
752
    def on_menuitem_stats_diff_activate(self, widget):
753
        """ 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.
754
        window = DiffWindow(parent=self.window)
0.13.13 by Jelmer Vernooij
Update TODO
755
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
756
        window.set_diff(self.wt.branch.nick, self.wt, parent_tree)
757
        window.show()
758
    
759
    def on_menuitem_stats_infos_activate(self, widget):
760
        """ Statistics/Informations... menu handler. """
761
        from info import OliveInfo
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
762
        if self.remote:
763
            info = OliveInfo(self.remote_branch)
764
        else:
765
            info = OliveInfo(self.wt.branch)
0.13.13 by Jelmer Vernooij
Update TODO
766
        info.display()
767
    
768
    def on_menuitem_stats_log_activate(self, widget):
769
        """ Statistics/Log... menu handler. """
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
770
195.1.20 by Szilveszter Farkas (Phanatic)
Make bzrk working with remote branches.
771
        if not self.remote:
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
772
            branch = self.wt.branch
195.1.20 by Szilveszter Farkas (Phanatic)
Make bzrk working with remote branches.
773
        else:
315 by Daniel Schierbeck
Removed BranchWindow.set_branch(), used constructor instead.
774
            branch = self.remote_branch
775
776
        window = branchwin.BranchWindow(branch, branch.last_revision(), None, parent=self.window)
0.13.13 by Jelmer Vernooij
Update TODO
777
        window.show()
778
    
779
    def on_menuitem_view_refresh_activate(self, widget):
780
        """ View/Refresh menu handler. """
781
        # Refresh the left pane
782
        self.refresh_left()
783
        # Refresh the right pane
784
        self.refresh_right()
785
   
786
    def on_menuitem_view_show_hidden_files_activate(self, widget):
787
        """ View/Show hidden files menu handler. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
788
        self.pref.set_preference('dotted_files', widget.get_active())
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
789
        if self.path is not None:
790
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
791
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
792
    def on_menuitem_view_show_ignored_files_activate(self, widget):
793
        """ Hide/Show ignored files menu handler. """
794
        self.pref.set_preference('ignored_files', widget.get_active())
795
        if self.path is not None:
796
            self.refresh_right()
797
            
0.13.13 by Jelmer Vernooij
Update TODO
798
    def on_treeview_left_button_press_event(self, widget, event):
799
        """ Occurs when somebody right-clicks in the bookmark list. """
800
        if event.button == 3:
801
            # Don't show context with nothing selected
802
            if self.get_selected_left() == None:
803
                return
804
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
805
            # Create a menu
806
            from menu import OliveMenu
121 by Szilveszter Farkas (Phanatic)
Use OliveBookmarkDialog instead of OliveBookmark.
807
            menu = OliveMenu(path=self.get_path(),
808
                             selected=self.get_selected_left(),
809
                             app=self)
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
810
            
811
            menu.left_context_menu().popup(None, None, None, 0,
812
                                           event.time)
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
813
435.3.1 by Farkas Szilveszter
Allow opening bookmarks with a single click (#151824).
814
    def on_treeview_left_button_release_event(self, widget, event):
815
        """ Occurs when somebody just clicks a bookmark. """
816
        if event.button != 3:
817
            # Allow one-click bookmark opening
818
            if self.get_selected_left() == None:
819
                return
820
            
821
            newdir = self.get_selected_left()
822
            if newdir == None:
823
                return
824
825
            if self.set_path(newdir):
826
                self.refresh_right()
827
0.13.13 by Jelmer Vernooij
Update TODO
828
    def on_treeview_left_row_activated(self, treeview, path, view_column):
829
        """ Occurs when somebody double-clicks or enters an item in the
830
        bookmark list. """
831
832
        newdir = self.get_selected_left()
833
        if newdir == None:
834
            return
835
195.1.16 by Szilveszter Farkas (Phanatic)
Switching between local and remote locations fixed.
836
        if self.set_path(newdir):
837
            self.refresh_right()
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
838
0.13.13 by Jelmer Vernooij
Update TODO
839
    def on_treeview_right_button_press_event(self, widget, event):
840
        """ Occurs when somebody right-clicks in the file list. """
841
        if event.button == 3:
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
842
            # Create a menu
843
            from menu import OliveMenu
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
844
            menu = OliveMenu(path=self.get_path(),
845
                             selected=self.get_selected_right(),
846
                             app=self)
0.13.13 by Jelmer Vernooij
Update TODO
847
            # get the menu items
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
848
            m_open = menu.ui.get_widget('/context_right/open')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
849
            m_add = menu.ui.get_widget('/context_right/add')
850
            m_remove = menu.ui.get_widget('/context_right/remove')
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
851
            m_rename = menu.ui.get_widget('/context_right/rename')
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
852
            m_revert = menu.ui.get_widget('/context_right/revert')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
853
            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.
854
            m_annotate = menu.ui.get_widget('/context_right/annotate')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
855
            m_diff = menu.ui.get_widget('/context_right/diff')
0.13.13 by Jelmer Vernooij
Update TODO
856
            # check if we're in a branch
857
            try:
858
                from bzrlib.branch import Branch
859
                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.
860
                if self.remote:
861
                    m_open.set_sensitive(False)
862
                    m_add.set_sensitive(False)
863
                    m_remove.set_sensitive(False)
864
                    m_rename.set_sensitive(False)
865
                    m_revert.set_sensitive(False)
866
                    m_commit.set_sensitive(False)
867
                    m_annotate.set_sensitive(False)
868
                    m_diff.set_sensitive(False)
869
                else:
870
                    m_open.set_sensitive(True)
871
                    m_add.set_sensitive(True)
872
                    m_remove.set_sensitive(True)
873
                    m_rename.set_sensitive(True)
874
                    m_revert.set_sensitive(True)
875
                    m_commit.set_sensitive(True)
876
                    m_annotate.set_sensitive(True)
877
                    m_diff.set_sensitive(True)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
878
            except bzrerrors.NotBranchError:
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
879
                m_open.set_sensitive(True)
0.13.13 by Jelmer Vernooij
Update TODO
880
                m_add.set_sensitive(False)
881
                m_remove.set_sensitive(False)
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
882
                m_rename.set_sensitive(False)
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
883
                m_revert.set_sensitive(False)
0.13.13 by Jelmer Vernooij
Update TODO
884
                m_commit.set_sensitive(False)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
885
                m_annotate.set_sensitive(False)
0.13.13 by Jelmer Vernooij
Update TODO
886
                m_diff.set_sensitive(False)
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
887
195.1.24 by Szilveszter Farkas (Phanatic)
The History feature kinda works now, but still needs some polishing.
888
            if not self.remote:
889
                menu.right_context_menu().popup(None, None, None, 0,
890
                                                event.time)
891
            else:
892
                menu.remote_context_menu().popup(None, None, None, 0,
893
                                                 event.time)
0.13.13 by Jelmer Vernooij
Update TODO
894
        
895
    def on_treeview_right_row_activated(self, treeview, path, view_column):
896
        """ Occurs when somebody double-clicks or enters an item in the
897
        file list. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
898
        from launch import launch
899
        
0.13.13 by Jelmer Vernooij
Update TODO
900
        newdir = self.get_selected_right()
901
        
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
902
        if not self.remote:
903
            # We're local
904
            if newdir == '..':
905
                self.set_path(os.path.split(self.get_path())[0])
906
            else:
907
                fullpath = os.path.join(self.get_path(), newdir)
908
                if os.path.isdir(fullpath):
909
                    # selected item is an existant directory
910
                    self.set_path(fullpath)
911
                else:
912
                    launch(fullpath)
0.13.13 by Jelmer Vernooij
Update TODO
913
        else:
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
914
            # We're remote
915
            if self._is_remote_dir(self.get_path() + newdir):
916
                self.set_path(self.get_path() + newdir)
0.13.13 by Jelmer Vernooij
Update TODO
917
        
918
        self.refresh_right()
919
    
920
    def on_window_main_delete_event(self, widget, event=None):
921
        """ Do some stuff before exiting. """
922
        width, height = self.window_main.get_size()
923
        self.pref.set_preference('window_width', width)
924
        self.pref.set_preference('window_height', height)
925
        x, y = self.window_main.get_position()
926
        self.pref.set_preference('window_x', x)
927
        self.pref.set_preference('window_y', y)
928
        self.pref.set_preference('paned_position',
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
929
                                 self.hpaned_main.get_position())
0.13.13 by Jelmer Vernooij
Update TODO
930
        
931
        self.pref.write()
932
        self.window_main.destroy()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
933
        
934
    def _load_left(self):
935
        """ Load data into the left panel. (Bookmarks) """
936
        # Create TreeStore
937
        treestore = gtk.TreeStore(str, str)
938
        
939
        # Get bookmarks
0.13.13 by Jelmer Vernooij
Update TODO
940
        bookmarks = self.pref.get_bookmarks()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
941
        
942
        # Add them to the TreeStore
943
        titer = treestore.append(None, [_('Bookmarks'), None])
944
        for item in bookmarks:
0.13.13 by Jelmer Vernooij
Update TODO
945
            title = self.pref.get_bookmark_title(item)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
946
            treestore.append(titer, [title, item])
947
        
948
        # Create the column and add it to the TreeView
949
        self.treeview_left.set_model(treestore)
950
        tvcolumn_bookmark = gtk.TreeViewColumn(_('Bookmark'))
951
        self.treeview_left.append_column(tvcolumn_bookmark)
952
        
953
        # Set up the cells
954
        cell = gtk.CellRendererText()
955
        tvcolumn_bookmark.pack_start(cell, True)
956
        tvcolumn_bookmark.add_attribute(cell, 'text', 0)
957
        
958
        # Expand the tree
959
        self.treeview_left.expand_all()
960
961
    def _load_right(self):
962
        """ Load data into the right panel. (Filelist) """
963
        # Create ListStore
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
964
        # Model: [ icon, dir, name, status text, status, size (int), size (human), mtime (int), mtime (local), fileid ]
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
965
        liststore = gtk.ListStore(gobject.TYPE_STRING,
966
                                  gobject.TYPE_BOOLEAN,
967
                                  gobject.TYPE_STRING,
968
                                  gobject.TYPE_STRING,
969
                                  gobject.TYPE_STRING,
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
970
                                  gobject.TYPE_STRING,
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
971
                                  gobject.TYPE_STRING,
972
                                  gobject.TYPE_INT,
973
                                  gobject.TYPE_STRING,
974
                                  gobject.TYPE_STRING)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
975
        
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
976
        dirs = []
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
977
        files = []
978
        
979
        # Fill the appropriate lists
980
        dotted_files = self.pref.get_preference('dotted_files', 'bool')
0.13.13 by Jelmer Vernooij
Update TODO
981
        for item in os.listdir(self.path):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
982
            if not dotted_files and item[0] == '.':
983
                continue
0.13.13 by Jelmer Vernooij
Update TODO
984
            if os.path.isdir(self.path + os.sep + item):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
985
                dirs.append(item)
986
            else:
987
                files.append(item)
988
        
0.13.13 by Jelmer Vernooij
Update TODO
989
        if not self.notbranch:
990
            branch = self.wt.branch
991
            tree2 = self.wt.branch.repository.revision_tree(branch.last_revision())
992
        
993
            delta = self.wt.changes_from(tree2, want_unchanged=True)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
994
        
995
        # Add'em to the ListStore
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
996
        for item in dirs:
423.12.1 by Farkas Szilveszter
A fix for the bad symlinks bug.
997
            try:
998
                statinfo = os.stat(self.path + os.sep + item)
999
            except OSError, e:
1000
                if e.errno == 40:
1001
                    continue
1002
                else:
1003
                    raise
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1004
            liststore.append([ gtk.STOCK_DIRECTORY,
1005
                               True,
1006
                               item,
1007
                               '',
1008
                               '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1009
                               "<DIR>",
1010
                               "<DIR>",
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1011
                               statinfo.st_mtime,
1012
                               self._format_date(statinfo.st_mtime),
1013
                               ''])
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1014
        for item in files:
1015
            status = 'unknown'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1016
            fileid = ''
0.13.13 by Jelmer Vernooij
Update TODO
1017
            if not self.notbranch:
1018
                filename = self.wt.relpath(self.path + os.sep + item)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1019
                
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1020
                try:
1021
                    self.wt.lock_read()
1022
                    
1023
                    for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1024
                        if rpathnew == filename:
1025
                            status = 'renamed'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1026
                            fileid = id
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1027
                    for rpath, id, kind in delta.added:
1028
                        if rpath == filename:
1029
                            status = 'added'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1030
                            fileid = id
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1031
                    for rpath, id, kind in delta.removed:
1032
                        if rpath == filename:
1033
                            status = 'removed'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1034
                            fileid = id
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1035
                    for rpath, id, kind, text_modified, meta_modified in delta.modified:
1036
                        if rpath == filename:
1037
                            status = 'modified'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1038
                            fileid = id
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1039
                    for rpath, id, kind in delta.unchanged:
1040
                        if rpath == filename:
1041
                            status = 'unchanged'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1042
                            fileid = id
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1043
                    for rpath, file_class, kind, id, entry in self.wt.list_files():
1044
                        if rpath == filename and file_class == 'I':
1045
                            status = 'ignored'
1046
                finally:
1047
                    self.wt.unlock()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1048
            
1049
            if status == 'renamed':
1050
                st = _('renamed')
1051
            elif status == 'removed':
1052
                st = _('removed')
1053
            elif status == 'added':
1054
                st = _('added')
1055
            elif status == 'modified':
1056
                st = _('modified')
1057
            elif status == 'unchanged':
1058
                st = _('unchanged')
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
1059
            elif status == 'ignored':
1060
                st = _('ignored')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1061
            else:
1062
                st = _('unknown')
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1063
            
423.12.1 by Farkas Szilveszter
A fix for the bad symlinks bug.
1064
            try:
1065
                statinfo = os.stat(self.path + os.sep + item)
1066
            except OSError, e:
1067
                if e.errno == 40:
1068
                    continue
1069
                else:
1070
                    raise
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1071
            liststore.append([gtk.STOCK_FILE,
1072
                              False,
1073
                              item,
1074
                              st,
1075
                              status,
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1076
                              str(statinfo.st_size), # NOTE: if int used there it will fail for large files (size expressed as long int)
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1077
                              self._format_size(statinfo.st_size),
1078
                              statinfo.st_mtime,
1079
                              self._format_date(statinfo.st_mtime),
1080
                              fileid])
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1081
        
1082
        # Create the columns and add them to the TreeView
1083
        self.treeview_right.set_model(liststore)
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1084
        self._tvcolumn_filename = gtk.TreeViewColumn(_('Filename'))
1085
        self._tvcolumn_status = gtk.TreeViewColumn(_('Status'))
1086
        self._tvcolumn_size = gtk.TreeViewColumn(_('Size'))
1087
        self._tvcolumn_mtime = gtk.TreeViewColumn(_('Last modified'))
1088
        self.treeview_right.append_column(self._tvcolumn_filename)
1089
        self.treeview_right.append_column(self._tvcolumn_status)
1090
        self.treeview_right.append_column(self._tvcolumn_size)
1091
        self.treeview_right.append_column(self._tvcolumn_mtime)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1092
        
1093
        # Set up the cells
1094
        cellpb = gtk.CellRendererPixbuf()
1095
        cell = gtk.CellRendererText()
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1096
        self._tvcolumn_filename.pack_start(cellpb, False)
1097
        self._tvcolumn_filename.pack_start(cell, True)
1098
        self._tvcolumn_filename.set_attributes(cellpb, stock_id=0)
1099
        self._tvcolumn_filename.add_attribute(cell, 'text', 2)
1100
        self._tvcolumn_status.pack_start(cell, True)
1101
        self._tvcolumn_status.add_attribute(cell, 'text', 3)
1102
        self._tvcolumn_size.pack_start(cell, True)
1103
        self._tvcolumn_size.add_attribute(cell, 'text', 6)
1104
        self._tvcolumn_mtime.pack_start(cell, True)
1105
        self._tvcolumn_mtime.add_attribute(cell, 'text', 8)
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1106
        
1107
        # Set up the properties of the TreeView
1108
        self.treeview_right.set_headers_visible(True)
1109
        self.treeview_right.set_headers_clickable(True)
1110
        self.treeview_right.set_search_column(1)
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1111
        self._tvcolumn_filename.set_resizable(True)
1112
        self._tvcolumn_status.set_resizable(True)
1113
        self._tvcolumn_size.set_resizable(True)
1114
        self._tvcolumn_mtime.set_resizable(True)
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1115
        # Set up sorting
1116
        liststore.set_sort_func(13, self._sort_filelist_callback, None)
1117
        liststore.set_sort_column_id(13, gtk.SORT_ASCENDING)
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1118
        self._tvcolumn_filename.set_sort_column_id(13)
1119
        self._tvcolumn_status.set_sort_column_id(3)
1120
        self._tvcolumn_size.set_sort_column_id(5)
1121
        self._tvcolumn_mtime.set_sort_column_id(7)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
1122
        
1123
        # Set sensitivity
1124
        self.set_sensitivity()
0.13.13 by Jelmer Vernooij
Update TODO
1125
        
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1126
    def get_selected_fileid(self):
1127
        """ Get the file_id of the selected file. """
1128
        treeselection = self.treeview_right.get_selection()
1129
        (model, iter) = treeselection.get_selected()
1130
        
1131
        if iter is None:
1132
            return None
1133
        else:
1134
            return model.get_value(iter, 9)
1135
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1136
    def get_selected_right(self):
1137
        """ Get the selected filename. """
1138
        treeselection = self.treeview_right.get_selection()
1139
        (model, iter) = treeselection.get_selected()
1140
        
1141
        if iter is None:
1142
            return None
1143
        else:
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1144
            return model.get_value(iter, 2)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1145
    
1146
    def get_selected_left(self):
1147
        """ Get the selected bookmark. """
1148
        treeselection = self.treeview_left.get_selection()
1149
        (model, iter) = treeselection.get_selected()
1150
        
1151
        if iter is None:
1152
            return None
1153
        else:
1154
            return model.get_value(iter, 1)
1155
1156
    def set_statusbar(self, message):
1157
        """ Set the statusbar message. """
1158
        self.statusbar.push(self.context_id, message)
1159
    
1160
    def clear_statusbar(self):
1161
        """ Clean the last message from the statusbar. """
1162
        self.statusbar.pop(self.context_id)
1163
    
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
1164
    def set_sensitivity(self):
1165
        """ Set menu and toolbar sensitivity. """
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
1166
        if not self.remote:
1167
            # We're local
1168
            self.menuitem_branch_init.set_sensitive(self.notbranch)
1169
            self.menuitem_branch_get.set_sensitive(self.notbranch)
1170
            self.menuitem_branch_checkout.set_sensitive(self.notbranch)
1171
            self.menuitem_branch_pull.set_sensitive(not self.notbranch)
1172
            self.menuitem_branch_push.set_sensitive(not self.notbranch)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
1173
            self.menuitem_branch_update.set_sensitive(not self.notbranch)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
1174
            self.menuitem_branch_revert.set_sensitive(not self.notbranch)
1175
            self.menuitem_branch_merge.set_sensitive(not self.notbranch)
1176
            self.menuitem_branch_commit.set_sensitive(not self.notbranch)
1177
            self.menuitem_branch_tags.set_sensitive(not self.notbranch)
1178
            self.menuitem_branch_status.set_sensitive(not self.notbranch)
1179
            self.menuitem_branch_missing.set_sensitive(not self.notbranch)
1180
            self.menuitem_branch_conflicts.set_sensitive(not self.notbranch)
1181
            self.menuitem_stats.set_sensitive(not self.notbranch)
1182
            self.menuitem_stats_diff.set_sensitive(not self.notbranch)
1183
            self.menuitem_add_files.set_sensitive(not self.notbranch)
1184
            self.menuitem_remove_files.set_sensitive(not self.notbranch)
1185
            self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
1186
            self.menuitem_file_rename.set_sensitive(not self.notbranch)
1187
            self.menuitem_file_move.set_sensitive(not self.notbranch)
1188
            self.menuitem_file_annotate.set_sensitive(not self.notbranch)
1189
            #self.menutoolbutton_diff.set_sensitive(True)
1190
            self.toolbutton_diff.set_sensitive(not self.notbranch)
1191
            self.toolbutton_log.set_sensitive(not self.notbranch)
1192
            self.toolbutton_commit.set_sensitive(not self.notbranch)
1193
            self.toolbutton_pull.set_sensitive(not self.notbranch)
1194
            self.toolbutton_push.set_sensitive(not self.notbranch)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
1195
            self.toolbutton_update.set_sensitive(not self.notbranch)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
1196
        else:
1197
            # We're remote
1198
            self.menuitem_branch_init.set_sensitive(False)
1199
            self.menuitem_branch_get.set_sensitive(True)
1200
            self.menuitem_branch_checkout.set_sensitive(True)
1201
            self.menuitem_branch_pull.set_sensitive(False)
1202
            self.menuitem_branch_push.set_sensitive(False)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
1203
            self.menuitem_branch_update.set_sensitive(False)
195.1.21 by Szilveszter Farkas (Phanatic)
Some small modifications to Branch, Checkout and Info to support remote branches.
1204
            self.menuitem_branch_revert.set_sensitive(False)
1205
            self.menuitem_branch_merge.set_sensitive(False)
1206
            self.menuitem_branch_commit.set_sensitive(False)
1207
            self.menuitem_branch_tags.set_sensitive(True)
1208
            self.menuitem_branch_status.set_sensitive(False)
1209
            self.menuitem_branch_missing.set_sensitive(False)
1210
            self.menuitem_branch_conflicts.set_sensitive(False)
1211
            self.menuitem_stats.set_sensitive(True)
1212
            self.menuitem_stats_diff.set_sensitive(False)
1213
            self.menuitem_add_files.set_sensitive(False)
1214
            self.menuitem_remove_files.set_sensitive(False)
1215
            self.menuitem_file_make_directory.set_sensitive(False)
1216
            self.menuitem_file_rename.set_sensitive(False)
1217
            self.menuitem_file_move.set_sensitive(False)
1218
            self.menuitem_file_annotate.set_sensitive(False)
1219
            #self.menutoolbutton_diff.set_sensitive(True)
1220
            self.toolbutton_diff.set_sensitive(False)
1221
            self.toolbutton_log.set_sensitive(True)
1222
            self.toolbutton_commit.set_sensitive(False)
1223
            self.toolbutton_pull.set_sensitive(False)
1224
            self.toolbutton_push.set_sensitive(False)
263.2.1 by matkor
Code for "branch update" menuitem and toolbox. Typo fix
1225
            self.toolbutton_update.set_sensitive(False)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
1226
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1227
    def refresh_left(self):
1228
        """ Refresh the bookmark list. """
1229
        
1230
        # Get TreeStore and clear it
1231
        treestore = self.treeview_left.get_model()
1232
        treestore.clear()
1233
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
1234
        # Re-read preferences
1235
        self.pref.read()
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
1236
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1237
        # Get bookmarks
1238
        bookmarks = self.pref.get_bookmarks()
1239
1240
        # Add them to the TreeStore
1241
        titer = treestore.append(None, [_('Bookmarks'), None])
1242
        for item in bookmarks:
1243
            title = self.pref.get_bookmark_title(item)
1244
            treestore.append(titer, [title, item])
1245
1246
        # Add the TreeStore to the TreeView
1247
        self.treeview_left.set_model(treestore)
1248
1249
        # Expand the tree
1250
        self.treeview_left.expand_all()
1251
1252
    def refresh_right(self, path=None):
1253
        """ Refresh the file list. """
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1254
        if not self.remote:
1255
            # We're local
1256
            from bzrlib.workingtree import WorkingTree
1257
    
1258
            if path is None:
1259
                path = self.get_path()
1260
    
1261
            # A workaround for double-clicking Bookmarks
1262
            if not os.path.exists(path):
1263
                return
1264
    
1265
            # Get ListStore and clear it
1266
            liststore = self.treeview_right.get_model()
1267
            liststore.clear()
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1268
            
1269
            # Show Status column
1270
            self._tvcolumn_status.set_visible(True)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1271
    
1272
            dirs = []
1273
            files = []
1274
    
1275
            # Fill the appropriate lists
1276
            dotted_files = self.pref.get_preference('dotted_files', 'bool')
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
1277
            ignored_files = self.pref.get_preference('ignored_files', 'bool')
1278
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1279
            for item in os.listdir(path):
1280
                if not dotted_files and item[0] == '.':
1281
                    continue
1282
                if os.path.isdir(path + os.sep + item):
1283
                    dirs.append(item)
1284
                else:
1285
                    files.append(item)
1286
            
1287
            # Try to open the working tree
1288
            notbranch = False
1289
            try:
1290
                tree1 = WorkingTree.open_containing(path)[0]
1291
            except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
1292
                notbranch = True
1293
            
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1294
            if not notbranch:
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1295
                branch = tree1.branch
1296
                tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
1297
            
1298
                delta = tree1.changes_from(tree2, want_unchanged=True)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1299
                
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1300
            # Add'em to the ListStore
1301
            for item in dirs:
423.12.2 by Szilveszter Farkas (Phanatic)
Some missing bits completed. Bad symlinks are ommitted on refresh as well.
1302
                try:
1303
                    statinfo = os.stat(self.path + os.sep + item)
1304
                except OSError, e:
1305
                    if e.errno == 40:
1306
                        continue
1307
                    else:
1308
                        raise
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1309
                liststore.append([gtk.STOCK_DIRECTORY,
1310
                                  True,
1311
                                  item,
1312
                                  '',
1313
                                  '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1314
                                  "<DIR>",
1315
                                  "<DIR>",
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1316
                                  statinfo.st_mtime,
1317
                                  self._format_date(statinfo.st_mtime),
1318
                                  ''])
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1319
            for item in files:
1320
                status = 'unknown'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1321
                fileid = ''
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1322
                if not notbranch:
1323
                    filename = tree1.relpath(path + os.sep + item)
126.1.39 by Szilveszter Farkas (Phanatic)
Fix the locking issue with Olive (LP: #91522)
1324
                    
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1325
                    try:
1326
                        self.wt.lock_read()
1327
                        
1328
                        for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
1329
                            if rpathnew == filename:
1330
                                status = 'renamed'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1331
                                fileid = id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1332
                        for rpath, id, kind in delta.added:
1333
                            if rpath == filename:
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1334
                                status = 'added'
1335
                                fileid = id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1336
                        for rpath, id, kind in delta.removed:
1337
                            if rpath == filename:
1338
                                status = 'removed'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1339
                                fileid = id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1340
                        for rpath, id, kind, text_modified, meta_modified in delta.modified:
1341
                            if rpath == filename:
1342
                                status = 'modified'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1343
                                fileid = id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1344
                        for rpath, id, kind in delta.unchanged:
1345
                            if rpath == filename:
1346
                                status = 'unchanged'
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1347
                                fileid = id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1348
                        for rpath, file_class, kind, id, entry in self.wt.list_files():
1349
                            if rpath == filename and file_class == 'I':
1350
                                status = 'ignored'
1351
                    finally:
1352
                        self.wt.unlock()
1353
                
1354
                if status == 'renamed':
1355
                    st = _('renamed')
1356
                elif status == 'removed':
1357
                    st = _('removed')
1358
                elif status == 'added':
1359
                    st = _('added')
1360
                elif status == 'modified':
1361
                    st = _('modified')
1362
                elif status == 'unchanged':
1363
                    st = _('unchanged')
1364
                elif status == 'ignored':
1365
                    st = _('ignored')
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
1366
                    if not ignored_files:
1367
                        continue
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1368
                else:
1369
                    st = _('unknown')
1370
                
423.12.2 by Szilveszter Farkas (Phanatic)
Some missing bits completed. Bad symlinks are ommitted on refresh as well.
1371
                try:
1372
                    statinfo = os.stat(self.path + os.sep + item)
1373
                except OSError, e:
1374
                    if e.errno == 40:
1375
                        continue
1376
                    else:
1377
                        raise
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1378
                liststore.append([gtk.STOCK_FILE,
1379
                                  False,
1380
                                  item,
1381
                                  st,
1382
                                  status,
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1383
                                  str(statinfo.st_size),
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1384
                                  self._format_size(statinfo.st_size),
1385
                                  statinfo.st_mtime,
1386
                                  self._format_date(statinfo.st_mtime),
1387
                                  fileid])
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1388
        else:
1389
            # We're remote
1390
            
1391
            # Get ListStore and clear it
1392
            liststore = self.treeview_right.get_model()
1393
            liststore.clear()
1394
            
195.1.17 by Szilveszter Farkas (Phanatic)
Show/hide Status column accordingly.
1395
            # Hide Status column
1396
            self._tvcolumn_status.set_visible(False)
1397
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1398
            dirs = []
1399
            files = []
1400
            
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1401
            self._show_stock_image(gtk.STOCK_REFRESH)
1402
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1403
            for (name, type) in self.remote_entries:
1404
                if type.kind == 'directory':
1405
                    dirs.append(type)
1406
                elif type.kind == 'file':
1407
                    files.append(type)
1408
            
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1409
            class HistoryCache:
1410
                """ Cache based on revision history. """
1411
                def __init__(self, history):
1412
                    self._history = history
1413
                
1414
                def _lookup_revision(self, revid):
1415
                    for r in self._history:
1416
                        if r.revision_id == revid:
1417
                            return r
1418
                    rev = repo.get_revision(revid)
1419
                    self._history.append(rev)
1420
                    return rev
1421
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1422
            repo = self.remote_branch.repository
1423
            
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1424
            revhistory = self.remote_branch.revision_history()
1425
            try:
1426
                revs = repo.get_revisions(revhistory)
1427
                cache = HistoryCache(revs)
1428
            except bzrerrors.InvalidHttpResponse:
1429
                # Fallback to dummy algorithm, because of LP: #115209
1430
                cache = HistoryCache([])
1431
            
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1432
            for item in dirs:
1433
                if item.parent_id == self.remote_parent:
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1434
                    rev = cache._lookup_revision(item.revision)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1435
                    liststore.append([ gtk.STOCK_DIRECTORY,
1436
                                       True,
1437
                                       item.name,
1438
                                       '',
1439
                                       '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1440
                                       "<DIR>",
1441
                                       "<DIR>",
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1442
                                       rev.timestamp,
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1443
                                       self._format_date(rev.timestamp),
1444
                                       ''
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1445
                                   ])
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.
1446
                while gtk.events_pending():
1447
                    gtk.main_iteration()
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1448
            
1449
            for item in files:
1450
                if item.parent_id == self.remote_parent:
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1451
                    rev = cache._lookup_revision(item.revision)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1452
                    liststore.append([ gtk.STOCK_FILE,
1453
                                       False,
1454
                                       item.name,
1455
                                       '',
1456
                                       '',
235.1.6 by Mateusz Korniak
Fixes crash when operating over files which are large enouth to have size represented by long int
1457
                                       str(item.text_size),
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1458
                                       self._format_size(item.text_size),
1459
                                       rev.timestamp,
195.1.25 by Szilveszter Farkas (Phanatic)
Fixed some minor things and added file_id to the list model.
1460
                                       self._format_date(rev.timestamp),
1461
                                       item.file_id
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1462
                                   ])
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.
1463
                while gtk.events_pending():
1464
                    gtk.main_iteration()
195.1.15 by Szilveszter Farkas (Phanatic)
Workaround for bug #115209 (in Bazaar itself).
1465
            
1466
            self.image_location_error.destroy()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1467
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.
1468
        # Columns should auto-size
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1469
        self.treeview_right.columns_autosize()
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
1470
        
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
1471
        # Set sensitivity
1472
        self.set_sensitivity()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1473
1474
    def _harddisks(self):
1475
        """ Returns hard drive letters under Win32. """
1476
        try:
1477
            import win32file
1478
            import string
1479
        except ImportError:
1480
            if sys.platform == 'win32':
1481
                print "pyWin32 modules needed to run Olive on Win32."
1482
                sys.exit(1)
1483
            else:
1484
                pass
1485
        
1486
        driveletters = []
1487
        for drive in string.ascii_uppercase:
1488
            if win32file.GetDriveType(drive+':') == win32file.DRIVE_FIXED:
1489
                driveletters.append(drive+':')
1490
        return driveletters
1491
    
1492
    def gen_hard_selector(self):
1493
        """ Generate the hard drive selector under Win32. """
1494
        drives = self._harddisks()
1495
        for drive in drives:
1496
            self.combobox_drive.append_text(drive)
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
1497
        self.combobox_drive.set_active(drives.index(os.getcwd()[0:2]))
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1498
    
1499
    def _refresh_drives(self, combobox):
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
1500
        if self._just_started:
1501
            return
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1502
        model = combobox.get_model()
1503
        active = combobox.get_active()
1504
        if active >= 0:
1505
            drive = model[active][0]
0.14.11 by Alexander Belchenko
Make change of drive letter on win32 is actually workable
1506
            self.set_path(drive + '\\')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1507
            self.refresh_right(drive + '\\')
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
1508
    
1509
    def check_for_changes(self):
1510
        """ Check whether there were changes in the current working tree. """
1511
        old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
1512
        delta = self.wt.changes_from(old_tree)
1513
1514
        changes = False
1515
        
1516
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
1517
            changes = True
1518
        
1519
        return changes
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1520
    
1521
    def _sort_filelist_callback(self, model, iter1, iter2, data):
1522
        """ The sort callback for the file list, return values:
1523
        -1: iter1 < iter2
1524
        0: iter1 = iter2
1525
        1: iter1 > iter2
1526
        """
1527
        name1 = model.get_value(iter1, 2)
1528
        name2 = model.get_value(iter2, 2)
1529
        
1530
        if model.get_value(iter1, 1):
1531
            # item1 is a directory
1532
            if not model.get_value(iter2, 1):
1533
                # item2 isn't
1534
                return -1
1535
            else:
1536
                # both of them are directories, we compare their names
1537
                if name1 < name2:
1538
                    return -1
1539
                elif name1 == name2:
1540
                    return 0
1541
                else:
1542
                    return 1
1543
        else:
1544
            # item1 is not a directory
1545
            if model.get_value(iter2, 1):
1546
                # item2 is
1547
                return 1
1548
            else:
1549
                # both of them are files, compare them
1550
                if name1 < name2:
1551
                    return -1
1552
                elif name1 == name2:
1553
                    return 0
1554
                else:
1555
                    return 1
1556
    
1557
    def _format_size(self, size):
1558
        """ 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
1559
        if size < 1000:
1560
            return "%d[B]" % (size,)
1561
        size = size / 1000.0
1562
        
1563
        for metric in ["kB","MB","GB","TB"]:
1564
            if size < 1000:
1565
                break
1566
            size = size / 1000.0
1567
        return "%.1f[%s]" % (size,metric) 
195.6.1 by Szilveszter Farkas (Phanatic)
Implemented sortable columns, and there are also some new columns
1568
    
1569
    def _format_date(self, timestamp):
1570
        """ Format the time (given in secs) to a human readable format. """
1571
        return time.ctime(timestamp)
195.1.9 by Szilveszter Farkas (Phanatic)
Browsing remote branches works. Still have to optimize some stuff.
1572
    
1573
    def _is_remote_dir(self, location):
1574
        """ Determine whether the given location is a directory or not. """
1575
        if not self.remote:
1576
            # We're in local mode
1577
            return False
1578
        else:
1579
            branch, path = Branch.open_containing(location)
1580
            for (name, type) in self.remote_entries:
1581
                if name == path and type.kind == 'directory':
1582
                    # We got it
1583
                    return True
1584
            # Either it's not a directory or not in the inventory
1585
            return False
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.
1586
    
1587
    def _show_stock_image(self, stock_id):
1588
        """ Show a stock image next to the location entry. """
1589
        self.image_location_error.destroy()
1590
        self.image_location_error = gtk.image_new_from_stock(stock_id, gtk.ICON_SIZE_BUTTON)
1591
        self.hbox_location.pack_start(self.image_location_error, False, False, 0)
195.1.12 by Szilveszter Farkas (Phanatic)
Display status icons on the left side of the location entry.
1592
        if sys.platform == 'win32':
1593
            self.hbox_location.reorder_child(self.image_location_error, 2)
1594
        else:
1595
            self.hbox_location.reorder_child(self.image_location_error, 1)
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.
1596
        self.image_location_error.show()
1597
        while gtk.events_pending():
1598
            gtk.main_iteration()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1599
0.13.13 by Jelmer Vernooij
Update TODO
1600
import ConfigParser
1601
142 by Jelmer Vernooij
Move some files to the top-level directory, add first test.
1602
class Preferences:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1603
    """ A class which handles Olive's preferences. """
170 by Jelmer Vernooij
Add test argument to Preferences().
1604
    def __init__(self, path=None):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1605
        """ Initialize the Preferences class. """
1606
        # Some default options
1607
        self.defaults = { 'strict_commit' : False,
1608
                          'dotted_files'  : False,
262.1.1 by Tom Badran
Add ability to hide 'ignored' files:
1609
                          'ignored_files' : True,
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1610
                          'window_width'  : 700,
1611
                          'window_height' : 400,
1612
                          'window_x'      : 40,
1613
                          'window_y'      : 40,
1614
                          'paned_position': 200 }
1615
1616
        # Create a config parser object
1617
        self.config = ConfigParser.RawConfigParser()
170 by Jelmer Vernooij
Add test argument to Preferences().
1618
1619
        # Set filename
1620
        if path is None:
1621
            if sys.platform == 'win32':
1622
                # Windows - no dotted files
1623
                self._filename = os.path.expanduser('~/olive.conf')
1624
            else:
1625
                self._filename = os.path.expanduser('~/.olive.conf')
1626
        else:
1627
            self._filename = path
126.1.35 by Szilveszter Farkas (Phanatic)
Make test suite not fail if Olive was run before.
1628
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1629
        # Load the configuration
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1630
        self.read()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1631
        
1632
    def _get_default(self, option):
1633
        """ Get the default option for a preference. """
1634
        try:
1635
            ret = self.defaults[option]
1636
        except KeyError:
1637
            return None
1638
        else:
1639
            return ret
1640
1641
    def refresh(self):
1642
        """ Refresh the configuration. """
1643
        # First write out the changes
1644
        self.write()
1645
        # Then load the configuration again
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1646
        self.read()
1647
1648
    def read(self):
1649
        """ Just read the configuration. """
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
1650
        # Re-initialize the config parser object to avoid some bugs
1651
        self.config = ConfigParser.RawConfigParser()
170 by Jelmer Vernooij
Add test argument to Preferences().
1652
        self.config.read([self._filename])
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
1653
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1654
    def write(self):
1655
        """ Write the configuration to the appropriate files. """
170 by Jelmer Vernooij
Add test argument to Preferences().
1656
        fp = open(self._filename, 'w')
1657
        self.config.write(fp)
1658
        fp.close()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1659
1660
    def get_bookmarks(self):
1661
        """ Return the list of bookmarks. """
1662
        bookmarks = self.config.sections()
1663
        if self.config.has_section('preferences'):
1664
            bookmarks.remove('preferences')
1665
        return bookmarks
1666
1667
    def add_bookmark(self, path):
1668
        """ Add bookmark. """
1669
        try:
1670
            self.config.add_section(path)
1671
        except ConfigParser.DuplicateSectionError:
1672
            return False
1673
        else:
1674
            return True
1675
1676
    def get_bookmark_title(self, path):
1677
        """ Get bookmark title. """
1678
        try:
1679
            ret = self.config.get(path, 'title')
1680
        except ConfigParser.NoOptionError:
1681
            ret = path
1682
        
1683
        return ret
1684
    
1685
    def set_bookmark_title(self, path, title):
1686
        """ Set bookmark title. """
143 by Jelmer Vernooij
More preference tests.
1687
        # FIXME: What if path isn't listed yet?
1688
        # FIXME: Canonicalize paths first?
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1689
        self.config.set(path, 'title', title)
1690
    
1691
    def remove_bookmark(self, path):
1692
        """ Remove bookmark. """
1693
        return self.config.remove_section(path)
0.13.13 by Jelmer Vernooij
Update TODO
1694
1695
    def set_preference(self, option, value):
1696
        """ Set the value of the given option. """
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1697
        if value is True:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1698
            value = 'yes'
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1699
        elif value is False:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1700
            value = 'no'
1701
        
0.13.13 by Jelmer Vernooij
Update TODO
1702
        if self.config.has_section('preferences'):
1703
            self.config.set('preferences', option, value)
1704
        else:
1705
            self.config.add_section('preferences')
1706
            self.config.set('preferences', option, value)
1707
1708
    def get_preference(self, option, kind='str'):
1709
        """ Get the value of the given option.
1710
        
1711
        :param kind: str/bool/int/float. default: str
1712
        """
1713
        if self.config.has_option('preferences', option):
1714
            if kind == 'bool':
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1715
                return self.config.getboolean('preferences', option)
0.13.13 by Jelmer Vernooij
Update TODO
1716
            elif kind == 'int':
1717
                return self.config.getint('preferences', option)
1718
            elif kind == 'float':
1719
                return self.config.getfloat('preferences', option)
1720
            else:
1721
                return self.config.get('preferences', option)
1722
        else:
1723
            try:
1724
                return self._get_default(option)
1725
            except KeyError:
1726
                return None
1727