Example #1
0
    def __init__(self, model, dag, parent=None, args=None):
        standard.Dialog.__init__(self, parent=parent)
        if utils.is_darwin():
            self.setAttribute(QtCore.Qt.WA_MacMetalStyle)
        # change when widgets are added/removed
        self.widget_version = 1

        self.model = model
        self.dag = dag
        self.setObjectName('dag')
        self.setMinimumSize(1, 1)

        self.revlabel = QtGui.QLabel()
        self.revlabel.setText('git log -')

        self.revtext = GitLogLineEdit(parent=self)

        self.maxresults = QtGui.QSpinBox()
        self.maxresults.setMinimum(-1)
        self.maxresults.setMaximum(2**31 - 1)

        self.displaybutton = QtGui.QPushButton()
        self.displaybutton.setText('Display')

        self.zoom_in = QtGui.QPushButton()
        self.zoom_in.setIcon(qtutils.theme_icon('zoom-in.png'))
        self.zoom_in.setFlat(True)

        self.zoom_out = QtGui.QPushButton()
        self.zoom_out.setIcon(qtutils.theme_icon('zoom-out.png'))
        self.zoom_out.setFlat(True)

        self._buttons_layt = QtGui.QHBoxLayout()
        self._buttons_layt.setMargin(2)
        self._buttons_layt.setSpacing(4)

        self._buttons_layt.addWidget(self.revlabel)
        self._buttons_layt.addWidget(self.maxresults)
        self._buttons_layt.addWidget(self.revtext)
        self._buttons_layt.addWidget(self.displaybutton)
        self._buttons_layt.addStretch()
        self._buttons_layt.addWidget(self.zoom_out)
        self._buttons_layt.addWidget(self.zoom_in)

        self._commits = {}
        self._notifier = notifier = observable.Observable()
        self._notifier.refs_updated = refs_updated = 'refs_updated'
        self._notifier.add_message_observer(refs_updated, self._display)

        self._graphview = GraphView(notifier)
        self._treewidget = CommitTreeWidget(notifier)
        self._diffwidget = DiffWidget(notifier)

        for signal in (archive,):
            qtutils.relay_signal(self, self._graphview, SIGNAL(signal))
            qtutils.relay_signal(self, self._treewidget, SIGNAL(signal))

        self._mainsplitter = QtGui.QSplitter()
        self._mainsplitter.setOrientation(QtCore.Qt.Horizontal)
        self._mainsplitter.setChildrenCollapsible(True)

        self._leftsplitter = QtGui.QSplitter()
        self._leftsplitter.setOrientation(QtCore.Qt.Vertical)
        self._leftsplitter.setChildrenCollapsible(True)
        self._leftsplitter.setStretchFactor(0, 1)
        self._leftsplitter.setStretchFactor(1, 1)
        self._leftsplitter.insertWidget(0, self._treewidget)
        self._leftsplitter.insertWidget(1, self._diffwidget)

        self._mainsplitter.insertWidget(0, self._leftsplitter)
        self._mainsplitter.insertWidget(1, self._graphview)

        self._mainsplitter.setStretchFactor(0, 1)
        self._mainsplitter.setStretchFactor(1, 1)

        self._layt = layt = QtGui.QVBoxLayout()
        layt.setMargin(0)
        layt.setSpacing(0)
        layt.addLayout(self._buttons_layt)
        layt.addWidget(self._mainsplitter)
        self.setLayout(layt)

        # Also re-loads dag.* from the saved state
        if not qtutils.apply_state(self):
            self.resize_to_desktop()

        # Update fields affected by model
        self.revtext.setText(dag.ref)
        self.maxresults.setValue(dag.count)
        self.update_window_title()

        self.thread = ReaderThread(self, dag)

        self.thread.connect(self.thread, self.thread.commits_ready,
                            self.add_commits)

        self.thread.connect(self.thread, self.thread.done,
                            self.thread_done)

        self.connect(self._mainsplitter, SIGNAL('splitterMoved(int,int)'),
                     self._splitter_moved)

        self.connect(self.zoom_in, SIGNAL('pressed()'),
                     self._graphview.zoom_in)

        self.connect(self.zoom_out, SIGNAL('pressed()'),
                     self._graphview.zoom_out)

        self.connect(self.maxresults, SIGNAL('valueChanged(int)'),
                     lambda(x): self.dag.set_count(x))

        self.connect(self.displaybutton, SIGNAL('pressed()'),
                     self._display)

        self.connect(self.revtext, SIGNAL('ref_changed'),
                     self._display)

        self.connect(self.revtext, SIGNAL('textChanged(QString)'),
                     self._text_changed)

        # The model is updated in another thread so use
        # signals/slots to bring control back to the main GUI thread
        self.model.add_message_observer(self.model.message_updated,
                                        self._model_updated)

        self.connect(self, SIGNAL('model_updated'),
                     self.model_updated)

        qtutils.add_close_action(self)
Example #2
0
class DAGView(standard.Dialog):
    """The git-dag widget."""
    def __init__(self, model, dag, parent=None, args=None):
        standard.Dialog.__init__(self, parent=parent)
        if utils.is_darwin():
            self.setAttribute(QtCore.Qt.WA_MacMetalStyle)
        # change when widgets are added/removed
        self.widget_version = 1

        self.model = model
        self.dag = dag
        self.setObjectName('dag')
        self.setMinimumSize(1, 1)

        self.revlabel = QtGui.QLabel()
        self.revlabel.setText('git log -')

        self.revtext = GitLogLineEdit(parent=self)

        self.maxresults = QtGui.QSpinBox()
        self.maxresults.setMinimum(-1)
        self.maxresults.setMaximum(2**31 - 1)

        self.displaybutton = QtGui.QPushButton()
        self.displaybutton.setText('Display')

        self.zoom_in = QtGui.QPushButton()
        self.zoom_in.setIcon(qtutils.theme_icon('zoom-in.png'))
        self.zoom_in.setFlat(True)

        self.zoom_out = QtGui.QPushButton()
        self.zoom_out.setIcon(qtutils.theme_icon('zoom-out.png'))
        self.zoom_out.setFlat(True)

        self._buttons_layt = QtGui.QHBoxLayout()
        self._buttons_layt.setMargin(2)
        self._buttons_layt.setSpacing(4)

        self._buttons_layt.addWidget(self.revlabel)
        self._buttons_layt.addWidget(self.maxresults)
        self._buttons_layt.addWidget(self.revtext)
        self._buttons_layt.addWidget(self.displaybutton)
        self._buttons_layt.addStretch()
        self._buttons_layt.addWidget(self.zoom_out)
        self._buttons_layt.addWidget(self.zoom_in)

        self._commits = {}
        self._notifier = notifier = observable.Observable()
        self._notifier.refs_updated = refs_updated = 'refs_updated'
        self._notifier.add_message_observer(refs_updated, self._display)

        self._graphview = GraphView(notifier)
        self._treewidget = CommitTreeWidget(notifier)
        self._diffwidget = DiffWidget(notifier)

        for signal in (archive,):
            qtutils.relay_signal(self, self._graphview, SIGNAL(signal))
            qtutils.relay_signal(self, self._treewidget, SIGNAL(signal))

        self._mainsplitter = QtGui.QSplitter()
        self._mainsplitter.setOrientation(QtCore.Qt.Horizontal)
        self._mainsplitter.setChildrenCollapsible(True)

        self._leftsplitter = QtGui.QSplitter()
        self._leftsplitter.setOrientation(QtCore.Qt.Vertical)
        self._leftsplitter.setChildrenCollapsible(True)
        self._leftsplitter.setStretchFactor(0, 1)
        self._leftsplitter.setStretchFactor(1, 1)
        self._leftsplitter.insertWidget(0, self._treewidget)
        self._leftsplitter.insertWidget(1, self._diffwidget)

        self._mainsplitter.insertWidget(0, self._leftsplitter)
        self._mainsplitter.insertWidget(1, self._graphview)

        self._mainsplitter.setStretchFactor(0, 1)
        self._mainsplitter.setStretchFactor(1, 1)

        self._layt = layt = QtGui.QVBoxLayout()
        layt.setMargin(0)
        layt.setSpacing(0)
        layt.addLayout(self._buttons_layt)
        layt.addWidget(self._mainsplitter)
        self.setLayout(layt)

        # Also re-loads dag.* from the saved state
        if not qtutils.apply_state(self):
            self.resize_to_desktop()

        # Update fields affected by model
        self.revtext.setText(dag.ref)
        self.maxresults.setValue(dag.count)
        self.update_window_title()

        self.thread = ReaderThread(self, dag)

        self.thread.connect(self.thread, self.thread.commits_ready,
                            self.add_commits)

        self.thread.connect(self.thread, self.thread.done,
                            self.thread_done)

        self.connect(self._mainsplitter, SIGNAL('splitterMoved(int,int)'),
                     self._splitter_moved)

        self.connect(self.zoom_in, SIGNAL('pressed()'),
                     self._graphview.zoom_in)

        self.connect(self.zoom_out, SIGNAL('pressed()'),
                     self._graphview.zoom_out)

        self.connect(self.maxresults, SIGNAL('valueChanged(int)'),
                     lambda(x): self.dag.set_count(x))

        self.connect(self.displaybutton, SIGNAL('pressed()'),
                     self._display)

        self.connect(self.revtext, SIGNAL('ref_changed'),
                     self._display)

        self.connect(self.revtext, SIGNAL('textChanged(QString)'),
                     self._text_changed)

        # The model is updated in another thread so use
        # signals/slots to bring control back to the main GUI thread
        self.model.add_message_observer(self.model.message_updated,
                                        self._model_updated)

        self.connect(self, SIGNAL('model_updated'),
                     self.model_updated)

        qtutils.add_close_action(self)

    def _text_changed(self, txt):
        self.dag.ref = unicode(txt)
        self.update_window_title()

    def update_window_title(self):
        project = self.model.project
        if self.dag.ref:
            self.setWindowTitle('%s: %s' % (project, self.dag.ref))
        else:
            self.setWindowTitle(project)

    def export_state(self):
        state = standard.Dialog.export_state(self)
        state['ref'] = self.dag.ref
        state['count'] = self.dag.count
        return state

    def apply_state(self, state):
        try:
            standard.Dialog.apply_state(self, state)
        except:
            return
        try:
            ref = state['ref']
            count = state['count']
        except KeyError:
            return

        if not self.dag.overridden('ref'):
            self.dag.set_ref(ref)

        if not self.dag.overridden('count'):
            self.dag.set_count(count)

    def _model_updated(self):
        self.emit(SIGNAL('model_updated'))

    def model_updated(self):
        if self.dag.ref:
            self.revtext.update_matches()
            return
        if not self.model.currentbranch:
            return
        self.revtext.setText(self.model.currentbranch)
        self._display()

    def _display(self):
        new_ref = unicode(self.revtext.text())
        if not new_ref:
            return
        self.stop()
        self.clear()
        self.dag.set_ref(new_ref)
        self.dag.set_count(self.maxresults.value())
        self.start()

    def show(self):
        standard.Dialog.show(self)
        self._mainsplitter.setSizes([self.width()/2, self.width()/2])
        self._leftsplitter.setSizes([self.height()/3, self.height()*2/3])
        self._treewidget.adjust_columns()

    def resizeEvent(self, e):
        standard.Dialog.resizeEvent(self, e)
        self._treewidget.adjust_columns()

    def _splitter_moved(self, pos, idx):
        self._treewidget.adjust_columns()

    def clear(self):
        self._graphview.clear()
        self._treewidget.clear()
        self._commits.clear()

    def add_commits(self, commits):
        # Keep track of commits
        for commit_obj in commits:
            self._commits[commit_obj.sha1] = commit_obj
            for tag in commit_obj.tags:
                self._commits[tag] = commit_obj
        self._graphview.add_commits(commits)
        self._treewidget.add_commits(commits)

    def thread_done(self):
        try:
            commit_obj = self._commits[self.dag.ref]
        except KeyError:
            return
        sig = signals.commits_selected
        self._notifier.notify_message_observers(sig, [commit_obj])
        self._graphview.view_fit()

    def done(self, ok):
        self.revtext.close_popup()
        qtutils.save_state(self)
        return standard.Dialog.done(self, ok)

    def close(self):
        self.stop()
        standard.Dialog.close(self)

    def pause(self):
        self.thread.mutex.lock()
        self.thread.stop = True
        self.thread.mutex.unlock()

    def stop(self):
        self.thread.abort = True
        self.thread.wait()

    def start(self):
        self.thread.abort = False
        self.thread.stop = False
        self.thread.start()

    def resume(self):
        self.thread.mutex.lock()
        self.thread.stop = False
        self.thread.mutex.unlock()
        self.thread.condition.wakeOne()

    def resize_to_desktop(self):
        desktop = QtGui.QApplication.instance().desktop()
        width = desktop.width()
        height = desktop.height()
        self.resize(width, height)