/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
1
# Copyright (C) 2006 by Szilveszter Farkas (Phanatic) <szilveszter.farkas@gmail.com>
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
import os
18
import sys
19
89 by Jelmer Vernooij
Rename OliveBranch -> BranchDialog.
20
# gettext support
21
import gettext
22
gettext.install('olive-gtk')
23
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
24
try:
25
    import pygtk
26
    pygtk.require("2.0")
27
except:
28
    pass
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
29
0.13.11 by Jelmer Vernooij
Bunch of small fixes, cleanups and simplifications.
30
import gtk
31
import gtk.gdk
32
import gtk.glade
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
33
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
34
from bzrlib.branch import Branch
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
35
import bzrlib.errors as bzrerrors
0.13.13 by Jelmer Vernooij
Update TODO
36
from bzrlib.workingtree import WorkingTree
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
37
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
38
from dialog import error_dialog, info_dialog, warning_dialog
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.
39
from errors import show_bzr_error
93.1.12 by Alexander Belchenko
Names XML files with GUI resources obtained via olive/guifiles.py
40
from guifiles import GLADEFILENAME
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
41
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
42
# import this classes only once
43
try:
44
    from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
45
    from bzrlib.plugins.gtk.viz.branchwin import BranchWindow
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
46
    from bzrlib.plugins.gtk.annotate.gannotate import GAnnotateWindow
47
    from bzrlib.plugins.gtk.annotate.config import GAnnotateConfig
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
48
except ImportError:
49
    # olive+bzr-gtk not installed. try to import from sources
50
    path = os.path.dirname(os.path.dirname(__file__))
51
    if path not in sys.path:
52
        sys.path.append(path)
53
    from viz.diffwin import DiffWindow
54
    from viz.branchwin import BranchWindow
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
55
    from annotate.gannotate import GAnnotateWindow
56
    from annotate.config import GAnnotateConfig
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
57
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
58
# History delimiter used in config files
59
delimiter = ' '
93.1.3 by Alexander Belchenko
olive is able to successfully work without installation
60
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
61
class OliveGtk:
62
    """ The main Olive GTK frontend class. This is called when launching the
63
    program. """
64
    
65
    def __init__(self):
93.1.6 by Alexander Belchenko
detecting name of glade file doing in separate module (olive.gladefile)
66
        self.toplevel = gtk.glade.XML(GLADEFILENAME, 'window_main', 'olive-gtk')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
67
        
68
        self.window = self.toplevel.get_widget('window_main')
69
        
70
        self.pref = OlivePreferences()
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
71
        
72
        self.path = None
0.13.13 by Jelmer Vernooij
Update TODO
73
74
        # Initialize the statusbar
75
        self.statusbar = self.toplevel.get_widget('statusbar')
76
        self.context_id = self.statusbar.get_context_id('olive')
77
        
78
        # Get the main window
79
        self.window_main = self.toplevel.get_widget('window_main')
80
        # Get the HPaned
81
        self.hpaned_main = self.toplevel.get_widget('hpaned_main')
82
        # Get the TreeViews
83
        self.treeview_left = self.toplevel.get_widget('treeview_left')
84
        self.treeview_right = self.toplevel.get_widget('treeview_right')
85
        # Get some important menu items
86
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
87
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
88
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
89
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
90
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
91
        self.menuitem_file_annotate = self.toplevel.get_widget('menuitem_file_annotate')
0.13.13 by Jelmer Vernooij
Update TODO
92
        self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
93
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
94
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
95
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
96
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
97
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
98
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
99
        self.menuitem_branch_revert = self.toplevel.get_widget('menuitem_branch_revert')
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
100
        self.menuitem_branch_merge = self.toplevel.get_widget('menuitem_branch_merge')
0.13.13 by Jelmer Vernooij
Update TODO
101
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
102
        self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
103
        self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
104
        self.menuitem_stats = self.toplevel.get_widget('menuitem_stats')
105
        self.menuitem_stats_diff = self.toplevel.get_widget('menuitem_stats_diff')
106
        self.menuitem_stats_log = self.toplevel.get_widget('menuitem_stats_log')
107
        # Get some toolbuttons
108
        #self.menutoolbutton_diff = self.toplevel.get_widget('menutoolbutton_diff')
109
        self.toolbutton_diff = self.toplevel.get_widget('toolbutton_diff')
110
        self.toolbutton_log = self.toplevel.get_widget('toolbutton_log')
111
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
112
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
113
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
114
        # Get the drive selector
115
        self.combobox_drive = gtk.combo_box_new_text()
116
        self.combobox_drive.connect("changed", self._refresh_drives)
117
        
118
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
119
 
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
120
        
121
        # Dictionary for signal_autoconnect
122
        dic = { "on_window_main_destroy": gtk.main_quit,
0.13.13 by Jelmer Vernooij
Update TODO
123
                "on_window_main_delete_event": self.on_window_main_delete_event,
124
                "on_quit_activate": self.on_window_main_delete_event,
125
                "on_about_activate": self.on_about_activate,
126
                "on_menuitem_add_files_activate": self.on_menuitem_add_files_activate,
127
                "on_menuitem_remove_file_activate": self.on_menuitem_remove_file_activate,
128
                "on_menuitem_file_make_directory_activate": self.on_menuitem_file_make_directory_activate,
129
                "on_menuitem_file_move_activate": self.on_menuitem_file_move_activate,
130
                "on_menuitem_file_rename_activate": self.on_menuitem_file_rename_activate,
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
131
                "on_menuitem_file_annotate_activate": self.on_menuitem_file_annotate_activate,
0.13.13 by Jelmer Vernooij
Update TODO
132
                "on_menuitem_view_show_hidden_files_activate": self.on_menuitem_view_show_hidden_files_activate,
133
                "on_menuitem_view_refresh_activate": self.on_menuitem_view_refresh_activate,
134
                "on_menuitem_branch_initialize_activate": self.on_menuitem_branch_initialize_activate,
135
                "on_menuitem_branch_get_activate": self.on_menuitem_branch_get_activate,
136
                "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.
137
                "on_menuitem_branch_revert_activate": self.on_menuitem_branch_revert_activate,
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
138
                "on_menuitem_branch_merge_activate": self.on_menuitem_branch_merge_activate,
0.13.13 by Jelmer Vernooij
Update TODO
139
                "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
140
                "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
141
                "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
142
                "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
143
                "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
144
                "on_menuitem_stats_diff_activate": self.on_menuitem_stats_diff_activate,
145
                "on_menuitem_stats_log_activate": self.on_menuitem_stats_log_activate,
146
                "on_menuitem_stats_infos_activate": self.on_menuitem_stats_infos_activate,
147
                "on_toolbutton_refresh_clicked": self.on_menuitem_view_refresh_activate,
148
                "on_toolbutton_log_clicked": self.on_menuitem_stats_log_activate,
149
                #"on_menutoolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
150
                "on_toolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
151
                "on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
152
                "on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
153
                "on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
154
                "on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
155
                "on_treeview_right_row_activated": self.on_treeview_right_row_activated,
156
                "on_treeview_left_button_press_event": self.on_treeview_left_button_press_event,
157
                "on_treeview_left_row_activated": self.on_treeview_left_row_activated }
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
158
        
159
        # Connect the signals to the handlers
160
        self.toplevel.signal_autoconnect(dic)
161
        
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
162
        self._just_started = True
163
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
164
        # Apply window size and position
165
        width = self.pref.get_preference('window_width', 'int')
166
        height = self.pref.get_preference('window_height', 'int')
167
        self.window.resize(width, height)
168
        x = self.pref.get_preference('window_x', 'int')
169
        y = self.pref.get_preference('window_y', 'int')
170
        self.window.move(x, y)
171
        # Apply paned position
172
        pos = self.pref.get_preference('paned_position', 'int')
0.13.13 by Jelmer Vernooij
Update TODO
173
        self.hpaned_main.set_position(pos)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
174
        
175
        # Apply menu to the toolbutton
176
        #menubutton = self.toplevel.get_widget('menutoolbutton_diff')
177
        #menubutton.set_menu(handler.menu.toolbar_diff)
178
        
179
        # Now we can show the window
180
        self.window.show()
181
        
182
        # Show drive selector if under Win32
183
        if sys.platform == 'win32':
0.13.13 by Jelmer Vernooij
Update TODO
184
            self.vbox_main_right.pack_start(self.combobox_drive, False, True, 0)
185
            self.vbox_main_right.reorder_child(self.combobox_drive, 0)
186
            self.combobox_drive.show()
187
            self.gen_hard_selector()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
188
        
189
        self._load_left()
0.13.13 by Jelmer Vernooij
Update TODO
190
191
        # Apply menu state
192
        self.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
193
194
        self.set_path(os.getcwd())
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
195
        self._load_right()
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
196
        
197
        self._just_started = False
0.13.13 by Jelmer Vernooij
Update TODO
198
199
    def set_path(self, path):
200
        self.path = path
201
        self.notbranch = False
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
202
        
0.13.13 by Jelmer Vernooij
Update TODO
203
        try:
204
            self.wt, self.wtpath = WorkingTree.open_containing(self.path)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
205
        except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
0.13.13 by Jelmer Vernooij
Update TODO
206
            self.notbranch = True
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
207
        
208
        self.statusbar.push(self.context_id, path)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
209
0.13.13 by Jelmer Vernooij
Update TODO
210
    def get_path(self):
211
        return self.path
212
   
213
    def on_about_activate(self, widget):
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
214
        from dialog import about
0.13.13 by Jelmer Vernooij
Update TODO
215
        about()
216
        
217
    def on_menuitem_add_files_activate(self, widget):
218
        """ Add file(s)... menu handler. """
219
        from add import OliveAdd
220
        add = OliveAdd(self.wt, self.wtpath, self.get_selected_right())
221
        add.display()
222
    
223
    def on_menuitem_branch_get_activate(self, widget):
224
        """ Branch/Get... menu handler. """
89 by Jelmer Vernooij
Rename OliveBranch -> BranchDialog.
225
        from branch import BranchDialog
126.1.15 by Szilveszter Farkas (Phanatic)
Refactoring the Branch dialog. We also have a Revision Browser now.
226
        branch = BranchDialog(self.get_path(), self.window)
227
        response = branch.run()
228
        if response != gtk.RESPONSE_NONE:
229
            branch.hide()
230
        
231
            if response == gtk.RESPONSE_OK:
232
                self.refresh_right()
233
            
234
            branch.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
235
    
236
    def on_menuitem_branch_checkout_activate(self, widget):
237
        """ Branch/Checkout... menu handler. """
126.1.18 by Szilveszter Farkas (Phanatic)
Improved Branch dialog. Refactored Checkout dialog.
238
        from checkout import CheckoutDialog
239
        checkout = CheckoutDialog(self.get_path(), self.window)
240
        response = checkout.run()
241
        if response != gtk.RESPONSE_NONE:
242
            checkout.hide()
243
        
244
            if response == gtk.RESPONSE_OK:
245
                self.refresh_right()
246
            
247
            checkout.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
248
    
249
    def on_menuitem_branch_commit_activate(self, widget):
250
        """ Branch/Commit... menu handler. """
135 by Jelmer Vernooij
Throw out the old CommitDialog code and use the new code instead, also for 'gcommit'.
251
        from commit import CommitDialog
252
        commit = CommitDialog(self.wt, self.wtpath, self.notbranch, self.get_selected_right(), self.window)
126.1.1 by Szilveszter Farkas (Phanatic)
New Commit dialog implementation (no more Glade).
253
        response = commit.run()
254
        if response != gtk.RESPONSE_NONE:
255
            commit.hide()
256
        
257
            if response == gtk.RESPONSE_OK:
258
                self.refresh_right()
259
            
260
            commit.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
261
    
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
262
    def on_menuitem_branch_merge_activate(self, widget):
263
        """ Branch/Merge... menu handler. """
264
        from merge import MergeDialog
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
265
        
266
        if self.check_for_changes():
267
            error_dialog(_('There are local changes in the branch'),
268
                         _('Please commit or revert the changes before merging.'))
269
        else:
270
            merge = MergeDialog(self.wt, self.wtpath)
271
            merge.display()
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
272
0.13.13 by Jelmer Vernooij
Update TODO
273
    def on_menuitem_branch_missing_revisions_activate(self, widget):
274
        """ Branch/Missing revisions menu handler. """
275
        local_branch = self.wt.branch
276
        
277
        other_branch = local_branch.get_parent()
278
        if other_branch is None:
279
            error_dialog(_('Parent location is unknown'),
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
280
                         _('Cannot determine missing revisions if no parent location is known.'))
0.13.13 by Jelmer Vernooij
Update TODO
281
            return
282
        
283
        remote_branch = Branch.open(other_branch)
284
        
285
        if remote_branch.base == local_branch.base:
286
            remote_branch = local_branch
287
288
        ret = len(local_branch.missing_revisions(remote_branch))
289
290
        if ret > 0:
291
            info_dialog(_('There are missing revisions'),
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
292
                        _('%d revision(s) missing.') % ret)
0.13.13 by Jelmer Vernooij
Update TODO
293
        else:
294
            info_dialog(_('Local branch up to date'),
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
295
                        _('There are no missing revisions.'))
0.13.13 by Jelmer Vernooij
Update TODO
296
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.
297
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
298
    def on_menuitem_branch_pull_activate(self, widget):
299
        """ Branch/Pull menu handler. """
300
        branch_to = self.wt.branch
301
302
        location = branch_to.get_parent()
303
        if location is None:
304
            error_dialog(_('Parent location is unknown'),
305
                                     _('Pulling is not possible until there is a parent location.'))
306
            return
307
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.
308
        branch_from = Branch.open(location)
0.13.13 by Jelmer Vernooij
Update TODO
309
310
        if branch_to.get_parent() is None:
311
            branch_to.set_parent(branch_from.base)
312
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
313
        #old_rh = branch_to.revision_history()
314
        #if tree_to is not None:
315
        #    tree_to.pull(branch_from)
316
        #else:
317
        #    branch_to.pull(branch_from)
0.14.14 by Alexander Belchenko
get number of pulled revision: it's return value of branch.pull() method
318
        ret = branch_to.pull(branch_from)
0.13.13 by Jelmer Vernooij
Update TODO
319
        
320
        info_dialog(_('Pull successful'), _('%d revision(s) pulled.') % ret)
321
    
322
    def on_menuitem_branch_push_activate(self, widget):
323
        """ Branch/Push... menu handler. """
126.1.19 by Szilveszter Farkas (Phanatic)
Refactored the Push dialog. Add 'gpush' command.
324
        from push import PushDialog
325
        push = PushDialog(self.wt.branch, self.window)
326
        response = push.run()
327
        if response != gtk.RESPONSE_NONE:
328
            push.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
329
    
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
330
    @show_bzr_error
331
    def on_menuitem_branch_revert_activate(self, widget):
332
        """ Branch/Revert all changes menu handler. """
333
        ret = self.wt.revert([])
334
        if ret:
335
            warning_dialog(_('Conflicts detected'),
336
                           _('Please have a look at the working tree before continuing.'))
337
        else:
338
            info_dialog(_('Revert successful'),
339
                        _('All files reverted to last revision.'))
340
        self.refresh_right()
341
    
0.13.13 by Jelmer Vernooij
Update TODO
342
    def on_menuitem_branch_status_activate(self, widget):
343
        """ Branch/Status... menu handler. """
344
        from status import OliveStatus
345
        status = OliveStatus(self.wt, self.wtpath)
346
        status.display()
347
    
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.
348
    @show_bzr_error
0.13.13 by Jelmer Vernooij
Update TODO
349
    def on_menuitem_branch_initialize_activate(self, widget):
350
        """ Initialize current directory. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
351
        import bzrlib.bzrdir as bzrdir
352
        
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.
353
        if not os.path.exists(self.path):
354
            os.mkdir(self.path)
355
 
0.13.13 by Jelmer Vernooij
Update TODO
356
        try:
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.
357
            existing_bzrdir = bzrdir.BzrDir.open(self.path)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
358
        except bzrerrors.NotBranchError:
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.
359
            bzrdir.BzrDir.create_branch_convenience(self.path)
360
        else:
361
            if existing_bzrdir.has_branch():
362
                if existing_bzrdir.has_workingtree():
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
363
                    raise bzrerrors.AlreadyBranchError(self.path)
0.13.13 by Jelmer Vernooij
Update TODO
364
                else:
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
365
                    raise bzrerrors.BranchExistsWithoutWorkingTree(self.path)
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.
366
            else:
367
                existing_bzrdir.create_branch()
368
                existing_bzrdir.create_workingtree()
369
        info_dialog(_('Initialize successful'),
370
                    _('Directory successfully initialized.'))
371
        self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
372
        
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
373
    def on_menuitem_file_annotate_activate(self, widget):
374
        """ File/Annotate... menu handler. """
375
        if self.get_selected_right() is None:
376
            error_dialog(_('No file was selected'),
377
                         _('Please select a file from the list.'))
378
            return
379
        
380
        branch = self.wt.branch
381
        file_id = self.wt.path2id(self.wt.relpath(os.path.join(self.path, self.get_selected_right())))
382
        
383
        window = GAnnotateWindow(all=False, plain=False)
384
        window.set_title(os.path.join(self.path, self.get_selected_right()) + " - Annotate")
385
        config = GAnnotateConfig(window)
386
        window.show()
387
        branch.lock_read()
388
        try:
66.2.17 by Aaron Bentley
Update olive to use current bzr.dev API. Used _repo_relpath. Bad phanatic!
389
            window.annotate(self.wt, branch, file_id)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
390
        finally:
391
            branch.unlock()
392
    
0.13.13 by Jelmer Vernooij
Update TODO
393
    def on_menuitem_file_make_directory_activate(self, widget):
394
        """ File/Make directory... menu handler. """
395
        from mkdir import OliveMkdir
396
        mkdir = OliveMkdir(self.wt, self.wtpath)
397
        mkdir.display()
398
    
399
    def on_menuitem_file_move_activate(self, widget):
400
        """ File/Move... menu handler. """
401
        from move import OliveMove
402
        move = OliveMove(self.wt, self.wtpath, self.get_selected_right())
403
        move.display()
404
    
405
    def on_menuitem_file_rename_activate(self, widget):
406
        """ File/Rename... menu handler. """
407
        from rename import OliveRename
408
        rename = OliveRename(self.wt, self.wtpath, self.get_selected_right())
409
        rename.display()
410
411
    def on_menuitem_remove_file_activate(self, widget):
412
        """ Remove (unversion) selected file. """
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
413
        from remove import OliveRemoveDialog
414
        remove = OliveRemoveDialog(self.wt, self.wtpath,
415
                                   selected=self.get_selected_right(),
121 by Szilveszter Farkas (Phanatic)
Use OliveBookmarkDialog instead of OliveBookmark.
416
                                   parent=self.window)
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
417
        response = remove.run()
418
        
419
        if response != gtk.RESPONSE_NONE:
420
            remove.hide()
421
        
422
            if response == gtk.RESPONSE_OK:
423
                self.set_path(self.path)
424
                self.refresh_right()
425
            
426
            remove.destroy()
0.13.13 by Jelmer Vernooij
Update TODO
427
    
428
    def on_menuitem_stats_diff_activate(self, widget):
429
        """ Statistics/Differences... menu handler. """
430
        window = DiffWindow()
431
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
432
        window.set_diff(self.wt.branch.nick, self.wt, parent_tree)
433
        window.show()
434
    
435
    def on_menuitem_stats_infos_activate(self, widget):
436
        """ Statistics/Informations... menu handler. """
437
        from info import OliveInfo
438
        info = OliveInfo(self.wt)
439
        info.display()
440
    
441
    def on_menuitem_stats_log_activate(self, widget):
442
        """ Statistics/Log... menu handler. """
443
        window = BranchWindow()
444
        window.set_branch(self.wt.branch, self.wt.branch.last_revision(), None)
445
        window.show()
446
    
447
    def on_menuitem_view_refresh_activate(self, widget):
448
        """ View/Refresh menu handler. """
449
        # Refresh the left pane
450
        self.refresh_left()
451
        # Refresh the right pane
452
        self.refresh_right()
453
   
454
    def on_menuitem_view_show_hidden_files_activate(self, widget):
455
        """ View/Show hidden files menu handler. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
456
        self.pref.set_preference('dotted_files', widget.get_active())
102 by Szilveszter Farkas (Phanatic)
Show current path in the statusbar.
457
        if self.path is not None:
458
            self.refresh_right()
0.13.13 by Jelmer Vernooij
Update TODO
459
460
    def on_treeview_left_button_press_event(self, widget, event):
461
        """ Occurs when somebody right-clicks in the bookmark list. """
462
        if event.button == 3:
463
            # Don't show context with nothing selected
464
            if self.get_selected_left() == None:
465
                return
466
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
467
            # Create a menu
468
            from menu import OliveMenu
121 by Szilveszter Farkas (Phanatic)
Use OliveBookmarkDialog instead of OliveBookmark.
469
            menu = OliveMenu(path=self.get_path(),
470
                             selected=self.get_selected_left(),
471
                             app=self)
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
472
            
473
            menu.left_context_menu().popup(None, None, None, 0,
474
                                           event.time)
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
475
0.13.13 by Jelmer Vernooij
Update TODO
476
    def on_treeview_left_row_activated(self, treeview, path, view_column):
477
        """ Occurs when somebody double-clicks or enters an item in the
478
        bookmark list. """
479
480
        newdir = self.get_selected_left()
481
        if newdir == None:
482
            return
483
484
        self.set_path(newdir)
485
        self.refresh_right()
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
486
0.13.13 by Jelmer Vernooij
Update TODO
487
    def on_treeview_right_button_press_event(self, widget, event):
488
        """ Occurs when somebody right-clicks in the file list. """
489
        if event.button == 3:
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
490
            # Create a menu
491
            from menu import OliveMenu
120 by Szilveszter Farkas (Phanatic)
Use OliveRemoveDialog class instead of OliveRemove.
492
            menu = OliveMenu(path=self.get_path(),
493
                             selected=self.get_selected_right(),
494
                             app=self)
0.13.13 by Jelmer Vernooij
Update TODO
495
            # get the menu items
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
496
            m_add = menu.ui.get_widget('/context_right/add')
497
            m_remove = menu.ui.get_widget('/context_right/remove')
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
498
            m_rename = menu.ui.get_widget('/context_right/rename')
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
499
            m_revert = menu.ui.get_widget('/context_right/revert')
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
500
            m_commit = menu.ui.get_widget('/context_right/commit')
501
            m_diff = menu.ui.get_widget('/context_right/diff')
0.13.13 by Jelmer Vernooij
Update TODO
502
            # check if we're in a branch
503
            try:
504
                from bzrlib.branch import Branch
505
                Branch.open_containing(self.get_path())
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
506
                m_add.set_sensitive(True)
507
                m_remove.set_sensitive(True)
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
508
                m_rename.set_sensitive(True)
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
509
                m_revert.set_sensitive(True)
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
510
                m_commit.set_sensitive(True)
511
                m_diff.set_sensitive(True)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
512
            except bzrerrors.NotBranchError:
0.13.13 by Jelmer Vernooij
Update TODO
513
                m_add.set_sensitive(False)
514
                m_remove.set_sensitive(False)
117 by Szilveszter Farkas (Phanatic)
Rename put into context menu (Fixed: #73774).
515
                m_rename.set_sensitive(False)
126.1.12 by Szilveszter Farkas (Phanatic)
Added revert functionality to the context menu.
516
                m_revert.set_sensitive(False)
0.13.13 by Jelmer Vernooij
Update TODO
517
                m_commit.set_sensitive(False)
518
                m_diff.set_sensitive(False)
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
519
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
520
            menu.right_context_menu().popup(None, None, None, 0,
521
                                            event.time)
0.13.13 by Jelmer Vernooij
Update TODO
522
        
523
    def on_treeview_right_row_activated(self, treeview, path, view_column):
524
        """ Occurs when somebody double-clicks or enters an item in the
525
        file list. """
0.8.92 by Szilveszter Farkas (Phanatic)
Cleanup Jelmer's changes.
526
        from launch import launch
527
        
0.13.13 by Jelmer Vernooij
Update TODO
528
        newdir = self.get_selected_right()
529
        
530
        if newdir == '..':
531
            self.set_path(os.path.split(self.get_path())[0])
532
        else:
0.14.11 by Alexander Belchenko
Make change of drive letter on win32 is actually workable
533
            fullpath = os.path.join(self.get_path(), newdir)
0.13.13 by Jelmer Vernooij
Update TODO
534
            if os.path.isdir(fullpath):
535
                # selected item is an existant directory
536
                self.set_path(fullpath)
537
            else:
538
                launch(fullpath) 
539
        
540
        self.refresh_right()
541
    
542
    def on_window_main_delete_event(self, widget, event=None):
543
        """ Do some stuff before exiting. """
544
        width, height = self.window_main.get_size()
545
        self.pref.set_preference('window_width', width)
546
        self.pref.set_preference('window_height', height)
547
        x, y = self.window_main.get_position()
548
        self.pref.set_preference('window_x', x)
549
        self.pref.set_preference('window_y', y)
550
        self.pref.set_preference('paned_position',
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
551
                                 self.hpaned_main.get_position())
0.13.13 by Jelmer Vernooij
Update TODO
552
        
553
        self.pref.write()
554
        self.window_main.destroy()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
555
        
556
    def _load_left(self):
557
        """ Load data into the left panel. (Bookmarks) """
558
        # Create TreeStore
559
        treestore = gtk.TreeStore(str, str)
560
        
561
        # Get bookmarks
0.13.13 by Jelmer Vernooij
Update TODO
562
        bookmarks = self.pref.get_bookmarks()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
563
        
564
        # Add them to the TreeStore
565
        titer = treestore.append(None, [_('Bookmarks'), None])
566
        for item in bookmarks:
0.13.13 by Jelmer Vernooij
Update TODO
567
            title = self.pref.get_bookmark_title(item)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
568
            treestore.append(titer, [title, item])
569
        
570
        # Create the column and add it to the TreeView
571
        self.treeview_left.set_model(treestore)
572
        tvcolumn_bookmark = gtk.TreeViewColumn(_('Bookmark'))
573
        self.treeview_left.append_column(tvcolumn_bookmark)
574
        
575
        # Set up the cells
576
        cell = gtk.CellRendererText()
577
        tvcolumn_bookmark.pack_start(cell, True)
578
        tvcolumn_bookmark.add_attribute(cell, 'text', 0)
579
        
580
        # Expand the tree
581
        self.treeview_left.expand_all()
582
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
583
    def _add_updir_to_dirlist(self, dirlist, curdir):
584
        """Add .. to the top of directories list if we not in root directory
585
91.1.9 by Jelmer Vernooij
Use epydoc style (for consistency with Bazaar).
586
        :param dirlist:     list of directories (modified in place)
587
        :param curdir:      current directory
588
        :return:            nothing
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
589
        """
590
        if curdir is None:
591
            curdir = self.path
592
593
        if sys.platform == 'win32':
594
            drive, tail = os.path.splitdrive(curdir)
595
            if tail in ('', '/', '\\'):
596
                return
597
        else:
598
            if curdir == '/':
599
                return
600
601
        # insert always as first element
602
        dirlist.insert(0, '..')
603
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
604
    def _load_right(self):
605
        """ Load data into the right panel. (Filelist) """
606
        # Create ListStore
607
        liststore = gtk.ListStore(str, str, str)
608
        
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
609
        dirs = []
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
610
        files = []
611
        
612
        # Fill the appropriate lists
613
        dotted_files = self.pref.get_preference('dotted_files', 'bool')
0.13.13 by Jelmer Vernooij
Update TODO
614
        for item in os.listdir(self.path):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
615
            if not dotted_files and item[0] == '.':
616
                continue
0.13.13 by Jelmer Vernooij
Update TODO
617
            if os.path.isdir(self.path + os.sep + item):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
618
                dirs.append(item)
619
            else:
620
                files.append(item)
621
            
622
        # Sort'em
623
        dirs.sort()
624
        files.sort()
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
625
626
        # add updir link to dirs
627
        self._add_updir_to_dirlist(dirs, self.path)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
628
        
0.13.13 by Jelmer Vernooij
Update TODO
629
        if not self.notbranch:
630
            branch = self.wt.branch
631
            tree2 = self.wt.branch.repository.revision_tree(branch.last_revision())
632
        
633
            delta = self.wt.changes_from(tree2, want_unchanged=True)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
634
        
635
        # Add'em to the ListStore
636
        for item in dirs:    
637
            liststore.append([gtk.STOCK_DIRECTORY, item, ''])
638
        for item in files:
639
            status = 'unknown'
0.13.13 by Jelmer Vernooij
Update TODO
640
            if not self.notbranch:
641
                filename = self.wt.relpath(self.path + os.sep + item)
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
642
                
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
643
                for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
644
                    if rpathnew == filename:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
645
                        status = 'renamed'
646
                for rpath, id, kind in delta.added:
647
                    if rpath == filename:
648
                        status = 'added'
0.13.10 by Jelmer Vernooij
Don't pass around gladefile all the time.
649
                for rpath, id, kind in delta.removed:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
650
                    if rpath == filename:
651
                        status = 'removed'
652
                for rpath, id, kind, text_modified, meta_modified in delta.modified:
653
                    if rpath == filename:
654
                        status = 'modified'
655
                for rpath, id, kind in delta.unchanged:
656
                    if rpath == filename:
657
                        status = 'unchanged'
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
658
                for rpath, file_class, kind, id, entry in self.wt.list_files():
659
                    if rpath == filename and file_class == 'I':
660
                        status = 'ignored'
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
661
            
662
            #try:
663
            #    status = fileops.status(path + os.sep + item)
664
            #except errors.PermissionDenied:
665
            #    continue
666
            
667
            if status == 'renamed':
668
                st = _('renamed')
669
            elif status == 'removed':
670
                st = _('removed')
671
            elif status == 'added':
672
                st = _('added')
673
            elif status == 'modified':
674
                st = _('modified')
675
            elif status == 'unchanged':
676
                st = _('unchanged')
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
677
            elif status == 'ignored':
678
                st = _('ignored')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
679
            else:
680
                st = _('unknown')
681
            liststore.append([gtk.STOCK_FILE, item, st])
682
        
683
        # Create the columns and add them to the TreeView
684
        self.treeview_right.set_model(liststore)
685
        tvcolumn_filename = gtk.TreeViewColumn(_('Filename'))
686
        tvcolumn_status = gtk.TreeViewColumn(_('Status'))
687
        self.treeview_right.append_column(tvcolumn_filename)
688
        self.treeview_right.append_column(tvcolumn_status)
689
        
690
        # Set up the cells
691
        cellpb = gtk.CellRendererPixbuf()
692
        cell = gtk.CellRendererText()
693
        tvcolumn_filename.pack_start(cellpb, False)
694
        tvcolumn_filename.pack_start(cell, True)
695
        tvcolumn_filename.set_attributes(cellpb, stock_id=0)
696
        tvcolumn_filename.add_attribute(cell, 'text', 1)
697
        tvcolumn_status.pack_start(cell, True)
698
        tvcolumn_status.add_attribute(cell, 'text', 2)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
699
        
700
        # Set sensitivity
701
        self.set_sensitivity()
0.13.13 by Jelmer Vernooij
Update TODO
702
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
703
    def get_selected_right(self):
704
        """ Get the selected filename. """
705
        treeselection = self.treeview_right.get_selection()
706
        (model, iter) = treeselection.get_selected()
707
        
708
        if iter is None:
709
            return None
710
        else:
711
            return model.get_value(iter, 1)
712
    
713
    def get_selected_left(self):
714
        """ Get the selected bookmark. """
715
        treeselection = self.treeview_left.get_selection()
716
        (model, iter) = treeselection.get_selected()
717
        
718
        if iter is None:
719
            return None
720
        else:
721
            return model.get_value(iter, 1)
722
723
    def set_statusbar(self, message):
724
        """ Set the statusbar message. """
725
        self.statusbar.push(self.context_id, message)
726
    
727
    def clear_statusbar(self):
728
        """ Clean the last message from the statusbar. """
729
        self.statusbar.pop(self.context_id)
730
    
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
731
    def set_sensitivity(self):
732
        """ Set menu and toolbar sensitivity. """
733
        self.menuitem_branch_init.set_sensitive(self.notbranch)
95 by Szilveszter Farkas (Phanatic)
Added pending merges to Commit dialog. Fixed bug #66091.
734
        self.menuitem_branch_get.set_sensitive(self.notbranch)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
735
        self.menuitem_branch_checkout.set_sensitive(self.notbranch)
736
        self.menuitem_branch_pull.set_sensitive(not self.notbranch)
737
        self.menuitem_branch_push.set_sensitive(not self.notbranch)
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
738
        self.menuitem_branch_revert.set_sensitive(not self.notbranch)
93 by Szilveszter Farkas (Phanatic)
Began to implement Merge dialog.
739
        self.menuitem_branch_merge.set_sensitive(not self.notbranch)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
740
        self.menuitem_branch_commit.set_sensitive(not self.notbranch)
741
        self.menuitem_branch_status.set_sensitive(not self.notbranch)
742
        self.menuitem_branch_missing.set_sensitive(not self.notbranch)
743
        self.menuitem_stats.set_sensitive(not self.notbranch)
744
        self.menuitem_add_files.set_sensitive(not self.notbranch)
745
        self.menuitem_remove_files.set_sensitive(not self.notbranch)
746
        self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
747
        self.menuitem_file_rename.set_sensitive(not self.notbranch)
748
        self.menuitem_file_move.set_sensitive(not self.notbranch)
124 by Szilveszter Farkas (Phanatic)
Implemented annotate functionality (Fixed: #73786).
749
        self.menuitem_file_annotate.set_sensitive(not self.notbranch)
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
750
        #self.menutoolbutton_diff.set_sensitive(True)
751
        self.toolbutton_diff.set_sensitive(not self.notbranch)
752
        self.toolbutton_log.set_sensitive(not self.notbranch)
753
        self.toolbutton_commit.set_sensitive(not self.notbranch)
754
        self.toolbutton_pull.set_sensitive(not self.notbranch)
755
        self.toolbutton_push.set_sensitive(not self.notbranch)
756
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
757
    def refresh_left(self):
758
        """ Refresh the bookmark list. """
759
        
760
        # Get TreeStore and clear it
761
        treestore = self.treeview_left.get_model()
762
        treestore.clear()
763
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
764
        # Re-read preferences
765
        self.pref.read()
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
766
        
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
767
        # Get bookmarks
768
        bookmarks = self.pref.get_bookmarks()
769
770
        # Add them to the TreeStore
771
        titer = treestore.append(None, [_('Bookmarks'), None])
772
        for item in bookmarks:
773
            title = self.pref.get_bookmark_title(item)
774
            treestore.append(titer, [title, item])
775
776
        # Add the TreeStore to the TreeView
777
        self.treeview_left.set_model(treestore)
778
779
        # Expand the tree
780
        self.treeview_left.expand_all()
781
782
    def refresh_right(self, path=None):
783
        """ Refresh the file list. """
784
        from bzrlib.workingtree import WorkingTree
785
786
        if path is None:
787
            path = self.get_path()
788
789
        # A workaround for double-clicking Bookmarks
790
        if not os.path.exists(path):
791
            return
792
793
        # Get ListStore and clear it
794
        liststore = self.treeview_right.get_model()
795
        liststore.clear()
796
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
797
        dirs = []
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
798
        files = []
799
800
        # Fill the appropriate lists
801
        dotted_files = self.pref.get_preference('dotted_files', 'bool')
802
        for item in os.listdir(path):
803
            if not dotted_files and item[0] == '.':
804
                continue
805
            if os.path.isdir(path + os.sep + item):
806
                dirs.append(item)
807
            else:
808
                files.append(item)
809
810
        # Sort'em
811
        dirs.sort()
812
        files.sort()
0.14.12 by Alexander Belchenko
updir link (..) added always to the top of directories list
813
814
        # add updir link to dirs
815
        self._add_updir_to_dirlist(dirs, path)
816
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
817
        # Try to open the working tree
818
        notbranch = False
819
        try:
820
            tree1 = WorkingTree.open_containing(path)[0]
126.1.11 by Szilveszter Farkas (Phanatic)
Add revert all functionality and fix another regression.
821
        except (bzrerrors.NotBranchError, bzrerrors.NoWorkingTree):
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
822
            notbranch = True
823
        
824
        if not notbranch:
825
            branch = tree1.branch
826
            tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
827
        
828
            delta = tree1.changes_from(tree2, want_unchanged=True)
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
829
            
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
830
        # Add'em to the ListStore
831
        for item in dirs:
832
            liststore.append([gtk.STOCK_DIRECTORY, item, ''])
833
        for item in files:
834
            status = 'unknown'
835
            if not notbranch:
836
                filename = tree1.relpath(path + os.sep + item)
837
                
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
838
                for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
839
                    if rpathnew == filename:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
840
                        status = 'renamed'
841
                for rpath, id, kind in delta.added:
842
                    if rpath == filename:
0.8.98 by Szilveszter Farkas (Phanatic)
Loads of fixes. Pyflakes cleanup.
843
                        status = 'added'                
89 by Jelmer Vernooij
Rename OliveBranch -> BranchDialog.
844
                for rpath, id, kind in delta.removed:
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
845
                    if rpath == filename:
846
                        status = 'removed'
847
                for rpath, id, kind, text_modified, meta_modified in delta.modified:
848
                    if rpath == filename:
849
                        status = 'modified'
850
                for rpath, id, kind in delta.unchanged:
851
                    if rpath == filename:
852
                        status = 'unchanged'
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
853
                for rpath, file_class, kind, id, entry in self.wt.list_files():
854
                    if rpath == filename and file_class == 'I':
855
                        status = 'ignored'
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
856
            
857
            #try:
858
            #    status = fileops.status(path + os.sep + item)
859
            #except errors.PermissionDenied:
860
            #    continue
861
862
            if status == 'renamed':
863
                st = _('renamed')
864
            elif status == 'removed':
865
                st = _('removed')
866
            elif status == 'added':
867
                st = _('added')
868
            elif status == 'modified':
869
                st = _('modified')
870
            elif status == 'unchanged':
871
                st = _('unchanged')
123 by Szilveszter Farkas (Phanatic)
Ignored files are no more shown as unknown (Fixed: #67926).
872
            elif status == 'ignored':
873
                st = _('ignored')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
874
            else:
875
                st = _('unknown')
876
            liststore.append([gtk.STOCK_FILE, item, st])
877
878
        # Add the ListStore to the TreeView
879
        self.treeview_right.set_model(liststore)
0.8.94 by Szilveszter Farkas (Phanatic)
Cleanups: bookmarks and sensitivity.
880
        
0.8.95 by Szilveszter Farkas (Phanatic)
Some sensitivity changes; branching (get) fixed.
881
        # Set sensitivity
882
        self.set_sensitivity()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
883
884
    def _harddisks(self):
885
        """ Returns hard drive letters under Win32. """
886
        try:
887
            import win32file
888
            import string
889
        except ImportError:
890
            if sys.platform == 'win32':
891
                print "pyWin32 modules needed to run Olive on Win32."
892
                sys.exit(1)
893
            else:
894
                pass
895
        
896
        driveletters = []
897
        for drive in string.ascii_uppercase:
898
            if win32file.GetDriveType(drive+':') == win32file.DRIVE_FIXED:
899
                driveletters.append(drive+':')
900
        return driveletters
901
    
902
    def gen_hard_selector(self):
903
        """ Generate the hard drive selector under Win32. """
904
        drives = self._harddisks()
905
        for drive in drives:
906
            self.combobox_drive.append_text(drive)
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
907
        self.combobox_drive.set_active(drives.index(os.getcwd()[0:2]))
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
908
    
909
    def _refresh_drives(self, combobox):
126.1.4 by Szilveszter Farkas (Phanatic)
Set default drive letter (Fixed: #67924)
910
        if self._just_started:
911
            return
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
912
        model = combobox.get_model()
913
        active = combobox.get_active()
914
        if active >= 0:
915
            drive = model[active][0]
0.14.11 by Alexander Belchenko
Make change of drive letter on win32 is actually workable
916
            self.set_path(drive + '\\')
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
917
            self.refresh_right(drive + '\\')
122 by Szilveszter Farkas (Phanatic)
Do not allow merge if there are local changes (Fixed: #73770).
918
    
919
    def check_for_changes(self):
920
        """ Check whether there were changes in the current working tree. """
921
        old_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
922
        delta = self.wt.changes_from(old_tree)
923
924
        changes = False
925
        
926
        if len(delta.added) or len(delta.removed) or len(delta.renamed) or len(delta.modified):
927
            changes = True
928
        
929
        return changes
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
930
0.13.13 by Jelmer Vernooij
Update TODO
931
import ConfigParser
932
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
933
class OlivePreferences:
934
    """ A class which handles Olive's preferences. """
935
    def __init__(self):
936
        """ Initialize the Preferences class. """
937
        # Some default options
938
        self.defaults = { 'strict_commit' : False,
939
                          'dotted_files'  : False,
940
                          'window_width'  : 700,
941
                          'window_height' : 400,
942
                          'window_x'      : 40,
943
                          'window_y'      : 40,
944
                          'paned_position': 200 }
945
946
        # Create a config parser object
947
        self.config = ConfigParser.RawConfigParser()
948
        
949
        # Load the configuration
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
950
        self.read()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
951
        
952
    def _get_default(self, option):
953
        """ Get the default option for a preference. """
954
        try:
955
            ret = self.defaults[option]
956
        except KeyError:
957
            return None
958
        else:
959
            return ret
960
961
    def refresh(self):
962
        """ Refresh the configuration. """
963
        # First write out the changes
964
        self.write()
965
        # Then load the configuration again
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
966
        self.read()
967
968
    def read(self):
969
        """ Just read the configuration. """
111 by Szilveszter Farkas (Phanatic)
Fixed bug: unable to remove bookmarks (not reported).
970
        # Re-initialize the config parser object to avoid some bugs
971
        self.config = ConfigParser.RawConfigParser()
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
972
        if sys.platform == 'win32':
973
            # Windows - no dotted files
974
            self.config.read([os.path.expanduser('~/olive.conf')])
975
        else:
976
            self.config.read([os.path.expanduser('~/.olive.conf')])
0.8.93 by Szilveszter Farkas (Phanatic)
Some further cleanups. More to come.
977
    
0.8.84 by Szilveszter Farkas (Phanatic)
Huge cleanup after removing backend codebase.
978
    def write(self):
979
        """ Write the configuration to the appropriate files. """
980
        if sys.platform == 'win32':
981
            # Windows - no dotted files
982
            fp = open(os.path.expanduser('~/olive.conf'), 'w')
983
            self.config.write(fp)
984
            fp.close()
985
        else:
986
            fp = open(os.path.expanduser('~/.olive.conf'), 'w')
987
            self.config.write(fp)
988
            fp.close()
989
990
    def get_bookmarks(self):
991
        """ Return the list of bookmarks. """
992
        bookmarks = self.config.sections()
993
        if self.config.has_section('preferences'):
994
            bookmarks.remove('preferences')
995
        return bookmarks
996
997
    def add_bookmark(self, path):
998
        """ Add bookmark. """
999
        try:
1000
            self.config.add_section(path)
1001
        except ConfigParser.DuplicateSectionError:
1002
            return False
1003
        else:
1004
            return True
1005
1006
    def get_bookmark_title(self, path):
1007
        """ Get bookmark title. """
1008
        try:
1009
            ret = self.config.get(path, 'title')
1010
        except ConfigParser.NoOptionError:
1011
            ret = path
1012
        
1013
        return ret
1014
    
1015
    def set_bookmark_title(self, path, title):
1016
        """ Set bookmark title. """
1017
        self.config.set(path, 'title', title)
1018
    
1019
    def remove_bookmark(self, path):
1020
        """ Remove bookmark. """
1021
        return self.config.remove_section(path)
0.13.13 by Jelmer Vernooij
Update TODO
1022
1023
    def set_preference(self, option, value):
1024
        """ Set the value of the given option. """
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1025
        if value is True:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1026
            value = 'yes'
109 by Szilveszter Farkas (Phanatic)
Fix #70134: Unable to run Olive after maximizing window.
1027
        elif value is False:
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1028
            value = 'no'
1029
        
0.13.13 by Jelmer Vernooij
Update TODO
1030
        if self.config.has_section('preferences'):
1031
            self.config.set('preferences', option, value)
1032
        else:
1033
            self.config.add_section('preferences')
1034
            self.config.set('preferences', option, value)
1035
1036
    def get_preference(self, option, kind='str'):
1037
        """ Get the value of the given option.
1038
        
1039
        :param kind: str/bool/int/float. default: str
1040
        """
1041
        if self.config.has_option('preferences', option):
1042
            if kind == 'bool':
101 by Szilveszter Farkas (Phanatic)
Show/hide hidden files should work now.
1043
                return self.config.getboolean('preferences', option)
0.13.13 by Jelmer Vernooij
Update TODO
1044
            elif kind == 'int':
1045
                return self.config.getint('preferences', option)
1046
            elif kind == 'float':
1047
                return self.config.getfloat('preferences', option)
1048
            else:
1049
                return self.config.get('preferences', option)
1050
        else:
1051
            try:
1052
                return self._get_default(option)
1053
            except KeyError:
1054
                return None
1055