Skip to content

Instantly share code, notes, and snippets.

@oglops
Last active September 5, 2016 20:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save oglops/868582a8847cc2244331e3642f527329 to your computer and use it in GitHub Desktop.
Save oglops/868582a8847cc2244331e3642f527329 to your computer and use it in GitHub Desktop.
hack script editor wip, 测试 lineedit 按到rect范围内就setfocus
#!/usr/bin/env python2
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import uic
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)
import re
CODE='''class A(object):
def __init__(self,*args):
pass
def method1_A(self):
pass
class B(object):
def __init__(self,*args):
pass
def method1_B(self):
pass
def main():
pass
'''
EVENT_TABLE= {v: k for k, v in QEvent.__dict__.items()}
class MyTextEdit(QTextEdit):
def mousePressEvent(self,event):
pass
print 'my own click event'
if self.lineedit.rect().contains( event.pos()):
print 'click inside lineedit'
self.lineedit.setFocus()
QTextEdit.mousePressEvent(self,event)
class MyWindow(QDialog):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
layout = QVBoxLayout()
textedit = QTextEdit()
# textedit = MyTextEdit()
def mousePressEvent(event):
pass
print 'my own click event'
if self.lineedit.rect().contains( event.pos()):
print 'click inside lineedit'
self.lineedit.setFocus()
self.lineedit.completer().complete()
QTextEdit.mousePressEvent(textedit,event)
textedit.mousePressEvent=mousePressEvent
textedit.setPlainText(CODE)
button = QPushButton('pop up completer')
layout.addWidget(textedit)
layout.addWidget(button)
self.setLayout(layout)
self.resize(640,280)
self.textedit=textedit
self.layout=layout
parent_widget= textedit.parent()
# parent_rect = textedit.childrenRect()
# _, _, w, h = parent_rect.getCoords()
_, _, w, h = textedit.rect().getCoords()
# print 'w,h',w,h
lineedit = QLineEdit(textedit)
textedit.lineedit=lineedit
lineedit.setGeometry(w/2-w*0.6/2, 0, w*0.6, 32)
symbols = get_symbols(CODE)
# completer = QCompleter(self)
completer = MyCompleter(self)
lineedit.setCompleter(completer)
model = QStringListModel(self)
completer.setModel(model)
print 'list:',[x for _,_,x in symbols]
model.setStringList([x for _,_,x in symbols])
completer.setCaseSensitivity(Qt.CaseInsensitive)
completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
def focusOutEvent(self,event):
print 'my focusout'
QListView.focusOutEvent(self,event)
completer.popup().focusOutEvent=focusOutEvent
self.completer=completer
self.lineedit = lineedit
lineedit.setAttribute(Qt.WA_TransparentForMouseEvents)
self.lineedit.setFocus()
button.clicked.connect(self._test)
# self.completer.complete()
QTimer.singleShot(0,self.completer.complete)
self.setAttribute(Qt.WA_DeleteOnClose)
def _test(self):
# print self.textedit.parent()
self.lineedit.setFocus()
self.completer.complete()
class MyCompleter(QCompleter):
def __init__(self,parent=None):
super(MyCompleter,self).__init__(parent)
# self.popupView = QListWidget()
# self.popupView.setAlternatingRowColors(True)
# self.popupView.setWordWrap(False)
# self.setPopup(self.popupView)
# self.setCompletionMode(QCompleter.PopupCompletion)
# self.setCaseSensitivity(Qt.CaseInsensitive)
def eventFilter(self,obj,event):
etype=event.type()
exclude = [1,12]
if etype not in exclude:
print 'event.type:',EVENT_TABLE[event.type()],obj
if event.type() == QEvent.Hide:
print 'hide! ',obj
# obj.show()
# return True
if event.type() == QEvent.FocusOut:
print 'yeah focus out on',obj
if event.type() == QEvent.MouseButtonRelease:
print 'yeah mouse release on',obj
super(MyCompleter,self).eventFilter(obj,event)
return False
def get_symbols(code):
symbols = []
symbol_regex = re.compile('^(\s*)(class|def)\s*([^\(\s]+\([^\(]*\))')
for n, line in enumerate(code.split('\n')):
if symbol_regex.search(line):
groups = symbol_regex.search(line).groups()
symbols.append((n+1, groups[1], groups[0]+groups[2]))
# print n+1,[str(x) for x in groups]
return symbols
def main():
if qApp.applicationName().startsWith('Maya'):
global win
try:
win.close()
except:
pass
win = MyWindow(getMayaWindow())
else:
app = QApplication(sys.argv)
win = MyWindow()
win.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
# todo
# ctrl+d remove multiple line
# double click go to line
# ctrl+g go to line
# ctrl+r sublime style
try:
qApp.removeEventFilter(myFilter)
print 'removed filter'
except:
print 'first run'
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtCore import Qt, QObject, QEvent, QChar, QModelIndex
from PyQt4.QtGui import QTextCursor, qApp
import maya.cmds as mc
import maya.mel as mel
import maya.OpenMayaUI as apiUI
import sip
import sys
import os
import re
import logging
_logger = logging.getLogger('hackScriptEditor')
for handler in _logger.handlers:
_logger.removeHandler(handler)
# _logger.setLevel(logging.INFO)
ch = logging.StreamHandler(sys.stdout)
ch.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)s:%(levelname)s: %(message)s')
ch.setFormatter(formatter)
_logger.addHandler(ch)
_logger.propagate = 0
class CustomFilter(QObject):
def __init__(self, parent=None):
super(CustomFilter, self).__init__(parent)
self.textedit = None
self.lineedit = None
def get_exec_type(self):
gCommandExecuterTabs = get_mel_global('$gCommandExecuterTabs')
tabIdx = mc.tabLayout(gCommandExecuterTabs, q=1, st=1)
cmd_executer = mc.layout(tabIdx, q=1, ca=1)[0]
return mc.cmdScrollFieldExecuter(cmd_executer, q=1, st=1)
def eventFilter(self, obj, event):
if event.type() == QEvent.KeyPress:
if 'scriptEditorPanel' in mc.getPanel(up=1):
self.get_text_edit()
self.exec_type = self.get_exec_type()
if self.exec_type == 'python':
self.comment_str = '#'
elif self.exec_type == 'mel':
self.comment_str = '//'
# print event.key(),event.modifiers()
if event.key() == Qt.Key_Slash and event.modifiers() == Qt.ControlModifier:
_logger.debug('ctrl+/ pressed')
self.toggle_comment()
return True
elif event.key() == Qt.Key_Tab and event.modifiers() == Qt.NoModifier:
_logger.debug('tab pressed')
self.tab('tab')
return True
elif event.key() == Qt.Key_Backtab and event.modifiers() == Qt.ShiftModifier:
_logger.debug('shift+tab pressed')
self.tab('shift_tab')
return True
elif event.key() == Qt.Key_D and event.modifiers() == Qt.ControlModifier:
_logger.debug('ctrl+d pressed')
self.test('delete_line')
return True
elif event.key() == Qt.Key_E and event.modifiers() == Qt.ControlModifier:
_logger.debug('ctrl+e pressed')
self.test('execute')
return True
elif event.key() == Qt.Key_Z and event.modifiers() == Qt.ControlModifier:
_logger.debug('ctrl+z pressed')
self.test('undo')
return True
elif event.key() == Qt.Key_R and event.modifiers() == Qt.ControlModifier:
_logger.debug('ctrl+r pressed')
self.test('goto_symbol')
return True
elif event.key() == Qt.Key_Escape:
_logger.debug('escape pressed')
self.test('cancel_completer')
return True
return False
def get_text_edit(self):
'get current qtextedit from script editor'
tabIdx = mc.tabLayout(gCommandExecuterTabs, q=1, st=1)
_logger.debug('current tab: %s', tabIdx)
cmd_executer = mc.layout(tabIdx, q=1, ca=1)[0]
ptr = apiUI.MQtUtil.findControl(cmd_executer)
self.textedit = sip.wrapinstance(long(ptr), QObject)
def moveToPosition(self, pos):
'move cursor actual position to pos'
cursor = self.textedit.textCursor()
cursor.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.Right, QTextCursor.MoveAnchor, pos)
self.textedit.setTextCursor(cursor)
def restore_selection(fn):
from functools import wraps
@wraps(fn)
def wrapper(self, *args, **kw):
_logger.debug('before')
self.test('get_range')
fn(self, *args, **kw)
_logger.debug('after')
self.test('load_range')
return wrapper
@restore_selection
def toggle_comment(self, *args):
self.last_change = 'toggle_comment'
self.test('multi_line_comment')
@restore_selection
def tab(self, mode='tab', *args):
self.test(mode)
def position_in_block(self, cursor):
# this can be replaced with cursor.positionInBlock after qt 4.7
pos = cursor.position()-cursor.block().position()
return pos
def get_line_range(self, cursor, start_pos, end_pos):
# find left most line
cursor.setPosition(end_pos)
last_line = cursor.block().blockNumber()
if cursor.atBlockStart() and start_pos != end_pos:
_logger.debug('start_pos: %s end_pos: %s', start_pos, end_pos)
last_line -= 1
cursor.setPosition(start_pos)
first_line = cursor.block().blockNumber()
return (first_line, last_line)
def get_min_indent(self, cursor, start_pos, first_line, last_line):
# find the leftmost line and get its position
cursor.setPosition(start_pos)
indents = []
for _line_nb in range(first_line, last_line+1):
text = str(cursor.block().text())
indent = len(text)-len(text.lstrip())
indents.append(indent)
cursor.movePosition(QTextCursor.NextBlock)
min_indent = min(indents)
_logger.debug('min_indent: %s', min_indent)
return min_indent
def is_empty_line(self, cursor):
empty = False
if len(str(cursor.block().text()).strip(' ')) == 0:
empty = True
_logger.debug('empty line [%s]', cursor.block().text())
return empty
def test(self, mode='current_pos'):
cursor = self.textedit.textCursor()
if mode == 'current_pos':
_logger.debug('current pos: %s', cursor.position())
elif mode == 'single_line_comment':
cursor.movePosition(
QTextCursor.StartOfBlock, QTextCursor.MoveAnchor)
self.textedit.setTextCursor(cursor)
cursor.insertText(self.comment_str+' ')
elif mode == 'get_range':
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
_logger.debug('range: %s %s', start_pos, end_pos)
self.sel_range = (start_pos, end_pos)
elif mode == 'load_range':
start_pos, end_pos = self.sel_range
_logger.debug('load range: %s %s', start_pos, end_pos)
self.moveToPosition(start_pos)
cursor = self.textedit.textCursor()
cursor.movePosition(
QTextCursor.Right, QTextCursor.KeepAnchor, end_pos - start_pos)
self.textedit.setTextCursor(cursor)
elif mode == 'multi_line_comment':
# find selected lines
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
first_line, last_line = self.get_line_range(
cursor, start_pos, end_pos)
# If the selection contains only commented lines and surrounding
# whitespace, uncomment. Otherwise, comment.
is_comment_or_whitespace = True
at_least_one_comment = False
for _line_nb in range(first_line, last_line+1):
text = str(cursor.block().text()).lstrip()
_logger.debug('dealing text: %s', text)
is_comment = text.startswith(self.comment_str)
is_whitespace = (text == '')
is_comment_or_whitespace *= (is_comment or is_whitespace)
if is_comment:
at_least_one_comment = True
cursor.movePosition(QTextCursor.NextBlock)
min_indent = self.get_min_indent(
cursor, start_pos, first_line, last_line)
cursor.beginEditBlock()
if is_comment_or_whitespace and at_least_one_comment:
_logger.debug('need to uncomment')
cursor.setPosition(start_pos)
for _line_nb in range(first_line, last_line+1):
if self.is_empty_line(cursor):
cursor.movePosition(QTextCursor.NextBlock)
continue
if _line_nb == first_line:
self.moveToPosition(start_pos)
if self.position_in_block(cursor) > min_indent:
start_pos -= len(self.comment_str)+1
cursor.movePosition(QTextCursor.StartOfLine)
cursor.movePosition(
QTextCursor.Right, QTextCursor.MoveAnchor, min_indent)
self.textedit.setTextCursor(cursor)
for i in range(len(self.comment_str)):
cursor.deleteChar()
end_pos -= 1
next_char = cursor.block().text()[
self.position_in_block(cursor)]
_logger.debug('next char: %s', next_char)
if next_char == ' ':
cursor.deleteChar()
end_pos -= 1
cursor.movePosition(QTextCursor.NextBlock)
self.sel_range = (start_pos, end_pos)
else:
_logger.debug('need to comment')
cursor.setPosition(start_pos)
for _line_nb in range(first_line, last_line+1):
if self.is_empty_line(cursor):
cursor.movePosition(QTextCursor.NextBlock)
continue
if _line_nb == first_line:
self.moveToPosition(start_pos)
if self.position_in_block(cursor) >= min_indent:
start_pos += len(self.comment_str)+1
cursor.movePosition(QTextCursor.StartOfLine)
cursor.movePosition(
QTextCursor.Right, QTextCursor.MoveAnchor, min_indent)
self.textedit.setTextCursor(cursor)
cursor.insertText('%s ' % self.comment_str)
end_pos += len(self.comment_str)+1
cursor.movePosition(QTextCursor.NextBlock)
self.sel_range = (start_pos, end_pos)
cursor.endEditBlock()
elif mode == 'get_text_cur_pos':
_logger.debug('get cur pos text')
cursor = self.textedit.textCursor()
positionInBlock = self.position_in_block(cursor)
_logger.debug('block pos: %s', positionInBlock)
_logger.debug('block text: %s', cursor.block().text())
_logger.debug(cursor.block().text()[positionInBlock])
elif mode == 'tab':
print 'tab'
cursor.beginEditBlock()
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
# get last first line
first_line, last_line = self.get_line_range(
cursor, start_pos, end_pos)
# range(first_line, last_line+1)
_logger.debug('tab key: %s %s', first_line, last_line)
start_pos += 4
# indent 4 spaces
for _line_nb in range(first_line, last_line+1):
cursor.movePosition(QTextCursor.StartOfLine)
self.textedit.setTextCursor(cursor)
# skip empty line
if len(str(cursor.block().text()).strip(' ')) or first_line == last_line:
cursor.insertText(' '*4)
end_pos += 4
cursor.movePosition(QTextCursor.NextBlock)
self.sel_range = (start_pos, end_pos)
cursor.endEditBlock()
elif mode == 'shift_tab':
_logger.debug('shift_tab')
cursor.beginEditBlock()
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
# get last first line
first_line, last_line = self.get_line_range(
cursor, start_pos, end_pos)
for _line_nb in range(first_line, last_line+1):
cursor.movePosition(QTextCursor.StartOfLine)
if _line_nb == first_line:
for i in range(4):
next_char = cursor.block().text()[
self.position_in_block(cursor)]
if next_char == ' ':
cursor.deleteChar()
start_pos -= 1
end_pos -= 1
else:
for i in range(4):
next_char = cursor.block().text()
if next_char:
next_char = next_char[
self.position_in_block(cursor)]
else:
break
if next_char == ' ':
cursor.deleteChar()
end_pos -= 1
self.textedit.setTextCursor(cursor)
cursor.movePosition(QTextCursor.NextBlock)
self.sel_range = (start_pos, end_pos)
cursor.endEditBlock()
elif mode == 'undo':
_logger.debug('undo') # self.sel_range
# if self.last_change=='toggle_comment':
# self.toggle_comment()
self.textedit.undo()
if getattr(self, 'sel_range', None):
self.test('load_range')
self.sel_range = None
elif mode == 'delete_line':
_logger.debug('delete_line')
cursor.beginEditBlock()
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
# get last first line
first_line, last_line = sorted(
self.get_line_range(cursor, start_pos, end_pos))
for _line_nb in reversed(range(first_line, last_line+1)):
text_block = self.textedit.document().findBlockByLineNumber(
_line_nb)
cursor.setPosition(text_block.position())
self.textedit.setTextCursor(cursor)
cursor.select(QTextCursor.LineUnderCursor)
cursor.removeSelectedText()
cursor.deleteChar()
cursor.endEditBlock()
elif mode == 'execute':
_logger.debug('execute')
# if self.lastnge=='toggle_comment':
# self.toggle_comment()
# if something selected, run it
start_pos, end_pos = [cursor.selectionStart(),
cursor.selectionEnd()]
run_all = 0
if start_pos == end_pos:
# run all
cmd = self.textedit.toPlainText()
run_all = 1
else:
cmd = cursor.selectedText()
# get first line content
cursor.movePosition(QTextCursor.Start, QTextCursor.MoveAnchor)
cursor.movePosition(
QTextCursor.Right, QTextCursor.MoveAnchor, start_pos)
first_line = str(cursor.block().text())
spaces = len(first_line)-len(first_line.lstrip(' '))
start_pos_in_block = self.position_in_block(cursor)
if not run_all:
if start_pos_in_block < spaces:
# f ill spaces
cmd = ' '*start_pos_in_block+cmd
else:
cmd = ' '*spaces + cmd
cmd = str(cmd.replace(QChar(0x2029), QChar('\n')))
cmd = self.dedent_code(cmd)
print 'will run cmd:\n', cmd
# exec(cmd)
elif mode == 'goto_symbol':
print self.textedit.parent()
print self.textedit.parent().__class__
print dir(self.textedit.parent())
parent_widget = self.textedit.parent()
parent_rect = parent_widget.childrenRect()
_, _, w, h = parent_rect.getCoords()
# btn =QtGui.QPushButton('yeah',parent=parent_widget)
if len(parent_widget.children()) == 3:
lineedit = parent_widget.children()[2]
# lineedit.deleteLater()
else:
# lineedit = MyLineEdit(parent_widget)
lineedit = QLineEdit(parent_widget)
completer = CustomQCompleter()
current_tab_text = self.get_current_tab_text()
print 'current tab:', current_tab_text
symbols = get_symbols(current_tab_text)
self.symbols = symbols
model = MyModel()
model.setup(symbols)
completer.setModel(model)
completer.linedit=lineedit
completer.setCaseSensitivity(QtCore.Qt.CaseInsensitive)
completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
completer.setWrapAround(False)
lineedit.setCompleter(completer)
completer.highlighted[QModelIndex].connect(self.goto_line)
lineedit.textChanged[QString].connect(self.pop)
lineedit.editingFinished.connect(self.repop)
lineedit.setFocus()
# lineedit.setFocusPolicy(Qt.NoFocus)
# lineedit.focusOutEvent=focusOutEvent
self.completer = completer
self.lineedit = lineedit
QTimer.singleShot(0, self.completer.complete)
lineedit.setGeometry(w/2-w*0.6/2, 0, w*0.6, 32)
lineedit.show()
print parent_widget.children()
QTimer.singleShot(0, self.scroll_to_nearest)
# button = parent_widget.children()[2]
# button.raise_()
# button.setGeometry(QtCore.QRect(100,100,80,20))
# button.raise_()
# parent_widget.children()[1].deleteLater()
# button.setMaximumSize(QtCore.QSize(32767, 32767))
# print self.textedit.
# button.activateWindow()
# self.textedit.stackUnder(button)
# parent_widget.children()[2].raise_()
# del parent_widget.children()[1]
# layout = parent_widget.children()[0]
# layout.addWidget(parent_widget.children()[2])
# layout.removeWidget(parent_widget.children()[2])
pass
elif mode == 'cancel_completer':
# check to see if complete is visible
pass
if self.lineedit is not None:
self.completer.deleteLater()
self.lineedit.deleteLater()
self.lineedit = None
def scroll_to_nearest(self):
# find current cursor line
cursor = self.textedit.textCursor()
line = cursor.blockNumber()+1
print 'current line:',line
# get all lines
all_lines= [ x for x,_,_ in self.symbols]
# print 'all_lines:',all_lines
# find nearest line
line_distance = [ abs(line-x) for x in all_lines]
sorted_lines=sorted(zip(all_lines,line_distance),key=lambda x:x[1])
nearest_line = sorted_lines[0][0]
print 'nearest line:',nearest_line
# find the nearest index
row= all_lines.index(nearest_line)
index = self.completer.model().index(row,0)
self.completer.popup().setCurrentIndex(index)
# self.completer.popup().scrollTo(index)
# QTimer.singleShot(0,lambda: self.completer.popup().scrollTo(index,QAbstractItemView.PositionAtCenter))
self.scroll_to_current_line(index)
def scroll_to_current_line(self,index):
self.completer.popup().scrollTo(index,QAbstractItemView.PositionAtCenter)
# self.first_down=False
# self.completer.popup().setCurrentIndex(index)
self.completer.popup().setFocus()
def repop(self):
print 'yeah repop'
# self.test('cancel_completer')
def pop(self, symbol):
print 'symbol:', symbol
if isinstance(symbol, bool) or str(symbol) == u'@':
print 'is @'
text = ''
else:
text = symbol
self.completer.splitPath(text)
self.lineedit.setFocus()
# self.completer.complete()
# QTimer.singleShot(0,self.completer.complete)
def goto_line(self, index):
# print self.completer.model().sourceModel().symbol_data[x[0].row()][0]
line = index.data(Qt.UserRole).toPyObject()
print 'goto_line:', line
block = self.textedit.document().findBlockByLineNumber(line-1)
# make the line appear in middle
# get first line visible
cursor = self.textedit.cursorForPosition(QPoint(2,2))
first_line = cursor.blockNumber()+1
# print 'first line:',first_line
# get last line visible
bottom_right=QPoint(self.textedit.viewport().width()-1,self.textedit.viewport().height()-1)
end_pos= self.textedit.cursorForPosition(bottom_right).position()
cursor.setPosition(end_pos)
last_line = cursor.blockNumber()+1
# print 'last line:',last_line
if first_line<=line<=last_line:
new_line=line
else:
mid = (last_line-first_line)/2
if line<first_line:
new_line = line -mid
elif line > last_line:
new_line = line +mid
dummy_block = self.textedit.document().findBlockByLineNumber(new_line-1)
cursor.setPosition(dummy_block.position())
self.textedit.setTextCursor(cursor)
# highlight
cursor.setPosition(block.position())
self.textedit.setTextCursor(cursor)
cursor.movePosition(QTextCursor.StartOfBlock)
cursor.select(QTextCursor.LineUnderCursor)
self.textedit.setTextCursor(cursor)
def dedent_code(self, code):
indents = []
for line in code.splitlines():
_logger.debug('---> %s', line)
spaces = len(line)-len(line.lstrip(' '))
if len(line.strip(' ')) > 0:
indents.append(spaces)
indent = min(indents)
_logger.debug('min indents: %s', indent)
new_code = ''
for line in code.splitlines():
if len(line) > indent:
_logger.debug('working on: %s', line)
new_code += line[indent:]+'\n'
else:
new_code += line+'\n'
return new_code
def get_current_tab_text(self):
text = self.textedit.toPlainText()
return text
class MyModel(QStandardItemModel):
def __init__(self, parent=None):
super(MyModel, self).__init__(parent)
def data(self, index, role):
symbol = self.symbol_data[index.row()]
if role == Qt.DisplayRole:
if symbol[1] == 'class':
return symbol[2]
elif symbol[1] == 'def':
return re.search('[^\()]*', symbol[2]).group()+'(...)'
elif role == Qt.UserRole:
return symbol[0]
def setup(self, data):
self.symbol_data = data
for n, type_, name in data:
item = QStandardItem(name)
self.appendRow(item)
class MyLineEdit(QLineEdit):
def focusOutEvent(self,event):
print 'yeah focus out!'
pass
def focusInEvent(self,event):
print 'yeah focus in!'
# self.completer().popup().show()
super(MyLineEdit,self).focusInEvent(event)
# def keyPressEvent(self, event):
# if event.key() == Qt.Key_Backspace:
# event.accept()
# super(MyLineEdit, self).keyPressEvent(event)
# if self.text() == '':
# self.completer().splitPath('')
# self.completer().complete()
class CustomQCompleter3(QCompleter):
def __init__(self, parent=None):
super(CustomQCompleter, self).__init__(parent)
self.local_completion_prefix = ""
self.source_model = None
def setModel(self, model):
self.source_model = model
self._proxy = QSortFilterProxyModel(
self)
self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
self._proxy.setSourceModel(model)
super(CustomQCompleter, self).setModel(self._proxy)
def splitPath(self, path):
self.local_completion_prefix = str(path)
self._proxy.setFilterFixedString(path)
return ""
class CustomQCompleter(QCompleter):
def __init__(self, parent=None):
super(CustomQCompleter, self).__init__(parent)
self.source_model = None
self.first_down = True
self.local_completion_prefix = ""
def setModel(self, model):
self.source_model = model
# self._proxy = QSortFilterProxyModel(self, filterCaseSensitivity=Qt.CaseInsensitive)
self._proxy = QSortFilterProxyModel(
self)
self._proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
self._proxy.setSourceModel(model)
super(CustomQCompleter, self).setModel(self._proxy)
def splitPath(self, path):
# print 'splitPath=[%s]' % path
# if str(path).startswith('@'):
# path=path[1:]
self.local_completion_prefix = str(path)
self._proxy.setFilterFixedString(path)
# self.complete()
return ""
def eventFilter(self, obj, event):
if event.type() == QEvent.KeyPress:
'This is used to mute the connection to clear lineedit'
if event.key() in (Qt.Key_Down, Qt.Key_Up):
# print 'yeah', self.popup()
curIndex = self.popup().currentIndex()
# print self.popup().selectionModel().selectedIndexes()
# selList = self.popup().selectionModel().selectedIndexes()
# print 'selList:',selList
if event.key() == Qt.Key_Down:
# curIndex = self.popup().selectionModel().createIndex( curIndex.row()+1,curIndex.column())
# print 'row count:', self._proxy.rowCount()
# the_index =self.popup().selectionModel().currentIndex()
# src_index = self._proxy.mapToSource(curIndex)
# print 'current source row:', src_index.row()
# print 'line proxy:', self._proxy.data(curIndex).toPyObject()[0]
# print 'line :', self._proxy.data(curIndex,Qt.DisplayRole)
# .toPyObject()[0]
if curIndex.row() == self._proxy.rowCount()-1:
print 'already last row'
if self._proxy.rowCount() == 1:
# return False
pass
# go to that line
else:
self.popup().setCurrentIndex(curIndex)
return True
else:
if not self.local_completion_prefix:
print ' manual add 1'
nextIndex = self._proxy.index(curIndex.row() + 1, curIndex.column());
next_nextIndex = self._proxy.index(nextIndex.row() + 1, curIndex.column());
# if not next_nextIndex.isValid():
# next_nextIndex=nextIndex
self.popup().setCurrentIndex(nextIndex)
first_visible_row = self.popup().indexAt(QPoint(0,0)).row()
# print first_visible_row,self.maxVisibleItems(),nextIndex.row()
# if we have not reached last visible row
if first_visible_row+self.maxVisibleItems()-1<=nextIndex.row():
# if we are at last row
if next_nextIndex.isValid():
self.popup().scrollTo(next_nextIndex,QAbstractItemView.PositionAtBottom)
else:
self.popup().scrollToBottom()
else:
# if current index is the 7th index
self.popup().scrollTo(next_nextIndex)
if self._proxy.rowCount() == curIndex.row() + 1:
print 'last row'
#
return True
else:
print 'pass'
pass
# qApp.processEvents()
# QTimer.singleShot(0,lambda:self.popup().scrollTo(nextIndex,QAbstractItemView.EnsureVisible))
# super(CustomQCompleter, self).eventFilter(obj, event)
pass
# return True
else:
if curIndex.row() == 0:
print 'already first row'
return True
else:
if not self.local_completion_prefix:
lastIndex = self._proxy.index(curIndex.row() - 1, curIndex.column());
self.popup().setCurrentIndex(lastIndex)
first_visible_row = self.popup().indexAt(QPoint(0,0)).row()
if lastIndex.row()>=first_visible_row:
self.popup().scrollTo(lastIndex)
else:
self.popup().scrollTo(lastIndex,QAbstractItemView.PositionAtTop)
return True
else:
pass
print 'current row:', curIndex.row()
# print 'line original:', curIndex.data(Qt.UserRole).toPyObject()
# self.popup().setCurrentIndex(curIndex)
# if selList==[]:
# print 'selList empty:',curIndex
# self.popup().setCurrentIndex(curIndex)
# return True
if curIndex.row() == 0 and self.first_down:
print 'already row 0 first'
self.popup().setCurrentIndex(curIndex)
self.first_down = False
return True
# QTimer.singleShot(0,lambda :self.popup().setCurrentIndex(curIndex))
# else:
# print 'selList has something:',curIndex.row()
# return True
super(CustomQCompleter, self).eventFilter( obj,event)
# print 'after super'
return False
def get_symbols(file_content=open('/home/oglop/tmp/enhancedScriptEditor.py').read()):
# if not os.path.isfile(file):
# print 'get symbols from file'
# f = open(file)
# elif isinstance(file,str):
# print 'get symbols from string'
# import StringIO
# f = StringIO.StringIO(file)
symbols = []
symbol_regex = re.compile('^(\s*)(class|def)\s*([^\(\s]+\([^\(]*\))')
# with open(file) as f:
# try:
for n, line in enumerate(file_content.split('\n')):
if symbol_regex.search(line):
groups = symbol_regex.search(line).groups()
symbols.append((n+1, groups[1], groups[0]+groups[2]))
print n+1,[str(x) for x in groups]
# finally:
# f.close()
return symbols
def get_mel_global(var):
try:
return mel.eval('$tmp_var1=%s' % var)
except:
return mel.eval('$tmp_var2=%s' % var)
# This can remove the filter we installed
# qApp.removeEventFilter(filter)
myFilter = None
gCommandExecuterTabs = None
def main():
global myFilter
global gCommandExecuterTabs
gCommandExecuterTabs = get_mel_global('$gCommandExecuterTabs')
myFilter = CustomFilter()
# qApp.removeEventFilter(filter)
qApp.installEventFilter(myFilter)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment