/b-gtk/fix-viz

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/b-gtk/fix-viz

« back to all changes in this revision

Viewing changes to olive/__init__.py

  • Committer: Szilveszter Farkas (Phanatic)
  • Date: 2006-10-03 06:44:48 UTC
  • mfrom: (0.8.98 merge)
  • mto: (93.1.1 win32.bialix)
  • mto: This revision was merged to the branch mainline in revision 103.
  • Revision ID: Szilveszter.Farkas@gmail.com-20061003064448-8cf3c9cc653346ab
Merge from the merge branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
 
import ConfigParser
18
17
import os
19
 
import os.path
20
18
import sys
21
19
 
22
20
try:
24
22
    pygtk.require("2.0")
25
23
except:
26
24
    pass
27
 
try:
28
 
    import gtk
29
 
    import gtk.gdk
30
 
    import gtk.glade
31
 
except:
32
 
    sys.exit(1)
33
 
 
34
 
from handler import OliveHandler
 
25
 
 
26
import gtk
 
27
import gtk.gdk
 
28
import gtk.glade
 
29
 
 
30
from bzrlib.branch import Branch
35
31
import bzrlib.errors as errors
 
32
from bzrlib.workingtree import WorkingTree
36
33
 
37
34
# Olive GTK UI version
38
35
__version__ = '0.11.0'
39
36
 
 
37
# Load the glade file
 
38
if sys.platform == 'win32':
 
39
    gladefile = os.path.dirname(sys.executable) + "/share/olive/olive.glade"
 
40
else:
 
41
    gladefile = "/usr/share/olive/olive.glade"
 
42
 
 
43
if not os.path.exists(gladefile):
 
44
    # Load from current directory if not installed
 
45
    gladefile = "olive.glade"
 
46
    # Check again
 
47
    if not os.path.exists(gladefile):
 
48
        # Fail
 
49
        print _('Glade file cannot be found.')
 
50
        sys.exit(1)
 
51
 
 
52
from dialog import error_dialog, info_dialog
 
53
 
40
54
class OliveGtk:
41
55
    """ The main Olive GTK frontend class. This is called when launching the
42
56
    program. """
43
57
    
44
58
    def __init__(self):
45
 
        # Load the glade file
46
 
        if sys.platform == 'win32':
47
 
            self.gladefile = os.path.dirname(sys.executable) + "/share/olive/olive.glade"
48
 
        else:
49
 
            self.gladefile = "/usr/share/olive/olive.glade"
50
 
 
51
 
        if not os.path.exists(self.gladefile):
52
 
            # Load from current directory if not installed
53
 
            self.gladefile = "olive.glade"
54
 
            # Check again
55
 
            if not os.path.exists(self.gladefile):
56
 
                # Fail
57
 
                print _('Glade file cannot be found.')
58
 
                sys.exit(1)
59
 
 
60
 
        self.toplevel = gtk.glade.XML(self.gladefile, 'window_main', 'olive-gtk')
 
59
        self.toplevel = gtk.glade.XML(gladefile, 'window_main', 'olive-gtk')
61
60
        
62
61
        self.window = self.toplevel.get_widget('window_main')
63
62
        
64
63
        self.pref = OlivePreferences()
65
 
        self.comm = OliveCommunicator(self.toplevel, self.pref)
66
 
        handler = OliveHandler(self.gladefile, self.comm)
 
64
 
 
65
        # Initialize the statusbar
 
66
        self.statusbar = self.toplevel.get_widget('statusbar')
 
67
        self.context_id = self.statusbar.get_context_id('olive')
 
68
        
 
69
        # Get the main window
 
70
        self.window_main = self.toplevel.get_widget('window_main')
 
71
        # Get the HPaned
 
72
        self.hpaned_main = self.toplevel.get_widget('hpaned_main')
 
73
        # Get the TreeViews
 
74
        self.treeview_left = self.toplevel.get_widget('treeview_left')
 
75
        self.treeview_right = self.toplevel.get_widget('treeview_right')
 
76
        # Get some important menu items
 
77
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
 
78
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
 
79
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
 
80
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
 
81
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
 
82
        self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
 
83
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
 
84
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
 
85
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
 
86
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
 
87
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
 
88
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
 
89
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
 
90
        self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
 
91
        self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
 
92
        self.menuitem_stats = self.toplevel.get_widget('menuitem_stats')
 
93
        self.menuitem_stats_diff = self.toplevel.get_widget('menuitem_stats_diff')
 
94
        self.menuitem_stats_log = self.toplevel.get_widget('menuitem_stats_log')
 
95
        # Get some toolbuttons
 
96
        #self.menutoolbutton_diff = self.toplevel.get_widget('menutoolbutton_diff')
 
97
        self.toolbutton_diff = self.toplevel.get_widget('toolbutton_diff')
 
98
        self.toolbutton_log = self.toplevel.get_widget('toolbutton_log')
 
99
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
 
100
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
 
101
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
 
102
        # Get the drive selector
 
103
        self.combobox_drive = gtk.combo_box_new_text()
 
104
        self.combobox_drive.connect("changed", self._refresh_drives)
 
105
        
 
106
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
 
107
 
67
108
        
68
109
        # Dictionary for signal_autoconnect
69
110
        dic = { "on_window_main_destroy": gtk.main_quit,
70
 
                "on_window_main_delete_event": handler.on_window_main_delete_event,
71
 
                "on_quit_activate": handler.on_window_main_delete_event,
72
 
                "on_about_activate": handler.on_about_activate,
73
 
                "on_menuitem_add_files_activate": handler.on_menuitem_add_files_activate,
74
 
                "on_menuitem_remove_file_activate": handler.on_menuitem_remove_file_activate,
75
 
                "on_menuitem_file_make_directory_activate": handler.on_menuitem_file_make_directory_activate,
76
 
                "on_menuitem_file_move_activate": handler.on_menuitem_file_move_activate,
77
 
                "on_menuitem_file_rename_activate": handler.on_menuitem_file_rename_activate,
78
 
                "on_menuitem_view_show_hidden_files_activate": handler.on_menuitem_view_show_hidden_files_activate,
79
 
                "on_menuitem_view_refresh_activate": handler.on_menuitem_view_refresh_activate,
80
 
                "on_menuitem_branch_initialize_activate": handler.on_menuitem_branch_initialize_activate,
81
 
                "on_menuitem_branch_get_activate": handler.on_menuitem_branch_get_activate,
82
 
                "on_menuitem_branch_checkout_activate": handler.on_menuitem_branch_checkout_activate,
83
 
                "on_menuitem_branch_commit_activate": handler.on_menuitem_branch_commit_activate,
84
 
                "on_menuitem_branch_push_activate": handler.on_menuitem_branch_push_activate,
85
 
                "on_menuitem_branch_pull_activate": handler.on_menuitem_branch_pull_activate,
86
 
                "on_menuitem_branch_status_activate": handler.on_menuitem_branch_status_activate,
87
 
                "on_menuitem_branch_missing_revisions_activate": handler.on_menuitem_branch_missing_revisions_activate,
88
 
                "on_menuitem_stats_diff_activate": handler.on_menuitem_stats_diff_activate,
89
 
                "on_menuitem_stats_log_activate": handler.on_menuitem_stats_log_activate,
90
 
                "on_menuitem_stats_infos_activate": handler.on_menuitem_stats_infos_activate,
91
 
                "on_toolbutton_refresh_clicked": handler.on_menuitem_view_refresh_activate,
92
 
                "on_toolbutton_log_clicked": handler.on_menuitem_stats_log_activate,
93
 
                #"on_menutoolbutton_diff_clicked": handler.on_menuitem_stats_diff_activate,
94
 
                "on_toolbutton_diff_clicked": handler.on_menuitem_stats_diff_activate,
95
 
                "on_toolbutton_commit_clicked": handler.on_menuitem_branch_commit_activate,
96
 
                "on_toolbutton_pull_clicked": handler.on_menuitem_branch_pull_activate,
97
 
                "on_toolbutton_push_clicked": handler.on_menuitem_branch_push_activate,
98
 
                "on_treeview_right_button_press_event": handler.on_treeview_right_button_press_event,
99
 
                "on_treeview_right_row_activated": handler.on_treeview_right_row_activated,
100
 
                "on_treeview_left_button_press_event": handler.on_treeview_left_button_press_event,
101
 
                "on_treeview_left_row_activated": handler.on_treeview_left_row_activated }
 
111
                "on_window_main_delete_event": self.on_window_main_delete_event,
 
112
                "on_quit_activate": self.on_window_main_delete_event,
 
113
                "on_about_activate": self.on_about_activate,
 
114
                "on_menuitem_add_files_activate": self.on_menuitem_add_files_activate,
 
115
                "on_menuitem_remove_file_activate": self.on_menuitem_remove_file_activate,
 
116
                "on_menuitem_file_make_directory_activate": self.on_menuitem_file_make_directory_activate,
 
117
                "on_menuitem_file_move_activate": self.on_menuitem_file_move_activate,
 
118
                "on_menuitem_file_rename_activate": self.on_menuitem_file_rename_activate,
 
119
                "on_menuitem_view_show_hidden_files_activate": self.on_menuitem_view_show_hidden_files_activate,
 
120
                "on_menuitem_view_refresh_activate": self.on_menuitem_view_refresh_activate,
 
121
                "on_menuitem_branch_initialize_activate": self.on_menuitem_branch_initialize_activate,
 
122
                "on_menuitem_branch_get_activate": self.on_menuitem_branch_get_activate,
 
123
                "on_menuitem_branch_checkout_activate": self.on_menuitem_branch_checkout_activate,
 
124
                "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
 
125
                "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
 
126
                "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
 
127
                "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
 
128
                "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
 
129
                "on_menuitem_stats_diff_activate": self.on_menuitem_stats_diff_activate,
 
130
                "on_menuitem_stats_log_activate": self.on_menuitem_stats_log_activate,
 
131
                "on_menuitem_stats_infos_activate": self.on_menuitem_stats_infos_activate,
 
132
                "on_toolbutton_refresh_clicked": self.on_menuitem_view_refresh_activate,
 
133
                "on_toolbutton_log_clicked": self.on_menuitem_stats_log_activate,
 
134
                #"on_menutoolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
 
135
                "on_toolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
 
136
                "on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
 
137
                "on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
 
138
                "on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
 
139
                "on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
 
140
                "on_treeview_right_row_activated": self.on_treeview_right_row_activated,
 
141
                "on_treeview_left_button_press_event": self.on_treeview_left_button_press_event,
 
142
                "on_treeview_left_row_activated": self.on_treeview_left_row_activated }
102
143
        
103
144
        # Connect the signals to the handlers
104
145
        self.toplevel.signal_autoconnect(dic)
112
153
        self.window.move(x, y)
113
154
        # Apply paned position
114
155
        pos = self.pref.get_preference('paned_position', 'int')
115
 
        self.comm.hpaned_main.set_position(pos)
 
156
        self.hpaned_main.set_position(pos)
116
157
        
117
158
        # Apply menu to the toolbutton
118
159
        #menubutton = self.toplevel.get_widget('menutoolbutton_diff')
123
164
        
124
165
        # Show drive selector if under Win32
125
166
        if sys.platform == 'win32':
126
 
            self.comm.vbox_main_right.pack_start(self.comm.combobox_drive, False, True, 0)
127
 
            self.comm.vbox_main_right.reorder_child(self.comm.combobox_drive, 0)
128
 
            self.comm.combobox_drive.show()
129
 
            self.comm.gen_hard_selector()
 
167
            self.vbox_main_right.pack_start(self.combobox_drive, False, True, 0)
 
168
            self.vbox_main_right.reorder_child(self.combobox_drive, 0)
 
169
            self.combobox_drive.show()
 
170
            self.gen_hard_selector()
130
171
        
131
 
        # Load default data into the panels
132
 
        self.treeview_left = self.toplevel.get_widget('treeview_left')
133
 
        self.treeview_right = self.toplevel.get_widget('treeview_right')
134
172
        self._load_left()
 
173
 
 
174
        # Apply menu state
 
175
        self.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
 
176
 
 
177
        self.set_path(os.getcwd())
135
178
        self._load_right()
136
179
 
137
 
        # Apply menu state
138
 
        self.comm.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
 
180
    def set_path(self, path):
 
181
        self.path = path
 
182
        self.notbranch = False
 
183
        try:
 
184
            self.wt, self.wtpath = WorkingTree.open_containing(self.path)
 
185
        except errors.NotBranchError:
 
186
            self.notbranch = True
 
187
 
 
188
    def get_path(self):
 
189
        return self.path
 
190
   
 
191
    def on_about_activate(self, widget):
 
192
        from dialog import about
 
193
        about()
 
194
        
 
195
    def on_menuitem_add_files_activate(self, widget):
 
196
        """ Add file(s)... menu handler. """
 
197
        from add import OliveAdd
 
198
        add = OliveAdd(self.wt, self.wtpath, self.get_selected_right())
 
199
        add.display()
 
200
    
 
201
    def on_menuitem_branch_get_activate(self, widget):
 
202
        """ Branch/Get... menu handler. """
 
203
        from branch import OliveBranch
 
204
        branch = OliveBranch(self.get_path())
 
205
        branch.display()
 
206
    
 
207
    def on_menuitem_branch_checkout_activate(self, widget):
 
208
        """ Branch/Checkout... menu handler. """
 
209
        from checkout import OliveCheckout
 
210
        checkout = OliveCheckout(self.get_path())
 
211
        checkout.display()
 
212
    
 
213
    def on_menuitem_branch_commit_activate(self, widget):
 
214
        """ Branch/Commit... menu handler. """
 
215
        from commit import OliveCommit
 
216
        commit = OliveCommit(self.wt, self.wtpath)
 
217
        commit.display()
 
218
    
 
219
    def on_menuitem_branch_missing_revisions_activate(self, widget):
 
220
        """ Branch/Missing revisions menu handler. """
 
221
        local_branch = self.wt.branch
 
222
        
 
223
        other_branch = local_branch.get_parent()
 
224
        if other_branch is None:
 
225
            error_dialog(_('Parent location is unknown'),
 
226
                         _('Cannot determine missing revisions if no parent location is known.'))
 
227
            return
 
228
        
 
229
        remote_branch = Branch.open(other_branch)
 
230
        
 
231
        if remote_branch.base == local_branch.base:
 
232
            remote_branch = local_branch
 
233
 
 
234
        ret = len(local_branch.missing_revisions(remote_branch))
 
235
 
 
236
        if ret > 0:
 
237
            info_dialog(_('There are missing revisions'),
 
238
                        _('%d revision(s) missing.') % ret)
 
239
        else:
 
240
            info_dialog(_('Local branch up to date'),
 
241
                        _('There are no missing revisions.'))
 
242
 
 
243
    def on_menuitem_branch_pull_activate(self, widget):
 
244
        """ Branch/Pull menu handler. """
 
245
        branch_to = self.wt.branch
 
246
 
 
247
        location = branch_to.get_parent()
 
248
        if location is None:
 
249
            error_dialog(_('Parent location is unknown'),
 
250
                                     _('Pulling is not possible until there is a parent location.'))
 
251
            return
 
252
 
 
253
        try:
 
254
            branch_from = Branch.open(location)
 
255
        except errors.NotBranchError:
 
256
            error_dialog(_('Directory is not a branch'),
 
257
                                     _('You can perform this action only in a branch.'))
 
258
 
 
259
        if branch_to.get_parent() is None:
 
260
            branch_to.set_parent(branch_from.base)
 
261
 
 
262
        #old_rh = branch_to.revision_history()
 
263
        #if tree_to is not None:
 
264
        #    tree_to.pull(branch_from)
 
265
        #else:
 
266
        #    branch_to.pull(branch_from)
 
267
        branch_to.pull(branch_from)
 
268
        
 
269
        # TODO: get the number of pulled revisions
 
270
        ret = 0
 
271
        
 
272
        info_dialog(_('Pull successful'), _('%d revision(s) pulled.') % ret)
 
273
    
 
274
    def on_menuitem_branch_push_activate(self, widget):
 
275
        """ Branch/Push... menu handler. """
 
276
        from push import OlivePush
 
277
        push = OlivePush(self.wt.branch)
 
278
        push.display()
 
279
    
 
280
    def on_menuitem_branch_status_activate(self, widget):
 
281
        """ Branch/Status... menu handler. """
 
282
        from status import OliveStatus
 
283
        status = OliveStatus(self.wt, self.wtpath)
 
284
        status.display()
 
285
    
 
286
    def on_menuitem_branch_initialize_activate(self, widget):
 
287
        """ Initialize current directory. """
 
288
        import bzrlib.bzrdir as bzrdir
 
289
        
 
290
        try:
 
291
            if not os.path.exists(self.path):
 
292
                os.mkdir(self.path)
 
293
     
 
294
            try:
 
295
                existing_bzrdir = bzrdir.BzrDir.open(self.path)
 
296
            except errors.NotBranchError:
 
297
                bzrdir.BzrDir.create_branch_convenience(self.path)
 
298
            else:
 
299
                if existing_bzrdir.has_branch():
 
300
                    if existing_bzrdir.has_workingtree():
 
301
                        raise errors.AlreadyBranchError(self.path)
 
302
                    else:
 
303
                        raise errors.BranchExistsWithoutWorkingTree(self.path)
 
304
                else:
 
305
                    existing_bzrdir.create_branch()
 
306
                    existing_bzrdir.create_workingtree()
 
307
        except errors.AlreadyBranchError, errmsg:
 
308
            error_dialog(_('Directory is already a branch'),
 
309
                                     _('The current directory (%s) is already a branch.\nYou can start using it, or initialize another directory.') % errmsg)
 
310
        except errors.BranchExistsWithoutWorkingTree, errmsg:
 
311
            error_dialog(_('Branch without a working tree'),
 
312
                                     _('The current directory (%s)\nis a branch without a working tree.') % errmsg)
 
313
        else:
 
314
            info_dialog(_('Initialize successful'),
 
315
                                    _('Directory successfully initialized.'))
 
316
            self.refresh_right()
 
317
        
 
318
    def on_menuitem_file_make_directory_activate(self, widget):
 
319
        """ File/Make directory... menu handler. """
 
320
        from mkdir import OliveMkdir
 
321
        mkdir = OliveMkdir(self.wt, self.wtpath)
 
322
        mkdir.display()
 
323
    
 
324
    def on_menuitem_file_move_activate(self, widget):
 
325
        """ File/Move... menu handler. """
 
326
        from move import OliveMove
 
327
        move = OliveMove(self.wt, self.wtpath, self.get_selected_right())
 
328
        move.display()
 
329
    
 
330
    def on_menuitem_file_rename_activate(self, widget):
 
331
        """ File/Rename... menu handler. """
 
332
        from rename import OliveRename
 
333
        rename = OliveRename(self.wt, self.wtpath, self.get_selected_right())
 
334
        rename.display()
 
335
 
 
336
    def on_menuitem_remove_file_activate(self, widget):
 
337
        """ Remove (unversion) selected file. """
 
338
        from remove import OliveRemove
 
339
        remove = OliveRemove(self.wt, self.wtpath, self.get_selected_right())
 
340
        remove.display()
 
341
    
 
342
    def on_menuitem_stats_diff_activate(self, widget):
 
343
        """ Statistics/Differences... menu handler. """
 
344
        from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
 
345
        window = DiffWindow()
 
346
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
 
347
        window.set_diff(self.wt.branch.nick, self.wt, parent_tree)
 
348
        window.show()
 
349
    
 
350
    def on_menuitem_stats_infos_activate(self, widget):
 
351
        """ Statistics/Informations... menu handler. """
 
352
        from info import OliveInfo
 
353
        info = OliveInfo(self.wt)
 
354
        info.display()
 
355
    
 
356
    def on_menuitem_stats_log_activate(self, widget):
 
357
        """ Statistics/Log... menu handler. """
 
358
        from bzrlib.plugins.gtk.viz.branchwin import BranchWindow
 
359
        window = BranchWindow()
 
360
        window.set_branch(self.wt.branch, self.wt.branch.last_revision(), None)
 
361
        window.show()
 
362
    
 
363
    def on_menuitem_view_refresh_activate(self, widget):
 
364
        """ View/Refresh menu handler. """
 
365
        # Refresh the left pane
 
366
        self.refresh_left()
 
367
        # Refresh the right pane
 
368
        self.refresh_right()
 
369
   
 
370
    def on_menuitem_view_show_hidden_files_activate(self, widget):
 
371
        """ View/Show hidden files menu handler. """
 
372
        self.pref.set_preference('dotted_files', widget.get_active())
 
373
 
 
374
    def on_treeview_left_button_press_event(self, widget, event):
 
375
        """ Occurs when somebody right-clicks in the bookmark list. """
 
376
        if event.button == 3:
 
377
            # Don't show context with nothing selected
 
378
            if self.get_selected_left() == None:
 
379
                return
 
380
 
 
381
            # Create a menu
 
382
            from menu import OliveMenu
 
383
            menu = OliveMenu(self.get_path(), self.get_selected_left())
 
384
            
 
385
            menu.left_context_menu().popup(None, None, None, 0,
 
386
                                           event.time)
 
387
 
 
388
    def on_treeview_left_row_activated(self, treeview, path, view_column):
 
389
        """ Occurs when somebody double-clicks or enters an item in the
 
390
        bookmark list. """
 
391
 
 
392
        newdir = self.get_selected_left()
 
393
        if newdir == None:
 
394
            return
 
395
 
 
396
        self.set_path(newdir)
 
397
        self.refresh_right()
 
398
 
 
399
    def on_treeview_right_button_press_event(self, widget, event):
 
400
        """ Occurs when somebody right-clicks in the file list. """
 
401
        if event.button == 3:
 
402
            # Create a menu
 
403
            from menu import OliveMenu
 
404
            menu = OliveMenu(self.get_path(), self.get_selected_right())
 
405
            # get the menu items
 
406
            m_add = menu.ui.get_widget('/context_right/add')
 
407
            m_remove = menu.ui.get_widget('/context_right/remove')
 
408
            m_commit = menu.ui.get_widget('/context_right/commit')
 
409
            m_diff = menu.ui.get_widget('/context_right/diff')
 
410
            # check if we're in a branch
 
411
            try:
 
412
                from bzrlib.branch import Branch
 
413
                Branch.open_containing(self.get_path())
 
414
                m_add.set_sensitive(True)
 
415
                m_remove.set_sensitive(True)
 
416
                m_commit.set_sensitive(True)
 
417
                m_diff.set_sensitive(True)
 
418
            except errors.NotBranchError:
 
419
                m_add.set_sensitive(False)
 
420
                m_remove.set_sensitive(False)
 
421
                m_commit.set_sensitive(False)
 
422
                m_diff.set_sensitive(False)
 
423
            menu.right_context_menu().popup(None, None, None, 0,
 
424
                                            event.time)
 
425
        
 
426
    def on_treeview_right_row_activated(self, treeview, path, view_column):
 
427
        """ Occurs when somebody double-clicks or enters an item in the
 
428
        file list. """
 
429
        import os.path
 
430
        
 
431
        from launch import launch
 
432
        
 
433
        newdir = self.get_selected_right()
 
434
        
 
435
        if newdir == '..':
 
436
            self.set_path(os.path.split(self.get_path())[0])
 
437
        else:
 
438
            fullpath = self.get_path() + os.sep + newdir
 
439
            if os.path.isdir(fullpath):
 
440
                # selected item is an existant directory
 
441
                self.set_path(fullpath)
 
442
            else:
 
443
                launch(fullpath) 
 
444
        
 
445
        self.refresh_right()
 
446
    
 
447
    def on_window_main_delete_event(self, widget, event=None):
 
448
        """ Do some stuff before exiting. """
 
449
        width, height = self.window_main.get_size()
 
450
        self.pref.set_preference('window_width', width)
 
451
        self.pref.set_preference('window_height', height)
 
452
        x, y = self.window_main.get_position()
 
453
        self.pref.set_preference('window_x', x)
 
454
        self.pref.set_preference('window_y', y)
 
455
        self.pref.set_preference('paned_position',
 
456
                                      self.hpaned_main.get_position())
 
457
        
 
458
        self.pref.write()
 
459
        self.window_main.destroy()
139
460
        
140
461
    def _load_left(self):
141
462
        """ Load data into the left panel. (Bookmarks) """
142
 
        # set cursor to busy
143
 
        self.comm.set_busy(self.treeview_left)
144
 
        
145
463
        # Create TreeStore
146
464
        treestore = gtk.TreeStore(str, str)
147
465
        
148
466
        # Get bookmarks
149
 
        bookmarks = self.comm.pref.get_bookmarks()
 
467
        bookmarks = self.pref.get_bookmarks()
150
468
        
151
469
        # Add them to the TreeStore
152
470
        titer = treestore.append(None, [_('Bookmarks'), None])
153
471
        for item in bookmarks:
154
 
            title = self.comm.pref.get_bookmark_title(item)
 
472
            title = self.pref.get_bookmark_title(item)
155
473
            treestore.append(titer, [title, item])
156
474
        
157
475
        # Create the column and add it to the TreeView
167
485
        # Expand the tree
168
486
        self.treeview_left.expand_all()
169
487
 
170
 
        self.comm.set_busy(self.treeview_left, False)
171
 
        
172
488
    def _load_right(self):
173
489
        """ Load data into the right panel. (Filelist) """
174
 
        from bzrlib.workingtree import WorkingTree
175
 
        
176
 
        # set cursor to busy
177
 
        self.comm.set_busy(self.treeview_right)
178
 
        
179
490
        # Create ListStore
180
491
        liststore = gtk.ListStore(str, str, str)
181
492
        
183
494
        files = []
184
495
        
185
496
        # Fill the appropriate lists
186
 
        path = self.comm.get_path()
187
497
        dotted_files = self.pref.get_preference('dotted_files', 'bool')
188
 
        for item in os.listdir(path):
 
498
        for item in os.listdir(self.path):
189
499
            if not dotted_files and item[0] == '.':
190
500
                continue
191
 
            if os.path.isdir(path + os.sep + item):
 
501
            if os.path.isdir(self.path + os.sep + item):
192
502
                dirs.append(item)
193
503
            else:
194
504
                files.append(item)
197
507
        dirs.sort()
198
508
        files.sort()
199
509
        
200
 
        # Try to open the working tree
201
 
        notbranch = False
202
 
        try:
203
 
            tree1 = WorkingTree.open_containing(path)[0]
204
 
        except errors.NotBranchError:
205
 
            notbranch = True
206
 
        except errors.PermissionDenied:
207
 
            print "DEBUG: permission denied."
208
 
        
209
 
        if not notbranch:
210
 
            branch = tree1.branch
211
 
            tree2 = tree1.branch.repository.revision_tree(branch.last_revision())
212
 
        
213
 
            delta = tree1.changes_from(tree2, want_unchanged=True)
 
510
        if not self.notbranch:
 
511
            branch = self.wt.branch
 
512
            tree2 = self.wt.branch.repository.revision_tree(branch.last_revision())
 
513
        
 
514
            delta = self.wt.changes_from(tree2, want_unchanged=True)
214
515
        
215
516
        # Add'em to the ListStore
216
517
        for item in dirs:    
217
518
            liststore.append([gtk.STOCK_DIRECTORY, item, ''])
218
519
        for item in files:
219
520
            status = 'unknown'
220
 
            if not notbranch:
221
 
                filename = tree1.relpath(path + os.sep + item)
 
521
            if not self.notbranch:
 
522
                filename = self.wt.relpath(self.path + os.sep + item)
222
523
                
223
 
                for rpath, id, kind, text_modified, meta_modified in delta.renamed:
224
 
                    if rpath == filename:
 
524
                for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
 
525
                    if rpathnew == filename:
225
526
                        status = 'renamed'
226
527
                for rpath, id, kind in delta.added:
227
528
                    if rpath == filename:
228
529
                        status = 'added'
229
 
                for rpath, id, kind, text_modified, meta_modified in delta.removed:
 
530
                for rpath, id, kind in delta.removed:
230
531
                    if rpath == filename:
231
532
                        status = 'removed'
232
533
                for rpath, id, kind, text_modified, meta_modified in delta.modified:
272
573
        tvcolumn_status.pack_start(cell, True)
273
574
        tvcolumn_status.add_attribute(cell, 'text', 2)
274
575
        
275
 
        # Check if current directory is a branch
276
 
        if not notbranch:
277
 
            # Activate some items
278
 
            self.comm.menuitem_branch_init.set_sensitive(False)
279
 
            self.comm.menuitem_branch_get.set_sensitive(True)
280
 
            self.comm.menuitem_branch_checkout.set_sensitive(True)
281
 
            self.comm.menuitem_branch_pull.set_sensitive(True)
282
 
            self.comm.menuitem_branch_push.set_sensitive(True)
283
 
            self.comm.menuitem_branch_commit.set_sensitive(True)
284
 
            self.comm.menuitem_branch_status.set_sensitive(True)
285
 
            self.comm.menuitem_branch_missing.set_sensitive(True)
286
 
            self.comm.menuitem_stats.set_sensitive(True)
287
 
            self.comm.menuitem_add_files.set_sensitive(True)
288
 
            self.comm.menuitem_remove_files.set_sensitive(True)
289
 
            self.comm.menuitem_file_make_directory.set_sensitive(True)
290
 
            self.comm.menuitem_file_rename.set_sensitive(True)
291
 
            self.comm.menuitem_file_move.set_sensitive(True)
292
 
            #self.comm.menutoolbutton_diff.set_sensitive(True)
293
 
            self.comm.toolbutton_diff.set_sensitive(True)
294
 
            self.comm.toolbutton_log.set_sensitive(True)
295
 
            self.comm.toolbutton_commit.set_sensitive(True)
296
 
            self.comm.toolbutton_pull.set_sensitive(True)
297
 
            self.comm.toolbutton_push.set_sensitive(True)
298
 
        else:
299
 
            # Deactivate some items
300
 
            self.comm.menuitem_branch_init.set_sensitive(True)
301
 
            self.comm.menuitem_branch_get.set_sensitive(False)
302
 
            self.comm.menuitem_branch_checkout.set_sensitive(False)
303
 
            self.comm.menuitem_branch_pull.set_sensitive(False)
304
 
            self.comm.menuitem_branch_push.set_sensitive(False)
305
 
            self.comm.menuitem_branch_commit.set_sensitive(False)
306
 
            self.comm.menuitem_branch_status.set_sensitive(False)
307
 
            self.comm.menuitem_branch_missing.set_sensitive(False)
308
 
            self.comm.menuitem_stats.set_sensitive(False)
309
 
            self.comm.menuitem_add_files.set_sensitive(False)
310
 
            self.comm.menuitem_remove_files.set_sensitive(False)
311
 
            self.comm.menuitem_file_make_directory.set_sensitive(False)
312
 
            self.comm.menuitem_file_rename.set_sensitive(False)
313
 
            self.comm.menuitem_file_move.set_sensitive(False)
314
 
            #self.comm.menutoolbutton_diff.set_sensitive(False)
315
 
            self.comm.toolbutton_diff.set_sensitive(False)
316
 
            self.comm.toolbutton_log.set_sensitive(False)
317
 
            self.comm.toolbutton_commit.set_sensitive(False)
318
 
            self.comm.toolbutton_pull.set_sensitive(False)
319
 
            self.comm.toolbutton_push.set_sensitive(False)
320
 
        
321
 
        # set cursor to default
322
 
        self.comm.set_busy(self.treeview_right, False)
323
 
 
324
 
class OliveCommunicator:
325
 
    """ This class is responsible for the communication between the different
326
 
    modules. """
327
 
    def __init__(self, toplevel, pref):
328
 
        # Get glade main component
329
 
        self.toplevel = toplevel
330
 
        # Preferences object
331
 
        self.pref = pref
332
 
        # Default path
333
 
        self._path = os.getcwd()
334
 
 
335
 
        # Initialize the statusbar
336
 
        self.statusbar = self.toplevel.get_widget('statusbar')
337
 
        self.context_id = self.statusbar.get_context_id('olive')
338
 
        
339
 
        # Get the main window
340
 
        self.window_main = self.toplevel.get_widget('window_main')
341
 
        # Get the HPaned
342
 
        self.hpaned_main = self.toplevel.get_widget('hpaned_main')
343
 
        # Get the TreeViews
344
 
        self.treeview_left = self.toplevel.get_widget('treeview_left')
345
 
        self.treeview_right = self.toplevel.get_widget('treeview_right')
346
 
        # Get some important menu items
347
 
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
348
 
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
349
 
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
350
 
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
351
 
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
352
 
        self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
353
 
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
354
 
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
355
 
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
356
 
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
357
 
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
358
 
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
359
 
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
360
 
        self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
361
 
        self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
362
 
        self.menuitem_stats = self.toplevel.get_widget('menuitem_stats')
363
 
        self.menuitem_stats_diff = self.toplevel.get_widget('menuitem_stats_diff')
364
 
        self.menuitem_stats_log = self.toplevel.get_widget('menuitem_stats_log')
365
 
        # Get some toolbuttons
366
 
        #self.menutoolbutton_diff = self.toplevel.get_widget('menutoolbutton_diff')
367
 
        self.toolbutton_diff = self.toplevel.get_widget('toolbutton_diff')
368
 
        self.toolbutton_log = self.toplevel.get_widget('toolbutton_log')
369
 
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
370
 
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
371
 
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
372
 
        # Get the drive selector
373
 
        self.combobox_drive = gtk.combo_box_new_text()
374
 
        self.combobox_drive.connect("changed", self._refresh_drives)
375
 
        
376
 
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
377
 
    
378
 
    def set_path(self, path):
379
 
        """ Set the current path while browsing the directories. """
380
 
        self._path = path
381
 
    
382
 
    def get_path(self):
383
 
        """ Get the current path. """
384
 
        return self._path
385
 
    
 
576
        # Set sensitivity
 
577
        self.set_sensitivity()
 
578
        
386
579
    def get_selected_right(self):
387
580
        """ Get the selected filename. """
388
581
        treeselection = self.treeview_right.get_selection()
411
604
        """ Clean the last message from the statusbar. """
412
605
        self.statusbar.pop(self.context_id)
413
606
    
 
607
    def set_sensitivity(self):
 
608
        """ Set menu and toolbar sensitivity. """
 
609
        self.menuitem_branch_init.set_sensitive(self.notbranch)
 
610
        self.menuitem_branch_get.set_sensitive(self.notbranch)
 
611
        self.menuitem_branch_checkout.set_sensitive(self.notbranch)
 
612
        self.menuitem_branch_pull.set_sensitive(not self.notbranch)
 
613
        self.menuitem_branch_push.set_sensitive(not self.notbranch)
 
614
        self.menuitem_branch_commit.set_sensitive(not self.notbranch)
 
615
        self.menuitem_branch_status.set_sensitive(not self.notbranch)
 
616
        self.menuitem_branch_missing.set_sensitive(not self.notbranch)
 
617
        self.menuitem_stats.set_sensitive(not self.notbranch)
 
618
        self.menuitem_add_files.set_sensitive(not self.notbranch)
 
619
        self.menuitem_remove_files.set_sensitive(not self.notbranch)
 
620
        self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
 
621
        self.menuitem_file_rename.set_sensitive(not self.notbranch)
 
622
        self.menuitem_file_move.set_sensitive(not self.notbranch)
 
623
        #self.menutoolbutton_diff.set_sensitive(True)
 
624
        self.toolbutton_diff.set_sensitive(not self.notbranch)
 
625
        self.toolbutton_log.set_sensitive(not self.notbranch)
 
626
        self.toolbutton_commit.set_sensitive(not self.notbranch)
 
627
        self.toolbutton_pull.set_sensitive(not self.notbranch)
 
628
        self.toolbutton_push.set_sensitive(not self.notbranch)
 
629
    
414
630
    def refresh_left(self):
415
631
        """ Refresh the bookmark list. """
416
 
        # set cursor to busy
417
 
        self.set_busy(self.treeview_left)
418
632
        
419
633
        # Get TreeStore and clear it
420
634
        treestore = self.treeview_left.get_model()
421
635
        treestore.clear()
422
636
 
 
637
        # Re-read preferences
 
638
        self.pref.read()
 
639
 
423
640
        # Get bookmarks
424
641
        bookmarks = self.pref.get_bookmarks()
425
642
 
435
652
        # Expand the tree
436
653
        self.treeview_left.expand_all()
437
654
 
438
 
        self.set_busy(self.treeview_left, False)
439
 
 
440
655
    def refresh_right(self, path=None):
441
656
        """ Refresh the file list. """
442
657
        from bzrlib.workingtree import WorkingTree
443
658
 
444
 
        self.set_busy(self.treeview_right)
445
 
 
446
659
        if path is None:
447
660
            path = self.get_path()
448
661
 
449
662
        # A workaround for double-clicking Bookmarks
450
663
        if not os.path.exists(path):
451
 
            self.set_busy(self.treeview_right, False)
452
664
            return
453
665
 
454
666
        # Get ListStore and clear it
495
707
            if not notbranch:
496
708
                filename = tree1.relpath(path + os.sep + item)
497
709
                
498
 
                for rpath, id, kind, text_modified, meta_modified in delta.renamed:
499
 
                    if rpath == filename:
 
710
                for rpath, rpathnew, id, kind, text_modified, meta_modified in delta.renamed:
 
711
                    if rpathnew == filename:
500
712
                        status = 'renamed'
501
713
                for rpath, id, kind in delta.added:
502
714
                    if rpath == filename:
503
 
                        status = 'added'
 
715
                        status = 'added'                
504
716
                for rpath, id, kind, text_modified, meta_modified in delta.removed:
505
717
                    if rpath == filename:
506
718
                        status = 'removed'
532
744
 
533
745
        # Add the ListStore to the TreeView
534
746
        self.treeview_right.set_model(liststore)
535
 
 
536
 
        # Check if current directory is a branch
537
 
        if not notbranch:
538
 
            # Activate some items
539
 
            self.menuitem_branch_init.set_sensitive(False)
540
 
            self.menuitem_branch_get.set_sensitive(True)
541
 
            self.menuitem_branch_checkout.set_sensitive(True)
542
 
            self.menuitem_branch_pull.set_sensitive(True)
543
 
            self.menuitem_branch_push.set_sensitive(True)
544
 
            self.menuitem_branch_commit.set_sensitive(True)
545
 
            self.menuitem_branch_status.set_sensitive(True)
546
 
            self.menuitem_branch_missing.set_sensitive(True)
547
 
            self.menuitem_stats.set_sensitive(True)
548
 
            self.menuitem_add_files.set_sensitive(True)
549
 
            self.menuitem_remove_files.set_sensitive(True)
550
 
            self.menuitem_file_make_directory.set_sensitive(True)
551
 
            self.menuitem_file_rename.set_sensitive(True)
552
 
            self.menuitem_file_move.set_sensitive(True)
553
 
            #self.menutoolbutton_diff.set_sensitive(True)
554
 
            self.toolbutton_diff.set_sensitive(True)
555
 
            self.toolbutton_log.set_sensitive(True)
556
 
            self.toolbutton_commit.set_sensitive(True)
557
 
            self.toolbutton_pull.set_sensitive(True)
558
 
            self.toolbutton_push.set_sensitive(True)
559
 
        else:
560
 
            # Deactivate some items
561
 
            self.menuitem_branch_init.set_sensitive(True)
562
 
            self.menuitem_branch_get.set_sensitive(False)
563
 
            self.menuitem_branch_checkout.set_sensitive(False)
564
 
            self.menuitem_branch_pull.set_sensitive(False)
565
 
            self.menuitem_branch_push.set_sensitive(False)
566
 
            self.menuitem_branch_commit.set_sensitive(False)
567
 
            self.menuitem_branch_status.set_sensitive(False)
568
 
            self.menuitem_branch_missing.set_sensitive(False)
569
 
            self.menuitem_stats.set_sensitive(False)
570
 
            self.menuitem_add_files.set_sensitive(False)
571
 
            self.menuitem_remove_files.set_sensitive(False)
572
 
            self.menuitem_file_make_directory.set_sensitive(False)
573
 
            self.menuitem_file_rename.set_sensitive(False)
574
 
            self.menuitem_file_move.set_sensitive(False)
575
 
            #self.menutoolbutton_diff.set_sensitive(False)
576
 
            self.toolbutton_diff.set_sensitive(False)
577
 
            self.toolbutton_log.set_sensitive(False)
578
 
            self.toolbutton_commit.set_sensitive(False)
579
 
            self.toolbutton_pull.set_sensitive(False)
580
 
            self.toolbutton_push.set_sensitive(False)
581
 
 
582
 
        self.set_busy(self.treeview_right, False)
583
 
 
584
 
    def set_busy(self, widget, busy=True):
585
 
        if busy:
586
 
            widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.WATCH))
587
 
        else:
588
 
            widget.window.set_cursor(gtk.gdk.Cursor(gtk.gdk.LEFT_PTR))
589
 
 
590
 
        gtk.main_iteration(0)
 
747
        
 
748
        # Set sensitivity
 
749
        self.set_sensitivity()
591
750
 
592
751
    def _harddisks(self):
593
752
        """ Returns hard drive letters under Win32. """
620
779
            drive = model[active][0]
621
780
            self.refresh_right(drive + '\\')
622
781
 
 
782
import ConfigParser
 
783
 
623
784
class OlivePreferences:
624
785
    """ A class which handles Olive's preferences. """
625
786
    def __init__(self):
637
798
        self.config = ConfigParser.RawConfigParser()
638
799
        
639
800
        # Load the configuration
640
 
        if sys.platform == 'win32':
641
 
            # Windows - no dotted files
642
 
            self.config.read([os.path.expanduser('~/olive.conf')])
643
 
        else:
644
 
            self.config.read([os.path.expanduser('~/.olive.conf')])
 
801
        self.read()
645
802
        
646
803
    def _get_default(self, option):
647
804
        """ Get the default option for a preference. """
657
814
        # First write out the changes
658
815
        self.write()
659
816
        # Then load the configuration again
 
817
        self.read()
 
818
 
 
819
    def read(self):
 
820
        """ Just read the configuration. """
660
821
        if sys.platform == 'win32':
661
822
            # Windows - no dotted files
662
823
            self.config.read([os.path.expanduser('~/olive.conf')])
663
824
        else:
664
825
            self.config.read([os.path.expanduser('~/.olive.conf')])
665
 
 
 
826
    
666
827
    def write(self):
667
828
        """ Write the configuration to the appropriate files. """
668
829
        if sys.platform == 'win32':
675
836
            self.config.write(fp)
676
837
            fp.close()
677
838
 
678
 
    def get_preference(self, option, kind='str'):
679
 
        """ Get the value of the given option.
680
 
        
681
 
        :param kind: str/bool/int/float. default: str
682
 
        """
683
 
        if self.config.has_option('preferences', option):
684
 
            if kind == 'bool':
685
 
                return self.config.getboolean('preferences', option)
686
 
            elif kind == 'int':
687
 
                return self.config.getint('preferences', option)
688
 
            elif kind == 'float':
689
 
                return self.config.getfloat('preferences', option)
690
 
            else:
691
 
                return self.config.get('preferences', option)
692
 
        else:
693
 
            try:
694
 
                return self._get_default(option)
695
 
            except KeyError:
696
 
                return None
697
 
    
698
 
    def set_preference(self, option, value):
699
 
        """ Set the value of the given option. """
700
 
        if self.config.has_section('preferences'):
701
 
            self.config.set('preferences', option, value)
702
 
        else:
703
 
            self.config.add_section('preferences')
704
 
            self.config.set('preferences', option, value)
705
 
    
706
839
    def get_bookmarks(self):
707
840
        """ Return the list of bookmarks. """
708
841
        bookmarks = self.config.sections()
735
868
    def remove_bookmark(self, path):
736
869
        """ Remove bookmark. """
737
870
        return self.config.remove_section(path)
 
871
 
 
872
    def set_preference(self, option, value):
 
873
        """ Set the value of the given option. """
 
874
        if self.config.has_section('preferences'):
 
875
            self.config.set('preferences', option, value)
 
876
        else:
 
877
            self.config.add_section('preferences')
 
878
            self.config.set('preferences', option, value)
 
879
 
 
880
    def get_preference(self, option, kind='str'):
 
881
        """ Get the value of the given option.
 
882
        
 
883
        :param kind: str/bool/int/float. default: str
 
884
        """
 
885
        if self.config.has_option('preferences', option):
 
886
            if kind == 'bool':
 
887
                #return self.config.getboolean('preferences', option)
 
888
                return True
 
889
            elif kind == 'int':
 
890
                return self.config.getint('preferences', option)
 
891
            elif kind == 'float':
 
892
                return self.config.getfloat('preferences', option)
 
893
            else:
 
894
                return self.config.get('preferences', option)
 
895
        else:
 
896
            try:
 
897
                return self._get_default(option)
 
898
            except KeyError:
 
899
                return None
 
900