Exemplo n.º 1
0
    def __init__(self, parent=None):
        MainWindow.__init__(self, parent)
        self.setAcceptDrops(True)

        # Qt does not support noun/verbs
        self.commit_button.setText(qtutils.tr('Commit@@verb'))
        self.commit_menu.setTitle(qtutils.tr('Commit@@verb'))

        self._has_threadpool = hasattr(QtCore, 'QThreadPool')

        # Diff/patch syntax highlighter
        self.syntax = DiffSyntaxHighlighter(self.display_text.document())

        # Display the current column
        self.connect(self.commitmsg,
                     SIGNAL('cursorPositionChanged()'),
                     self.show_cursor_position)

        # Keeps track of merge messages we've seen
        self.merge_message_hash = ''

        # Initialize the seen tree widget indexes
        self._seen_indexes = set()

        # Initialize the GUI to show 'Column: 00'
        self.show_cursor_position()

        # Internal field used by import/export_state().
        # Change this whenever dockwidgets are removed.
        self._widget_version = 1

        self.model = cola.model()
        self.model.add_message_observer(self.model.message_updated,
                                        self._update_view)

        # Listen for text and amend messages
        cola.notifier().connect(signals.diff_text, self.set_display)
        cola.notifier().connect(signals.mode, self._mode_changed)
        cola.notifier().connect(signals.amend, self.amend_checkbox.setChecked)

        # Broadcast the amend mode
        self.connect(self.amend_checkbox, SIGNAL('toggled(bool)'),
                     SLOT(signals.amend_mode))

        # Add button callbacks
        self._relay_button(self.alt_button, signals.reset_mode)
        self._relay_button(self.rescan_button, signals.rescan)

        self._connect_button(self.signoff_button, self.signoff)
        self._connect_button(self.stage_button, self.stage)
        self._connect_button(self.unstage_button, self.unstage)
        self._connect_button(self.commit_button, self.commit)
        self._connect_button(self.fetch_button, guicmds.fetch_slot(self))
        self._connect_button(self.push_button, guicmds.push_slot(self))
        self._connect_button(self.pull_button, guicmds.pull_slot(self))
        self._connect_button(self.stash_button, lambda: stash.stash(parent=self))

        # Menu actions
        actions = [
            (self.menu_quit, self.close),
            (self.menu_branch_compare, compare.branch_compare),
            (self.menu_branch_diff, guicmds.branch_diff),
            (self.menu_branch_review, guicmds.review_branch),
            (self.menu_browse_branch, guicmds.browse_current),
            (self.menu_browse_other_branch, guicmds.browse_other),
            (self.menu_browse_commits, guicmds.browse_commits),
            (self.menu_create_tag, createtag.create_tag),
            (self.menu_create_branch, create_new_branch),
            (self.menu_checkout_branch, guicmds.checkout_branch),
            (self.menu_delete_branch, guicmds.branch_delete),
            (self.menu_rebase_branch, guicmds.rebase),
            (self.menu_clone_repo, guicmds.clone_repo),
            (self.menu_commit_compare, compare.compare),
            (self.menu_commit_compare_file, compare.compare_file),
            (self.menu_cherry_pick, guicmds.cherry_pick),
            (self.menu_diff_expression, guicmds.diff_expression),
            (self.menu_diff_branch, guicmds.diff_branch),
            (self.menu_export_patches, guicmds.export_patches),
            (self.menu_help_about, about.launch_about_dialog),
            (self.menu_help_docs,
                lambda: self.model.git.web__browse(resources.html_docs())),
            (self.menu_load_commitmsg, guicmds.load_commitmsg_slot(self)),
            (self.menu_load_commitmsg_template,
                SLOT(signals.load_commit_template)),
            (self.menu_manage_bookmarks, manage_bookmarks),
            (self.menu_save_bookmark, save_bookmark),
            (self.menu_merge_local, merge.local_merge),
            (self.menu_merge_abort, merge.abort_merge),
            (self.menu_fetch, guicmds.fetch_slot(self)),
            (self.menu_push, guicmds.push_slot(self)),
            (self.menu_pull, guicmds.pull_slot(self)),
            (self.menu_open_repo, guicmds.open_repo_slot(self)),
            (self.menu_options, update_options),
            (self.menu_rescan, SLOT(signals.rescan)),
            (self.menu_grep, guicmds.grep),
            (self.menu_search_commits, smod.search),
            (self.menu_show_diffstat, SLOT(signals.diffstat)),
            (self.menu_stash, lambda: stash.stash(parent=self)),
            (self.menu_stage_modified, SLOT(signals.stage_modified)),
            (self.menu_stage_untracked, SLOT(signals.stage_untracked)),
            (self.menu_unstage_selected, SLOT(signals.unstage_selected)),
            (self.menu_unstage_all, SLOT(signals.unstage_all)),
            (self.menu_visualize_all, SLOT(signals.visualize_all)),
            (self.menu_visualize_current, SLOT(signals.visualize_current)),
            # TODO This edit menu stuff should/could be command objects
            (self.menu_cut, self.action_cut),
            (self.menu_copy, self.action_copy),
            (self.menu_paste, self.commitmsg.paste),
            (self.menu_delete, self.action_delete),
            (self.menu_select_all, self.commitmsg.selectAll),
            (self.menu_undo, self.commitmsg.undo),
            (self.menu_redo, self.commitmsg.redo),
            (self.menu_classic, classic.cola_classic),
            (self.menu_dag, dag.git_dag),
        ]

        # Diff Actions
        if hasattr(Qt, 'WidgetWithChildrenShortcut'):
            # We can only enable this shortcut on newer versions of Qt
            # that support WidgetWithChildrenShortcut otherwise we get
            # an ambiguous shortcut error.
            self.diff_copy = QtGui.QAction(self.display_text)
            self.diff_copy.setShortcut(QtGui.QKeySequence.Copy)
            self.diff_copy.setShortcutContext(Qt.WidgetWithChildrenShortcut)
            self.display_text.addAction(self.diff_copy)
            actions.append((self.diff_copy, self.copy_display,))

        for menu, callback in actions:
            self.connect(menu, SIGNAL('triggered()'), callback)

        # Install UI wrappers for command objects
        actionsmod.install_command_wrapper(self)
        guicmds.install_command_wrapper(self)

        # Install diff shortcut keys for stage/unstage
        self.display_text.keyPressEvent = self.diff_key_press_event
        self.display_text.contextMenuEvent = self.diff_context_menu_event

        self.connect(self, SIGNAL('update'), self._update_callback)
        self.connect(self, SIGNAL('import_state'), self.import_state)
        self.connect(self, SIGNAL('install_config_actions'),
                     self._install_config_actions)

        # Install .git-config-defined actions
        self._config_task = None
        self.install_config_actions()

        # Restore saved settings
        self._gui_state_task = None
        self._load_gui_state()
Exemplo n.º 2
0
def main(context):
    """Parses the command-line arguments and starts git-cola
    """
    setup_environment()
    opts, args = parse_args(context)
    repo = process_args(opts, args)

    # Allow Ctrl-C to exit
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    # Initialize the app
    app = ColaApplication(sys.argv)

    # Ensure that we're working in a valid git repository.
    # If not, try to find one.  When found, chdir there.
    model = cola.model()
    valid = model.use_worktree(repo) and not opts.prompt
    while not valid:
        startup_dlg = startup.StartupDialog(app.activeWindow())
        gitdir = startup_dlg.find_git_repo()
        if not gitdir:
            sys.exit(-1)
        valid = model.use_worktree(gitdir)

    # Finally, go to the root of the git repo
    os.chdir(model.git.worktree())

    # Show the GUI
    if opts.classic:
        view = cola_classic(update=False)
    elif context == 'git-cola':
        view = MainView(model, qtutils.active_window())
        ctl = MainController(model, view)
    elif context == 'git-dag':
        ctl = git_dag(model, opts=opts, args=args)
        view = ctl.view

    # Install UI wrappers for command objects
    cfgactions.install_command_wrapper()
    guicmds.install_command_wrapper()

    # Show the view and start the main event loop
    view.show()

    # Make sure that we start out on top
    view.raise_()

    # Scan for the first time
    task = _start_update_thread(model)

    # Start the inotify thread
    inotify.start()

    msg_timer = QtCore.QTimer()
    msg_timer.setSingleShot(True)
    msg_timer.connect(msg_timer, SIGNAL('timeout()'), _send_msg)
    msg_timer.start(0)

    # Start the event loop
    result = app.exec_()

    # All done, cleanup
    inotify.stop()
    QtCore.QThreadPool.globalInstance().waitForDone()

    pattern = cola.model().tmp_file_pattern()
    for filename in glob.glob(pattern):
        os.unlink(filename)
    sys.exit(result)

    return ctl, task
Exemplo n.º 3
0
def main(context):
    """Parses the command-line arguments and starts git-cola
    """
    setup_environment()
    opts, args, context = parse_args(context)
    repo = process_args(opts, args)

    # Allow Ctrl-C to exit
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    # Initialize the app
    app = ColaApplication(sys.argv)

    # Ensure that we're working in a valid git repository.
    # If not, try to find one.  When found, chdir there.
    model = cola.model()
    valid = model.set_worktree(repo) and not opts.prompt
    while not valid:
        startup_dlg = startup.StartupDialog(app.activeWindow())
        gitdir = startup_dlg.find_git_repo()
        if not gitdir:
            sys.exit(-1)
        valid = model.set_worktree(gitdir)

    # Finally, go to the root of the git repo
    os.chdir(model.git.worktree())

    # Show the GUI
    if context == "archive":
        from cola.widgets.archive import GitArchiveDialog

        model.update_status()
        view = GitArchiveDialog(model.currentbranch)
    elif context == "branch":
        from cola.widgets.createbranch import create_new_branch

        view = create_new_branch()
    elif context in ("git-dag", "dag"):
        from cola.dag import git_dag

        ctl = git_dag(model, opts=opts, args=args)
        view = ctl.view
    elif context in ("classic", "browse"):
        from cola.classic import cola_classic

        view = cola_classic(update=False)
    elif context == "config":
        from cola.prefs import preferences

        ctl = preferences()
        view = ctl.view
    elif context == "fetch":
        # TODO: the calls to update_status() can be done asynchronously
        # by hooking into the message_updated notification.
        from cola.widgets import remote

        model.update_status()
        view = remote.fetch()
    elif context == "grep":
        from cola.widgets import grep

        view = grep.run_grep(parent=None)
    elif context == "pull":
        from cola.widgets import remote

        model.update_status()
        view = remote.pull()
    elif context == "push":
        from cola.widgets import remote

        model.update_status()
        view = remote.push()
    elif context == "remote":
        from cola.widgets import editremotes

        view = editremotes.edit()
    elif context == "search":
        from cola.widgets.search import search

        view = search()
    elif context == "stash":
        from cola.stash import stash

        model.update_status()
        view = stash().view
    elif context == "tag":
        from cola.widgets.createtag import create_tag

        view = create_tag()
    else:
        view = MainView(model, qtutils.active_window())
        ctl = MainController(model, view)

    # Install UI wrappers for command objects
    cfgactions.install_command_wrapper()
    guicmds.install_command_wrapper()

    # Make sure that we start out on top
    view.show()
    view.raise_()

    # Scan for the first time
    task = _start_update_thread(model)

    # Start the inotify thread
    inotify.start()

    msg_timer = QtCore.QTimer()
    msg_timer.setSingleShot(True)
    msg_timer.connect(msg_timer, SIGNAL("timeout()"), _send_msg)
    msg_timer.start(0)

    # Start the event loop
    result = app.exec_()

    # All done, cleanup
    inotify.stop()
    QtCore.QThreadPool.globalInstance().waitForDone()

    pattern = utils.tmp_file_pattern()
    for filename in glob.glob(pattern):
        os.unlink(filename)
    sys.exit(result)

    return ctl, task
Exemplo n.º 4
0
def main(context):
    """Parses the command-line arguments and starts git-cola
    """
    setup_environment()
    opts, args, context = parse_args(context)
    repo = process_args(opts, args)

    # Allow Ctrl-C to exit
    signal.signal(signal.SIGINT, signal.SIG_DFL)

    # Initialize the app
    app = ColaApplication(sys.argv)

    # Ensure that we're working in a valid git repository.
    # If not, try to find one.  When found, chdir there.
    model = cola.model()
    valid = model.set_worktree(repo) and not opts.prompt
    while not valid:
        startup_dlg = startup.StartupDialog(app.activeWindow())
        gitdir = startup_dlg.find_git_repo()
        if not gitdir:
            sys.exit(-1)
        valid = model.set_worktree(gitdir)

    # Finally, go to the root of the git repo
    os.chdir(model.git.worktree())

    # Show the GUI
    if context == 'archive':
        from cola.widgets.archive import GitArchiveDialog
        model.update_status()
        view = GitArchiveDialog(model.currentbranch)
    elif context == 'branch':
        from cola.widgets.createbranch import create_new_branch
        view = create_new_branch()
    elif context in ('git-dag', 'dag'):
        from cola.dag import git_dag
        ctl = git_dag(model, opts=opts, args=args)
        view = ctl.view
    elif context in ('classic', 'browse'):
        from cola.classic import cola_classic
        view = cola_classic(update=False)
    elif context == 'config':
        from cola.prefs import preferences
        ctl = preferences()
        view = ctl.view
    elif context == 'fetch':
        # TODO: the calls to update_status() can be done asynchronously
        # by hooking into the message_updated notification.
        from cola.widgets import remote
        model.update_status()
        view = remote.fetch()
    elif context == 'grep':
        from cola.widgets import grep
        view = grep.run_grep(parent=None)
    elif context == 'pull':
        from cola.widgets import remote
        model.update_status()
        view = remote.pull()
    elif context == 'push':
        from cola.widgets import remote
        model.update_status()
        view = remote.push()
    elif context == 'remote':
        from cola.widgets import editremotes
        view = editremotes.edit()
    elif context == 'search':
        from cola.widgets.search import search
        view = search()
    elif context == 'stash':
        from cola.stash import stash
        model.update_status()
        view = stash().view
    elif context == 'tag':
        from cola.widgets.createtag import create_tag
        view = create_tag()
    else:
        view = MainView(model, qtutils.active_window())
        ctl = MainController(model, view)

    # Install UI wrappers for command objects
    cfgactions.install_command_wrapper()
    guicmds.install_command_wrapper()

    # Make sure that we start out on top
    view.show()
    view.raise_()

    # Scan for the first time
    task = _start_update_thread(model)

    # Start the inotify thread
    inotify.start()

    msg_timer = QtCore.QTimer()
    msg_timer.setSingleShot(True)
    msg_timer.connect(msg_timer, SIGNAL('timeout()'), _send_msg)
    msg_timer.start(0)

    # Start the event loop
    result = app.exec_()

    # All done, cleanup
    inotify.stop()
    QtCore.QThreadPool.globalInstance().waitForDone()

    pattern = utils.tmp_file_pattern()
    for filename in glob.glob(pattern):
        os.unlink(filename)
    sys.exit(result)

    return ctl, task