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)
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)