24 #include <QtGui/QKeyEvent>
25 #include <QtGui/QTextCursor>
26 #include <QtGui/QTextList>
27 #include <QtGui/QTextBlock>
28 #include <QtGui/QTextDocumentFragment>
33 NestedListHelper::NestedListHelper(
QTextEdit *te)
36 listBottomMargin = 12;
41 NestedListHelper::~NestedListHelper()
45 bool NestedListHelper::handleBeforeKeyPressEvent(QKeyEvent *event)
47 QTextCursor cursor = textEdit->textCursor();
50 if ((event->key() != Qt::Key_Backspace)
51 || (!cursor.currentList()))
56 if (!cursor.hasSelection()
57 && cursor.currentList()
58 &&
event->key() == Qt::Key_Backspace
59 && cursor.atBlockStart()) {
64 if (cursor.hasSelection()
65 && cursor.currentList()
66 &&
event->key() == Qt::Key_Backspace
67 && cursor.atBlockStart()) {
80 cursor.removeSelectedText();
87 bool NestedListHelper::canIndent()
const
89 if ((textEdit->textCursor().block().isValid())
92 QTextBlock block = textEdit->textCursor().block();
93 QTextBlock prevBlock = textEdit->textCursor().block().previous();
94 if (block.textList()) {
95 if (prevBlock.textList()) {
96 return block.textList()->format().indent() <= prevBlock.textList()->format().indent();
105 bool NestedListHelper::canDedent()
const
107 QTextBlock thisBlock = textEdit->textCursor().block();
108 QTextBlock nextBlock = thisBlock.next();
109 if (thisBlock.isValid()) {
110 int nextBlockIndent = 0;
111 int thisBlockIndent = 0;
112 if (nextBlock.isValid() && nextBlock.textList())
113 nextBlockIndent = nextBlock.textList()->format().indent();
114 if (thisBlock.textList()) {
115 thisBlockIndent = thisBlock.textList()->format().indent();
116 if (thisBlockIndent >= nextBlockIndent)
117 return thisBlock.textList()->format().indent() > 0;
124 bool NestedListHelper::handleAfterKeyPressEvent(QKeyEvent *event)
127 if ((event->key() != Qt::Key_Backspace)
128 && (event->key() != Qt::Key_Return))
131 QTextCursor cursor = textEdit->textCursor();
132 bool handled =
false;
134 if (!cursor.hasSelection() && cursor.currentList()) {
138 QTextBlock currentBlock = cursor.block();
139 if (cursor.currentList()->count() == cursor.currentList()->itemNumber(currentBlock) + 1) {
141 if (currentBlock.next().textList()) {
146 if ((event->key() == Qt::Key_Return) || (event->key() == Qt::Key_Backspace)) {
147 reformatBoundingItemSpacing();
158 bool NestedListHelper::handleAfterDropEvent(QDropEvent *dropEvent)
161 QTextCursor cursor = topOfSelection();
163 QTextBlock droppedBlock = cursor.block();
164 int firstDroppedItemIndent = droppedBlock.textList()->format().indent();
166 int minimumIndent = droppedBlock.previous().textList()->format().indent();
168 if (firstDroppedItemIndent < minimumIndent) {
169 cursor = QTextCursor(droppedBlock);
170 QTextListFormat fmt = droppedBlock.textList()->format();
171 fmt.setIndent(minimumIndent);
172 QTextList* list = cursor.createList(fmt);
174 int endOfDrop = bottomOfSelection().position();
175 while (droppedBlock.next().position() < endOfDrop) {
176 droppedBlock = droppedBlock.next();
177 if (droppedBlock.textList()->format().indent() != firstDroppedItemIndent) {
181 list->add(droppedBlock);
186 reformatBoundingItemSpacing();
190 void NestedListHelper::processList(QTextList* list)
192 QTextBlock block = list->item(0);
193 int thisListIndent = list->format().indent();
195 QTextCursor cursor = QTextCursor(block);
196 list = cursor.createList(list->format());
197 bool processingSubList =
false;
198 while (block.next().textList() != 0) {
199 block = block.next();
201 QTextList* nextList = block.textList();
202 int nextItemIndent = nextList->format().indent();
203 if (nextItemIndent < thisListIndent) {
205 }
else if (nextItemIndent > thisListIndent) {
206 if (processingSubList) {
209 processingSubList =
true;
210 processList(nextList);
212 processingSubList =
false;
220 void NestedListHelper::reformatList(QTextBlock block)
222 if (block.textList()) {
223 int minimumIndent = block.textList()->format().indent();
226 while (block.previous().textList() != 0) {
227 if (block.previous().textList()->format().indent() < minimumIndent) {
230 block = block.previous();
233 processList(block.textList());
238 void NestedListHelper::reformatList()
240 QTextCursor cursor = textEdit->textCursor();
241 reformatList(cursor.block());
244 QTextCursor NestedListHelper::topOfSelection()
246 QTextCursor cursor = textEdit->textCursor();
248 if (cursor.hasSelection())
249 cursor.setPosition(qMin(cursor.position(), cursor.anchor()));
253 QTextCursor NestedListHelper::bottomOfSelection()
255 QTextCursor cursor = textEdit->textCursor();
257 if (cursor.hasSelection())
258 cursor.setPosition(qMax(cursor.position(), cursor.anchor()));
262 void NestedListHelper::handleOnIndentMore()
264 QTextCursor cursor = textEdit->textCursor();
266 QTextListFormat listFmt;
267 if (!cursor.currentList()) {
269 QTextListFormat::Style style;
270 cursor = topOfSelection();
271 cursor.movePosition(QTextCursor::PreviousBlock);
272 if (cursor.currentList()) {
273 style = cursor.currentList()->format().style();
276 cursor = bottomOfSelection();
277 cursor.movePosition(QTextCursor::NextBlock);
279 if (cursor.currentList()) {
280 style = cursor.currentList()->format().style();
282 style = QTextListFormat::ListDisc;
285 handleOnBulletType(style);
287 listFmt = cursor.currentList()->format();
288 listFmt.setIndent(listFmt.indent() + 1);
290 cursor.createList(listFmt);
294 reformatBoundingItemSpacing();
297 void NestedListHelper::handleOnIndentLess()
299 QTextCursor cursor = textEdit->textCursor();
300 QTextList* currentList = cursor.currentList();
303 QTextListFormat listFmt;
304 listFmt = currentList->format();
305 if (listFmt.indent() > 1) {
306 listFmt.setIndent(listFmt.indent() - 1);
307 cursor.createList(listFmt);
308 reformatList(cursor.block());
310 QTextBlockFormat bfmt;
311 bfmt.setObjectIndex(-1);
312 cursor.setBlockFormat(bfmt);
313 reformatList(cursor.block().next());
315 reformatBoundingItemSpacing();
319 void NestedListHelper::handleOnBulletType(
int styleIndex)
321 QTextCursor cursor = textEdit->textCursor();
322 if (styleIndex != 0) {
323 QTextListFormat::Style style = (QTextListFormat::Style)styleIndex;
324 QTextList *currentList = cursor.currentList();
325 QTextListFormat listFmt;
327 cursor.beginEditBlock();
330 listFmt = currentList->format();
331 listFmt.setStyle(style);
332 currentList->setFormat(listFmt);
334 listFmt.setStyle(style);
335 cursor.createList(listFmt);
338 cursor.endEditBlock();
340 QTextBlockFormat bfmt;
341 bfmt.setObjectIndex(-1);
342 cursor.setBlockFormat(bfmt);
343 reformatBoundingItemSpacing();
346 reformatBoundingItemSpacing();
350 void NestedListHelper::reformatBoundingItemSpacing(QTextBlock block)
357 int nextBlockTopMargin = listNoMargin;
358 int previousBlockBottomMargin = listNoMargin;
359 int thisBlockBottomMargin = listBottomMargin;
360 int thisBlockTopMargin = listTopMargin;
361 bool prevBlockValid = block.previous().isValid();
362 bool nextBlockValid = block.next().isValid();
364 if (block.textList()) {
365 if (prevBlockValid && block.previous().textList()) {
366 thisBlockTopMargin = listNoMargin;
369 if (nextBlockValid && block.next().textList()) {
370 thisBlockBottomMargin = listNoMargin;
373 if (prevBlockValid && !block.previous().textList()) {
374 thisBlockTopMargin = listNoMargin;
376 if (nextBlockValid && !block.next().textList()) {
377 thisBlockBottomMargin = listNoMargin;
381 QTextBlockFormat fmt;
384 fmt = block.blockFormat();
385 fmt.setBottomMargin(thisBlockBottomMargin);
386 fmt.setTopMargin(thisBlockTopMargin);
387 cursor = QTextCursor(block);
388 cursor.setBlockFormat(fmt);
390 if (nextBlockValid) {
391 block = block.next();
392 fmt = block.blockFormat();
393 fmt.setTopMargin(nextBlockTopMargin);
394 cursor = QTextCursor(block);
395 cursor.setBlockFormat(fmt);
397 block = block.previous();
399 if (prevBlockValid) {
400 block = block.previous();
401 fmt = block.blockFormat();
402 fmt.setBottomMargin(previousBlockBottomMargin);
403 cursor = QTextCursor(block);
404 cursor.setBlockFormat(fmt);
408 void NestedListHelper::reformatBoundingItemSpacing()
410 reformatBoundingItemSpacing(topOfSelection().block());
411 reformatBoundingItemSpacing(bottomOfSelection().block());