/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-09-29 09:31:57 UTC
  • mfrom: (0.12.2 olive)
  • mto: (0.14.3 main)
  • mto: This revision was merged to the branch mainline in revision 83.
  • Revision ID: Szilveszter.Farkas@gmail.com-20060929093157-da322bf8ce59c456
Merge from Jelmer Vernooij's integration 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
18
import os.path
20
19
import sys
24
23
    pygtk.require("2.0")
25
24
except:
26
25
    pass
27
 
try:
28
 
    import gtk
29
 
    import gtk.gdk
30
 
    import gtk.glade
31
 
except:
32
 
    sys.exit(1)
 
26
import gtk
 
27
import gtk.gdk
 
28
import gtk.glade
33
29
 
34
 
from handler import OliveHandler
35
30
import bzrlib.errors as errors
 
31
from bzrlib.workingtree import WorkingTree
36
32
 
37
33
# Olive GTK UI version
38
34
__version__ = '0.11.0'
39
35
 
 
36
# Load the glade file
 
37
if sys.platform == 'win32':
 
38
    gladefile = os.path.dirname(sys.executable) + "/share/olive/olive.glade"
 
39
else:
 
40
    gladefile = "/usr/share/olive/olive.glade"
 
41
 
 
42
if not os.path.exists(gladefile):
 
43
    # Load from current directory if not installed
 
44
    gladefile = "olive.glade"
 
45
    # Check again
 
46
    if not os.path.exists(gladefile):
 
47
        # Fail
 
48
        print _('Glade file cannot be found.')
 
49
        sys.exit(1)
 
50
 
40
51
class OliveGtk:
41
52
    """ The main Olive GTK frontend class. This is called when launching the
42
53
    program. """
43
54
    
44
55
    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')
 
56
        self.toplevel = gtk.glade.XML(gladefile, 'window_main', 'olive-gtk')
61
57
        
62
58
        self.window = self.toplevel.get_widget('window_main')
63
59
        
64
60
        self.pref = OlivePreferences()
65
 
        self.comm = OliveCommunicator(self.toplevel, self.pref)
66
 
        handler = OliveHandler(self.gladefile, self.comm)
 
61
 
 
62
        # Initialize the statusbar
 
63
        self.statusbar = self.toplevel.get_widget('statusbar')
 
64
        self.context_id = self.statusbar.get_context_id('olive')
 
65
        
 
66
        # Get the main window
 
67
        self.window_main = self.toplevel.get_widget('window_main')
 
68
        # Get the HPaned
 
69
        self.hpaned_main = self.toplevel.get_widget('hpaned_main')
 
70
        # Get the TreeViews
 
71
        self.treeview_left = self.toplevel.get_widget('treeview_left')
 
72
        self.treeview_right = self.toplevel.get_widget('treeview_right')
 
73
        # Get some important menu items
 
74
        self.menuitem_add_files = self.toplevel.get_widget('menuitem_add_files')
 
75
        self.menuitem_remove_files = self.toplevel.get_widget('menuitem_remove_file')
 
76
        self.menuitem_file_make_directory = self.toplevel.get_widget('menuitem_file_make_directory')
 
77
        self.menuitem_file_rename = self.toplevel.get_widget('menuitem_file_rename')
 
78
        self.menuitem_file_move = self.toplevel.get_widget('menuitem_file_move')
 
79
        self.menuitem_view_show_hidden_files = self.toplevel.get_widget('menuitem_view_show_hidden_files')
 
80
        self.menuitem_branch = self.toplevel.get_widget('menuitem_branch')
 
81
        self.menuitem_branch_init = self.toplevel.get_widget('menuitem_branch_initialize')
 
82
        self.menuitem_branch_get = self.toplevel.get_widget('menuitem_branch_get')
 
83
        self.menuitem_branch_checkout = self.toplevel.get_widget('menuitem_branch_checkout')
 
84
        self.menuitem_branch_pull = self.toplevel.get_widget('menuitem_branch_pull')
 
85
        self.menuitem_branch_push = self.toplevel.get_widget('menuitem_branch_push')
 
86
        self.menuitem_branch_commit = self.toplevel.get_widget('menuitem_branch_commit')
 
87
        self.menuitem_branch_status = self.toplevel.get_widget('menuitem_branch_status')
 
88
        self.menuitem_branch_missing = self.toplevel.get_widget('menuitem_branch_missing_revisions')
 
89
        self.menuitem_stats = self.toplevel.get_widget('menuitem_stats')
 
90
        self.menuitem_stats_diff = self.toplevel.get_widget('menuitem_stats_diff')
 
91
        self.menuitem_stats_log = self.toplevel.get_widget('menuitem_stats_log')
 
92
        # Get some toolbuttons
 
93
        #self.menutoolbutton_diff = self.toplevel.get_widget('menutoolbutton_diff')
 
94
        self.toolbutton_diff = self.toplevel.get_widget('toolbutton_diff')
 
95
        self.toolbutton_log = self.toplevel.get_widget('toolbutton_log')
 
96
        self.toolbutton_commit = self.toplevel.get_widget('toolbutton_commit')
 
97
        self.toolbutton_pull = self.toplevel.get_widget('toolbutton_pull')
 
98
        self.toolbutton_push = self.toplevel.get_widget('toolbutton_push')
 
99
        # Get the drive selector
 
100
        self.combobox_drive = gtk.combo_box_new_text()
 
101
        self.combobox_drive.connect("changed", self._refresh_drives)
 
102
        
 
103
        self.vbox_main_right = self.toplevel.get_widget('vbox_main_right')
 
104
 
67
105
        
68
106
        # Dictionary for signal_autoconnect
69
107
        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 }
 
108
                "on_window_main_delete_event": self.on_window_main_delete_event,
 
109
                "on_quit_activate": self.on_window_main_delete_event,
 
110
                "on_about_activate": self.on_about_activate,
 
111
                "on_menuitem_add_files_activate": self.on_menuitem_add_files_activate,
 
112
                "on_menuitem_remove_file_activate": self.on_menuitem_remove_file_activate,
 
113
                "on_menuitem_file_make_directory_activate": self.on_menuitem_file_make_directory_activate,
 
114
                "on_menuitem_file_move_activate": self.on_menuitem_file_move_activate,
 
115
                "on_menuitem_file_rename_activate": self.on_menuitem_file_rename_activate,
 
116
                "on_menuitem_view_show_hidden_files_activate": self.on_menuitem_view_show_hidden_files_activate,
 
117
                "on_menuitem_view_refresh_activate": self.on_menuitem_view_refresh_activate,
 
118
                "on_menuitem_branch_initialize_activate": self.on_menuitem_branch_initialize_activate,
 
119
                "on_menuitem_branch_get_activate": self.on_menuitem_branch_get_activate,
 
120
                "on_menuitem_branch_checkout_activate": self.on_menuitem_branch_checkout_activate,
 
121
                "on_menuitem_branch_commit_activate": self.on_menuitem_branch_commit_activate,
 
122
                "on_menuitem_branch_push_activate": self.on_menuitem_branch_push_activate,
 
123
                "on_menuitem_branch_pull_activate": self.on_menuitem_branch_pull_activate,
 
124
                "on_menuitem_branch_status_activate": self.on_menuitem_branch_status_activate,
 
125
                "on_menuitem_branch_missing_revisions_activate": self.on_menuitem_branch_missing_revisions_activate,
 
126
                "on_menuitem_stats_diff_activate": self.on_menuitem_stats_diff_activate,
 
127
                "on_menuitem_stats_log_activate": self.on_menuitem_stats_log_activate,
 
128
                "on_menuitem_stats_infos_activate": self.on_menuitem_stats_infos_activate,
 
129
                "on_toolbutton_refresh_clicked": self.on_menuitem_view_refresh_activate,
 
130
                "on_toolbutton_log_clicked": self.on_menuitem_stats_log_activate,
 
131
                #"on_menutoolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
 
132
                "on_toolbutton_diff_clicked": self.on_menuitem_stats_diff_activate,
 
133
                "on_toolbutton_commit_clicked": self.on_menuitem_branch_commit_activate,
 
134
                "on_toolbutton_pull_clicked": self.on_menuitem_branch_pull_activate,
 
135
                "on_toolbutton_push_clicked": self.on_menuitem_branch_push_activate,
 
136
                "on_treeview_right_button_press_event": self.on_treeview_right_button_press_event,
 
137
                "on_treeview_right_row_activated": self.on_treeview_right_row_activated,
 
138
                "on_treeview_left_button_press_event": self.on_treeview_left_button_press_event,
 
139
                "on_treeview_left_row_activated": self.on_treeview_left_row_activated }
102
140
        
103
141
        # Connect the signals to the handlers
104
142
        self.toplevel.signal_autoconnect(dic)
112
150
        self.window.move(x, y)
113
151
        # Apply paned position
114
152
        pos = self.pref.get_preference('paned_position', 'int')
115
 
        self.comm.hpaned_main.set_position(pos)
 
153
        self.hpaned_main.set_position(pos)
116
154
        
117
155
        # Apply menu to the toolbutton
118
156
        #menubutton = self.toplevel.get_widget('menutoolbutton_diff')
123
161
        
124
162
        # Show drive selector if under Win32
125
163
        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()
 
164
            self.vbox_main_right.pack_start(self.combobox_drive, False, True, 0)
 
165
            self.vbox_main_right.reorder_child(self.combobox_drive, 0)
 
166
            self.combobox_drive.show()
 
167
            self.gen_hard_selector()
130
168
        
131
169
        # Load default data into the panels
132
170
        self.treeview_left = self.toplevel.get_widget('treeview_left')
133
171
        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())
 
178
 
 
179
    def set_path(self, path):
 
180
        self.path = path
 
181
        self.notbranch = False
 
182
        try:
 
183
            self.wt, self.wtpath = WorkingTree.open_containing(self.path)
 
184
        except NotBranchError:
 
185
            self.notbranch = True
135
186
        self._load_right()
136
187
 
137
 
        # Apply menu state
138
 
        self.comm.menuitem_view_show_hidden_files.set_active(self.pref.get_preference('dotted_files', 'bool'))
 
188
    def get_path(self):
 
189
        return self.path
 
190
   
 
191
    def on_about_activate(self, widget):
 
192
        about()
 
193
        
 
194
    def on_menuitem_add_files_activate(self, widget):
 
195
        """ Add file(s)... menu handler. """
 
196
        from add import OliveAdd
 
197
        add = OliveAdd(self.wt, self.wtpath, self.get_selected_right())
 
198
        add.display()
 
199
    
 
200
    def on_menuitem_branch_get_activate(self, widget):
 
201
        """ Branch/Get... menu handler. """
 
202
        from branch import OliveBranch
 
203
        branch = OliveBranch()
 
204
        branch.display()
 
205
    
 
206
    def on_menuitem_branch_checkout_activate(self, widget):
 
207
        """ Branch/Checkout... menu handler. """
 
208
        from checkout import OliveCheckout
 
209
        checkout = OliveCheckout()
 
210
        checkout.display()
 
211
    
 
212
    def on_menuitem_branch_commit_activate(self, widget):
 
213
        """ Branch/Commit... menu handler. """
 
214
        from commit import OliveCommit
 
215
        commit = OliveCommit(self.wt, self.wtpath)
 
216
        commit.display()
 
217
    
 
218
    def on_menuitem_branch_missing_revisions_activate(self, widget):
 
219
        """ Branch/Missing revisions menu handler. """
 
220
        
 
221
        import bzrlib
 
222
        
 
223
        local_branch = self.wt.branch
 
224
        
 
225
        other_branch = local_branch.get_parent()
 
226
        if other_branch is None:
 
227
            error_dialog(_('Parent location is unknown'),
 
228
                                     _('Cannot determine missing revisions if no parent location is known.'))
 
229
            return
 
230
        
 
231
        remote_branch = Branch.open(other_branch)
 
232
        
 
233
        if remote_branch.base == local_branch.base:
 
234
            remote_branch = local_branch
 
235
 
 
236
        ret = len(local_branch.missing_revisions(remote_branch))
 
237
 
 
238
        if ret > 0:
 
239
            info_dialog(_('There are missing revisions'),
 
240
                                    _('%d revision(s) missing.') % ret)
 
241
        else:
 
242
            info_dialog(_('Local branch up to date'),
 
243
                                    _('There are no missing revisions.'))
 
244
 
 
245
    def on_menuitem_branch_pull_activate(self, widget):
 
246
        """ Branch/Pull menu handler. """
 
247
        
 
248
        branch_to = self.wt.branch
 
249
 
 
250
        location = branch_to.get_parent()
 
251
        if location is None:
 
252
            error_dialog(_('Parent location is unknown'),
 
253
                                     _('Pulling is not possible until there is a parent location.'))
 
254
            return
 
255
 
 
256
        try:
 
257
            branch_from = Branch.open(location)
 
258
        except errors.NotBranchError:
 
259
            error_dialog(_('Directory is not a branch'),
 
260
                                     _('You can perform this action only in a branch.'))
 
261
 
 
262
        if branch_to.get_parent() is None:
 
263
            branch_to.set_parent(branch_from.base)
 
264
 
 
265
        old_rh = branch_to.revision_history()
 
266
        if tree_to is not None:
 
267
            tree_to.pull(branch_from)
 
268
        else:
 
269
            branch_to.pull(branch_from)
 
270
        
 
271
        info_dialog(_('Pull successful'), _('%d revision(s) pulled.') % ret)
 
272
    
 
273
    def on_menuitem_branch_push_activate(self, widget):
 
274
        """ Branch/Push... menu handler. """
 
275
        from push import OlivePush
 
276
        push = OlivePush(self.wt.branch)
 
277
        push.display()
 
278
    
 
279
    def on_menuitem_branch_status_activate(self, widget):
 
280
        """ Branch/Status... menu handler. """
 
281
        from status import OliveStatus
 
282
        status = OliveStatus(self.wt, self.wtpath)
 
283
        status.display()
 
284
    
 
285
    def on_menuitem_branch_initialize_activate(self, widget):
 
286
        """ Initialize current directory. """
 
287
        try:
 
288
            if not os.path.exists(self.path):
 
289
                os.mkdir(self.path)
 
290
     
 
291
            try:
 
292
                existing_bzrdir = bzrdir.BzrDir.open(self.path)
 
293
            except NotBranchError:
 
294
                bzrdir.BzrDir.create_branch_convenience(self.path)
 
295
            else:
 
296
                if existing_bzrdir.has_branch():
 
297
                    if existing_bzrdir.has_workingtree():
 
298
                        raise AlreadyBranchError(self.path)
 
299
                    else:
 
300
                        raise BranchExistsWithoutWorkingTree(self.path)
 
301
                else:
 
302
                    existing_bzrdir.create_branch()
 
303
                    existing_bzrdir.create_workingtree()
 
304
        except errors.AlreadyBranchError, errmsg:
 
305
            error_dialog(_('Directory is already a branch'),
 
306
                                     _('The current directory (%s) is already a branch.\nYou can start using it, or initialize another directory.') % errmsg)
 
307
        except errors.BranchExistsWithoutWorkingTree, errmsg:
 
308
            error_dialog(_('Branch without a working tree'),
 
309
                                     _('The current directory (%s)\nis a branch without a working tree.') % errmsg)
 
310
        else:
 
311
            info_dialog(_('Initialize successful'),
 
312
                                    _('Directory successfully initialized.'))
 
313
            self.refresh_right()
 
314
        
 
315
    def on_menuitem_file_make_directory_activate(self, widget):
 
316
        """ File/Make directory... menu handler. """
 
317
        from mkdir import OliveMkdir
 
318
        mkdir = OliveMkdir(self.wt, self.wtpath)
 
319
        mkdir.display()
 
320
    
 
321
    def on_menuitem_file_move_activate(self, widget):
 
322
        """ File/Move... menu handler. """
 
323
        from move import OliveMove
 
324
        move = OliveMove(self.wt, self.wtpath, self.get_selected_right())
 
325
        move.display()
 
326
    
 
327
    def on_menuitem_file_rename_activate(self, widget):
 
328
        """ File/Rename... menu handler. """
 
329
        from rename import OliveRename
 
330
        rename = OliveRename(self.wt, self.wtpath, self.get_selected_right())
 
331
        rename.display()
 
332
 
 
333
    def on_menuitem_remove_file_activate(self, widget):
 
334
        """ Remove (unversion) selected file. """
 
335
        from remove import OliveRemove
 
336
        remove = OliveRemove(self.wt, self.wtpath, self.get_selected_right())
 
337
        remove.display()
 
338
    
 
339
    def on_menuitem_stats_diff_activate(self, widget):
 
340
        """ Statistics/Differences... menu handler. """
 
341
        from bzrlib.plugins.gtk.viz.diffwin import DiffWindow
 
342
        window = DiffWindow()
 
343
        parent_tree = self.wt.branch.repository.revision_tree(self.wt.branch.last_revision())
 
344
        window.set_diff(self.wt.branch.nick, self.wt, parent_tree)
 
345
        window.show()
 
346
    
 
347
    def on_menuitem_stats_infos_activate(self, widget):
 
348
        """ Statistics/Informations... menu handler. """
 
349
        from info import OliveInfo
 
350
        info = OliveInfo(self.wt)
 
351
        info.display()
 
352
    
 
353
    def on_menuitem_stats_log_activate(self, widget):
 
354
        """ Statistics/Log... menu handler. """
 
355
        from bzrlib.plugins.gtk.viz.branchwin import BranchWindow
 
356
        window = BranchWindow()
 
357
        window.set_branch(self.wt.branch, self.wt.branch.last_revision(), None)
 
358
        window.show()
 
359
    
 
360
    def on_menuitem_view_refresh_activate(self, widget):
 
361
        """ View/Refresh menu handler. """
 
362
        # Refresh the left pane
 
363
        self.refresh_left()
 
364
        # Refresh the right pane
 
365
        self.refresh_right()
 
366
 
 
367
   
 
368
    def on_menuitem_view_show_hidden_files_activate(self, widget):
 
369
        """ View/Show hidden files menu handler. """
 
370
        self.set_preference('dotted_files', widget.get_active())
 
371
 
 
372
    def on_treeview_left_button_press_event(self, widget, event):
 
373
        """ Occurs when somebody right-clicks in the bookmark list. """
 
374
        if event.button == 3:
 
375
            # Don't show context with nothing selected
 
376
            if self.get_selected_left() == None:
 
377
                return
 
378
 
 
379
            self.menu.left_context_menu().popup(None, None, None, 0,
 
380
                                                event.time)
 
381
        
 
382
    def on_treeview_left_row_activated(self, treeview, path, view_column):
 
383
        """ Occurs when somebody double-clicks or enters an item in the
 
384
        bookmark list. """
 
385
 
 
386
        newdir = self.get_selected_left()
 
387
        if newdir == None:
 
388
            return
 
389
 
 
390
        self.set_path(newdir)
 
391
        self.refresh_right()
 
392
    
 
393
    def on_treeview_right_button_press_event(self, widget, event):
 
394
        """ Occurs when somebody right-clicks in the file list. """
 
395
        if event.button == 3:
 
396
            # get the menu items
 
397
            m_add = self.menu.ui.get_widget('/context_right/add')
 
398
            m_remove = self.menu.ui.get_widget('/context_right/remove')
 
399
            m_commit = self.menu.ui.get_widget('/context_right/commit')
 
400
            m_diff = self.menu.ui.get_widget('/context_right/diff')
 
401
            # check if we're in a branch
 
402
            try:
 
403
                from bzrlib.branch import Branch
 
404
                Branch.open_containing(self.get_path())
 
405
                m_add.set_sensitive(False)
 
406
                m_remove.set_sensitive(False)
 
407
                m_commit.set_sensitive(False)
 
408
                m_diff.set_sensitive(False)
 
409
            except errors.NotBranchError:
 
410
                m_add.set_sensitive(True)
 
411
                m_remove.set_sensitive(True)
 
412
                m_commit.set_sensitive(True)
 
413
                m_diff.set_sensitive(True)
 
414
            self.menu.right_context_menu().popup(None, None, None, 0,
 
415
                                                 event.time)
 
416
        
 
417
    def on_treeview_right_row_activated(self, treeview, path, view_column):
 
418
        """ Occurs when somebody double-clicks or enters an item in the
 
419
        file list. """
 
420
        import os.path
 
421
        
 
422
        newdir = self.get_selected_right()
 
423
        
 
424
        if newdir == '..':
 
425
            self.set_path(os.path.split(self.get_path())[0])
 
426
        else:
 
427
            fullpath = self.get_path() + os.sep + newdir
 
428
            if os.path.isdir(fullpath):
 
429
                # selected item is an existant directory
 
430
                self.set_path(fullpath)
 
431
            else:
 
432
                launch(fullpath) 
 
433
        
 
434
        self.refresh_right()
 
435
    
 
436
    def on_window_main_delete_event(self, widget, event=None):
 
437
        """ Do some stuff before exiting. """
 
438
        width, height = self.window_main.get_size()
 
439
        self.pref.set_preference('window_width', width)
 
440
        self.pref.set_preference('window_height', height)
 
441
        x, y = self.window_main.get_position()
 
442
        self.pref.set_preference('window_x', x)
 
443
        self.pref.set_preference('window_y', y)
 
444
        self.pref.set_preference('paned_position',
 
445
                                      self.hpaned_main.get_position())
 
446
        
 
447
        self.pref.write()
 
448
        self.window_main.destroy()
139
449
        
140
450
    def _load_left(self):
141
451
        """ Load data into the left panel. (Bookmarks) """
142
 
        # set cursor to busy
143
 
        self.comm.set_busy(self.treeview_left)
144
 
        
145
452
        # Create TreeStore
146
453
        treestore = gtk.TreeStore(str, str)
147
454
        
148
455
        # Get bookmarks
149
 
        bookmarks = self.comm.pref.get_bookmarks()
 
456
        bookmarks = self.pref.get_bookmarks()
150
457
        
151
458
        # Add them to the TreeStore
152
459
        titer = treestore.append(None, [_('Bookmarks'), None])
153
460
        for item in bookmarks:
154
 
            title = self.comm.pref.get_bookmark_title(item)
 
461
            title = self.pref.get_bookmark_title(item)
155
462
            treestore.append(titer, [title, item])
156
463
        
157
464
        # Create the column and add it to the TreeView
167
474
        # Expand the tree
168
475
        self.treeview_left.expand_all()
169
476
 
170
 
        self.comm.set_busy(self.treeview_left, False)
171
 
        
172
477
    def _load_right(self):
173
478
        """ 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
479
        # Create ListStore
180
480
        liststore = gtk.ListStore(str, str, str)
181
481
        
183
483
        files = []
184
484
        
185
485
        # Fill the appropriate lists
186
 
        path = self.comm.get_path()
187
486
        dotted_files = self.pref.get_preference('dotted_files', 'bool')
188
 
        for item in os.listdir(path):
 
487
        for item in os.listdir(self.path):
189
488
            if not dotted_files and item[0] == '.':
190
489
                continue
191
 
            if os.path.isdir(path + os.sep + item):
 
490
            if os.path.isdir(self.path + os.sep + item):
192
491
                dirs.append(item)
193
492
            else:
194
493
                files.append(item)
197
496
        dirs.sort()
198
497
        files.sort()
199
498
        
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)
 
499
        if not self.notbranch:
 
500
            branch = self.wt.branch
 
501
            tree2 = self.wt.branch.repository.revision_tree(branch.last_revision())
 
502
        
 
503
            delta = self.wt.changes_from(tree2, want_unchanged=True)
214
504
        
215
505
        # Add'em to the ListStore
216
506
        for item in dirs:    
217
507
            liststore.append([gtk.STOCK_DIRECTORY, item, ''])
218
508
        for item in files:
219
509
            status = 'unknown'
220
 
            if not notbranch:
221
 
                filename = tree1.relpath(path + os.sep + item)
 
510
            if not self.notbranch:
 
511
                filename = self.wt.relpath(self.path + os.sep + item)
222
512
                
223
513
                for rpath, id, kind, text_modified, meta_modified in delta.renamed:
224
514
                    if rpath == filename:
226
516
                for rpath, id, kind in delta.added:
227
517
                    if rpath == filename:
228
518
                        status = 'added'
229
 
                for rpath, id, kind, text_modified, meta_modified in delta.removed:
 
519
                for rpath, id, kind in delta.removed:
230
520
                    if rpath == filename:
231
521
                        status = 'removed'
232
522
                for rpath, id, kind, text_modified, meta_modified in delta.modified:
271
561
        tvcolumn_filename.add_attribute(cell, 'text', 1)
272
562
        tvcolumn_status.pack_start(cell, True)
273
563
        tvcolumn_status.add_attribute(cell, 'text', 2)
274
 
        
 
564
 
 
565
        self.menuitem_branch_init.set_sensitive(self.notbranch)
275
566
        # 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
 
    
 
567
        self.menuitem_branch_get.set_sensitive(not self.notbranch)
 
568
        self.menuitem_branch_checkout.set_sensitive(not self.notbranch)
 
569
        self.menuitem_branch_pull.set_sensitive(not self.notbranch)
 
570
        self.menuitem_branch_push.set_sensitive(not self.notbranch)
 
571
        self.menuitem_branch_commit.set_sensitive(not self.notbranch)
 
572
        self.menuitem_branch_status.set_sensitive(not self.notbranch)
 
573
        self.menuitem_branch_missing.set_sensitive(not self.notbranch)
 
574
        self.menuitem_stats.set_sensitive(not self.notbranch)
 
575
        self.menuitem_add_files.set_sensitive(not self.notbranch)
 
576
        self.menuitem_remove_files.set_sensitive(not self.notbranch)
 
577
        self.menuitem_file_make_directory.set_sensitive(not self.notbranch)
 
578
        self.menuitem_file_rename.set_sensitive(not self.notbranch)
 
579
        self.menuitem_file_move.set_sensitive(not self.notbranch)
 
580
        #self.menutoolbutton_diff.set_sensitive(True)
 
581
        self.toolbutton_diff.set_sensitive(not self.notbranch)
 
582
        self.toolbutton_log.set_sensitive(not self.notbranch)
 
583
        self.toolbutton_commit.set_sensitive(not self.notbranch)
 
584
        self.toolbutton_pull.set_sensitive(not self.notbranch)
 
585
        self.toolbutton_push.set_sensitive(not self.notbranch)
 
586
        
386
587
    def get_selected_right(self):
387
588
        """ Get the selected filename. """
388
589
        treeselection = self.treeview_right.get_selection()
413
614
    
414
615
    def refresh_left(self):
415
616
        """ Refresh the bookmark list. """
416
 
        # set cursor to busy
417
 
        self.set_busy(self.treeview_left)
418
617
        
419
618
        # Get TreeStore and clear it
420
619
        treestore = self.treeview_left.get_model()
435
634
        # Expand the tree
436
635
        self.treeview_left.expand_all()
437
636
 
438
 
        self.set_busy(self.treeview_left, False)
439
 
 
440
637
    def refresh_right(self, path=None):
441
638
        """ Refresh the file list. """
442
639
        from bzrlib.workingtree import WorkingTree
443
640
 
444
 
        self.set_busy(self.treeview_right)
445
 
 
446
641
        if path is None:
447
642
            path = self.get_path()
448
643
 
449
644
        # A workaround for double-clicking Bookmarks
450
645
        if not os.path.exists(path):
451
 
            self.set_busy(self.treeview_right, False)
452
646
            return
453
647
 
454
648
        # Get ListStore and clear it
533
727
        # Add the ListStore to the TreeView
534
728
        self.treeview_right.set_model(liststore)
535
729
 
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)
591
 
 
592
730
    def _harddisks(self):
593
731
        """ Returns hard drive letters under Win32. """
594
732
        try:
620
758
            drive = model[active][0]
621
759
            self.refresh_right(drive + '\\')
622
760
 
 
761
import ConfigParser
 
762
 
623
763
class OlivePreferences:
624
764
    """ A class which handles Olive's preferences. """
625
765
    def __init__(self):
642
782
            self.config.read([os.path.expanduser('~/olive.conf')])
643
783
        else:
644
784
            self.config.read([os.path.expanduser('~/.olive.conf')])
 
785
 
 
786
 
645
787
        
646
788
    def _get_default(self, option):
647
789
        """ Get the default option for a preference. """
675
817
            self.config.write(fp)
676
818
            fp.close()
677
819
 
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
820
    def get_bookmarks(self):
707
821
        """ Return the list of bookmarks. """
708
822
        bookmarks = self.config.sections()
735
849
    def remove_bookmark(self, path):
736
850
        """ Remove bookmark. """
737
851
        return self.config.remove_section(path)
 
852
 
 
853
    def set_preference(self, option, value):
 
854
        """ Set the value of the given option. """
 
855
        if self.config.has_section('preferences'):
 
856
            self.config.set('preferences', option, value)
 
857
        else:
 
858
            self.config.add_section('preferences')
 
859
            self.config.set('preferences', option, value)
 
860
 
 
861
    def get_preference(self, option, kind='str'):
 
862
        """ Get the value of the given option.
 
863
        
 
864
        :param kind: str/bool/int/float. default: str
 
865
        """
 
866
        if self.config.has_option('preferences', option):
 
867
            if kind == 'bool':
 
868
                return self.config.getboolean('preferences', option)
 
869
            elif kind == 'int':
 
870
                return self.config.getint('preferences', option)
 
871
            elif kind == 'float':
 
872
                return self.config.getfloat('preferences', option)
 
873
            else:
 
874
                return self.config.get('preferences', option)
 
875
        else:
 
876
            try:
 
877
                return self._get_default(option)
 
878
            except KeyError:
 
879
                return None
 
880