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());