Basic formatting and small corrections

This commit is contained in:
Olivier Keshavjee 2015-06-25 13:41:55 +02:00
parent 546eb4d819
commit ef1ba855e7
10 changed files with 254 additions and 48 deletions

View file

@ -448,6 +448,8 @@ class outlineItem():
e = QTextEdit()
e.setHtml(self._data[Outline.text])
self._data[Outline.text] = e.toPlainText()
elif oldType in ["txt", "t2t"] and data == "html":
self._data[Outline.text] = self._data[Outline.text].replace("\n", "<br>")
# Setting data
self._data[Outline(column)] = data

View file

@ -11,25 +11,26 @@ class basicHighlighter(QSyntaxHighlighter):
self.editor = editor
self._misspelledColor = Qt.red
self._defaultBlockFormat = QTextBlockFormat()
self._defaultCharFormat = QTextCharFormat()
def setDefaultBlockFormat(self, bf):
self._defaultBlockFormat = bf
self.rehighlight()
def setDefaultCharFormat(self, cf):
self._defaultCharFormat = cf
self.rehighlight()
def setMisspelledColor(self, color):
self._misspelledColor = color
def setStyle(self):
"""t2tHighlighter needs to reupdates styles on some occasions (see themes.py).
This lazy function allow to update without checking the type of highlighter.
"""
pass
def highlightBlock(self, text):
"""Apply syntax highlighting to the given block of text.
"""
QTextCursor(self.currentBlock()).setBlockFormat(self._defaultBlockFormat)
#self.setFormat(0, len(text), self._defaultCharFormat)
# Spell checking
# Based on http://john.nachtimwald.com/2009/08/22/qplaintextedit-with-in-line-spell-check/

View file

@ -2,7 +2,108 @@
# -*- coding: utf-8 -*-
from qt import *
import re
def t2tFormatSelection(editor, style):
"""
Formats the current selection of ``editor`` in the format given by ``style``,
style being:
0: bold
1: italic
2: underline
3: strike
4: code
5: tagged
"""
print("Formatting:", style)
formatChar = "*/_-`'"[style]
# FIXME: doesn't work if selection spans over several blocks.
cursor = editor.textCursor()
cursor.beginEditBlock()
if cursor.hasSelection():
pass
else:
# If no selection, selects the word in which the cursor is now
cursor.movePosition(QTextCursor.StartOfWord,
QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.EndOfWord,
QTextCursor.KeepAnchor)
if not cursor.hasSelection():
# No selection means we are outside a word,
# so we insert markup and put cursor in the middle
cursor.insertText(formatChar * 4)
cursor.setPosition(cursor.position() - 2)
cursor.endEditBlock()
editor.setTextCursor(cursor)
# And we are done
return
# Get start and end of selection
start = cursor.selectionStart() - cursor.block().position()
end = cursor.selectionEnd() - cursor.block().position()
if start > end:
start, end = end, start
# Whole block
text = cursor.block().text()
# Adjusts selection to exclude the markup
while text[start:start + 1] == formatChar:
start += 1
while text[end - 1:end] ==formatChar:
end -= 1
# Get the text without formatting, and the array of format
fText, fArray = textToFormatArrayNoMarkup(text)
# Get the translated start and end of selection in the unformated text
tStart, tEnd = translateSelectionToUnformattedText(text, start, end)
# We want only the array that contains the propper formatting
propperArray = fArray[style]
if 0 in propperArray[tStart:tEnd]:
# have some unformated text in the selection, so we format the
# whole selection
propperArray = propperArray[:tStart] + [1] * \
(tEnd - tStart) + propperArray[tEnd:]
else:
# The whole selection is already formatted, so we remove the
# formatting
propperArray = propperArray[:tStart] + [0] * \
(tEnd - tStart) + propperArray[tEnd:]
fArray = fArray[0:style] + [propperArray] + fArray[style + 1:]
text = reformatText(fText, fArray)
# Replaces the whole block
cursor.movePosition(QTextCursor.StartOfBlock)
cursor.movePosition(QTextCursor.EndOfBlock,
QTextCursor.KeepAnchor)
cursor.insertText(text)
cursor.setPosition(end + cursor.block().position())
cursor.endEditBlock()
editor.setTextCursor(cursor)
def t2tClearFormat(editor):
"Clears format on ``editor``'s current selection."
cursor = editor.textCursor()
cursor.beginEditBlock()
text = cursor.selectedText()
t, a = textToFormatArrayNoMarkup(text)
cursor.insertText(t)
cursor.endEditBlock()
editor.setTextCursor(cursor)
def textToFormatArray(text):
"""
@ -131,24 +232,24 @@ def reformatText(text, markupArray):
for k in range(len(markupArray)):
m = markupArray[k]
open = False # Are we in an openned markup
_open = False # Are we in an _openned markup
d = 0
alreadySeen = []
for i in range(len(text)):
insert = False
if not open and m[i] == 1:
if not _open and m[i] == 1:
insert = True
open = True
_open = True
if open and m[i] == 0:
if _open and m[i] == 0:
insert = True
open = False
if open and m[i] > 1:
_open = False
if _open and m[i] > 1:
z = i
while m[z] == m[i]: z += 1
if m[z] != 1 and not m[i] in alreadySeen:
insert = True
open = False
_open = False
alreadySeen.append(m[i])
if insert:
rText += markup[k]
@ -161,7 +262,7 @@ def reformatText(text, markupArray):
alreadySeen = []
d += 2
rText += text[i]
if open:
if _open:
rText += markup[k]
for j in range(len(markupArray)):
# The other array still have the same length
@ -175,12 +276,18 @@ def reformatText(text, markupArray):
## Clean up
# Exclude first and last space of the markup
for markup in ["\*", "/", "_", "-", "`", "\'"]:
r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')')
r.setMinimal(True)
text.replace(r, "\\2\\1\\3\\4")
r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')')
r.setMinimal(True)
text.replace(r, "\\1\\2\\4\\3")
#r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')')
#r.setMinimal(True)
#text.replace(r, "\\2\\1\\3\\4")
text = re.sub(r'(' + markup * 2 + ')(\s+?)(.+?)(' + markup * 2 + ')',
"\\2\\1\\3\\4",
text)
#r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')')
#r.setMinimal(True)
#text.replace(r, "\\1\\2\\4\\3")
text = re.sub(r'(' + markup * 2 + ')(.+?)(\s+?)(' + markup * 2 + ')',
"\\1\\2\\4\\3",
text)
return text

View file

@ -27,9 +27,10 @@ class t2tHighlighter (QSyntaxHighlighter):
# Stupid variable that fixes the loss of QTextBlockUserData.
self.thisDocument = editor.document()
self.style = t2tHighlighterStyle(self.editor, style)
self._defaultBlockFormat = QTextBlockFormat()
self._defaultCharFormat = QTextCharFormat()
self._misspelledColor = Qt.red
self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style)
self.inDocRules = []
@ -65,6 +66,11 @@ class t2tHighlighter (QSyntaxHighlighter):
def setDefaultBlockFormat(self, bf):
self._defaultBlockFormat = bf
self.rehighlight()
def setDefaultCharFormat(self, cf):
self._defaultCharFormat = cf
self.setStyle()
self.rehighlight()
def setMisspelledColor(self, color):
self._misspelledColor = color
@ -95,7 +101,8 @@ class t2tHighlighter (QSyntaxHighlighter):
op = self.style.format(State.MARKUP)
self.setFormat(0, len(text), self.style.format(State.DEFAULT))
#self.setFormat(0, len(text), self.style.format(State.DEFAULT))
#self.setFormat(0, len(text), self._defaultCharFormat)
# InDocRules: is it a settings which might have a specific rule,
# a comment which contains color infos, or a include conf?
@ -341,13 +348,6 @@ class t2tHighlighter (QSyntaxHighlighter):
self.setFormat(word_object.start(),
word_object.end() - word_object.start(), format)
# If a title was changed, we emit the corresponding signal
if oldState in State.TITLES or \
self.currentBlockState() in State.TITLES:
self.editor.structureChanged.emit()
#FIXME: si du texte est supprimé et qu'il y a un titre dedans,
# cela n'est pas détecté et le signal pas émis.
def identifyBlock(self, block):
"""Identifies what block type it is, and set userState and userData
accordingly."""
@ -490,7 +490,7 @@ class t2tHighlighter (QSyntaxHighlighter):
def setStyle(self, style="Default"):
if style in t2tHighlighterStyle.validStyles:
self.style = t2tHighlighterStyle(self.editor, style)
self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style)
else:
self.style = None
self.rehighlight()

View file

@ -14,13 +14,14 @@ class t2tHighlighterStyle ():
validStyles = ["Default", "Monospace"]
def __init__(self, editor, name="Default"):
def __init__(self, editor, charFormat, name="Default"):
self.editor = editor
self.name = name
self._defaultCharFormat = charFormat
# Defaults
self.defaultFontPointSize = self.editor.defaultFontPointSize
#self.defaultFontPointSize = self.editor.defaultFontPointSize
self.defaultFontFamily = qApp.font().family()
self.tabStopWidth = 40
@ -36,7 +37,7 @@ class t2tHighlighterStyle ():
f = self.styles[i]
f.setFontFixedPitch(True)
f.setFontFamily(self.defaultFontFamily)
f.setFontPointSize(self.defaultFontPointSize)
f.setFontPointSize(self._defaultCharFormat.font().pointSize())
self.styles[i] = f
def setupEditor(self):
@ -127,7 +128,7 @@ class t2tHighlighterStyle ():
n = blockUserData.getUserData(block).leadingSpaces() + 1
f = QFontMetrics(QFont(self.defaultFontFamily,
self.defaultFontPointSize))
self._defaultCharFormat.font().pointSize()))
fm = f.width(" " * n +
blockUserData.getUserData(block).listSymbol())
blockFormat.setTextIndent(-fm)
@ -144,11 +145,10 @@ class t2tHighlighterStyle ():
"""
_color = QColor()
_format = QTextCharFormat()
#size = self.defaultFontPointSize
#_format.setFontFamily(self.defaultFontFamily)
_format.setFont(self.editor.font())
size = _format.fontPointSize()
#_format = QTextCharFormat()
#_format.setFont(self.editor.font())
#size = _format.fontPointSize()
_format = QTextCharFormat(self._defaultCharFormat)
# Base
if base: _format = base
@ -184,7 +184,7 @@ class t2tHighlighterStyle ():
if preset in State.TITLES:
style = "bold"
color = "darkRed" if State.titleLevel(preset) % 2 == 1 else "blue"
size = (self.defaultFontPointSize
size = (self._defaultCharFormat.font().pointSize()
+ 11 - 2 * State.titleLevel(preset))
if preset == State.TABLE_HEADER:

View file

@ -22,12 +22,14 @@ class textFormat(QWidget, Ui_textFormat):
"Left": [self.btnLeft, "format-justify-left", self.tr("CTRL+L")],
"Center": [self.btnCenter, "format-justify-center", self.tr("CTRL+E")],
"Right": [self.btnRight, "format-justify-right", self.tr("CTRL+R")],
"Justify": [self.btnJustify, "format-justify-fill", self.tr("CTRL+J")],
}
for f in formats:
val = formats[f]
a = QAction(QIcon.fromTheme(val[1]), f, self)
a.setShortcut(val[2])
a.setToolTip("Format {} ({})".format(f, val[2]))
a.triggered.connect(self.setFormat)
val[0].setDefaultAction(a)

View file

@ -70,6 +70,11 @@ class Ui_textFormat(object):
self.btnRight.setIcon(icon)
self.btnRight.setObjectName("btnRight")
self.horizontalLayout_2.addWidget(self.btnRight)
self.btnJustify = QtWidgets.QToolButton(self.align)
self.btnJustify.setText("")
self.btnJustify.setIcon(icon)
self.btnJustify.setObjectName("btnJustify")
self.horizontalLayout_2.addWidget(self.btnJustify)
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.horizontalLayout_2.addItem(spacerItem3)
self.horizontalLayout_3.addWidget(self.align)

View file

@ -149,6 +149,18 @@
</property>
</widget>
</item>
<item>
<widget class="QToolButton" name="btnJustify">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_4">
<property name="orientation">

View file

@ -212,12 +212,18 @@ def setThemeEditorDatas(editor, themeDatas, pixmap, screenRect):
editor.setTabStopWidth(themeDatas["Spacings/TabWidth"])
editor.document().setIndentWidth(themeDatas["Spacings/TabWidth"])
f = QFont()
f.fromString(themeDatas["Text/Font"])
editor.setFont(f)
editor.highlighter.setMisspelledColor(QColor(themeDatas["Text/Misspelled"]))
editor.highlighter.setStyle() # Reupdates highlighter styles
cf = QTextCharFormat()
f = QFont()
f.fromString(themeDatas["Text/Font"])
cf.setFont(f)
editor.highlighter.setDefaultCharFormat(cf)
#f = QFont()
#f.fromString(themeDatas["Text/Font"])
editor.setFont(f)
def addThemePreviewText(pixmap, themeDatas, screenRect):

View file

@ -4,10 +4,12 @@
from qt import *
from enums import *
from ui.editors.t2tHighlighter import *
from ui.editors.t2tFunctions import *
from ui.editors.basicHighlighter import *
from ui.editors.textFormat import *
from models.outlineModel import *
from functions import *
import re
try:
import enchant
@ -220,7 +222,8 @@ class textEditView(QTextEdit):
if self._textFormat == "html":
if self.toHtml() != toString(self._model.data(self._index)):
#print(" Updating html")
self.document().setHtml(toString(self._model.data(self._index)))
html = self._model.data(self._index)
self.document().setHtml(toString(html))
else:
if self.toPlainText() != toString(self._model.data(self._index)):
#print(" Updating plaintext")
@ -261,7 +264,11 @@ class textEditView(QTextEdit):
if self.toHtml() != self._model.data(self._index):
#print(" Submitting html")
self._updating = True
self._model.setData(self._index, self.toHtml())
html = self.toHtml()
# We don't store font settings
html = re.sub(r"font-family:.*?;", "", html)
html = re.sub(r"font-size:.*?;", "", html)
self._model.setData(self._index, html)
self._updating = False
else:
if self.toPlainText() != self._model.data(self._index):
@ -405,6 +412,70 @@ class textEditView(QTextEdit):
tF.setTextEdit(self)
def applyFormat(self, _format):
#FIXME
print(_format)
if self._textFormat == "html":
if _format == "Clear":
cursor = self.textCursor()
if _format == "Clear":
fmt = QTextCharFormat()
cursor.setCharFormat(fmt)
bf = QTextBlockFormat()
cursor.setBlockFormat(bf)
elif _format in ["Bold", "Italic", "Underline"]:
cursor = self.textCursor()
# If no selection, selects the word in which the cursor is now
if not cursor.hasSelection():
cursor.movePosition(QTextCursor.StartOfWord,
QTextCursor.MoveAnchor)
cursor.movePosition(QTextCursor.EndOfWord,
QTextCursor.KeepAnchor)
fmt = cursor.charFormat()
if _format == "Bold":
fmt.setFontWeight(QFont.Bold if fmt.fontWeight() != QFont.Bold else QFont.Normal)
elif _format == "Italic":
fmt.setFontItalic(not fmt.fontItalic())
elif _format == "Underline":
fmt.setFontUnderline(not fmt.fontUnderline())
fmt2 = QTextCharFormat()
fmt2.setFontWeight(fmt.fontWeight())
fmt2.setFontItalic(fmt.fontItalic())
fmt2.setFontUnderline(fmt.fontUnderline())
cursor.mergeCharFormat(fmt2)
elif _format in ["Left", "Center", "Right", "Justify"]:
cursor = self.textCursor()
bf = cursor.blockFormat()
bf.setAlignment(
Qt.AlignLeft if _format == "Left" else
Qt.AlignHCenter if _format == "Center" else
Qt.AlignRight if _format == "Right" else
Qt.AlignJustify)
print(bf.alignment() == Qt.AlignLeft)
cursor.mergeBlockFormat(bf)
self.setTextCursor(cursor)
elif self._textFormat == "t2t":
if _format == "Bold":
t2tFormatSelection(self, 0)
elif _format == "Italic":
t2tFormatSelection(self, 1)
elif _format == "Underline":
t2tFormatSelection(self, 2)
elif _format == "Clear":
t2tClearFormat(self)