View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0009568 | Scribus | Undo/Redo | public | 2010-12-10 14:59 | 2011-03-07 19:07 |
Reporter | cezaryece | Assigned To | |||
Priority | high | Severity | feature | Reproducibility | N/A |
Status | closed | Resolution | fixed | ||
Product Version | 1.4.0svn | ||||
Target Version | 1.4.0svn | Fixed in Version | 1.4.0svn | ||
Summary | 0009568: [FEATURE SOLVED] undow for text frames | ||||
Description | Unfortunately I have no time for long describe my patch for text undo. Maybe in few days I will write more here. patch gives undo for almost all operations on text - editing, changing styles etc. I think inline frames and inserting special characters is problem. Apply, test and review. | ||||
Tags | No tags attached. | ||||
Patch | |||||
has duplicate | 0009522 | closed | cbradney | [PATCH] for disabling Undo/Redo while typing text in text frames |
has duplicate | 0009665 | closed | Undo in Text Editing | |
has duplicate | 0003301 | closed | Undo does not work on text object | |
has duplicate | 0008744 | closed | cbradney | undo disabled by default in 1.4? |
has duplicate | 0003445 | closed | cbradney | Type fill does not undo. |
|
I'd like to test, but I'm not very familiar with applying patches. If someone will give instruction, I will try. |
|
to apply this patch 1. download 1.3.9 code from SVN and install all needed libs to build Scribus from source (more you can find here: http://wiki.scribus.net/index.php/Building_SVN_versions_with_CMake) 2. copy patch file into Version135 dir in your SVN work copy 3. in terminal as user run command "patch -p0 -l < textUndo.patch" |
|
What this patch do? For pageitem_textframe is definied new method "updateUndo" where main parameter is "action" with type enum EditAct. EditAct can be: - PARAMFULL for changing styles (font, color, typographic etc) for whole text story - PARAMSEL for changing styles for selection - INSSAX and DELSAX - inserting and deleting portions of text storing it with styles - INS and DEL - inserting and deleting portions of text without styles (in fact only for pasting clear "non-Scribus" text) During all actions on text before apply any changes edited portion (selection on whole text) is stored in itemTextSaxed field. Method getItemTextSaxed returns QString with text with styles in string format (like in Copy/Paste actions) from selection or whole text storie. After applying changes updateUndo is invoked for create undo state, where old text, new text, action type and action place (CPos) is stored. |
|
I downloaded SVN, ran patch, the, cmake, make and got error: /home/anton/pageitem_textframe.cpp: In member function ‘virtual void PageItem_TextFrame::handleModeEditKey(QKeyEvent*, bool&)’: /home/anton/scribus_svn/scribus/pageitem_textframe.cpp:2749: error: ‘currItem’ was not declared in this scope make[2]: *** [scribus/CMakeFiles/scribus.dir/pageitem_textframe.cpp.o] Error 1 make[1]: *** [scribus/CMakeFiles/scribus.dir/all] Error 2 make: *** [all] Error 2 |
|
hi subeditor, afaik there will be a new patch around christmas... |
|
hi ale! so there is no way to test this patch for now? |
|
there's no need to test until cezary uploads a new version of it... the new patch will be very different (at least this is what he has announced on irc). i'm eager to test it, too (now that i have 1.4beta installed...) |
|
This time I check if path is compiling after applying on current SVN snapshot. So I hope you can test it. I try to make sequence of same actions in one undo step. So now if you insert text chars it all will be stored in one undo/redo action until you insert SPACE or new line (Enter key), which made new sequence. If you change text parameters without changing target for this action it is also stored in one sequence. So if are changing font, size of text or kerning parameters continuously in undo state first state of text will be saved. Changing cursor position breaks sequence and new undo state will created after this. Deleting or replacing text is not sequenced (as we deleting styles in this case, not only chars). Also cutting/pasting text. This patch is for undo for text frames, not for text on path. Somebody should expand it for text on path. I am not interesting in this issue as I am not using it at all. I hope you will have big joy using this patch. |
|
I got error again. [ 24%] Building CXX object scribus/CMakeFiles/scribus.dir/pageitem_textframe.cpp.o /home/anton/scribus_svn/scribus/pageitem_textframe.cpp: In member function ‘virtual void PageItem_TextFrame::handleModeEditKey(QKeyEvent*, bool&)’: /home/anton/scribus_svn/scribus/pageitem_textframe.cpp:2749: error: ‘currItem’ was not declared in this scope make[2]: *** [scribus/CMakeFiles/scribus.dir/pageitem_textframe.cpp.o] Error 1 make[1]: *** [scribus/CMakeFiles/scribus.dir/all] Error 2 make: *** [all] Error 2 |
|
subeditor: are you sure you apply ONLY undoText2.patch? The first one (textUndo.patch) is outdated and should not be applied, but I cant delete it. |
|
Well, my steps today: 1. svn co 2. applying patch 3. cmake 4. make Though I didn't wipe folders from previous try but files should be overwritten, shouldn't they? Ok, I'll try delete everything and start again. |
|
better make clean SVN snaphot and apply ONLY second patch!!! you can see in this there is any currItem in pageitem_textframe.cpp |
|
Yes, clean install succeed. Great work! Text undo is what we missed a lot! Go for testing now, though there is seems to be no real work until New Year. |
|
installed! i had to use the "-l" switch when patching but now i finally have an undo for text in scribus! i will let scribus run in the debugger to catch possible bugs... |
|
New version of patch with small fix is ready for download - undoText2.1.patch Apply it for clean snapshot, not for patched with previous patch. For you with already previous patch aplied it is one small change: in pageitem_textframe.cpp in line 3682 change "else" into "if (newState)". Hope this fixes crushes. --- 8< --- edit by a.l.e: in my patched pageitem_textframe.cpp it's line 3664: } - else + if (newState) { ss = new SimpleState(UndoManager::EditText); ss->set("STEXT_CPOS",oldCPos); } |
|
avox..ping |
|
Please... let someone delete first two patch files - they are buggy! Only last undoText2.1.patch should be applied and tested! |
|
Done! |
|
Scribus crashes with signal 11 randomly on different changes. I don't know for sure if it connected with with this patch. How can I get more specific information about these crashes? |
|
if your computer is fast enough and you're using linux, you can run scribus through the gnu debugger $ gdb scribus run und we scribus crashes, you issue the "bt" command to get the full backtrace which tells exactly where the problem happened. don't hesitate to ask, if you want more information |
|
Here is error report: [Thread 0x7fffd53c2700 (LWP 4652) exited] ExpandParSel 2650 10 ExpandParSel 2650 10 storytext::charstyle: access at end of text %i 2660 Program received signal SIGSEGV, Segmentation fault. 0x0000000000e6ddc4 in StoryText::text(int) const () Beside it while editing text in layout mode cursor jumps few paragraphs backward on pressing "backspace" or ctrl-z. |
|
And again: setNewFont true Program received signal SIGSEGV, Segmentation fault. 0x0000000d0000000b in ?? () |
|
hi subeditor, you should probably post the full backtrace... |
|
There was nothing special (except some issues with font metrics), but next time I'll will do what you say. |
|
I have found one bug in 2.1 patch, maybe it is reason for some instability. In line 1418 of patch file there should be: currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; Now there is: currItem->asTextFrame()->lastUndoAction == PageItem::NOACTION; where error is in comparison instead setting value. New correct version of patch is uploaded. Please delete previous file. |
|
undoText2.2.patch (57,515 bytes)
Index: Scribus/scribus/canvasmode_legacy.cpp =================================================================== --- Scribus/scribus/canvasmode_legacy.cpp (wersja 16088) +++ Scribus/scribus/canvasmode_legacy.cpp (kopia robocza) @@ -1800,7 +1800,9 @@ if (!cc.isNull()) { // K.I.S.S.: + currItem->oldCPos = 0; currItem->itemText.insertChars(0, cc, true); + currItem->asTextFrame()->updateUndo(PageItem::INS,cc); if (m_doc->docHyphenator->AutoCheck) m_doc->docHyphenator->slotHyphenate(currItem); m_ScMW->BookMarkTxT(currItem); Index: Scribus/scribus/pageitem.cpp =================================================================== --- Scribus/scribus/pageitem.cpp (wersja 16088) +++ Scribus/scribus/pageitem.cpp (kopia robocza) @@ -34,6 +34,9 @@ #include <QPolygon> #include <cassert> #include <QDebug> +#include <iostream> +#include <sstream> +#include <string> #include "canvas.h" #include "scpaths.h" @@ -44,6 +47,7 @@ #include "guidemanager.h" #include "page.h" #include "pageitem_latexframe.h" +#include "pageitem_textframe.h" #include "prefsmanager.h" #include "propertiespalette.h" #include "resourcecollection.h" @@ -60,9 +64,11 @@ #include "scribusstructs.h" #include "scribuswin.h" #include "sctextstream.h" +#include "serializer.h" #include "selection.h" #include "sclimits.h" #include "text/nlsconfig.h" +#include "desaxe/saxXML.h" #include "undomanager.h" #include "undostate.h" #include "util.h" @@ -327,6 +333,7 @@ CurX = 0; CurY = 0; CPos = 0; + oldCPos = 0; Extra = 0; TExtra = 0; BExtra = 0; @@ -3209,6 +3216,9 @@ restoreShapeContour(ss, isUndo); else if (ss->contains("APPLY_IMAGE_EFFECTS")) restoreImageEffects(ss, isUndo); + else if (ss->contains("STEXT")) + restoreEditText(ss, isUndo); + } if (!OnMasterPage.isEmpty()) m_Doc->setCurrentPage(oldCurrentPage); @@ -3707,8 +3717,190 @@ } } +void PageItem::restoreEditText(SimpleState *state, bool isUndo) +{ + if (!isTextFrame()) + return; + EditAct action = (EditAct) state->getInt("STEXT"); + if (action == PARAMFULL || action == PARAMSEL) + { + QString buffer; + if (isUndo) + buffer.append(state->get("STEXT_OLD")); + else + buffer.append(state->get("STEXT_NEW")); + if (!buffer.isEmpty()) + { + Serializer dig(*m_Doc); + dig.store<ScribusDoc>("<scribusdoc>", m_Doc); + StoryText::desaxeRules("/", dig, "SCRIBUSTEXT"); + dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>()); + dig.parseMemory(buffer.toStdString().c_str(), buffer.length()); + StoryText* story = dig.result<StoryText>(); + if (action == PARAMFULL) + { + itemText.selectAll(); + itemText.clear(); + itemText.append(*story); + } + else if (action == PARAMSEL) + { + itemText.deselectAll(); + itemText.select(state->getInt("STEXT_SELSTART"),state->getInt("STEXT_SELLEN")); + asTextFrame()->deleteSelectedTextFromFrame(); + itemText.insert(state->getInt("STEXT_SELSTART"), *story); + itemText.select(state->getInt("STEXT_SELSTART"), story->length()); + HasSel = true; + } + CPos = itemText.endOfSelection(); + delete story; + } + else { qDebug() << "UNDO buffer EMPTY";} + } + else if (action == REPSAX) + { + QString buffout, buffin; //buffout is deleted, buffin is inserted + int pos = state->getInt("STEXT_CPOS"); + if (isUndo) + { + buffin.append(state->get("STEXT_OLD")); + buffout.append(state->get("STEXT_NEW")); + } + else + { + buffin.append(state->get("STEXT_NEW")); + buffout.append(state->get("STEXT_OLD")); + } + + Serializer dig(*m_Doc); + dig.store<ScribusDoc>("<scribusdoc>", m_Doc); + StoryText::desaxeRules("/", dig, "SCRIBUSTEXT"); + dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>()); + dig.parseMemory(buffout.toStdString().c_str(), buffout.length()); + StoryText* story = dig.result<StoryText>(); + itemText.select(pos,story->length(), true); + asTextFrame()->deleteSelectedTextFromFrame(); + + Serializer dig2(*m_Doc); + dig2.store<ScribusDoc>("<scribusdoc>", m_Doc); + StoryText::desaxeRules("/", dig2, "SCRIBUSTEXT"); + dig2.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>()); + dig2.parseMemory(buffin.toStdString().c_str(), buffin.length()); + story = dig2.result<StoryText>(); + itemText.insert(pos,*story); + itemText.select(pos, story->length()); + HasSel = true; + CPos = pos + story->length(); + delete story; + } + else if (action == INSSAX || action == DELSAX) + { + QString str = state->get("STEXT_STR"); + if (str.isEmpty()) + str = itemTextSaxed; + int pos = state->getInt("STEXT_CPOS"); + Serializer dig(*m_Doc); + dig.store<ScribusDoc>("<scribusdoc>", m_Doc); + StoryText::desaxeRules("/", dig, "SCRIBUSTEXT"); + dig.addRule("/SCRIBUSTEXT", desaxe::Result<StoryText>()); + dig.parseMemory(str.toStdString().c_str(), str.length()); + StoryText* story = dig.result<StoryText>(); + if ((action == INSSAX && isUndo) || (action == DELSAX && !isUndo)) + { + //undo for INSSAX, redo for DELSAX + itemText.select(pos, story->length()); + asTextFrame()->deleteSelectedTextFromFrame(); + } + else + { + //undo for DELSAX, redo for INSSAX + itemText.insert(pos, *story); + CPos = pos + story->length(); + } + delete story; + } + else if (action == INS) + { + QString str = state->get("STEXT_STR"); + int pos = state->getInt("STEXT_CPOS"); + if (isUndo) + { + itemText.select(pos, str.length()); + asTextFrame()->deleteSelectedTextFromFrame(); + } + else + { + itemText.insertChars(pos, str, true); + CPos = pos + str.length(); + } + } + // after Undo or Redo new actions should create new undoStates + asTextFrame()->lastUndoAction = NOACTION; + + m_Doc->scMW()->setTBvals(this); + update(); +} + +QString PageItem::getItemTextSaxed(EditActPlace undoItem) +{ + if (!isTextFrame()) return ""; + StoryText iT(m_Doc); + iT.setDefaultStyle(itemText.defaultStyle()); + if (undoItem == FRAME) + iT.insert(0, itemText); + else + { + int StartOldSel = 0, LenOldSel = 0; + if (undoItem == PARAGRAPH) + { + if (HasSel) + { + StartOldSel = itemText.startOfSelection(); + LenOldSel = itemText.lengthOfSelection(); + } + asTextFrame()->ExpandParSel(); + } + else if (undoItem == CHAR || (undoItem == SELECTION && !HasSel)) + { + itemText.select(CPos,1); + HasSel = true; + } + //is SELECTION + iT.insert(0, itemText, true); + if (LenOldSel > 0) //restoring old selection if undoItem was PARAPGRAPH + { + itemText.select(StartOldSel, LenOldSel); + HasSel = true; + } + } + //saxing text + std::ostringstream xmlString; + SaxXML xmlStream(xmlString); + xmlStream.beginDoc(); + iT.saxx(xmlStream, "SCRIBUSTEXT"); + xmlStream.endDoc(); + std::string xml(xmlString.str()); + return QString(xml.c_str()); +} + +QString PageItem::getTextSaxed(QString str) +{ + StoryText iT(m_Doc); + iT.setDefaultStyle(itemText.defaultStyle()); + iT.insertChars(0,str,true); + std::ostringstream xmlString; + SaxXML xmlStream(xmlString); + xmlStream.beginDoc(); + iT.saxx(xmlStream, "SCRIBUSTEXT"); + xmlStream.endDoc(); + std::string xml(xmlString.str()); + return QString(xml.c_str()); +} + void PageItem::select() { + if (m_Doc->m_Selection->count() == 1 && m_Doc->m_Selection->itemAt()->isTextFrame()) + m_Doc->m_Selection->itemAt()->asTextFrame()->lastUndoAction = PageItem::NOACTION; m_Doc->view()->Deselect(false); //CB #2969 add this true parm to addItem so we dont connectToGUI, the rest of view->SelectItem isnt needed anyway m_Doc->m_Selection->addItem(this, true); Index: Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Scribus/scribus/pageitem_textframe.cpp (wersja 16160) +++ Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -46,6 +46,8 @@ #include "scribus.h" #include "scribusdoc.h" #include "scribusstructs.h" +#include "scribusXml.h" +#include "serializer.h" #include "selection.h" #include "text/nlsconfig.h" #include "undomanager.h" @@ -67,6 +69,8 @@ unicodeTextEditMode = false; unicodeInputCount = 0; unicodeInputString = ""; + lastUndoAction = NOACTION; +// lastAction4Paragraph = false; connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout())); } @@ -78,7 +82,9 @@ unicodeTextEditMode = false; unicodeInputCount = 0; unicodeInputString = ""; - + lastUndoAction = NOACTION; +// lastAction4Paragraph = false; + connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout())); } @@ -2653,11 +2676,11 @@ PageItem *nextItem = this; while (nextItem->prevInChain() != 0) nextItem = nextItem->prevInChain(); - + nextItem->itemTextSaxed = nextItem->getItemTextSaxed(PageItem::FRAME); //for undo ParagraphStyle defaultStyle = nextItem->itemText.defaultStyle(); nextItem->itemText.clear(); nextItem->itemText.setDefaultStyle(defaultStyle); - + nextItem->asTextFrame()->updateUndo(); //for undo while (nextItem != 0) { nextItem->CPos = 0; @@ -2710,6 +2733,7 @@ case Qt::Key_Down: if ( (buttonModifiers & Qt::ShiftModifier) == 0 ) deselectAll(); + lastUndoAction = PageItem::NOACTION; } if (unicodeTextEditMode) @@ -2735,11 +2759,25 @@ if (ok) { if (itemText.lengthOfSelection() > 0) + { + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + lastUndoAction = PageItem::NOACTION; + } if (conv < 31) conv = 32; + if (conv == 32) + { + qDebug() << "SPACE conv?"; + lastUndoAction = PageItem::NOACTION; + } + oldCPos = CPos; itemText.insertChars(CPos, QString(QChar(conv)), true); CPos += 1; + if (itemTextSaxed.isEmpty()) + updateUndo(INS, QString(QChar(conv))); + else + updateUndo(REPSAX, getTextSaxed(QString(QChar(conv)))); // Tinput = true; m_Doc->scMW()->setTBvals(this); update(); @@ -3016,7 +3054,10 @@ { if (itemText.lengthOfSelection() > 0) { + oldCPos = itemText.startOfSelection(); + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + updateUndo(DELSAX); m_Doc->scMW()->setTBvals(this); update(); // view->RefreshItem(this); @@ -3031,8 +3072,14 @@ } cr = itemText.text(CPos,1); if (itemText.lengthOfSelection() == 0) + { itemText.select(CPos, 1, true); + HasSel = true; + } + oldCPos = itemText.startOfSelection(); + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + updateUndo(DELSAX); update(); // Tinput = false; if ((cr == QChar(13)) && (itemText.length() != 0)) @@ -3048,7 +3095,10 @@ { if (itemText.lengthOfSelection() > 0) { + oldCPos = itemText.startOfSelection(); + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + updateUndo(DELSAX); m_Doc->scMW()->setTBvals(this); update(); } @@ -3061,8 +3111,12 @@ { --CPos; itemText.select(CPos, 1, true); + HasSel = true; } + oldCPos = itemText.startOfSelection(); + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + updateUndo(DELSAX); // Tinput = false; if ((cr == QChar(13)) && (itemText.length() != 0)) { @@ -3090,7 +3144,10 @@ #endif if (!controlCharHack && !x11Hack && !k->text().isEmpty()) { + oldCPos = itemText.startOfSelection(); + itemTextSaxed = getItemTextSaxed(PageItem::SELECTION); deleteSelectedTextFromFrame(); + lastUndoAction = PageItem::NOACTION; doUpdate = true; } /* @@ -3106,16 +3163,30 @@ //if ((kk == Qt::Key_Tab) || ((kk == Qt::Key_Return) && (buttonState & Qt::ShiftButton))) if (kk == Qt::Key_Tab) { + oldCPos = CPos; itemText.insertChars(CPos, QString(SpecialChars::TAB), true); CPos += 1; + lastUndoAction = PageItem::NOACTION; + if (itemTextSaxed.isEmpty()) + updateUndo(INS, QString(SpecialChars::TAB)); + else + updateUndo(REPSAX, getTextSaxed(QString(SpecialChars::TAB))); // Tinput = true; // view->RefreshItem(this); doUpdate = true; } else if ((uc[0] > QChar(31) && m_Doc->currentStyle.charStyle().font().canRender(uc[0])) || (as == 13) || (as == 30)) { + if (uc[0] == QChar(32) || uc[0] == QChar(13)) + lastUndoAction = PageItem::NOACTION; + if (lastUndoAction != PageItem::INS) + oldCPos = CPos; itemText.insertChars(CPos, uc, true); CPos += 1; + if (itemTextSaxed.isEmpty()) + updateUndo(INS, uc); + else + updateUndo(REPSAX, getTextSaxed(uc)); if ((m_Doc->docHyphenator->AutoCheck) && (CPos > 1)) { Twort = ""; @@ -3278,8 +3348,30 @@ // layoutWeakLock = true; // update(); m_Doc->regionsChanged()->update(getBoundingRect()); + lastUndoAction = PageItem::NOACTION; } +void PageItem_TextFrame::ExpandParSel() //expand selection to whole paragrpah(s) +{ + if (m_Doc->appMode != modeEdit) + return; + int StartSel = 0, LenSel = 0; + if (HasSel) + { + //extend selection to whole paragraphs + StartSel = itemText.startOfParagraph(itemText.nrOfParagraph(itemText.startOfSelection())); + LenSel = itemText.endOfParagraph(itemText.nrOfParagraph(itemText.endOfSelection())) - StartSel; + } + else + { + //extend selection to whole paragraph + StartSel = itemText.startOfParagraph(itemText.nrOfParagraph(CPos)); + LenSel = itemText.endOfParagraph(itemText.nrOfParagraph(CPos)) - StartSel; + } + itemText.select(StartSel, LenSel); + qDebug() << "ExpandParSel" << StartSel << LenSel; +} + void PageItem_TextFrame::deselectAll() { if ( itemText.lengthOfSelection() > 0 ) @@ -3299,6 +3391,7 @@ } //CB Replace with direct call for now //emit HasNoTextSel(); m_Doc->scMW()->DisableTxEdit(); + lastUndoAction = PageItem::NOACTION; } double PageItem_TextFrame::columnWidth() @@ -3558,3 +3651,75 @@ { invalidateLayout(); } + +void PageItem_TextFrame::updateUndo(EditAct action, QString str) +{ + if (UndoManager::undoEnabled() && undoManager->undoEnabled()) + { + SimpleState* ss; + bool newState = true; // indicate when new undoState should be created + if (lastUndoAction == action && action != REPSAX && action != DELSAX) + { + ss = (SimpleState*) undoManager->getLastUndoState(); + if (ss->undoObject() == this) + { + if (action == PARAMFULL || action == PARAMSEL) + { + itemTextSaxed = ss->get("STEXT_OLD"); + newState = false; + } + else if (action == INSSAX || action == INS) + { + QString tmpstr(ss->get("STEXT_STR")); + tmpstr.append(str); + str = tmpstr; + newState = false; + } + } + } + if (newState) + { + ss = new SimpleState(UndoManager::EditText); + ss->set("STEXT_CPOS",oldCPos); + } + if (action == INSSAX || action == INS) + ss->set("STEXT_STR",str); + else if (action == DELSAX) + ss->set("STEXT_STR",itemTextSaxed); + else if (action == REPSAX) + { + ss->set("STEXT_NEW",str); + ss->set("STEXT_OLD",itemTextSaxed); + } + else + { + if (action == PARAMFULL && m_Doc->appMode == modeEdit) + { + //action is for paragraph where cursor is + ExpandParSel(); + action = PARAMSEL; + } + if (action == PARAMSEL) + { + ss->set("STEXT_CPOS",CPos); + ss->set("STEXT_SELSTART", itemText.startOfSelection()); + ss->set("STEXT_SELLEN", itemText.endOfSelection() - itemText.startOfSelection()); + } + ss->set("STEXT_OLD", itemTextSaxed); + itemTextSaxed = getItemTextSaxed((action == PARAMSEL) ? SELECTION : FRAME); + ss->set("STEXT_NEW", itemTextSaxed); + if (QString::compare(ss->get("STEXT_OLD"),ss->get("STEXT_NEW")) == 0) + { + //nothing change - quit without set new Undo step + itemTextSaxed.clear(); + delete ss; + return; + } + } + itemTextSaxed.clear(); + lastUndoAction = action; + ss->set("STEXT",(int) action); + if (newState) + undoManager->action(this, ss); + } +} Index: Scribus/scribus/scribus.cpp =================================================================== --- Scribus/scribus/scribus.cpp (wersja 16088) +++ Scribus/scribus/scribus.cpp (kopia robocza) @@ -137,6 +137,7 @@ #include "nodeeditpalette.h" #include "outlinepalette.h" #include "page.h" +#include "pageitem.h" #include "pageitem_imageframe.h" #include "pageitem_latexframe.h" #include "pageitem_textframe.h" @@ -1112,9 +1120,18 @@ if (unicodevalue!=-1) { if (currItem->HasSel && currItem->itemType()==PageItem::TextFrame) + { + currItem->oldCPos = currItem->itemText.startOfSelection(); + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::SELECTION); currItem->asTextFrame()->deleteSelectedTextFromFrame(); - + } + else + currItem->oldCPos = currItem->CPos; currItem->itemText.insertChars(currItem->CPos, QString(QChar(unicodevalue)), true); + if (currItem->itemTextSaxed.isEmpty()) + currItem->asTextFrame()->updateUndo(PageItem::INS, QString(QChar(unicodevalue))); + else + currItem->asTextFrame()->updateUndo(PageItem::REPSAX, currItem->getTextSaxed(QString(QChar(unicodevalue)))); currItem->CPos += 1; // currItem->Tinput = true; currItem->update(); @@ -1131,7 +1148,9 @@ currItem->itemText.item(qMax(currItem->CPos-1,0))->setEffects(fl); #else currItem->itemText.insertChars(currItem->CPos, QString(SpecialChars::SHYPHEN), true); + currItem->oldCPos = currItem->CPos; currItem->CPos += 1; + currItem->asTextFrame()->updateUndo(PageItem::INS, QString(SpecialChars::SHYPHEN)); #endif // currItem->Tinput = true; currItem->update(); @@ -3318,7 +3337,6 @@ scrActions["itemLockSize"]->setChecked(currItem->sizeLocked()); scrActions["itemPrintingEnabled"]->setChecked(currItem->printEnabled()); } - //propertiesPalette->NewSel(SelectedType); if (SelectedType != -1) { @@ -4289,6 +4307,7 @@ ImportSetup impsetup=gt->run(); if (impsetup.runDialog) { + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::FRAME); if (currItem->itemText.length() != 0) { int t = QMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your text?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No); @@ -4296,6 +4315,7 @@ return; } gt->launchImporter(impsetup.importer, impsetup.filename, impsetup.textOnly, impsetup.encoding, false); + currItem->asTextFrame()->updateUndo(); } delete gt; if (doc->docHyphenator->AutoCheck) @@ -4321,7 +4341,8 @@ if (!currItem->asTextFrame()) return; // not a text frame - + // I dont know what is doing here, but Undo dont hurts + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::FRAME); ScGTPluginManager::instance()->run(); if (doc->docHyphenator->AutoCheck) doc->docHyphenator->slotHyphenate(currItem); @@ -4330,6 +4351,7 @@ if (doc->Items->at(a)->isBookmark) bookmarkPalette->BView->ChangeText(doc->Items->at(a)); } + currItem->asTextFrame()->updateUndo(); view->DrawNew(); slotDocCh(); } @@ -4385,7 +4407,10 @@ ImportSetup impsetup=gt->run(); if (impsetup.runDialog) { + PageItem *currItem = doc->m_Selection->itemAt(0); + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::FRAME); gt->launchImporter(impsetup.importer, impsetup.filename, impsetup.textOnly, impsetup.encoding, true); + currItem->asTextFrame()->updateUndo(); } delete gt; //CB Hyphenating now emits doc changed, plus we change lang as appropriate @@ -4964,6 +4989,10 @@ { if ((currItem->itemText.length() == 0) || (!currItem->HasSel)) return; + currItem->oldCPos = currItem->itemText.startOfSelection(); + //for undo + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::SELECTION); + StoryText itemText(doc); itemText.setDefaultStyle(currItem->itemText.defaultStyle()); itemText.insert(0, currItem->itemText, true); @@ -4981,6 +5010,8 @@ QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); dynamic_cast<PageItem_TextFrame*>(currItem)->deleteSelectedTextFromFrame(); + //for undo + currItem->asTextFrame()->updateUndo(PageItem::DELSAX); currItem->update(); } else @@ -5116,14 +5147,19 @@ { PageItem_TextFrame *currItem = dynamic_cast<PageItem_TextFrame*>(doc->m_Selection->itemAt(0)); assert(currItem != NULL); + currItem->lastUndoAction = PageItem::NOACTION; if (currItem->HasSel) + { + //for text undo, storing current selection + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::SELECTION); currItem->deleteSelectedTextFromFrame(); + } if (currItem->CPos < 0) currItem->CPos = 0; if (currItem->CPos > currItem->itemText.length()) currItem->CPos = currItem->itemText.length(); - + currItem->oldCPos = currItem->CPos; if (ScMimeData::clipboardHasScribusText()) { Serializer dig(*doc); @@ -5137,6 +5173,13 @@ StoryText* story = dig.result<StoryText>(); currItem->itemText.insert(currItem->CPos, *story); + + //for text undo, select inserted text for saxing it + currItem->itemText.select(currItem->CPos,story->length()); + currItem->HasSel = true; + //if itemTextSaxed is not empty there was selection + currItem->updateUndo(currItem->itemTextSaxed.isEmpty() ? PageItem::INSSAX : PageItem::REPSAX,currItem->getItemTextSaxed(PageItem::SELECTION)); + currItem->CPos += story->length(); delete story; @@ -5222,6 +5265,11 @@ currItem->itemText.insertObject(currItem->CPos, currItem3); currItem->CPos += 1; undoManager->setUndoEnabled(true); + //for text undo, select inserted text for saxing it + currItem->itemText.select(currItem->oldCPos,currItem->CPos - currItem->oldCPos); + currItem->HasSel = true; + //if itemTextSaxed is not empty there was selection + currItem->updateUndo(currItem->itemTextSaxed.isEmpty() ? PageItem::INSSAX : PageItem::REPSAX,currItem->getItemTextSaxed(PageItem::SELECTION)); } else { @@ -5230,6 +5278,15 @@ text = text.replace("\r\n", SpecialChars::PARSEP); text = text.replace('\n', SpecialChars::PARSEP); currItem->itemText.insertChars(currItem->CPos, text, true); + //for text undo, select inserted text for saxing it + currItem->itemText.select(currItem->CPos,text.length()); + currItem->HasSel = true; + //if itemTextSaxed is not empty there was selection + if (currItem->itemTextSaxed.isEmpty()) + currItem->updateUndo(PageItem::INS, text); + else + currItem->updateUndo(PageItem::REPSAX, currItem->getTextSaxed(text)); + } currItem->update(); } @@ -6927,7 +6984,15 @@ } } } + //for undo + PageItem *currItem = doc->m_Selection->itemAt(0); + if (currItem->asTextFrame()) + currItem->itemTextSaxed = currItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); + qDebug() << "setNewFont" << currItem->HasSel; doc->itemSelection_SetFont(nf2); + if (currItem->asTextFrame()) + currItem->asTextFrame()->updateUndo(currItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); + // doc->currentStyle.charStyle().setFont((*doc->AllFonts)[nf2]); view->DrawNew(); // slotDocCh(); @@ -6935,6 +7000,10 @@ void ScribusMainWindow::setItemFSize(int id) { + PageItem *currItem = doc->m_Selection->itemAt(0); + if (currItem->asTextFrame()) + currItem->itemTextSaxed = currItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); + int c = id; if (c != -1) doc->itemSelection_SetFontSize(c*10); @@ -6950,6 +7019,9 @@ } delete dia; } + if (currItem->asTextFrame()) + currItem->asTextFrame()->updateUndo(currItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); + propertiesPalette->setSize(c*10); // slotDocCh(); } @@ -7330,9 +7402,9 @@ if (HaveDoc) { // doc->currentStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(a)); + PageItem *currItem = doc->m_Selection->itemAt(0); doc->itemSelection_SetAlignment(a); propertiesPalette->setAli(a); - PageItem *currItem = doc->m_Selection->itemAt(0); setTBvals(currItem); } } @@ -7347,8 +7419,16 @@ doc->itemSelection_EraseParagraphStyle(); } else */ - doc->itemSelection_SetNamedParagraphStyle(name); PageItem *currItem = doc->m_Selection->itemAt(0); + if (currItem->asTextFrame()) + { +// currItem->asTextFrame()->ExpandParSel(); +// currItem->asTextFrame()->lastAction4Paragraph = true; + currItem->itemTextSaxed = currItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); + } + doc->itemSelection_SetNamedParagraphStyle(name); + if (currItem->asTextFrame()) + currItem->asTextFrame()->updateUndo(); setTBvals(currItem); } } @@ -7363,8 +7443,12 @@ doc->itemSelection_EraseCharStyle(); } else */ - doc->itemSelection_SetNamedCharStyle(name); PageItem *currItem = doc->m_Selection->itemAt(0); + if (currItem->asTextFrame()) + currItem->itemTextSaxed = currItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); + doc->itemSelection_SetNamedCharStyle(name); + if (currItem->asTextFrame()) + currItem->asTextFrame()->updateUndo(currItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); setTBvals(currItem); } } Index: Scribus/scribus/propertiespalette.cpp =================================================================== --- Scribus/scribus/propertiespalette.cpp (wersja 16088) +++ Scribus/scribus/propertiespalette.cpp (kopia robocza) @@ -52,7 +52,9 @@ #include "colorlistbox.h" #include "sccolorengine.h" #include "cpalette.h" +#include "pageitem.h" #include "pageitem_textframe.h" +#include "styles/paragraphstyle.h" #include "sccombobox.h" #include "scfonts.h" #include "scribus.h" @@ -2923,8 +2936,16 @@ { if ((HaveDoc) && (HaveItem)) { + if (CurItem->asTextFrame()) + { +// CurItem->asTextFrame()->ExpandParSel(); + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); +// CurItem->asTextFrame()->lastAction4Paragraph = true; + } doc->itemSelection_SetLineSpacingMode(id); updateStyle(doc->appMode == modeEdit? CurItem->currentStyle() : CurItem->itemText.defaultStyle()); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); } } @@ -3266,6 +3285,8 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(PageItem::FRAME); int omt(ParagraphStyle::OM_None); // if (optMarginCheckLeftProtruding->isChecked()) omt+=ParagraphStyle::OM_LeftProtruding; if (optMarginRadioBoth->isChecked()) @@ -3276,6 +3297,8 @@ omt = ParagraphStyle::OM_RightHangingPunct; doc->itemSelection_SetOpticalMargins(omt); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); } void PropertiesPalette::resetOpticalMargins() @@ -3303,9 +3326,13 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); ParagraphStyle newStyle; newStyle.setMinWordTracking(minWordTrackingSpinBox->value() / 100.0); doc->itemSelection_ApplyParagraphStyle(newStyle); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } @@ -3313,28 +3340,40 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); ParagraphStyle newStyle; // newStyle.setNormWordTracking(percent / 100.0); newStyle.charStyle().setWordTracking(normWordTrackingSpinBox->value() / 100.0); doc->itemSelection_ApplyParagraphStyle(newStyle); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::setMinGlyphExtension() { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); ParagraphStyle newStyle; newStyle.setMinGlyphExtension(minGlyphExtSpinBox->value() / 100.0); doc->itemSelection_ApplyParagraphStyle(newStyle); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::setMaxGlyphExtension() { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); ParagraphStyle newStyle; newStyle.setMaxGlyphExtension(maxGlyphExtSpinBox->value() / 100.0); doc->itemSelection_ApplyParagraphStyle(newStyle); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } @@ -3352,14 +3391,22 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetScaleV(qRound(ChScaleV->value() * 10)); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::NewTBase() { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetBaselineOffset(qRound(ChBase->value() * 10)); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::setTScale(double e) @@ -3386,7 +3433,11 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetScaleH(qRound(ChScale->value() * 10)); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::NewX() @@ -3810,7 +3861,15 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + { +// CurItem->asTextFrame()->ExpandParSel(); + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); +// CurItem->asTextFrame()->lastAction4Paragraph = true; + } doc->itemSelection_SetLineSpacing(LineSp->value()); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); } void PropertiesPalette::HandleGapSwitch() @@ -3872,14 +3931,22 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetFontSize(qRound(Size->value()*10.0)); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::NewTracking() { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetTracking(qRound(Extra->value() * 10.0)); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::NewLocalXY() @@ -4197,25 +4264,72 @@ void PropertiesPalette::NewAlignement(int a) { + int StartSel = 0, EndSel = 0, LenSel = 0; if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + { + // hack for apply left align for text with no align at all + //so during Undo/Redo some align will be applied + if (doc->appMode == modeEdit) + { + //selected parapgraph(s) only + CurItem->asTextFrame()->ExpandParSel(); + StartSel = CurItem->itemText.startOfSelection(); + EndSel = CurItem->itemText.endOfSelection(); + for (uint i = CurItem->itemText.nrOfParagraph(StartSel); i <= CurItem->itemText.nrOfParagraph(EndSel); i++) + { + if (CurItem->itemText.paragraphStyle(CurItem->itemText.startOfParagraph(i)).alignment() == 0) + { + CurItem->itemText.select(CurItem->itemText.startOfParagraph(i), CurItem->itemText.endOfParagraph(i) - CurItem->itemText.startOfParagraph(i)); + CurItem->HasSel = true; + doc->itemSelection_SetAlignment(0); + } + } + } + else + { + //for whole frame + for (uint i = 0; i <= CurItem->itemText.nrOfParagraph(CurItem->itemText.lastInFrame()); i++) + { + if (CurItem->itemText.paragraphStyle(CurItem->itemText.startOfParagraph(i)).alignment() == 0) + { + CurItem->CPos = CurItem->itemText.startOfParagraph(i); + doc->itemSelection_SetAlignment(0); + } + + } + } + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); +// CurItem->asTextFrame()->lastAction4Paragraph = true; + } doc->itemSelection_SetAlignment(a); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); } void PropertiesPalette::setTypeStyle(int s) { if (!m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); emit NewEffects(s); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::newShadowOffs() { if ((HaveDoc) && (HaveItem)) { + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); int x = qRound(SeStyle->ShadowVal->Xoffset->value() * 10.0); int y = qRound(SeStyle->ShadowVal->Yoffset->value() * 10.0); doc->itemSelection_SetShadowOffsets(x, y); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } } @@ -4235,9 +4349,13 @@ { if ((HaveDoc) && (HaveItem)) { + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); int x = qRound(SeStyle->UnderlineVal->LPos->value() * 10.0); int y = qRound(SeStyle->UnderlineVal->LWidth->value() * 10.0); doc->itemSelection_SetUnderline(x, y); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } } @@ -4257,9 +4375,13 @@ { if ((HaveDoc) && (HaveItem)) { + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); int x = qRound(SeStyle->StrikeVal->LPos->value() * 10.0); int y = qRound(SeStyle->StrikeVal->LWidth->value() * 10.0); doc->itemSelection_SetStrikethru(x, y); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } } @@ -4288,7 +4410,13 @@ { int x = qRound(SeStyle->OutlineVal->LWidth->value() * 10.0); if ((HaveDoc) && (HaveItem)) + { + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetOutlineWidth(x); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); + } } void PropertiesPalette::DoLower() @@ -4614,7 +4742,11 @@ return; if (HaveDoc) { + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_EraseCharStyle(); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(doc->appMode == modeEdit? PageItem::PARAMSEL : PageItem::PARAMFULL); } } @@ -4625,9 +4757,17 @@ return; if (HaveDoc) { + if (CurItem->asTextFrame()) + { +// CurItem->asTextFrame()->ExpandParSel(); + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); +// CurItem->asTextFrame()->lastAction4Paragraph = true; + } doc->itemSelection_EraseParagraphStyle(); CharStyle emptyCStyle; doc->itemSelection_SetCharStyle(emptyCStyle); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(doc->appMode == modeEdit ? PageItem::PARAMSEL : PageItem::PARAMFULL); } } @@ -4773,14 +4913,23 @@ { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetFillColor(TxFill->currentColor()); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::newTxtStroke() { if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); doc->itemSelection_SetStrokeColor(TxStroke->currentColor()); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); + } void PropertiesPalette::setActShade() @@ -4788,6 +4937,8 @@ if (!HaveDoc || !HaveItem || !m_ScMW || m_ScMW->scriptIsRunning()) return; int b; + if (CurItem->asTextFrame()) + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::SELECTION : PageItem::FRAME); if (PM1 == sender()) { b = PM1->getValue(); @@ -4798,6 +4949,8 @@ b = PM2->getValue(); doc->itemSelection_SetFillShade(b); } + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(CurItem->HasSel? PageItem::PARAMSEL : PageItem::PARAMFULL); } void PropertiesPalette::setActFarben(QString p, QString b, double shp, double shb) @@ -4945,6 +5098,10 @@ return; CurItem->fillRule = EvenOdd->isChecked(); CurItem->update(); + qDebug() << "PropertiesPalette::handleFillRule() updateUNDO"; + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); + emit DocChanged(); } @@ -5028,6 +5185,11 @@ TabManager *dia = new TabManager(this, doc->unitIndex(), style.tabValues(), i2->columnWidth()); if (dia->exec()) { + if (CurItem->asTextFrame()) + { + CurItem->itemTextSaxed = CurItem->getItemTextSaxed(doc->appMode == modeEdit? PageItem::PARAGRAPH : PageItem::FRAME); +// CurItem->asTextFrame()->lastAction4Paragraph = true; + } if (doc->appMode != modeEdit) { ParagraphStyle newStyle(CurItem->itemText.defaultStyle()); @@ -5041,6 +5203,9 @@ doc->itemSelection_ApplyParagraphStyle(newStyle); } CurItem->update(); + if (CurItem->asTextFrame()) + CurItem->asTextFrame()->updateUndo(); + emit DocChanged(); } delete dia; Index: Scribus/scribus/undomanager.cpp =================================================================== --- Scribus/scribus/undomanager.cpp (wersja 16088) +++ Scribus/scribus/undomanager.cpp (kopia robocza) @@ -525,6 +526,11 @@ target->setUName(oldName); } +UndoState* UndoManager::getLastUndoState() +{ + return stacks_[currentDoc_].undoActions_[0]; +} + void UndoManager::undo(int steps) { if (!undoEnabled_) @@ -958,6 +964,7 @@ UndoManager::Copy = tr("Copy"); UndoManager::CopyPage = tr("Copy page"); UndoManager::ToOutlines = tr("Convert to outlines"); + UndoManager::EditText = tr("Edit text"); } void UndoManager::initIcons() @@ -1158,6 +1165,7 @@ QString UndoManager::Copy = ""; QString UndoManager::CopyPage = ""; QString UndoManager::ToOutlines = ""; +QString UndoManager::EditText = ""; /*** Icons for UndoObjects *******************************************/ QPixmap *UndoManager::IImageFrame = 0; Index: Scribus/scribus/loremipsum.cpp =================================================================== --- Scribus/scribus/loremipsum.cpp (wersja 16088) +++ Scribus/scribus/loremipsum.cpp (kopia robocza) @@ -311,6 +311,7 @@ continue; if (currItem->itemText.length() != 0) { + currItem->itemTextSaxed = currItem->getItemTextSaxed(PageItem::FRAME); m_Doc->itemSelection_ClearItem(); /* ClearItem() doesn't return true or false so the following test has to be done */ @@ -342,7 +343,12 @@ #endif // K.I.S.S.: - currItem->itemText.insertChars(0, lp->createLorem(paraCount, random)); + QString Lorip = lp->createLorem(paraCount, random); + currItem->itemText.insertChars(0, Lorip); + if (currItem->itemTextSaxed.isEmpty()) + currItem->asTextFrame()->updateUndo(PageItem::INS,Lorip); + else + currItem->asTextFrame()->updateUndo(PageItem::REPSAX, currItem->getTextSaxed(Lorip)); delete lp; //if (ScMW->view->SelItem.at(i)->Doc->docHyphenator->AutoCheck) Index: Scribus/scribus/undomanager.h =================================================================== --- Scribus/scribus/undomanager.h (wersja 16088) +++ Scribus/scribus/undomanager.h (kopia robocza) @@ -434,8 +434,11 @@ void setTexts(); public: - /** + * @brief Returns last saved Undo state + */ + UndoState* getLastUndoState(); + /** * @name Action strings * Strings describing undo actions */ @@ -585,6 +588,7 @@ static QString Copy; static QString CopyPage; static QString ToOutlines; + static QString EditText; /*@}*/ /** Index: Scribus/scribus/charselect.cpp =================================================================== --- Scribus/scribus/charselect.cpp (wersja 16088) +++ Scribus/scribus/charselect.cpp (kopia robocza) @@ -15,6 +15,7 @@ #include "scpaths.h" #include "scribusdoc.h" #include "scribusview.h" +#include "undomanager.h" #include "util.h" #include "util_icon.h" #include "charselectenhanced.h" @@ -106,16 +107,20 @@ void CharSelect::slot_insertSpecialChar() { emit insertSpecialChar(); - if (!m_Item) return; - if (m_Item->HasSel) + { + m_Item->itemTextSaxed = m_Item->getItemTextSaxed(PageItem::SELECTION); m_Item->asTextFrame()->deleteSelectedTextFromFrame(); + m_Item->asTextFrame()->lastUndoAction = PageItem::NOACTION; + } if (m_Item->asTextFrame()) m_Item->asTextFrame()->invalidateLayout(); //CB: Avox please make text->insertchar(char) so none of this happens in gui code, and item can tell doc its changed so the view and mainwindow slotdocch are not necessary QChar ch; + QString txtIns; + m_Item->oldCPos = m_Item->CPos; for (int a=0; a<chToIns.length(); ++a) { ch = chToIns.at(a); @@ -125,7 +130,12 @@ ch = QChar(32); m_Item->itemText.insertChars(m_Item->CPos, ch, true); m_Item->CPos += 1; + txtIns.append(ch); } + if (m_Item->itemTextSaxed.isEmpty()) + m_Item->asTextFrame()->updateUndo(PageItem::INS, txtIns); + else + m_Item->asTextFrame()->updateUndo(PageItem::REPSAX, m_Item->getTextSaxed(txtIns)); m_doc->updateFrameItems(); m_doc->view()->DrawNew(); m_doc->changed(); @@ -137,7 +147,11 @@ if (!m_Item) return; if (m_Item->HasSel) + { + m_Item->itemTextSaxed = m_Item->getItemTextSaxed(PageItem::SELECTION); m_Item->asTextFrame()->deleteSelectedTextFromFrame(); + m_Item->asTextFrame()->lastUndoAction = PageItem::NOACTION; + } if (m_Item->asTextFrame()) m_Item->asTextFrame()->invalidateLayout(); // //CB: Avox please make text->insertchar(char) so none of this happens in gui code, and item can tell doc its changed so the view and mainwindow slotdocch are not necessary @@ -145,7 +159,12 @@ ch = QChar(13); if (ch == QChar(9)) ch = QChar(32); + m_Item->oldCPos = m_Item->CPos; m_Item->itemText.insertChars(m_Item->CPos, ch, true); + if (m_Item->itemTextSaxed.isEmpty()) + m_Item->asTextFrame()->updateUndo(PageItem::INS, QString(ch)); + else + m_Item->asTextFrame()->updateUndo(PageItem::REPSAX, m_Item->getTextSaxed(QString(ch))); m_doc->updateFrameItems(); m_Item->CPos += 1; m_doc->view()->DrawNew(); Index: Scribus/scribus/canvasmode_edit.cpp =================================================================== --- Scribus/scribus/canvasmode_edit.cpp (wersja 16160) +++ Scribus/scribus/canvasmode_edit.cpp (kopia robocza) @@ -375,6 +377,7 @@ PageItem *currItem = 0; if (GetItem(&currItem) && (m_doc->appMode == modeEdit) && currItem->asTextFrame()) { + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; //CB if annotation, open the annotation dialog if (currItem->isAnnotation()) { @@ -619,7 +622,10 @@ qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor)); } if (currItem->asTextFrame()) + { m_view->slotSetCurs(m->globalPos().x(), m->globalPos().y()); + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; + } } else { @@ -636,6 +642,7 @@ //CB Where we set the cursor for a click in text frame if (currItem->asTextFrame()) { + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; inText = m_view->slotSetCurs(m->globalPos().x(), m->globalPos().y()); //CB If we clicked outside a text frame to go out of edit mode and deselect the frame if (!inText) @@ -644,6 +651,8 @@ m_view->Deselect(true); //m_view->slotDoCurs(true); m_view->requestMode(modeNormal); + if (currItem->isTextFrame()) + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; return; } @@ -668,6 +677,7 @@ oldP = currItem->itemText.endOfSelection(); } currItem->asTextFrame()->itemText.extendSelection(oldP, currItem->CPos); + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; oldCp = currItem->CPos; } else @@ -683,6 +693,7 @@ currItem->CPos = currItem->itemText.startOfParagraph(currItem->itemText.nrOfParagraph(currItem->CPos)); } currItem->asTextFrame()->ExpandSel(dir, oldP); + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; oldCp = oldP; } } @@ -690,6 +701,7 @@ { oldCp = currItem->CPos; currItem->itemText.deselectAll(); + currItem->asTextFrame()->lastUndoAction = PageItem::NOACTION; currItem->HasSel = false; } currItem->emitAllToGUI(); @@ -704,7 +716,9 @@ if (!cc.isNull()) { // K.I.S.S.: + currItem->oldCPos = 0; currItem->itemText.insertChars(0, cc, true); + currItem->asTextFrame()->updateUndo(PageItem::INS,cc); if (m_doc->docHyphenator->AutoCheck) m_doc->docHyphenator->slotHyphenate(currItem); m_ScMW->BookMarkTxT(currItem); @@ -722,6 +736,7 @@ else if (!currItem->asImageFrame() || m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), currItem) < 0) { + m_doc->m_Selection->delaySignalsOn(); m_view->Deselect(true); if (SeleItem(m)) { Index: Scribus/scribus/pageitem.h =================================================================== --- Scribus/scribus/pageitem.h (wersja 16088) +++ Scribus/scribus/pageitem.h (kopia robocza) @@ -167,7 +167,24 @@ TextFlowUsesContourLine = 3, TextFlowUsesImageClipping = 4 }; + //enum for actions in updateUndo and restoreEditText + typedef enum { + NOACTION = -1, //it is for checking if sequence of actions was done - after deselect text frame new sequence will be + PARAMFULL = 0, //parameters for whole frame + PARAMSEL = 1, //paramaters for selected text + DELSAX = 2, //delete with styles + INSSAX = 3, //insert with styles + REPSAX = 4, //replace with styles + INS = 5 //inserting chars without styles (from keyboard) + } EditAct; + typedef enum { // for recognise what was changing during text edition/changing + FRAME = 1, + PARAGRAPH = 2, + SELECTION = 3, + CHAR = 4 + } EditActPlace; + /* these do essentially the same as a dynamic cast but might be more readable */ virtual PageItem_ImageFrame * asImageFrame() { return NULL; } virtual PageItem_Line * asLine() { return NULL; } @@ -448,6 +465,11 @@ int CPos; /** Text des Elements */ StoryText itemText; + // for itemText undo purpose + int oldCPos; + QString itemTextSaxed; + QString getItemTextSaxed(EditActPlace undoItem); + QString getTextSaxed(QString str); /** Flag fuer PDF-Bookmark */ bool isBookmark; /** Flag for redraw in EditMode */ @@ -1060,6 +1082,8 @@ void restoreShapeContour(UndoState *state, bool isUndo); void restoreImageEffects(UndoState *state, bool isUndo); + void restoreEditText(SimpleState *state, bool isUndo); + /*@}*/ /** Index: Scribus/scribus/pageitem_textframe.h =================================================================== --- Scribus/scribus/pageitem_textframe.h (wersja 16088) +++ Scribus/scribus/pageitem_textframe.h (kopia robocza) @@ -66,6 +66,7 @@ void deleteSelectedTextFromFrame(); void setNewPos(int oldPos, int len, int dir); void ExpandSel(int dir, int oldPos); + void ExpandParSel(); //expand selection to whole paragrpah(s) void deselectAll(); virtual void invalidateLayout(); @@ -104,7 +105,9 @@ void setShadow(); QString currentShadow; QMap<QString,StoryText> shadows; - +public: + void updateUndo(EditAct action = PARAMFULL, QString str = ""); + EditAct lastUndoAction; private slots: void slotInvalidateLayout(); }; |
|
subeditor - I create new bug for cursor jumps http://bugs.scribus.net/view.php?id=9735 If you notice this behave also you can describe it there. I am 100% sure it is not related with text undo patch, but it is still strange issue we must solving. |
|
Yes, it's very possible, true reason for posting this issue here was the fact that I avoid text editing withou your patch, so I could catch it only with your patch installed. |
|
Ok, the latest patch is in svn rev 16342 |
|
I am not resolving this, until its out in the wold. |
|
Resolving, this is in 1.4.0.rc1 |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-12-10 14:59 | cezaryece | New Issue | |
2010-12-10 14:59 | cezaryece | File Added: textUndo.patch | |
2010-12-10 22:41 | subeditor | Note Added: 0025058 | |
2010-12-13 08:57 | cezaryece | Note Added: 0025099 | |
2010-12-13 09:26 | cezaryece | Note Added: 0025100 | |
2010-12-14 03:58 | cbradney | Target Version | => 1.4.0 |
2010-12-23 09:39 | subeditor | Note Added: 0025183 | |
2010-12-23 10:48 | subeditor | Note Edited: 0025183 | |
2010-12-23 21:49 | ale | Note Added: 0025188 | |
2010-12-24 09:21 | subeditor | Note Added: 0025191 | |
2010-12-24 13:12 | ale | Note Added: 0025192 | |
2010-12-25 00:26 | cezaryece | Note Added: 0025196 | |
2010-12-25 00:26 | cezaryece | File Added: undoText2.patch | |
2010-12-25 18:03 | subeditor | Note Added: 0025197 | |
2010-12-25 20:37 | cezaryece | Note Added: 0025198 | |
2010-12-25 21:04 | subeditor | Note Added: 0025199 | |
2010-12-25 22:11 | cezaryece | Note Added: 0025200 | |
2010-12-25 22:21 |
|
Assigned To | => avox |
2010-12-25 22:21 |
|
Status | new => assigned |
2010-12-25 23:41 | subeditor | Note Added: 0025201 | |
2010-12-29 08:52 | ale | Note Added: 0025215 | |
2010-12-30 18:02 | cezaryece | File Added: undoText2.1.patch | |
2010-12-30 18:06 | cezaryece | Note Added: 0025222 | |
2010-12-30 18:23 | ale | Note Edited: 0025222 | |
2010-12-30 18:29 | cezaryece | Note Edited: 0025222 | |
2011-01-02 13:02 | cbradney | Relationship added | has duplicate 0009522 |
2011-01-07 20:13 | cbradney | Note Added: 0025305 | |
2011-01-10 20:07 |
|
Relationship added | has duplicate 0009665 |
2011-01-12 07:50 | cezaryece | Note Added: 0025348 | |
2011-01-12 08:20 | jghali | File Deleted: textUndo.patch | |
2011-01-12 08:20 | jghali | File Deleted: undoText2.patch | |
2011-01-12 08:20 | jghali | Note Added: 0025352 | |
2011-01-20 12:45 | subeditor | Note Added: 0025446 | |
2011-01-20 21:55 | ale | Note Added: 0025453 | |
2011-01-27 09:41 | subeditor | Note Added: 0025484 | |
2011-01-27 10:15 | subeditor | Note Added: 0025485 | |
2011-01-28 09:11 | ale | Note Added: 0025490 | |
2011-01-28 09:35 | subeditor | Note Added: 0025491 | |
2011-01-30 12:45 | cezaryece | Note Added: 0025496 | |
2011-01-30 12:45 | cezaryece | File Added: undoText2.2.patch | |
2011-01-30 15:31 | cezaryece | Note Edited: 0025496 | |
2011-01-30 15:46 | cbradney | File Deleted: undoText2.1.patch | |
2011-02-09 07:20 | cezaryece | Note Added: 0025547 | |
2011-02-09 12:16 | subeditor | Note Added: 0025548 | |
2011-02-09 15:24 |
|
Note Added: 0025550 | |
2011-02-09 15:25 |
|
Note Added: 0025551 | |
2011-02-09 15:25 |
|
Severity | text => feature |
2011-02-09 15:25 |
|
Resolution | open => fixed |
2011-02-09 15:25 |
|
Fixed in Version | => 1.4.0svn |
2011-02-09 15:25 |
|
Target Version | 1.4.0 => 1.4.0svn |
2011-02-09 17:42 | cbradney | Relationship added | has duplicate 0003301 |
2011-02-09 17:44 | cbradney | Relationship added | has duplicate 0008744 |
2011-02-09 17:52 | cbradney | Relationship added | has duplicate 0003445 |
2011-03-06 16:55 | cbradney | Note Added: 0025746 | |
2011-03-06 16:55 | cbradney | Status | assigned => resolved |
2011-03-06 16:55 | cbradney | Assigned To | avox => plinnell |
2011-03-06 16:56 | cbradney | Issue cloned: 0009802 | |
2011-03-07 19:07 | cbradney | Status | resolved => closed |