View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0009156 | Scribus | Canvas | public | 2010-06-10 20:41 | 2012-06-19 19:39 |
Reporter | pspencer | Assigned To | cezaryece | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | linux | OS | Fedora | OS Version | 10 |
Product Version | 1.3.7 | ||||
Target Version | 1.5.0 | Fixed in Version | 1.5.0svn | ||
Summary | 0009156: Feature: adjust frame to contents for text frames | ||||
Description | This is one of what will be several feature-request reports I will be filing over the next few weeks, after we tried unsuccessfully to persuade someone to use Scribus so we didn't have to maintain an InDesign installation and she came up with a list of specific shortcomings of Scribus versus InDesign for her work. In InDesign you can double-click the bottom of a text frame to automatically adjust the frame's height to fit the contents, and can double-click the bottom-right to automatically adjust both the width and the height for "optimal" text flow (using some algorithm I don't entirely understand, but whose most useful purpose is to shrink both the width and the height of a single-line text frame). This is very useful for typesetting frames with short one-line captions, and for adjusting frame height after altering text content, rather than having to drag to a manually chosen height. The attached patch implements this. If the bottom frame handle is double-clicked, it adjusts the height to find the smallest height that doesn't cause overflow (but won't go smaller than 10 points or larger than to the bottom of the page). If the bottom-right corner is double-clicked, it first adjusts the height and then tries to shrink the width as much as possible without creating overflow. For a text frame that links to another frame, where there is already overflow into the other frame, it simply reduces height/width as much as possible without pushing additional characters into the other frame. I first tried to implement this by seeing how much free space was left over then reducing height by a corresponding amount, but could see no way to make that work with frames of non-rectangular shape or frames with multiple columns where the column breaks might be influenced by other factors. So instead it now just does a straight binary search. The trial resizings are not entered into the undo mechanism, but after the trial and error process the original dimensions are restored then an undoable change is made to the new size. | ||||
Tags | usability | ||||
Patch | |||||
|
Arggh, just noticed I after hitting Submit that I submitted a bad patch (forgot the page offset). I'll upload a corrected one in a few minutes. |
|
scribus-1.3.7-textsnap-corrected.patch (3,432 bytes)
--- Scribus-orig/scribus/canvasmode_normal.cpp 2010-06-07 15:24:19.000000000 -0400 +++ Scribus/scribus/canvasmode_normal.cpp 2010-06-10 14:07:54.000000000 -0400 @@ -212,6 +212,10 @@ } else if (currItem->itemType() == PageItem::TextFrame) { + // See if double click was on a frame handle + FPoint p = m_canvas->globalToCanvas(m->globalPos()); + Canvas::FrameHandle fh = m_canvas->frameHitTest(QPointF(p.x(),p.y()), currItem); + //CB old code //emit currItem->isAnnotation() ? AnnotProps() : Amode(modeEdit); //mousePressEvent(m); @@ -222,6 +226,80 @@ m_view->requestMode(submodeAnnotProps); //mousePressEvent(m); } + + //else if on the south or southeast frame handle, + //adjust text frame size to fit contents + else if (fh == Canvas::SOUTH || fh == Canvas::SOUTHEAST) { + currItem->layout(); + double w = currItem->width(); + double h = currItem->height(); + double worig = w; // Remember original width and height + double horig = h; + // Bounds of binary search for optimal height: + // hmin = too small (text overflows, or + // box would be unreasonably short (< 10pt)) + // hmax = big enough (text does not overflow, + // or box is as big as will fit on page) + double hmin = 10; + double hmax = qMax(10.0, m_doc->Pages->at(currItem->OwnPage)->yOffset() + m_doc->Pages->at(currItem->OwnPage)->height() - currItem->yPos()); + // Criterion for "text overflows": + // If no linked frame after this one, + // normal meaning of "overflows". + // If linked frame after this one, + // means more characters get shifted + // to that frame than are currently + PageItem *next = currItem->nextInChain(); + int lc = currItem->lastInFrame(); + + if (h > hmax) h = hmax; + if (h < hmin) h = hmin; + while (hmax - hmin > 0.1) { + if (next ? currItem->lastInFrame() < lc : currItem->frameOverflows()) { + hmin = h; + h = (h+hmax)/2.0; + } else { + hmax = h; + h = (h+hmin)/2.0; + } + currItem->setWidthHeight(w,h,true); + currItem->invalidateLayout(); + currItem->updateClip(); + currItem->layout(); + } + // hmax is now the height we want. + // If on southeast frame point, also + // shrink width until text overflows. + double wmin = 10; + double wmax = w; + if (fh == Canvas::SOUTHEAST) { + currItem->setWidthHeight(w,hmax,true); + currItem->invalidateLayout(); + currItem->updateClip(); + currItem->layout(); + while (wmax - wmin > 0.1) { + if (next ? currItem->lastInFrame() < lc : currItem->frameOverflows()) { + wmin = w; + w = (w+wmax)/2.0; + } else { + wmax = w; + w = (w+wmin)/2.0; + } + currItem->setWidthHeight(w,hmax,true); + currItem->invalidateLayout(); + currItem->updateClip(); + currItem->layout(); + } + } + // Restore original width, height for undo manager to remember + currItem->setWidthHeight(worig,horig,true); + // then set new width and height + currItem->setWidthHeight(wmax,hmax,false); + currItem->invalidateLayout(); + currItem->updateClip(); + currItem->layout(); + m_doc->regionsChanged()->update(QRect()); + } + //else if not in mode edit, set mode edit else if (m_doc->appMode != modeEdit) { |
|
@pspencer I like that "bottom of a text frame to automatically adjust the frame's height to fit the contents", saves a lot of clicks in newspaper layout. Reading your patch code: your patch fires only if frame handle is double-clicked. I feel there should be a key and/or menu entry for this, as double clicking on frames is very messy in scribus. More general: clicking on specific parts on scribus frames is a major usability problem, as you dont know which frame will be selected on a page with many overlapping frames. A workaround is using layers. |
|
i think that cezary is working on this... |
|
First initial patch for that issue. For now it only brings two features: 1. adjusting text frame height to last line(s) descents (no matter if text fits in frame or flow away - frame`s height only shrinks to descents in last lines Action has menu and contextmenu entry and is applicable by double click on bottom frame handle. 2. resize item size to page margin (in direction from which handle is clicked - right handle - resize to right margin, left handle - left margin, bottom/right handle - to bottom/left margin corner). As benefit it is working for all frames (image, render). Patch is attached, you can see also autoheight branch in our scribus.git repo. |
|
autoheight.diff (21,389 bytes)
diff --git a/Scribus/scribus/actionmanager.cpp b/Scribus/scribus/actionmanager.cpp index b0348b1..60c01e1 100644 --- a/Scribus/scribus/actionmanager.cpp +++ b/Scribus/scribus/actionmanager.cpp @@ -449,6 +449,8 @@ void ActionManager::initItemMenuActions() scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow)); name="tableAdjustFrameToTable"; scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow)); + name="itemAdjustFrameHeightToText"; + scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow)); name = "tableAdjustTableToFrame"; scrActions->insert(name, new ScrAction("", defaultKey(name), mainWindow)); name="itemAdjustFrameToImage"; @@ -1107,6 +1109,7 @@ void ActionManager::disconnectNewDocActions() disconnect( (*scrActions)["tableDistributeColumnsEvenly"], 0, 0, 0 ); disconnect( (*scrActions)["tableAdjustFrameToTable"], 0, 0, 0 ); disconnect( (*scrActions)["tableAdjustTableToFrame"], 0, 0, 0 ); + disconnect( (*scrActions)["itemAdjustFrameHeightToText"], 0, 0, 0 ); disconnect( (*scrActions)["itemAdjustFrameToImage"], 0, 0, 0 ); disconnect( (*scrActions)["itemAdjustImageToFrame"], 0, 0, 0 ); disconnect( (*scrActions)["itemLock"], 0, 0, 0); @@ -1129,7 +1132,6 @@ void ActionManager::disconnectNewDocActions() disconnect( (*scrActions)["itemRaise"], 0, 0, 0); disconnect( (*scrActions)["toolsUnlinkTextFrameWithTextCopy"], 0, 0, 0 ); disconnect( (*scrActions)["toolsUnlinkTextFrameWithTextCut"], 0, 0, 0 ); - } void ActionManager::connectNewDocActions(ScribusDoc *currDoc) @@ -1159,6 +1161,7 @@ void ActionManager::connectNewDocActions(ScribusDoc *currDoc) connect( (*scrActions)["tableDistributeColumnsEvenly"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_DistributeTableColumnsEvenly())); connect( (*scrActions)["tableAdjustFrameToTable"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_AdjustFrameToTable())); connect( (*scrActions)["tableAdjustTableToFrame"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_AdjustTableToFrame())); + connect( (*scrActions)["itemAdjustFrameHeightToText"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_AdjustFrameHeightToText()) ); connect( (*scrActions)["itemAdjustFrameToImage"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_AdjustFrametoImageSize()) ); connect( (*scrActions)["itemAdjustImageToFrame"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_AdjustImagetoFrameSize()) ); connect( (*scrActions)["itemsUnWeld"], SIGNAL(triggered()), currDoc, SLOT(itemSelection_UnWeld()) ); @@ -1464,6 +1467,7 @@ void ActionManager::languageChange() (*scrActions)["tableDistributeColumnsEvenly"]->setTexts(tr("Distribute Columns Evenly")); (*scrActions)["tableAdjustFrameToTable"]->setTexts(tr("Adjust Frame to Table")); (*scrActions)["tableAdjustTableToFrame"]->setTexts(tr("Adjust Table to Frame")); + (*scrActions)["itemAdjustFrameHeightToText"]->setTexts( tr("Adjust Frame Height to Text")); (*scrActions)["itemAdjustFrameToImage"]->setTexts( tr("Adjust Frame to Image")); (*scrActions)["itemAdjustImageToFrame"]->setTexts( tr("Adjust Image to Frame")); (*scrActions)["itemToggleInlineImage"]->setTexts( tr("Embed Image")); @@ -1939,7 +1943,9 @@ void ActionManager::createDefaultMenus() << "tableDistributeRowsEvenly" << "tableDistributeColumnsEvenly" << "tableAdjustFrameToTable" + << "itemAdjustFrameHeightToText" << "tableAdjustTableToFrame" + << "itemAdjustFrameHeightToText" << "itemAdjustFrameToImage" << "itemAdjustImageToFrame" << "itemToggleInlineImage" diff --git a/Scribus/scribus/canvasgesture_resize.cpp b/Scribus/scribus/canvasgesture_resize.cpp index e4780a1..1588d10 100644 --- a/Scribus/scribus/canvasgesture_resize.cpp +++ b/Scribus/scribus/canvasgesture_resize.cpp @@ -183,6 +183,12 @@ void ResizeGesture::mouseReleaseEvent(QMouseEvent *m) if (currItem->asImageFrame()) currItem->AdjustPictScale(); } + else if (m->button() == Qt::RightButton) + { + const FPoint mousePointDoc = m_canvas->globalToCanvas(m->globalPos()); + Canvas::FrameHandle fh = m_canvas->frameHitTest(QPointF(mousePointDoc.x(),mousePointDoc.y()), currItem); + currItem->resizeToMargin(fh); + } m_view->resetMousePressed(); // necessary since mousebutton is still recorded pressed, and otherwise checkchanges() will do nothing // we must check changes on whole selection otherwise resize operation won't undo correctly on groups diff --git a/Scribus/scribus/canvasmode_normal.cpp b/Scribus/scribus/canvasmode_normal.cpp index 3007ba5..ee0ce5c 100644 --- a/Scribus/scribus/canvasmode_normal.cpp +++ b/Scribus/scribus/canvasmode_normal.cpp @@ -223,6 +223,9 @@ void CanvasMode_Normal::mouseDoubleClickEvent(QMouseEvent *m) } else if (currItem->itemType() == PageItem::TextFrame) { + // See if double click was on a frame handle + FPoint p = m_canvas->globalToCanvas(m->globalPos()); + Canvas::FrameHandle fh = m_canvas->frameHitTest(QPointF(p.x(),p.y()), currItem); //CB old code //emit currItem->isAnnotation() ? AnnotProps() : Amode(modeEdit); //mousePressEvent(m); @@ -233,6 +236,8 @@ void CanvasMode_Normal::mouseDoubleClickEvent(QMouseEvent *m) m_view->requestMode(submodeAnnotProps); //mousePressEvent(m); } + else if (fh == Canvas::SOUTH) + currItem->asTextFrame()->setTextFrameHeight(); //else if not in mode edit, set mode edit else if (m_doc->appMode != modeEdit) { diff --git a/Scribus/scribus/pageitem.cpp b/Scribus/scribus/pageitem.cpp index edf0a74..05ede18 100644 --- a/Scribus/scribus/pageitem.cpp +++ b/Scribus/scribus/pageitem.cpp @@ -7470,3 +7470,52 @@ void PageItem::unWeld() } weldList.clear(); } + + +void PageItem::resizeToMargin(Canvas::FrameHandle direction) +{ + //FIX ME: for now avoid for rotated items + if (rotation() != 0) + return; + ScPage *currPage = m_Doc->Pages->at(OwnPage); + QMatrix ma; + ma.translate(xPos(), yPos()); + double inX = ma.dx() - m_Doc->rulerXoffset; + double inY = ma.dy() - m_Doc->rulerYoffset; + if (m_Doc->guidesPrefs().rulerMode) + { + inX -= m_Doc->currentPage()->xOffset(); + inY -= m_Doc->currentPage()->yOffset(); + } + if (direction == Canvas::NORTH || direction == Canvas::NORTHWEST || direction == Canvas::NORTHEAST) + { + double top = currPage->topMargin(); + double dY = inY - top; + moveBy(0, -dY); + setHeight(height() + dY); + } + if (direction == Canvas::SOUTH || direction == Canvas::SOUTHWEST || direction == Canvas::SOUTHEAST) + { + double bottom = currPage->height() - currPage->bottomMargin(); + double dY = bottom - (inY + height()); + setHeight(height() + dY); + } + if (direction == Canvas::EAST || direction == Canvas::NORTHEAST || direction == Canvas::SOUTHEAST) + { + double right = currPage->width() - currPage->rightMargin(); + double dX = right - (inX + width()); + setWidth(width() + dX); + } + if (direction == Canvas::WEST || direction == Canvas::NORTHWEST || direction == Canvas::SOUTHWEST) + { + double left = currPage->leftMargin(); + double dX = inX - left; + moveBy(-dX,0); + setWidth(width() + dX); + } + + updateClip(); + invalid = true; + m_Doc->changed(); + m_Doc->regionsChanged()->update(QRect()); +} diff --git a/Scribus/scribus/pageitem.h b/Scribus/scribus/pageitem.h index 19b877f..7a71637 100644 --- a/Scribus/scribus/pageitem.h +++ b/Scribus/scribus/pageitem.h @@ -38,6 +38,7 @@ for which a new license (GPL+exception) is in place. #include "scribusapi.h" #include "annotation.h" +#include "canvas.h" #include "colormgmt/sccolormgmtstructs.h" #include "desaxe/saxio.h" #include "observable.h" @@ -1574,8 +1575,11 @@ signals: //void textToFrameDistances(double, double, double, double); //left, top, bottom, right: Extra, TExtra, BExtra, RExtra //FIXME: columns, grid ? - //items welding (item follows while item moves which they are connected with) public: + //resize item to margin in direction given from clicked handle + void resizeToMargin(Canvas::FrameHandle direction); + + //items welding (item follows while item moves which they are connected with) struct weldingInfo { PageItem *weldItem; diff --git a/Scribus/scribus/pageitem_textframe.cpp b/Scribus/scribus/pageitem_textframe.cpp index 23ad9c1..de8d15a 100644 --- a/Scribus/scribus/pageitem_textframe.cpp +++ b/Scribus/scribus/pageitem_textframe.cpp @@ -1427,6 +1427,7 @@ void PageItem_TextFrame::layout() current.mustLineEnd = current.colRight; current.restartX = 0; int lastStat = 0, curStat = 0; + setMaxY(-1); for (int a = firstInFrame(); a < itemText.length(); ++a) { @@ -1823,7 +1824,7 @@ void PageItem_TextFrame::layout() } } current.recalculateY = true; - int maxYAsc = 0, maxYDesc = 0; + double maxYAsc = 0.0, maxYDesc = 0.0; if (current.startOfCol) { //qMax is used for glyphs shifted or vertically scalled above ascent or below descent @@ -1835,13 +1836,13 @@ void PageItem_TextFrame::layout() else if (firstLineOffset() == FLOPLineSpacing) addAsce = style.lineSpacing(); } - maxYAsc = static_cast<int>(floor(current.yPos - addAsce)); + maxYAsc = current.yPos - addAsce; } else - maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce))); + maxYAsc = current.yPos - qMax(realAsce, asce); //fix for glyphs with negative realAsce value - maxYAsc = qMax(maxYAsc, 0); - maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc))); + maxYAsc = qMax(maxYAsc, 0.0); + maxYDesc = current.yPos + qMax(realDesc, desc); if (current.itemsInLine == 0 && !current.afterOverflow) { @@ -1849,8 +1850,8 @@ void PageItem_TextFrame::layout() goNoRoom = false; // find line`s start - pt1 = QPoint(static_cast<int>(floor(current.xPos)), maxYAsc); - pt2 = QPoint(static_cast<int>(ceil(current.xPos + (style.minGlyphExtension() * wide))),maxYDesc); + pt1 = QPoint(static_cast<int>(floor(current.xPos)), static_cast<int>(floor(maxYAsc))); + pt2 = QPoint(static_cast<int>(ceil(current.xPos + (style.minGlyphExtension() * wide))), static_cast<int>(ceil(maxYDesc))); pt = QRect(pt1, pt2); realEnd = 0; //check if there is overflow at start of line, if so jump behind it and check again @@ -1877,7 +1878,7 @@ void PageItem_TextFrame::layout() //check if in indent any overflow occurs while (Xpos <= Xend && Xpos < current.colRight) { - pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)),maxYAsc)); + pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)), static_cast<int>(floor(maxYAsc)))); if (!regionContainsRect(m_availableRegion, pt)) { Xpos = current.xPos = realEnd = findRealOverflowEnd(m_availableRegion, pt, current.colRight); @@ -1909,7 +1910,7 @@ void PageItem_TextFrame::layout() current.yPos += (current.startOfCol ? 1 : style.lineSpacing()); else current.yPos++; - lastLineY = maxYAsc +1; + lastLineY = maxYAsc; if (current.startOfCol) { //qMax is used for glyphs shifted or vertically scalled above ascent or below descent @@ -1921,13 +1922,13 @@ void PageItem_TextFrame::layout() else if (firstLineOffset() == FLOPLineSpacing) addAsce = style.lineSpacing(); } - maxYAsc = static_cast<int>(floor(current.yPos - addAsce)); + maxYAsc = current.yPos - addAsce; } else - maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce))); - maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc))); + maxYAsc = current.yPos - qMax(realAsce, asce); + maxYDesc = current.yPos + qMax(realDesc, desc); - pt.moveTopLeft(QPoint(static_cast<int>(floor(current.xPos)),maxYAsc)); + pt.moveTopLeft(QPoint(static_cast<int>(floor(current.xPos)), static_cast<int>(floor(maxYAsc)))); done = false; } if (current.isEndOfCol(realDesc)) @@ -2220,24 +2221,24 @@ void PageItem_TextFrame::layout() { if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN) { - pt1 = QPoint(charStart, maxYAsc); - pt2 = QPoint(static_cast<int>(charEnd + hyphWidth), maxYDesc); + pt1 = QPoint(charStart, static_cast<int>(floor(maxYAsc))); + pt2 = QPoint(static_cast<int>(charEnd + hyphWidth), static_cast<int>(ceil(maxYDesc))); } else { - pt1 = QPoint(charStart, maxYAsc); - pt2 = QPoint(charEnd, maxYDesc); + pt1 = QPoint(charStart, static_cast<int>(floor(maxYAsc))); + pt2 = QPoint(charEnd, static_cast<int>(ceil(maxYDesc))); } } else if (!legacy && SpecialChars::isBreakingSpace(hl->ch)) { - pt1 = QPoint(static_cast<int>(qMax(floor(breakPos - current.maxShrink - (style.minGlyphExtension() * wide)),0.0)), maxYAsc); - pt2 = QPoint(charEnd, maxYDesc); + pt1 = QPoint(static_cast<int>(qMax(floor(breakPos - current.maxShrink - (style.minGlyphExtension() * wide)),0.0)), static_cast<int>(floor(maxYAsc))); + pt2 = QPoint(charEnd, static_cast<int>(ceil(maxYDesc))); } else { - pt1 = QPoint(charStart, maxYAsc); - pt2 = QPoint(charEnd, maxYDesc); + pt1 = QPoint(charStart, static_cast<int>(floor(maxYAsc))); + pt2 = QPoint(charEnd, static_cast<int>(ceil(maxYDesc))); } pt = QRect(pt1, pt2); if (!regionContainsRect(m_availableRegion, pt)) @@ -2323,6 +2324,8 @@ void PageItem_TextFrame::layout() else inOverflow = true; } + else + setMaxY(maxYDesc); } // hyphenation @@ -2399,7 +2402,7 @@ void PageItem_TextFrame::layout() { // find end of line current.breakLine(itemText, style, firstLineOffset(), a); - EndX = current.endOfLine(m_availableRegion, style.rightMargin(), maxYAsc, maxYDesc); + EndX = current.endOfLine(m_availableRegion, style.rightMargin(), static_cast<int>(floor(maxYAsc)), static_cast<int>(ceil(maxYDesc))); current.finishLine(EndX); //addLine = true; assert(current.addLine); @@ -2476,7 +2479,7 @@ void PageItem_TextFrame::layout() current.updateHeightMetrics(itemText); //current.updateLineOffset(itemText, style, firstLineOffset()); //current.xPos = current.breakXPos; - EndX = current.endOfLine(m_availableRegion, current.rightMargin, maxYAsc, maxYDesc); + EndX = current.endOfLine(m_availableRegion, current.rightMargin, static_cast<int>(floor(maxYAsc)), static_cast<int>(ceil(maxYDesc))); current.finishLine(EndX); hyphWidth = 0.0; @@ -2549,7 +2552,11 @@ void PageItem_TextFrame::layout() } goNextColumn = true; } + else + setMaxY(maxYDesc); } + else + setMaxY(maxYDesc); if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0) { if (current.addLine && current.breakIndex >= 0) @@ -2563,6 +2570,7 @@ void PageItem_TextFrame::layout() fillInTabLeaders(itemText, current.line); //if right margin is set we temporally save line, not append it itemText.appendLine(current.line); + setMaxY(maxYDesc); current.restartIndex = current.line.lastItem +1; a = current.restartIndex -1; current.rowDesc = qMax(current.rowDesc,current.yPos + current.line.descent); @@ -2606,7 +2614,6 @@ void PageItem_TextFrame::layout() maxDX = 0; } } - lastLineY = current.rowDesc; current.mustLineEnd = current.colRight; current.restartRowIndex = current.restartIndex; } @@ -2749,6 +2756,7 @@ void PageItem_TextFrame::layout() goNextColumn = false; itemText.appendLine(current.line); + setMaxY(maxYDesc); current.startOfCol = false; if (moveLinesFromPreviousFrame ()) { @@ -4202,7 +4210,10 @@ void PageItem_TextFrame::applicableActions(QStringList & actionList) } actionList << "itemConvertToOutlines"; if (itemText.lines() != 0) + { actionList << "editClearContents"; + actionList << "itemAdjustFrameHeightToText"; + } } QString PageItem_TextFrame::infoDescription() @@ -4214,3 +4225,20 @@ void PageItem_TextFrame::slotInvalidateLayout() { invalidateLayout(); } + +void PageItem_TextFrame::setMaxY(double y) +{ + if (y == -1) + maxY = 0; + else + maxY = qMax(y, maxY); +} + +void PageItem_TextFrame::setTextFrameHeight() +{ + setHeight(ceil(maxY) + BExtra + 0.5); + updateClip(); + invalid = true; + m_Doc->changed(); + m_Doc->regionsChanged()->update(QRect()); +} diff --git a/Scribus/scribus/pageitem_textframe.h b/Scribus/scribus/pageitem_textframe.h index d178410..50bd63d 100644 --- a/Scribus/scribus/pageitem_textframe.h +++ b/Scribus/scribus/pageitem_textframe.h @@ -116,6 +116,13 @@ private: QMap<QString,StoryText> shadows; bool checkKeyIsShortcut(QKeyEvent *k); + // set text frame height to last line of text + double maxY; + void setMaxY(double y); + +public: + void setTextFrameHeight(); + private slots: void slotInvalidateLayout(); }; diff --git a/Scribus/scribus/scribus.cpp b/Scribus/scribus/scribus.cpp index 7058096..a44a2ac 100644 --- a/Scribus/scribus/scribus.cpp +++ b/Scribus/scribus/scribus.cpp @@ -799,6 +799,7 @@ void ScribusMainWindow::initMenuBar() scrMenuMgr->addMenuSeparator("Item"); // End Table submenu. scrMenuMgr->addMenuSeparator("Item"); + scrMenuMgr->addMenuItem(scrActions["itemAdjustFrameHeightToText"], "Item", false); scrMenuMgr->addMenuItem(scrActions["itemAdjustFrameToImage"], "Item", false); scrMenuMgr->addMenuItem(scrActions["itemAdjustImageToFrame"], "Item", false); scrMenuMgr->addMenuItem(scrActions["itemUpdateImage"], "Item", false); @@ -2644,6 +2645,7 @@ void ScribusMainWindow::HaveNewSel(int SelectedType) #else scrActions["editEditRenderSource"]->setEnabled(SelectedType==PageItem::ImageFrame && currItem && (currItem->asLatexFrame())); #endif + scrActions["itemAdjustFrameHeightToText"]->setEnabled(SelectedType==PageItem::TextFrame && currItem->itemText.length() >0); if (SelectedType!=PageItem::ImageFrame) { scrActions["itemImageIsVisible"]->setChecked(false); diff --git a/Scribus/scribus/scribusdoc.cpp b/Scribus/scribus/scribusdoc.cpp index 282e200..d6869d4 100644 --- a/Scribus/scribus/scribusdoc.cpp +++ b/Scribus/scribus/scribusdoc.cpp @@ -14389,6 +14389,31 @@ void ScribusDoc::itemSelection_AdjustImagetoFrameSize( Selection *customSelectio } } +void ScribusDoc::itemSelection_AdjustFrameHeightToText( Selection *customSelection) +{ + Selection* itemSelection = (customSelection!=0) ? customSelection : m_Selection; + assert(itemSelection!=0); + uint selectedItemCount=itemSelection->count(); + if (selectedItemCount == 0) + return; + + if (selectedItemCount > 0) + { + for (uint i = 0; i < selectedItemCount; ++i) + { + PageItem *currItem = itemSelection->itemAt(i); + if (currItem!=NULL) + { + if (currItem->asTextFrame() && (currItem->itemText.length() > 0) && !currItem->isTableItem) + currItem ->asTextFrame()->setTextFrameHeight(); + } + } + regionsChanged()->update(QRectF()); + changed(); + itemSelection->itemAt(0)->emitAllToGUI(); + } +} + void ScribusDoc::itemSelection_AdjustFrameToTable() { // TODO: Do this in an undo transaction? diff --git a/Scribus/scribus/scribusdoc.h b/Scribus/scribus/scribusdoc.h index ad46b78..34b2aba 100644 --- a/Scribus/scribus/scribusdoc.h +++ b/Scribus/scribus/scribusdoc.h @@ -1452,6 +1452,7 @@ public slots: * Adjust an image size to fit the size of the frame */ void itemSelection_AdjustImagetoFrameSize(Selection* customSelection=0); + void itemSelection_AdjustFrameHeightToText( Selection *customSelection=0); //! @brief startArrowID or endArrowID of -1 mean not applying a selection at this point. void itemSelection_ApplyArrowHead(int startArrowID=-1, int endArrowID=-1, Selection* customSelection=0); void itemSelection_ApplyArrowScale(int startArrowSc, int endArrowSc, Selection* customSelection); diff --git a/Scribus/scribus/ui/contextmenu.cpp b/Scribus/scribus/ui/contextmenu.cpp index 3edd30c..5906998 100644 --- a/Scribus/scribus/ui/contextmenu.cpp +++ b/Scribus/scribus/ui/contextmenu.cpp @@ -216,7 +216,8 @@ void ContextMenu::createMenuItems_Selection() addAction(m_AP->scrActions["tableAdjustFrameToTable"]); if (m_actionList.contains("tableAdjustTableToFrame")) addAction(m_AP->scrActions["tableAdjustTableToFrame"]); - + if (m_actionList.contains("itemAdjustFrameHeightToText")) + addAction(m_AP->scrActions["itemAdjustFrameHeightToText"]); if (m_actionList.contains("itemExtendedImageProperties")) addAction(m_AP->scrActions["itemExtendedImageProperties"]); if (m_actionList.contains("itemAdjustFrameToImage")) @@ -270,6 +271,11 @@ void ContextMenu::createMenuItems_Selection() } } + if ((selectedItemCount==1) && currItem->asTextFrame()) + { + if (currItem->itemText.length() > 0) + m_AP->scrActions["itemAdjustFrameHeightToText"]->setEnabled(true); + } } //--> |
|
First part committed.. I'd prefer other options for activating 2) and it to be in scribusdoc probably rather than pageitem. |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-06-10 20:41 | pspencer | New Issue | |
2010-06-10 20:41 | pspencer | File Added: scribus-1.3.7-textsnap.patch | |
2010-06-10 20:46 | pspencer | Note Added: 0024036 | |
2010-06-10 21:09 | pspencer | File Added: scribus-1.3.7-textsnap-corrected.patch | |
2010-06-11 21:27 | jghali | File Deleted: scribus-1.3.7-textsnap.patch | |
2010-06-11 21:29 | jghali | Target Version | => 1.5.0 |
2012-01-06 08:49 | StefanM | Tag Attached: usability | |
2012-01-06 09:14 | StefanM | Note Added: 0027473 | |
2012-06-18 06:33 | ale | Note Added: 0028180 | |
2012-06-18 19:25 | ale | Assigned To | => cezaryece |
2012-06-18 19:25 | ale | Status | new => assigned |
2012-06-19 13:59 | cezaryece | Note Added: 0028217 | |
2012-06-19 13:59 | cezaryece | File Added: autoheight.diff | |
2012-06-19 14:00 | cezaryece | Note Edited: 0028217 | |
2012-06-19 19:27 | cbradney | Note Added: 0028223 | |
2012-06-19 19:33 | cbradney | Status | assigned => resolved |
2012-06-19 19:33 | cbradney | Fixed in Version | => 1.5.0svn |
2012-06-19 19:33 | cbradney | Resolution | open => fixed |
2012-06-19 19:39 | cbradney | Status | resolved => closed |