Show More
@@ -0,0 +1,22 b'' | |||||
|
1 | """ A Qt API selector that can be used to switch between PyQt and PySide. | |||
|
2 | """ | |||
|
3 | ||||
|
4 | import os | |||
|
5 | ||||
|
6 | # Use PyQt by default until PySide is stable. | |||
|
7 | qt_api = os.environ.get('QT_API', 'pyqt') | |||
|
8 | ||||
|
9 | if qt_api == 'pyqt': | |||
|
10 | # For PySide compatibility, use the new string API that automatically | |||
|
11 | # converts QStrings to unicode Python strings. | |||
|
12 | import sip | |||
|
13 | sip.setapi('QString', 2) | |||
|
14 | ||||
|
15 | from PyQt4 import QtCore, QtGui, QtSvg | |||
|
16 | ||||
|
17 | # Alias PyQt-specific functions for PySide compatibility. | |||
|
18 | QtCore.Signal = QtCore.pyqtSignal | |||
|
19 | QtCore.Slot = QtCore.pyqtSlot | |||
|
20 | ||||
|
21 | else: | |||
|
22 | from PySide import QtCore, QtGui, QtSvg |
@@ -9,7 +9,7 b' from collections import namedtuple' | |||||
9 | import re |
|
9 | import re | |
10 |
|
10 | |||
11 | # System library imports |
|
11 | # System library imports | |
12 |
from |
|
12 | from IPython.external.qt import QtCore, QtGui | |
13 |
|
13 | |||
14 | #----------------------------------------------------------------------------- |
|
14 | #----------------------------------------------------------------------------- | |
15 | # Constants and datatypes |
|
15 | # Constants and datatypes |
@@ -2,7 +2,7 b'' | |||||
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # System library imports |
|
4 | # System library imports | |
5 |
from |
|
5 | from IPython.external.qt import QtCore, QtGui | |
6 |
|
6 | |||
7 |
|
7 | |||
8 | class BracketMatcher(QtCore.QObject): |
|
8 | class BracketMatcher(QtCore.QObject): | |
@@ -42,8 +42,7 b' class BracketMatcher(QtCore.QObject):' | |||||
42 | """ |
|
42 | """ | |
43 | # Decide what character to search for and what direction to search in. |
|
43 | # Decide what character to search for and what direction to search in. | |
44 | document = self._text_edit.document() |
|
44 | document = self._text_edit.document() | |
45 |
|
|
45 | start_char = document.characterAt(position) | |
46 | start_char = qchar.toAscii() |
|
|||
47 | search_char = self._opening_map.get(start_char) |
|
46 | search_char = self._opening_map.get(start_char) | |
48 | if search_char: |
|
47 | if search_char: | |
49 | increment = 1 |
|
48 | increment = 1 | |
@@ -55,9 +54,9 b' class BracketMatcher(QtCore.QObject):' | |||||
55 | return -1 |
|
54 | return -1 | |
56 |
|
55 | |||
57 | # Search for the character. |
|
56 | # Search for the character. | |
|
57 | char = start_char | |||
58 | depth = 0 |
|
58 | depth = 0 | |
59 | while position >= 0 and position < document.characterCount(): |
|
59 | while position >= 0 and position < document.characterCount(): | |
60 | char = qchar.toAscii() |
|
|||
61 | if char == start_char: |
|
60 | if char == start_char: | |
62 | depth += 1 |
|
61 | depth += 1 | |
63 | elif char == search_char: |
|
62 | elif char == search_char: | |
@@ -65,7 +64,7 b' class BracketMatcher(QtCore.QObject):' | |||||
65 | if depth == 0: |
|
64 | if depth == 0: | |
66 | break |
|
65 | break | |
67 | position += increment |
|
66 | position += increment | |
68 |
|
|
67 | char = document.characterAt(position) | |
69 | else: |
|
68 | else: | |
70 | position = -1 |
|
69 | position = -1 | |
71 | return position |
|
70 | return position |
@@ -1,9 +1,10 b'' | |||||
1 | # Standard library imports |
|
1 | # Standard library imports | |
2 | import re |
|
2 | import re | |
3 | from textwrap import dedent |
|
3 | from textwrap import dedent | |
|
4 | from unicodedata import category | |||
4 |
|
5 | |||
5 | # System library imports |
|
6 | # System library imports | |
6 |
from |
|
7 | from IPython.external.qt import QtCore, QtGui | |
7 |
|
8 | |||
8 |
|
9 | |||
9 | class CallTipWidget(QtGui.QLabel): |
|
10 | class CallTipWidget(QtGui.QLabel): | |
@@ -184,11 +185,10 b' class CallTipWidget(QtGui.QLabel):' | |||||
184 | """ |
|
185 | """ | |
185 | commas = depth = 0 |
|
186 | commas = depth = 0 | |
186 | document = self._text_edit.document() |
|
187 | document = self._text_edit.document() | |
187 |
|
|
188 | char = document.characterAt(position) | |
188 | while (position > 0 and qchar.isPrint() and |
|
189 | # Search until a match is found or a non-printable character is | |
189 | # Need to check explicitly for line/paragraph separators: |
|
190 | # encountered. | |
190 | qchar.unicode() not in (0x2028, 0x2029)): |
|
191 | while category(char) != 'Cc' and position > 0: | |
191 | char = qchar.toAscii() |
|
|||
192 | if char == ',' and depth == 0: |
|
192 | if char == ',' and depth == 0: | |
193 | commas += 1 |
|
193 | commas += 1 | |
194 | elif char == ')': |
|
194 | elif char == ')': | |
@@ -200,7 +200,7 b' class CallTipWidget(QtGui.QLabel):' | |||||
200 | break |
|
200 | break | |
201 | depth -= 1 |
|
201 | depth -= 1 | |
202 | position += 1 if forward else -1 |
|
202 | position += 1 if forward else -1 | |
203 |
|
|
203 | char = document.characterAt(position) | |
204 | else: |
|
204 | else: | |
205 | position = -1 |
|
205 | position = -1 | |
206 | return position, commas |
|
206 | return position, commas |
@@ -1,5 +1,5 b'' | |||||
1 | # System library imports |
|
1 | # System library imports | |
2 |
from |
|
2 | from IPython.external.qt import QtCore, QtGui | |
3 |
|
3 | |||
4 |
|
4 | |||
5 | class CompletionWidget(QtGui.QListWidget): |
|
5 | class CompletionWidget(QtGui.QListWidget): |
@@ -5,14 +5,15 b'' | |||||
5 | #----------------------------------------------------------------------------- |
|
5 | #----------------------------------------------------------------------------- | |
6 |
|
6 | |||
7 | # Standard library imports |
|
7 | # Standard library imports | |
|
8 | import os | |||
8 | from os.path import commonprefix |
|
9 | from os.path import commonprefix | |
9 | import re |
|
10 | import re | |
10 | import os |
|
|||
11 | import sys |
|
11 | import sys | |
12 | from textwrap import dedent |
|
12 | from textwrap import dedent | |
|
13 | from unicodedata import category | |||
13 |
|
14 | |||
14 | # System library imports |
|
15 | # System library imports | |
15 |
from |
|
16 | from IPython.external.qt import QtCore, QtGui | |
16 |
|
17 | |||
17 | # Local imports |
|
18 | # Local imports | |
18 | from IPython.config.configurable import Configurable |
|
19 | from IPython.config.configurable import Configurable | |
@@ -22,6 +23,16 b' from ansi_code_processor import QtAnsiCodeProcessor' | |||||
22 | from completion_widget import CompletionWidget |
|
23 | from completion_widget import CompletionWidget | |
23 |
|
24 | |||
24 | #----------------------------------------------------------------------------- |
|
25 | #----------------------------------------------------------------------------- | |
|
26 | # Functions | |||
|
27 | #----------------------------------------------------------------------------- | |||
|
28 | ||||
|
29 | def is_letter_or_number(char): | |||
|
30 | """ Returns whether the specified unicode character is a letter or a number. | |||
|
31 | """ | |||
|
32 | cat = category(char) | |||
|
33 | return cat.startswith('L') or cat.startswith('N') | |||
|
34 | ||||
|
35 | #----------------------------------------------------------------------------- | |||
25 | # Classes |
|
36 | # Classes | |
26 | #----------------------------------------------------------------------------- |
|
37 | #----------------------------------------------------------------------------- | |
27 |
|
38 | |||
@@ -78,16 +89,16 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
78 | #------ Signals ------------------------------------------------------------ |
|
89 | #------ Signals ------------------------------------------------------------ | |
79 |
|
90 | |||
80 | # Signals that indicate ConsoleWidget state. |
|
91 | # Signals that indicate ConsoleWidget state. | |
81 |
copy_available = QtCore. |
|
92 | copy_available = QtCore.Signal(bool) | |
82 |
redo_available = QtCore. |
|
93 | redo_available = QtCore.Signal(bool) | |
83 |
undo_available = QtCore. |
|
94 | undo_available = QtCore.Signal(bool) | |
84 |
|
95 | |||
85 | # Signal emitted when paging is needed and the paging style has been |
|
96 | # Signal emitted when paging is needed and the paging style has been | |
86 | # specified as 'custom'. |
|
97 | # specified as 'custom'. | |
87 |
custom_page_requested = QtCore. |
|
98 | custom_page_requested = QtCore.Signal(object) | |
88 |
|
99 | |||
89 | # Signal emitted when the font is changed. |
|
100 | # Signal emitted when the font is changed. | |
90 |
font_changed = QtCore. |
|
101 | font_changed = QtCore.Signal(QtGui.QFont) | |
91 |
|
102 | |||
92 | #------ Protected class variables ------------------------------------------ |
|
103 | #------ Protected class variables ------------------------------------------ | |
93 |
|
104 | |||
@@ -267,7 +278,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
267 | elif etype == QtCore.QEvent.Drop and obj == self._control.viewport(): |
|
278 | elif etype == QtCore.QEvent.Drop and obj == self._control.viewport(): | |
268 | cursor = self._control.cursorForPosition(event.pos()) |
|
279 | cursor = self._control.cursorForPosition(event.pos()) | |
269 | if self._in_buffer(cursor.position()): |
|
280 | if self._in_buffer(cursor.position()): | |
270 |
text = |
|
281 | text = event.mimeData().text() | |
271 | self._insert_plain_text_into_buffer(cursor, text) |
|
282 | self._insert_plain_text_into_buffer(cursor, text) | |
272 |
|
283 | |||
273 | # Qt is expecting to get something here--drag and drop occurs in its |
|
284 | # Qt is expecting to get something here--drag and drop occurs in its | |
@@ -328,7 +339,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
328 | """ Returns whether text can be pasted from the clipboard. |
|
339 | """ Returns whether text can be pasted from the clipboard. | |
329 | """ |
|
340 | """ | |
330 | if self._control.textInteractionFlags() & QtCore.Qt.TextEditable: |
|
341 | if self._control.textInteractionFlags() & QtCore.Qt.TextEditable: | |
331 |
return |
|
342 | return bool(QtGui.QApplication.clipboard().text()) | |
332 | return False |
|
343 | return False | |
333 |
|
344 | |||
334 | def can_export(self): |
|
345 | def can_export(self): | |
@@ -469,7 +480,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
469 |
|
480 | |||
470 | cursor = self._get_end_cursor() |
|
481 | cursor = self._get_end_cursor() | |
471 | cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor) |
|
482 | cursor.setPosition(self._prompt_pos, QtGui.QTextCursor.KeepAnchor) | |
472 |
input_buffer = |
|
483 | input_buffer = cursor.selection().toPlainText() | |
473 |
|
484 | |||
474 | # Strip out continuation prompts. |
|
485 | # Strip out continuation prompts. | |
475 | return input_buffer.replace('\n' + self._continuation_prompt, '\n') |
|
486 | return input_buffer.replace('\n' + self._continuation_prompt, '\n') | |
@@ -532,7 +543,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
532 |
|
543 | |||
533 | # Remove any trailing newline, which confuses the GUI and forces the |
|
544 | # Remove any trailing newline, which confuses the GUI and forces the | |
534 | # user to backspace. |
|
545 | # user to backspace. | |
535 |
text = |
|
546 | text = QtGui.QApplication.clipboard().text(mode).rstrip() | |
536 | self._insert_plain_text_into_buffer(cursor, dedent(text)) |
|
547 | self._insert_plain_text_into_buffer(cursor, dedent(text)) | |
537 |
|
548 | |||
538 | def print_(self, printer = None): |
|
549 | def print_(self, printer = None): | |
@@ -895,7 +906,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
895 | while cursor.movePosition(QtGui.QTextCursor.NextBlock): |
|
906 | while cursor.movePosition(QtGui.QTextCursor.NextBlock): | |
896 | temp_cursor = QtGui.QTextCursor(cursor) |
|
907 | temp_cursor = QtGui.QTextCursor(cursor) | |
897 | temp_cursor.select(QtGui.QTextCursor.BlockUnderCursor) |
|
908 | temp_cursor.select(QtGui.QTextCursor.BlockUnderCursor) | |
898 |
text = |
|
909 | text = temp_cursor.selection().toPlainText().lstrip() | |
899 | if not text.startswith(prompt): |
|
910 | if not text.startswith(prompt): | |
900 | break |
|
911 | break | |
901 | else: |
|
912 | else: | |
@@ -1088,7 +1099,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1088 | elif not self._executing: |
|
1099 | elif not self._executing: | |
1089 | cursor.movePosition(QtGui.QTextCursor.End, |
|
1100 | cursor.movePosition(QtGui.QTextCursor.End, | |
1090 | QtGui.QTextCursor.KeepAnchor) |
|
1101 | QtGui.QTextCursor.KeepAnchor) | |
1091 |
at_end = cursor.selectedText(). |
|
1102 | at_end = len(cursor.selectedText().strip()) == 0 | |
1092 | single_line = (self._get_end_cursor().blockNumber() == |
|
1103 | single_line = (self._get_end_cursor().blockNumber() == | |
1093 | self._get_prompt_cursor().blockNumber()) |
|
1104 | self._get_prompt_cursor().blockNumber()) | |
1094 | if (at_end or shift_down or single_line) and not ctrl_down: |
|
1105 | if (at_end or shift_down or single_line) and not ctrl_down: | |
@@ -1430,7 +1441,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1430 | cursor.movePosition(QtGui.QTextCursor.StartOfBlock) |
|
1441 | cursor.movePosition(QtGui.QTextCursor.StartOfBlock) | |
1431 | cursor.movePosition(QtGui.QTextCursor.EndOfBlock, |
|
1442 | cursor.movePosition(QtGui.QTextCursor.EndOfBlock, | |
1432 | QtGui.QTextCursor.KeepAnchor) |
|
1443 | QtGui.QTextCursor.KeepAnchor) | |
1433 |
return |
|
1444 | return cursor.selection().toPlainText() | |
1434 |
|
1445 | |||
1435 | def _get_cursor(self): |
|
1446 | def _get_cursor(self): | |
1436 | """ Convenience method that returns a cursor for the current position. |
|
1447 | """ Convenience method that returns a cursor for the current position. | |
@@ -1506,10 +1517,10 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1506 | document = self._control.document() |
|
1517 | document = self._control.document() | |
1507 | position -= 1 |
|
1518 | position -= 1 | |
1508 | while position >= self._prompt_pos and \ |
|
1519 | while position >= self._prompt_pos and \ | |
1509 |
not document.characterAt(position) |
|
1520 | not is_letter_or_number(document.characterAt(position)): | |
1510 | position -= 1 |
|
1521 | position -= 1 | |
1511 | while position >= self._prompt_pos and \ |
|
1522 | while position >= self._prompt_pos and \ | |
1512 |
document.characterAt(position) |
|
1523 | is_letter_or_number(document.characterAt(position)): | |
1513 | position -= 1 |
|
1524 | position -= 1 | |
1514 | cursor = self._control.textCursor() |
|
1525 | cursor = self._control.textCursor() | |
1515 | cursor.setPosition(position + 1) |
|
1526 | cursor.setPosition(position + 1) | |
@@ -1523,10 +1534,10 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1523 | document = self._control.document() |
|
1534 | document = self._control.document() | |
1524 | end = self._get_end_cursor().position() |
|
1535 | end = self._get_end_cursor().position() | |
1525 | while position < end and \ |
|
1536 | while position < end and \ | |
1526 |
not document.characterAt(position) |
|
1537 | not is_letter_or_number(document.characterAt(position)): | |
1527 | position += 1 |
|
1538 | position += 1 | |
1528 | while position < end and \ |
|
1539 | while position < end and \ | |
1529 |
document.characterAt(position) |
|
1540 | is_letter_or_number(document.characterAt(position)): | |
1530 | position += 1 |
|
1541 | position += 1 | |
1531 | cursor = self._control.textCursor() |
|
1542 | cursor = self._control.textCursor() | |
1532 | cursor.setPosition(position) |
|
1543 | cursor.setPosition(position) | |
@@ -1573,7 +1584,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1573 | self._insert_html(cursor, html) |
|
1584 | self._insert_html(cursor, html) | |
1574 | end = cursor.position() |
|
1585 | end = cursor.position() | |
1575 | cursor.setPosition(start, QtGui.QTextCursor.KeepAnchor) |
|
1586 | cursor.setPosition(start, QtGui.QTextCursor.KeepAnchor) | |
1576 |
text = |
|
1587 | text = cursor.selection().toPlainText() | |
1577 |
|
1588 | |||
1578 | cursor.setPosition(end) |
|
1589 | cursor.setPosition(end) | |
1579 | cursor.endEditBlock() |
|
1590 | cursor.endEditBlock() | |
@@ -1614,7 +1625,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1614 | must be in the input buffer), ensuring that continuation prompts are |
|
1625 | must be in the input buffer), ensuring that continuation prompts are | |
1615 | inserted as necessary. |
|
1626 | inserted as necessary. | |
1616 | """ |
|
1627 | """ | |
1617 |
lines = |
|
1628 | lines = text.splitlines(True) | |
1618 | if lines: |
|
1629 | if lines: | |
1619 | cursor.beginEditBlock() |
|
1630 | cursor.beginEditBlock() | |
1620 | cursor.insertText(lines[0]) |
|
1631 | cursor.insertText(lines[0]) | |
@@ -1821,7 +1832,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):' | |||||
1821 | if cursor.position() > 0: |
|
1832 | if cursor.position() > 0: | |
1822 | cursor.movePosition(QtGui.QTextCursor.Left, |
|
1833 | cursor.movePosition(QtGui.QTextCursor.Left, | |
1823 | QtGui.QTextCursor.KeepAnchor) |
|
1834 | QtGui.QTextCursor.KeepAnchor) | |
1824 |
if |
|
1835 | if cursor.selection().toPlainText() != '\n': | |
1825 | self._append_plain_text('\n') |
|
1836 | self._append_plain_text('\n') | |
1826 |
|
1837 | |||
1827 | # Write the prompt. |
|
1838 | # Write the prompt. |
@@ -7,7 +7,7 b' import time' | |||||
7 |
|
7 | |||
8 | # System library imports |
|
8 | # System library imports | |
9 | from pygments.lexers import PythonLexer |
|
9 | from pygments.lexers import PythonLexer | |
10 |
from |
|
10 | from IPython.external.qt import QtCore, QtGui | |
11 |
|
11 | |||
12 | # Local imports |
|
12 | # Local imports | |
13 | from IPython.core.inputsplitter import InputSplitter, transform_classic_prompt |
|
13 | from IPython.core.inputsplitter import InputSplitter, transform_classic_prompt | |
@@ -32,13 +32,13 b' class FrontendHighlighter(PygmentsHighlighter):' | |||||
32 | self._frontend = frontend |
|
32 | self._frontend = frontend | |
33 | self.highlighting_on = False |
|
33 | self.highlighting_on = False | |
34 |
|
34 | |||
35 |
def highlightBlock(self, |
|
35 | def highlightBlock(self, string): | |
36 | """ Highlight a block of text. Reimplemented to highlight selectively. |
|
36 | """ Highlight a block of text. Reimplemented to highlight selectively. | |
37 | """ |
|
37 | """ | |
38 | if not self.highlighting_on: |
|
38 | if not self.highlighting_on: | |
39 | return |
|
39 | return | |
40 |
|
40 | |||
41 | # The input to this function is unicode string that may contain |
|
41 | # The input to this function is a unicode string that may contain | |
42 | # paragraph break characters, non-breaking spaces, etc. Here we acquire |
|
42 | # paragraph break characters, non-breaking spaces, etc. Here we acquire | |
43 | # the string as plain text so we can compare it. |
|
43 | # the string as plain text so we can compare it. | |
44 | current_block = self.currentBlock() |
|
44 | current_block = self.currentBlock() | |
@@ -53,11 +53,11 b' class FrontendHighlighter(PygmentsHighlighter):' | |||||
53 | # Don't highlight the part of the string that contains the prompt. |
|
53 | # Don't highlight the part of the string that contains the prompt. | |
54 | if string.startswith(prompt): |
|
54 | if string.startswith(prompt): | |
55 | self._current_offset = len(prompt) |
|
55 | self._current_offset = len(prompt) | |
56 |
|
|
56 | string = string[len(prompt):] | |
57 | else: |
|
57 | else: | |
58 | self._current_offset = 0 |
|
58 | self._current_offset = 0 | |
59 |
|
59 | |||
60 |
PygmentsHighlighter.highlightBlock(self, |
|
60 | PygmentsHighlighter.highlightBlock(self, string) | |
61 |
|
61 | |||
62 | def rehighlightBlock(self, block): |
|
62 | def rehighlightBlock(self, block): | |
63 | """ Reimplemented to temporarily enable highlighting if disabled. |
|
63 | """ Reimplemented to temporarily enable highlighting if disabled. | |
@@ -81,20 +81,20 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
81 | # An option and corresponding signal for overriding the default kernel |
|
81 | # An option and corresponding signal for overriding the default kernel | |
82 | # interrupt behavior. |
|
82 | # interrupt behavior. | |
83 | custom_interrupt = Bool(False) |
|
83 | custom_interrupt = Bool(False) | |
84 |
custom_interrupt_requested = QtCore. |
|
84 | custom_interrupt_requested = QtCore.Signal() | |
85 |
|
85 | |||
86 | # An option and corresponding signals for overriding the default kernel |
|
86 | # An option and corresponding signals for overriding the default kernel | |
87 | # restart behavior. |
|
87 | # restart behavior. | |
88 | custom_restart = Bool(False) |
|
88 | custom_restart = Bool(False) | |
89 |
custom_restart_kernel_died = QtCore. |
|
89 | custom_restart_kernel_died = QtCore.Signal(float) | |
90 |
custom_restart_requested = QtCore. |
|
90 | custom_restart_requested = QtCore.Signal() | |
91 |
|
91 | |||
92 | # Emitted when an 'execute_reply' has been received from the kernel and |
|
92 | # Emitted when an 'execute_reply' has been received from the kernel and | |
93 | # processed by the FrontendWidget. |
|
93 | # processed by the FrontendWidget. | |
94 |
executed = QtCore. |
|
94 | executed = QtCore.Signal(object) | |
95 |
|
95 | |||
96 | # Emitted when an exit request has been received from the kernel. |
|
96 | # Emitted when an exit request has been received from the kernel. | |
97 |
exit_requested = QtCore. |
|
97 | exit_requested = QtCore.Signal() | |
98 |
|
98 | |||
99 | # Protected class variables. |
|
99 | # Protected class variables. | |
100 | _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) |
|
100 | _CallTipRequest = namedtuple('_CallTipRequest', ['id', 'pos']) | |
@@ -153,7 +153,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
153 | def copy(self): |
|
153 | def copy(self): | |
154 | """ Copy the currently selected text to the clipboard, removing prompts. |
|
154 | """ Copy the currently selected text to the clipboard, removing prompts. | |
155 | """ |
|
155 | """ | |
156 |
text = |
|
156 | text = self._control.textCursor().selection().toPlainText() | |
157 | if text: |
|
157 | if text: | |
158 | lines = map(transform_classic_prompt, text.splitlines()) |
|
158 | lines = map(transform_classic_prompt, text.splitlines()) | |
159 | text = '\n'.join(lines) |
|
159 | text = '\n'.join(lines) | |
@@ -491,7 +491,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
491 | # Decide if it makes sense to show a call tip |
|
491 | # Decide if it makes sense to show a call tip | |
492 | cursor = self._get_cursor() |
|
492 | cursor = self._get_cursor() | |
493 | cursor.movePosition(QtGui.QTextCursor.Left) |
|
493 | cursor.movePosition(QtGui.QTextCursor.Left) | |
494 |
if cursor.document().characterAt(cursor.position()) |
|
494 | if cursor.document().characterAt(cursor.position()) != '(': | |
495 | return False |
|
495 | return False | |
496 | context = self._get_context(cursor) |
|
496 | context = self._get_context(cursor) | |
497 | if not context: |
|
497 | if not context: | |
@@ -534,7 +534,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):' | |||||
534 | cursor = self._get_cursor() |
|
534 | cursor = self._get_cursor() | |
535 | cursor.movePosition(QtGui.QTextCursor.StartOfBlock, |
|
535 | cursor.movePosition(QtGui.QTextCursor.StartOfBlock, | |
536 | QtGui.QTextCursor.KeepAnchor) |
|
536 | QtGui.QTextCursor.KeepAnchor) | |
537 |
text = |
|
537 | text = cursor.selection().toPlainText() | |
538 | return self._completion_lexer.get_context(text) |
|
538 | return self._completion_lexer.get_context(text) | |
539 |
|
539 | |||
540 | def _process_execute_abort(self, msg): |
|
540 | def _process_execute_abort(self, msg): |
@@ -1,5 +1,5 b'' | |||||
1 | # System library imports |
|
1 | # System library imports | |
2 |
from |
|
2 | from IPython.external.qt import QtGui | |
3 |
|
3 | |||
4 | # Local imports |
|
4 | # Local imports | |
5 | from console_widget import ConsoleWidget |
|
5 | from console_widget import ConsoleWidget |
@@ -17,7 +17,7 b' from subprocess import Popen' | |||||
17 | from textwrap import dedent |
|
17 | from textwrap import dedent | |
18 |
|
18 | |||
19 | # System library imports |
|
19 | # System library imports | |
20 |
from |
|
20 | from IPython.external.qt import QtCore, QtGui | |
21 |
|
21 | |||
22 | # Local imports |
|
22 | # Local imports | |
23 | from IPython.core.inputsplitter import IPythonInputSplitter, \ |
|
23 | from IPython.core.inputsplitter import IPythonInputSplitter, \ | |
@@ -56,7 +56,7 b' class IPythonWidget(FrontendWidget):' | |||||
56 | # an editor is needed for a file. This overrides 'editor' and 'editor_line' |
|
56 | # an editor is needed for a file. This overrides 'editor' and 'editor_line' | |
57 | # settings. |
|
57 | # settings. | |
58 | custom_edit = Bool(False) |
|
58 | custom_edit = Bool(False) | |
59 |
custom_edit_requested = QtCore. |
|
59 | custom_edit_requested = QtCore.Signal(object, object) | |
60 |
|
60 | |||
61 | # A command for invoking a system text editor. If the string contains a |
|
61 | # A command for invoking a system text editor. If the string contains a | |
62 | # {filename} format specifier, it will be used. Otherwise, the filename will |
|
62 | # {filename} format specifier, it will be used. Otherwise, the filename will | |
@@ -227,7 +227,7 b' class IPythonWidget(FrontendWidget):' | |||||
227 | """ Copy the currently selected text to the clipboard, removing prompts |
|
227 | """ Copy the currently selected text to the clipboard, removing prompts | |
228 | if possible. |
|
228 | if possible. | |
229 | """ |
|
229 | """ | |
230 |
text = |
|
230 | text = self._control.textCursor().selection().toPlainText() | |
231 | if text: |
|
231 | if text: | |
232 | lines = map(transform_ipy_prompt, text.splitlines()) |
|
232 | lines = map(transform_ipy_prompt, text.splitlines()) | |
233 | text = '\n'.join(lines) |
|
233 | text = '\n'.join(lines) | |
@@ -325,7 +325,7 b' class IPythonWidget(FrontendWidget):' | |||||
325 |
|
325 | |||
326 | # Load code from the %loadpy magic, if necessary. |
|
326 | # Load code from the %loadpy magic, if necessary. | |
327 | if self._code_to_load is not None: |
|
327 | if self._code_to_load is not None: | |
328 |
self.input_buffer = dedent( |
|
328 | self.input_buffer = dedent(self._code_to_load.rstrip()) | |
329 | self._code_to_load = None |
|
329 | self._code_to_load = None | |
330 |
|
330 | |||
331 | def _show_interpreter_prompt_for_reply(self, msg): |
|
331 | def _show_interpreter_prompt_for_reply(self, msg): |
@@ -6,8 +6,9 b'' | |||||
6 | #----------------------------------------------------------------------------- |
|
6 | #----------------------------------------------------------------------------- | |
7 |
|
7 | |||
8 | # Systemm library imports |
|
8 | # Systemm library imports | |
9 |
from |
|
9 | from IPython.external.qt import QtGui | |
10 | from pygments.styles import get_all_styles |
|
10 | from pygments.styles import get_all_styles | |
|
11 | ||||
11 | # Local imports |
|
12 | # Local imports | |
12 | from IPython.external.argparse import ArgumentParser |
|
13 | from IPython.external.argparse import ArgumentParser | |
13 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget |
|
14 | from IPython.frontend.qt.console.frontend_widget import FrontendWidget | |
@@ -82,7 +83,8 b' class MainWindow(QtGui.QMainWindow):' | |||||
82 | justthis.setShortcut('N') |
|
83 | justthis.setShortcut('N') | |
83 | closeall = QtGui.QPushButton("&Yes, quit everything", self) |
|
84 | closeall = QtGui.QPushButton("&Yes, quit everything", self) | |
84 | closeall.setShortcut('Y') |
|
85 | closeall.setShortcut('Y') | |
85 |
box = QtGui.QMessageBox(QtGui.QMessageBox.Question, |
|
86 | box = QtGui.QMessageBox(QtGui.QMessageBox.Question, | |
|
87 | title, msg) | |||
86 | box.setInformativeText(info) |
|
88 | box.setInformativeText(info) | |
87 | box.addButton(cancel) |
|
89 | box.addButton(cancel) | |
88 | box.addButton(justthis, QtGui.QMessageBox.NoRole) |
|
90 | box.addButton(justthis, QtGui.QMessageBox.NoRole) |
@@ -1,5 +1,5 b'' | |||||
1 | # System library imports. |
|
1 | # System library imports. | |
2 |
from |
|
2 | from IPython.external.qt import QtGui | |
3 | from pygments.formatters.html import HtmlFormatter |
|
3 | from pygments.formatters.html import HtmlFormatter | |
4 | from pygments.lexer import RegexLexer, _TokenType, Text, Error |
|
4 | from pygments.lexer import RegexLexer, _TokenType, Text, Error | |
5 | from pygments.lexers import PythonLexer |
|
5 | from pygments.lexers import PythonLexer | |
@@ -99,12 +99,10 b' class PygmentsHighlighter(QtGui.QSyntaxHighlighter):' | |||||
99 | self._lexer = lexer if lexer else PythonLexer() |
|
99 | self._lexer = lexer if lexer else PythonLexer() | |
100 | self.set_style('default') |
|
100 | self.set_style('default') | |
101 |
|
101 | |||
102 |
def highlightBlock(self, |
|
102 | def highlightBlock(self, string): | |
103 | """ Highlight a block of text. |
|
103 | """ Highlight a block of text. | |
104 | """ |
|
104 | """ | |
105 | qstring = unicode(qstring) |
|
|||
106 | prev_data = self.currentBlock().previous().userData() |
|
105 | prev_data = self.currentBlock().previous().userData() | |
107 |
|
||||
108 | if prev_data is not None: |
|
106 | if prev_data is not None: | |
109 | self._lexer._saved_state_stack = prev_data.syntax_stack |
|
107 | self._lexer._saved_state_stack = prev_data.syntax_stack | |
110 | elif hasattr(self._lexer, '_saved_state_stack'): |
|
108 | elif hasattr(self._lexer, '_saved_state_stack'): | |
@@ -112,7 +110,7 b' class PygmentsHighlighter(QtGui.QSyntaxHighlighter):' | |||||
112 |
|
110 | |||
113 | # Lex the text using Pygments |
|
111 | # Lex the text using Pygments | |
114 | index = 0 |
|
112 | index = 0 | |
115 |
for token, text in self._lexer.get_tokens( |
|
113 | for token, text in self._lexer.get_tokens(string): | |
116 | length = len(text) |
|
114 | length = len(text) | |
117 | self.setFormat(index, length, self._get_format(token)) |
|
115 | self.setFormat(index, length, self._get_format(token)) | |
118 | index += length |
|
116 | index += length |
@@ -1,8 +1,10 b'' | |||||
1 |
# S |
|
1 | # Standard libary imports. | |
|
2 | from base64 import decodestring | |||
2 | import os |
|
3 | import os | |
3 | import re |
|
4 | import re | |
4 | from base64 import decodestring |
|
5 | ||
5 | from PyQt4 import QtCore, QtGui |
|
6 | # System libary imports. | |
|
7 | from IPython.external.qt import QtCore, QtGui | |||
6 |
|
8 | |||
7 | # Local imports |
|
9 | # Local imports | |
8 | from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image |
|
10 | from IPython.frontend.qt.svg import save_svg, svg_to_clipboard, svg_to_image | |
@@ -171,7 +173,7 b' class RichIPythonWidget(IPythonWidget):' | |||||
171 | QTextImageFormat that references it. |
|
173 | QTextImageFormat that references it. | |
172 | """ |
|
174 | """ | |
173 | document = self._control.document() |
|
175 | document = self._control.document() | |
174 |
name = |
|
176 | name = str(image.cacheKey()) | |
175 | document.addResource(QtGui.QTextDocument.ImageResource, |
|
177 | document.addResource(QtGui.QTextDocument.ImageResource, | |
176 | QtCore.QUrl(name), image) |
|
178 | QtCore.QUrl(name), image) | |
177 | format = QtGui.QTextImageFormat() |
|
179 | format = QtGui.QTextImageFormat() |
@@ -2,7 +2,7 b'' | |||||
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # System library imports. |
|
4 | # System library imports. | |
5 |
from |
|
5 | from IPython.external.qt import QtCore | |
6 |
|
6 | |||
7 | # IPython imports. |
|
7 | # IPython imports. | |
8 | from IPython.utils.traitlets import Type |
|
8 | from IPython.utils.traitlets import Type | |
@@ -14,10 +14,10 b' from util import MetaQObjectHasTraits, SuperQObject' | |||||
14 | class SocketChannelQObject(SuperQObject): |
|
14 | class SocketChannelQObject(SuperQObject): | |
15 |
|
15 | |||
16 | # Emitted when the channel is started. |
|
16 | # Emitted when the channel is started. | |
17 |
started = QtCore. |
|
17 | started = QtCore.Signal() | |
18 |
|
18 | |||
19 | # Emitted when the channel is stopped. |
|
19 | # Emitted when the channel is stopped. | |
20 |
stopped = QtCore. |
|
20 | stopped = QtCore.Signal() | |
21 |
|
21 | |||
22 | #--------------------------------------------------------------------------- |
|
22 | #--------------------------------------------------------------------------- | |
23 | # 'ZmqSocketChannel' interface |
|
23 | # 'ZmqSocketChannel' interface | |
@@ -39,16 +39,16 b' class SocketChannelQObject(SuperQObject):' | |||||
39 | class QtXReqSocketChannel(SocketChannelQObject, XReqSocketChannel): |
|
39 | class QtXReqSocketChannel(SocketChannelQObject, XReqSocketChannel): | |
40 |
|
40 | |||
41 | # Emitted when any message is received. |
|
41 | # Emitted when any message is received. | |
42 |
message_received = QtCore. |
|
42 | message_received = QtCore.Signal(object) | |
43 |
|
43 | |||
44 | # Emitted when a reply has been received for the corresponding request |
|
44 | # Emitted when a reply has been received for the corresponding request | |
45 | # type. |
|
45 | # type. | |
46 |
execute_reply = QtCore. |
|
46 | execute_reply = QtCore.Signal(object) | |
47 |
complete_reply = QtCore. |
|
47 | complete_reply = QtCore.Signal(object) | |
48 |
object_info_reply = QtCore. |
|
48 | object_info_reply = QtCore.Signal(object) | |
49 |
|
49 | |||
50 | # Emitted when the first reply comes back. |
|
50 | # Emitted when the first reply comes back. | |
51 |
first_reply = QtCore. |
|
51 | first_reply = QtCore.Signal() | |
52 |
|
52 | |||
53 | # Used by the first_reply signal logic to determine if a reply is the |
|
53 | # Used by the first_reply signal logic to determine if a reply is the | |
54 | # first. |
|
54 | # first. | |
@@ -87,29 +87,29 b' class QtXReqSocketChannel(SocketChannelQObject, XReqSocketChannel):' | |||||
87 | class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel): |
|
87 | class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel): | |
88 |
|
88 | |||
89 | # Emitted when any message is received. |
|
89 | # Emitted when any message is received. | |
90 |
message_received = QtCore. |
|
90 | message_received = QtCore.Signal(object) | |
91 |
|
91 | |||
92 | # Emitted when a message of type 'stream' is received. |
|
92 | # Emitted when a message of type 'stream' is received. | |
93 |
stream_received = QtCore. |
|
93 | stream_received = QtCore.Signal(object) | |
94 |
|
94 | |||
95 | # Emitted when a message of type 'pyin' is received. |
|
95 | # Emitted when a message of type 'pyin' is received. | |
96 |
pyin_received = QtCore. |
|
96 | pyin_received = QtCore.Signal(object) | |
97 |
|
97 | |||
98 | # Emitted when a message of type 'pyout' is received. |
|
98 | # Emitted when a message of type 'pyout' is received. | |
99 |
pyout_received = QtCore. |
|
99 | pyout_received = QtCore.Signal(object) | |
100 |
|
100 | |||
101 | # Emitted when a message of type 'pyerr' is received. |
|
101 | # Emitted when a message of type 'pyerr' is received. | |
102 |
pyerr_received = QtCore. |
|
102 | pyerr_received = QtCore.Signal(object) | |
103 |
|
103 | |||
104 | # Emitted when a message of type 'display_data' is received |
|
104 | # Emitted when a message of type 'display_data' is received | |
105 | display_data_received = QtCore.pyqtSignal(object) |
|
105 | display_data_received = QtCore.pyqtSignal(object) | |
106 |
|
106 | |||
107 | # Emitted when a crash report message is received from the kernel's |
|
107 | # Emitted when a crash report message is received from the kernel's | |
108 | # last-resort sys.excepthook. |
|
108 | # last-resort sys.excepthook. | |
109 |
crash_received = QtCore. |
|
109 | crash_received = QtCore.Signal(object) | |
110 |
|
110 | |||
111 | # Emitted when a shutdown is noticed. |
|
111 | # Emitted when a shutdown is noticed. | |
112 |
shutdown_reply_received = QtCore. |
|
112 | shutdown_reply_received = QtCore.Signal(object) | |
113 |
|
113 | |||
114 | #--------------------------------------------------------------------------- |
|
114 | #--------------------------------------------------------------------------- | |
115 | # 'SubSocketChannel' interface |
|
115 | # 'SubSocketChannel' interface | |
@@ -138,10 +138,10 b' class QtSubSocketChannel(SocketChannelQObject, SubSocketChannel):' | |||||
138 | class QtRepSocketChannel(SocketChannelQObject, RepSocketChannel): |
|
138 | class QtRepSocketChannel(SocketChannelQObject, RepSocketChannel): | |
139 |
|
139 | |||
140 | # Emitted when any message is received. |
|
140 | # Emitted when any message is received. | |
141 |
message_received = QtCore. |
|
141 | message_received = QtCore.Signal(object) | |
142 |
|
142 | |||
143 | # Emitted when an input request is received. |
|
143 | # Emitted when an input request is received. | |
144 |
input_requested = QtCore. |
|
144 | input_requested = QtCore.Signal(object) | |
145 |
|
145 | |||
146 | #--------------------------------------------------------------------------- |
|
146 | #--------------------------------------------------------------------------- | |
147 | # 'RepSocketChannel' interface |
|
147 | # 'RepSocketChannel' interface | |
@@ -162,7 +162,7 b' class QtRepSocketChannel(SocketChannelQObject, RepSocketChannel):' | |||||
162 | class QtHBSocketChannel(SocketChannelQObject, HBSocketChannel): |
|
162 | class QtHBSocketChannel(SocketChannelQObject, HBSocketChannel): | |
163 |
|
163 | |||
164 | # Emitted when the kernel has died. |
|
164 | # Emitted when the kernel has died. | |
165 |
kernel_died = QtCore. |
|
165 | kernel_died = QtCore.Signal(object) | |
166 |
|
166 | |||
167 | #--------------------------------------------------------------------------- |
|
167 | #--------------------------------------------------------------------------- | |
168 | # 'HBSocketChannel' interface |
|
168 | # 'HBSocketChannel' interface | |
@@ -182,10 +182,10 b' class QtKernelManager(KernelManager, SuperQObject):' | |||||
182 | __metaclass__ = MetaQObjectHasTraits |
|
182 | __metaclass__ = MetaQObjectHasTraits | |
183 |
|
183 | |||
184 | # Emitted when the kernel manager has started listening. |
|
184 | # Emitted when the kernel manager has started listening. | |
185 |
started_channels = QtCore. |
|
185 | started_channels = QtCore.Signal() | |
186 |
|
186 | |||
187 | # Emitted when the kernel manager has stopped listening. |
|
187 | # Emitted when the kernel manager has stopped listening. | |
188 |
stopped_channels = QtCore. |
|
188 | stopped_channels = QtCore.Signal() | |
189 |
|
189 | |||
190 | # Use Qt-specific channel classes that emit signals. |
|
190 | # Use Qt-specific channel classes that emit signals. | |
191 | sub_channel_class = Type(QtSubSocketChannel) |
|
191 | sub_channel_class = Type(QtSubSocketChannel) |
@@ -2,7 +2,7 b'' | |||||
2 | """ |
|
2 | """ | |
3 |
|
3 | |||
4 | # System library imports. |
|
4 | # System library imports. | |
5 |
from |
|
5 | from IPython.external.qt import QtCore, QtGui, QtSvg | |
6 |
|
6 | |||
7 |
|
7 | |||
8 | def save_svg(string, parent=None): |
|
8 | def save_svg(string, parent=None): | |
@@ -11,7 +11,7 b' def save_svg(string, parent=None):' | |||||
11 | Parameters: |
|
11 | Parameters: | |
12 | ----------- |
|
12 | ----------- | |
13 | string : str |
|
13 | string : str | |
14 |
A Python string |
|
14 | A Python string containing a SVG document. | |
15 |
|
15 | |||
16 | parent : QWidget, optional |
|
16 | parent : QWidget, optional | |
17 | The parent to use for the file dialog. |
|
17 | The parent to use for the file dialog. | |
@@ -41,14 +41,10 b' def svg_to_clipboard(string):' | |||||
41 | Parameters: |
|
41 | Parameters: | |
42 | ----------- |
|
42 | ----------- | |
43 | string : str |
|
43 | string : str | |
44 |
A Python string |
|
44 | A Python string containing a SVG document. | |
45 | """ |
|
45 | """ | |
46 | if isinstance(string, basestring): |
|
|||
47 | bytes = QtCore.QByteArray(string) |
|
|||
48 | else: |
|
|||
49 | bytes = string.toAscii() |
|
|||
50 | mime_data = QtCore.QMimeData() |
|
46 | mime_data = QtCore.QMimeData() | |
51 |
mime_data.setData('image/svg+xml', |
|
47 | mime_data.setData('image/svg+xml', string) | |
52 | QtGui.QApplication.clipboard().setMimeData(mime_data) |
|
48 | QtGui.QApplication.clipboard().setMimeData(mime_data) | |
53 |
|
49 | |||
54 | def svg_to_image(string, size=None): |
|
50 | def svg_to_image(string, size=None): | |
@@ -57,7 +53,7 b' def svg_to_image(string, size=None):' | |||||
57 | Parameters: |
|
53 | Parameters: | |
58 | ----------- |
|
54 | ----------- | |
59 | string : str |
|
55 | string : str | |
60 |
A Python string |
|
56 | A Python string containing a SVG document. | |
61 |
|
57 | |||
62 | size : QSize, optional |
|
58 | size : QSize, optional | |
63 | The size of the image that is produced. If not specified, the SVG |
|
59 | The size of the image that is produced. If not specified, the SVG | |
@@ -72,12 +68,7 b' def svg_to_image(string, size=None):' | |||||
72 | -------- |
|
68 | -------- | |
73 | A QImage of format QImage.Format_ARGB32. |
|
69 | A QImage of format QImage.Format_ARGB32. | |
74 | """ |
|
70 | """ | |
75 | if isinstance(string, basestring): |
|
71 | renderer = QtSvg.QSvgRenderer(QtCore.QByteArray(string)) | |
76 | bytes = QtCore.QByteArray.fromRawData(string) # shallow copy |
|
|||
77 | else: |
|
|||
78 | bytes = string.toAscii() |
|
|||
79 |
|
||||
80 | renderer = QtSvg.QSvgRenderer(bytes) |
|
|||
81 | if not renderer.isValid(): |
|
72 | if not renderer.isValid(): | |
82 | raise ValueError('Invalid SVG data.') |
|
73 | raise ValueError('Invalid SVG data.') | |
83 |
|
74 |
@@ -5,7 +5,7 b'' | |||||
5 | import inspect |
|
5 | import inspect | |
6 |
|
6 | |||
7 | # System library imports. |
|
7 | # System library imports. | |
8 |
from |
|
8 | from IPython.external.qt import QtCore, QtGui | |
9 |
|
9 | |||
10 | # IPython imports. |
|
10 | # IPython imports. | |
11 | from IPython.utils.traitlets import HasTraits, TraitType |
|
11 | from IPython.utils.traitlets import HasTraits, TraitType |
General Comments 0
You need to be logged in to leave comments.
Login now