Skip to content

Commit

Permalink
cmds: clear diffs when the selection becomes empty
Browse files Browse the repository at this point in the history
Detect the empty state and refresh the diff text and selection.
We originally used a separate event to track clicks, which made
the code harder to follow.

We now check for the empty state in when refreshing and empty
out the diff text when no selection or no changes exist.

Closes #194

Reported-by: Avinash-Bhat <nashpapa@gmail.com>
Signed-off-by: David Aguilar <davvid@gmail.com>
  • Loading branch information
davvid committed Aug 17, 2013
1 parent ed35edf commit 068064d
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 38 deletions.
7 changes: 7 additions & 0 deletions cola/main/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from cola.compat import set
from cola.observable import Observable
from cola.decorators import memoize
from cola.models.selection import selection_model


# Static GitConfig instance
Expand Down Expand Up @@ -190,6 +191,12 @@ def _update_files(self, update_index=False):
self.untracked = state.get('untracked', [])
self.submodules = state.get('submodules', set())
self.upstream_changed = state.get('upstream_changed', [])
if self.is_empty() or selection_model().is_empty():
self.set_diff_text('')

def is_empty(self):
return not(bool(self.staged or self.modified or
self.unmerged or self.untracked))

def _update_refs(self):
self.remotes = self.git.remote().splitlines()
Expand Down
4 changes: 4 additions & 0 deletions cola/models/selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ def __init__(self):
self.modified = []
self.untracked = []

def is_empty(self):
return not(bool(self.staged or self.unmerged or
self.modified or self.untracked))

def set_selection(self, s):
"""Set the new selection."""
self.staged = s.staged
Expand Down
7 changes: 6 additions & 1 deletion cola/widgets/diff.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,16 @@ def __init__(self, parent):

model.add_observer(model.message_mode_about_to_change,
self._mode_about_to_change)
model.add_observer(model.message_diff_text_changed, self.setPlainText)
model.add_observer(model.message_diff_text_changed, self._emit_text)

self.connect(self, SIGNAL('copyAvailable(bool)'),
self.enable_selection_actions)

self.connect(self, SIGNAL('set_text'), self.setPlainText)

def _emit_text(self, text):
self.emit(SIGNAL('set_text'), text)

# Qt overrides
def contextMenuEvent(self, event):
"""Create the context menu for the diff display."""
Expand Down
68 changes: 31 additions & 37 deletions cola/widgets/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ def __init__(self, parent):
self.old_selection = None
self.old_contents = None
self.old_current_item = None
self.busy = False

self.expanded_items = set()

Expand Down Expand Up @@ -134,16 +135,13 @@ def __init__(self, parent):
self.connect(self, SIGNAL('itemSelectionChanged()'),
self.show_selection)

self.connect(self,
SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'),
self.connect(self, SIGNAL('itemDoubleClicked(QTreeWidgetItem*,int)'),
self.double_clicked)

self.connect(self,
SIGNAL('itemCollapsed(QTreeWidgetItem*)'),
self.connect(self, SIGNAL('itemCollapsed(QTreeWidgetItem*)'),
lambda x: self.update_column_widths())

self.connect(self,
SIGNAL('itemExpanded(QTreeWidgetItem*)'),
self.connect(self, SIGNAL('itemExpanded(QTreeWidgetItem*)'),
lambda x: self.update_column_widths())

def add_item(self, txt, hide=False):
Expand All @@ -160,9 +158,13 @@ def add_item(self, txt, hide=False):
self.setItemHidden(item, True)

def restore_selection(self):
# clear() generates more callbacks, which we can safely ignore
if self.busy:
return
if not self.old_selection or not self.old_contents:
return

empty = True
old_c = self.old_contents
old_s = self.old_selection
new_c = self.contents()
Expand Down Expand Up @@ -200,8 +202,9 @@ def select(item, current=False):
category, idx = self.old_current_item
if category == self.idx_header:
item = self.invisibleRootItem().child(idx)
self.setCurrentItem(item)
self.setItemSelected(item, True)
if item is not None:
self.setCurrentItem(item)
self.setItemSelected(item, True)
return
# Reselect the current item
selection_info = saved_selection[category]
Expand All @@ -214,6 +217,7 @@ def select(item, current=False):
return
if item in new:
reselect(item, current=True)
empty = False

# Restore selection
# When reselecting we only care that the items are selected;
Expand All @@ -224,6 +228,7 @@ def select(item, current=False):
for item in selection:
if item in new:
reselect(item, current=False)
empty = False
self.blockSignals(False)

for (new, old, selection, reselect) in saved_selection:
Expand All @@ -245,6 +250,10 @@ def select(item, current=False):
if j in new:
reselect(j, current=True)
return
if empty:
self.busy = True
self.clear()
self.busy = False

def restore_scrollbar(self):
vscroll = self.verticalScrollBar()
Expand Down Expand Up @@ -302,6 +311,9 @@ def save_scrollbar(self):
self.old_scroll = None

def current_item(self):
s = self.selected_indexes()
if not s:
return None
current = self.currentItem()
if not current:
return None
Expand Down Expand Up @@ -354,6 +366,7 @@ def _set_subtree(self, items, idx,
untracked=False,
check=True):
"""Add a list of items to a treewidget item."""
self.blockSignals(True)
parent = self.topLevelItem(idx)
if items:
self.setItemHidden(parent, False)
Expand All @@ -374,6 +387,7 @@ def _set_subtree(self, items, idx,
untracked=untracked)
parent.addChild(treeitem)
self.expand_items(idx, items)
self.blockSignals(False)

def update_column_widths(self):
self.resizeColumnToContents(0)
Expand Down Expand Up @@ -777,34 +791,6 @@ def _subtree_selection(self, idx, items):
item = self.topLevelItem(idx)
return qtutils.tree_selection(item, items)

def mouseReleaseEvent(self, event):
result = QtGui.QTreeWidget.mouseReleaseEvent(self, event)
self.clicked()
return result

def clicked(self, item=None, idx=None):
"""Called when a repo status tree item is clicked.
This handles the behavior where clicking on the icon invokes
the a context-specific action.
"""
# Sync the selection model
s = self.selection()
cola.selection_model().set_selection(s)

# Clear the selection if an empty area was clicked
selection = self.selected_indexes()
if not selection:
if self.m.amending():
cmds.do(cmds.SetDiffText, '')
else:
cmds.do(cmds.ResetMode)
self.blockSignals(True)
self.clearSelection()
self.blockSignals(False)
return

def double_clicked(self, item, idx):
"""Called when an item is double-clicked in the repo status tree."""
self._process_selection()
Expand Down Expand Up @@ -832,13 +818,21 @@ def _open_parent_dir(self):
selection = self.selected_group()
cmds.do(cmds.OpenParentDir, selection)

def clear(self):
if self.m.amending():
cmds.do(cmds.SetDiffText, '')
else:
cmds.do(cmds.ResetMode)

def show_selection(self):
"""Show the selected item."""
# Sync the selection model
cola.selection_model().set_selection(self.selection())
s = self.selection()
cola.selection_model().set_selection(s)

selection = self.selected_indexes()
if not selection:
self.clear()
return
category, idx = selection[0]
# A header item e.g. 'Staged', 'Modified', etc.
Expand Down

0 comments on commit 068064d

Please sign in to comment.