Add jump to change
Add a dialog that prompts for a change number and syncs that change if needed then immediately opens the change. Change-Id: Ic2d4f41ad9bd944c2540e8d71bdd3e730bb96117
This commit is contained in:
parent
e63c26f2ed
commit
3252d29400
@ -26,6 +26,7 @@ from gertty import gitrepo
|
||||
from gertty import mywid
|
||||
from gertty import sync
|
||||
from gertty.view import project_list as view_project_list
|
||||
from gertty.view import change as view_change
|
||||
|
||||
palette=[('focused', 'default,standout', ''),
|
||||
('header', 'white,bold', 'dark blue'),
|
||||
@ -125,6 +126,28 @@ class StatusHeader(urwid.WidgetWrap):
|
||||
self.error.set_text(u'')
|
||||
self.sync.set_text(u' Sync: %i' % self.app.sync.queue.qsize())
|
||||
|
||||
class OpenChangeDialog(mywid.ButtonDialog):
|
||||
signals = ['open', 'cancel']
|
||||
def __init__(self):
|
||||
open_button = mywid.FixedButton('Open')
|
||||
cancel_button = mywid.FixedButton('Cancel')
|
||||
urwid.connect_signal(open_button, 'click',
|
||||
lambda button:self._emit('open'))
|
||||
urwid.connect_signal(cancel_button, 'click',
|
||||
lambda button:self._emit('cancel'))
|
||||
super(OpenChangeDialog, self).__init__("Open Change",
|
||||
"Enter a change number to open that change.",
|
||||
entry_prompt="Number: ",
|
||||
buttons=[open_button,
|
||||
cancel_button])
|
||||
|
||||
def keypress(self, size, key):
|
||||
r = super(OpenChangeDialog, self).keypress(size, key)
|
||||
if r == 'enter':
|
||||
self._emit('open')
|
||||
return None
|
||||
return r
|
||||
|
||||
class App(object):
|
||||
def __init__(self, server=None, debug=False, disable_sync=False):
|
||||
self.server = server
|
||||
@ -159,6 +182,8 @@ class App(object):
|
||||
self.sync_thread.start()
|
||||
else:
|
||||
self.sync_thread = None
|
||||
self.sync.offline = True
|
||||
self.status.update(offline=True)
|
||||
|
||||
def run(self):
|
||||
self.loop.run()
|
||||
@ -220,6 +245,50 @@ class App(object):
|
||||
lambda button: self.backScreen())
|
||||
self.popup(dialog, min_width=76, min_height=len(lines)+4)
|
||||
|
||||
def openChange(self):
|
||||
dialog = OpenChangeDialog()
|
||||
urwid.connect_signal(dialog, 'cancel',
|
||||
lambda button: self.backScreen())
|
||||
urwid.connect_signal(dialog, 'open',
|
||||
lambda button: self._openChange(dialog))
|
||||
self.popup(dialog, min_width=76, min_height=8)
|
||||
|
||||
def _openChange(self, open_change_dialog):
|
||||
self.backScreen()
|
||||
number = open_change_dialog.entry.edit_text
|
||||
try:
|
||||
number = int(number)
|
||||
except Exception:
|
||||
return self.error('Change number must be an integer.')
|
||||
with self.db.getSession() as session:
|
||||
change = session.getChangeByNumber(number)
|
||||
change_key = change and change.key or None
|
||||
if change_key is None:
|
||||
if self.sync.offline:
|
||||
return self.error('Can not sync change while offline.')
|
||||
task = sync.SyncChangeByNumberTask(number, sync.HIGH_PRIORITY)
|
||||
self.sync.submitTask(task)
|
||||
succeeded = task.wait(300)
|
||||
if not succeeded:
|
||||
return self.error('Unable to find change.')
|
||||
for subtask in task.tasks:
|
||||
succeeded = task.wait(300)
|
||||
if not succeeded:
|
||||
return self.error('Unable to sync change.')
|
||||
with self.db.getSession() as session:
|
||||
change = session.getChangeByNumber(number)
|
||||
change_key = change and change.key or None
|
||||
if change_key is None:
|
||||
return self.error('Change is not in local database.')
|
||||
self.changeScreen(view_change.ChangeView(self, change_key))
|
||||
|
||||
def error(self, message):
|
||||
dialog = mywid.MessageDialog('Error', message)
|
||||
urwid.connect_signal(dialog, 'close',
|
||||
lambda button: self.backScreen())
|
||||
self.popup(dialog, min_height=4)
|
||||
return None
|
||||
|
||||
def unhandledInput(self, key):
|
||||
if key == 'esc':
|
||||
self.backScreen()
|
||||
@ -227,6 +296,8 @@ class App(object):
|
||||
self.help()
|
||||
elif key == 'ctrl q':
|
||||
self.quit()
|
||||
elif key == 'ctrl o':
|
||||
self.openChange()
|
||||
|
||||
def getRepo(self, project_name):
|
||||
local_path = os.path.join(self.config.git_root, project_name)
|
||||
|
@ -419,6 +419,12 @@ class DatabaseSession(object):
|
||||
except sqlalchemy.orm.exc.NoResultFound:
|
||||
return None
|
||||
|
||||
def getChangeByNumber(self, number):
|
||||
try:
|
||||
return self.session().query(Change).filter_by(number=number).one()
|
||||
except sqlalchemy.orm.exc.NoResultFound:
|
||||
return None
|
||||
|
||||
def getRevision(self, key):
|
||||
try:
|
||||
return self.session().query(Revision).filter_by(key=key).one()
|
||||
|
@ -57,13 +57,18 @@ class Table(urwid.WidgetWrap):
|
||||
self._w.contents[i][0].contents.append((widget, ('pack', None)))
|
||||
|
||||
class ButtonDialog(urwid.WidgetWrap):
|
||||
def __init__(self, title, message, buttons=[]):
|
||||
def __init__(self, title, message, entry_prompt=None, entry_text='', buttons=[]):
|
||||
button_widgets = []
|
||||
for button in buttons:
|
||||
button_widgets.append(('pack', button))
|
||||
button_columns = urwid.Columns(button_widgets, dividechars=2)
|
||||
rows = []
|
||||
rows.append(urwid.Text(message))
|
||||
if entry_prompt:
|
||||
self.entry = urwid.Edit(entry_prompt, edit_text=entry_text)
|
||||
rows.append(self.entry)
|
||||
else:
|
||||
self.entry = None
|
||||
rows.append(urwid.Divider())
|
||||
rows.append(button_columns)
|
||||
pile = urwid.Pile(rows)
|
||||
|
@ -83,8 +83,9 @@ class Task(object):
|
||||
self.succeeded = success
|
||||
self.event.set()
|
||||
|
||||
def wait(self):
|
||||
self.event.wait()
|
||||
def wait(self, timeout=None):
|
||||
self.event.wait(timeout)
|
||||
return self.succeeded
|
||||
|
||||
class SyncProjectListTask(Task):
|
||||
def __repr__(self):
|
||||
@ -168,6 +169,27 @@ class SyncChangeByCommitTask(Task):
|
||||
sync.submitTask(SyncChangeTask(c['id'], self.priority))
|
||||
self.log.debug("Sync change %s for its commit %s" % (c['id'], self.commit))
|
||||
|
||||
class SyncChangeByNumberTask(Task):
|
||||
def __init__(self, number, priority=NORMAL_PRIORITY):
|
||||
super(SyncChangeByNumberTask, self).__init__(priority)
|
||||
self.number = number
|
||||
self.tasks = []
|
||||
|
||||
def __repr__(self):
|
||||
return '<SyncChangeByNumberTask %s>' % (self.number,)
|
||||
|
||||
def run(self, sync):
|
||||
app = sync.app
|
||||
with app.db.getSession() as session:
|
||||
query = '%s' % self.number
|
||||
changes = sync.get('changes/?q=%s' % query)
|
||||
self.log.debug('Query: %s ' % (query,))
|
||||
for c in changes:
|
||||
task = SyncChangeTask(c['id'], self.priority)
|
||||
self.tasks.append(task)
|
||||
sync.submitTask(task)
|
||||
self.log.debug("Sync change %s because it is number %s" % (c['id'], self.number))
|
||||
|
||||
class SyncChangeTask(Task):
|
||||
def __init__(self, change_id, priority=NORMAL_PRIORITY):
|
||||
super(SyncChangeTask, self).__init__(priority)
|
||||
|
Loading…
x
Reference in New Issue
Block a user