Index: scribus/appmodehelper.cpp =================================================================== --- scribus/appmodehelper.cpp (revision 22354) +++ scribus/appmodehelper.cpp (working copy) @@ -215,11 +215,20 @@ case modeNormal: { bool editSearchReplace = false; - if (currItem != 0) + //enable search if at least one text frame is in the document + if (doc->Items->count() != 0) { - editSearchReplace |= currItem->isTextFrame(); - editSearchReplace |= (currItem->itemText.length() > 0); - editSearchReplace |= (doc->m_Selection->count() == 1); + for (int i = 0; i < doc->Items->count(); i++) + { + if (doc->Items->at(i)->isTextFrame()) + { + if (doc->Items->at(i)->itemText.length() > 0) + { + editSearchReplace = true; + break; + } + } + } } (*a_scrActions)["editSearchReplace"]->setEnabled(editSearchReplace); @@ -526,7 +535,23 @@ (*a_scrActions)["editCut"]->setEnabled(false); (*a_scrActions)["editCopy"]->setEnabled(false); (*a_scrActions)["editCopyContents"]->setEnabled(false); - (*a_scrActions)["editSearchReplace"]->setEnabled(false); + if (doc->Items->count() != 0) + { + for (int i = 0; i < doc->Items->count(); i++) + { + if (doc->Items->at(i)->isTextFrame()) + { + if (doc->Items->at(i)->itemText.length() > 0) + { + (*a_scrActions)["editSearchReplace"]->setEnabled(true); + break; + } + } + } + } + else + (*a_scrActions)["editSearchReplace"]->setEnabled(false); + (*a_scrActions)["extrasHyphenateText"]->setEnabled(false); (*a_scrActions)["extrasDeHyphenateText"]->setEnabled(false); Index: scribus/scribus.cpp =================================================================== --- scribus/scribus.cpp (revision 22354) +++ scribus/scribus.cpp (working copy) @@ -8502,10 +8502,74 @@ void ScribusMainWindow::SearchText() { - PageItem *currItem = doc->m_Selection->itemAt(0); + PageItem *currItem = NULL; + bool SearchCur = false; + bool flag = false; + + /* + * The currItem is selected based on: + * 1- first text frame selected. + * if not + * select first text frame in current page. + * if not + * got to next page and select the first text frame + * if you reach the end of the document + * start from the first page. + */ + if (doc->Items->count() == 0) + return; + else if (doc->m_Selection->count() > 0) + { + //start searching from the selected text frame + for (int i = 0 ; i < doc->m_Selection->count(); i++) + if (doc->m_Selection->itemAt(i)->isTextFrame() && doc->m_Selection->itemAt(i)->itemText.length() > 0 ) + { + flag = true; + currItem = doc->m_Selection->itemAt(i); + if (doc->m_Selection->count() == 1) + SearchCur = true; + break; + } + } + // if no text frame selected + if (!flag) + { + int i = 0; + int j = 0; + //find current page index + for (i = 0; i < doc->Items->count(); i++) + { + if (doc->Items->at(i)->OwnPage >= doc->currentPageNumber()) + break; + } + j = i; + //start from current page till the end of the document + for (i = j; i < doc->Items->count(); i++) + { + if (doc->Items->at(i)->isTextFrame() && doc->Items->at(i)->itemText.length() > 0) + { + flag= true; + currItem = doc->Items->at(i); + break; + } + } + //if reached the end of the document start from beggining + if (!flag) + for (i = 0; i < j; i++) + { + if (doc->Items->at(i)->isTextFrame() && doc->Items->at(i)->itemText.length() > 0) + { + currItem = doc->Items->at(i); + break; + } + } + } + + doc->m_Selection->addItem(currItem); + //PageItem *currItem = doc->m_Selection->itemAt(0); view->requestMode(modeEdit); - currItem->itemText.setCursorPosition(0); - SearchReplace* dia = new SearchReplace(this, doc, currItem); + currItem->itemText.setCursorPosition(currItem->firstInFrame()); + SearchReplace* dia = new SearchReplace(this, doc, currItem, true , SearchCur); connect(dia, SIGNAL(NewFont(const QString&)), this, SLOT(SetNewFont(const QString&))); connect(dia, SIGNAL(NewAbs(int)), this, SLOT(setAlignmentValue(int))); dia->exec(); =================================================================== --- scribus/ui/search.cpp (revision 22354) +++ scribus/ui/search.cpp (working copy) @@ -30,7 +30,9 @@ #include "prefsmanager.h" #include "scpage.h" #include "scribus.h" +#include "scribusview.h" #include "scrspinbox.h" +#include "selection.h" #include "shadebutton.h" #include "styleselect.h" #include "ui/storyeditor.h" @@ -37,7 +39,7 @@ #include "util.h" #include "util_text.h" -SearchReplace::SearchReplace( QWidget* parent, ScribusDoc *doc, PageItem* ite, bool mode ) +SearchReplace::SearchReplace( QWidget* parent, ScribusDoc *doc, PageItem* ite, bool mode, bool SearchCur ) : QDialog( parent ), matchesFound(0) { @@ -46,7 +48,33 @@ m_notFound = false; m_itemMode = mode; m_firstMatchPosition = -1; + m_SearchCurrent = SearchCur; + // Mapping between page number and text frames + QList TFItems; //list of text frames + PageItem* tempPageItem; //temporary page item + for (int i = 0; i < m_doc->DocPages.count(); i++) + { + for (int j = 0; j < m_doc->Items->count(); j++) + { + tempPageItem = m_doc->Items->at(j); + //check if item is text frame and in the same page, add it to the map + if (tempPageItem->isTextFrame() && i == tempPageItem->OwnPage) + { + tempPageItem->itemText.deselectAll(); + tempPageItem->HasSel = false; + TFItems.append(tempPageItem); + } + } + if (!TFItems.empty()) + ItemsPageNum.insert(i,TFItems); + + TFItems.clear(); + } + //for chain text start form the first letter in the chain + if (m_item->itemText.cursorPosition() == 0) + m_item->itemText.setCursorPosition(m_item->firstInFrame()); + setModal(true); setWindowTitle( tr( "Search/Replace" ) ); setWindowIcon(IconManager::instance()->loadIcon("AppIcon.png")); @@ -261,6 +289,10 @@ if (mode) Word->setEnabled(false); OptsLayout->addWidget( Word ); + SearchCurrent = new QCheckBox ( tr ("Current Selected Text Frame") , this); + OptsLayout -> addWidget(SearchCurrent); + if (mode) + SearchCurrent->setEnabled(false); CaseIgnore = new QCheckBox( tr( "&Ignore Case, Diacritics and Kashida" ), this ); if (mode) CaseIgnore->setEnabled(false); @@ -377,14 +409,10 @@ void SearchReplace::slotDoSearch() { - int maxChar = m_item->itemText.length() - 1; + int maxChar = m_item->maxCharsInFrame() - 1; DoReplace->setEnabled(false); AllReplace->setEnabled(false); - if (m_itemMode) - { - m_item->itemText.deselectAll(); - m_item->HasSel = false; - } + QString fCol = ""; QString sCol = ""; QString sFont = ""; @@ -437,11 +465,18 @@ int a, textLen(0); if (m_itemMode) { + m_item->itemText.deselectAll(); + m_item->HasSel = false; + m_doc->m_Selection->clear(); + m_item->setSelected(true); + maxChar = m_item->maxCharsInFrame() - 1; + as = m_item->itemText.cursorPosition(); + m_replStart = as; Qt::CaseSensitivity cs = Qt::CaseSensitive; if (CaseIgnore->isChecked()) cs = Qt::CaseInsensitive; - for (a = as; a < m_item->itemText.length(); ++a) + for (a = as; a < m_item->maxCharsInFrame(); ++a) { found = true; if (SText->isChecked()) @@ -510,6 +545,17 @@ { m_item->itemText.select(a, textLen); m_item->HasSel = true; + m_doc->DoDrawing = true; + m_item->update(); + + //move scroll bar to the selected element + QTransform itemTrans = m_item->getTransform(); + double xOffset=0.0, yOffset=0.0; + xOffset = m_item->width() / 2.0; + yOffset = m_item->height() / 2.0; + QPointF point = itemTrans.map(QPointF(xOffset, yOffset)); + m_doc->view()->SetCCPo(point.x(), point.y()); + if (rep) { DoReplace->setEnabled(true); @@ -533,15 +579,68 @@ } } } - if ((!found) || (a == m_item->itemText.length())) + if ((!found) || (a >= maxChar+1)) { m_doc->DoDrawing = true; m_item->update(); + m_item->setSelected(false); DoReplace->setEnabled(false); AllReplace->setEnabled(false); - ScMessageBox::information(this, tr("Search/Replace"), tr("Search finished")); - m_item->itemText.setCursorPosition(0); m_notFound = false; + + if (SearchCurrent->isChecked()) + { + ScMessageBox::information(this, tr("Search/Replace"), tr("Search finished")); + m_item->itemText.setCursorPosition(m_item->firstInFrame()); + } + else + { + //update m_item to the next text frame + QList pageKeys = ItemsPageNum.keys(); + int pageKeysIndex = pageKeys.indexOf(m_item->OwnPage); //index for pages + + for (int i = 0; i < ItemsPageNum.value(pageKeys.at(pageKeysIndex)).count(); i++) + { + if (m_item == ItemsPageNum.value(pageKeys.at(pageKeysIndex)).at(i)) + { + //go to next item in the same page + if (!ItemsPageNum.value(pageKeys.at(pageKeysIndex)).endsWith(m_item)) + { + m_item = ItemsPageNum.value(pageKeys.at(pageKeysIndex)).at(i + 1); + m_item->itemText.setCursorPosition(m_item->firstInFrame()); + slotDoSearch(); + break; + } + else // if the text frame was the last item in the page + { + pageKeysIndex ++;//increase index + if (pageKeysIndex >= pageKeys.count()) //if the last page search finished + { + if (ScMessageBox::question(this, tr( "Search/Replace" ), + tr("You reached the end of the document.\nDo you want to start from beginning?"), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::NoButton, // GUI default + QMessageBox::Ok) // batch default + == QMessageBox::Ok) + { + m_item = ItemsPageNum.value(pageKeys.first()).first(); + m_item->itemText.setCursorPosition(m_item->firstInFrame()); + slotDoSearch(); + } + break; + } + else + { + m_item = ItemsPageNum.value(pageKeys.at(pageKeysIndex)).first(); + m_item->itemText.setCursorPosition(m_item->firstInFrame()); + slotDoSearch(); + break; + } + } + } + } + SearchCurrent->setEnabled(false); + } } } else if (m_doc->scMW()->CurrStED != NULL) @@ -686,6 +785,8 @@ { // if (m_itemMode) // m_doc->view()->slotDoCurs(false); + m_doc->m_Selection->clear(); + m_doc->m_Selection->addItem(m_item); slotDoReplace(); if (m_itemMode) { @@ -700,12 +801,11 @@ { QString repl, sear; int cs, cx; - int textLen = 0; + int textLen = m_item->itemText.lengthOfSelection(); if (RText->isChecked()) { repl = RTextVal->text(); sear = STextVal->text(); - textLen = m_item->itemText.lengthOfSelection(); if (textLen == repl.length()) { for (cs = 0; cs < textLen; ++cs) @@ -727,12 +827,12 @@ m_item->itemText.removeChars(m_replStart+cs, textLen - cs); } } + } + if (repl.length() > 0) + { m_item->itemText.deselectAll(); - if (repl.length() > 0) - { - m_item->itemText.select(m_replStart, repl.length()); - m_item->itemText.setCursorPosition(m_replStart + repl.length()); - } + m_item->itemText.select(m_replStart, repl.length()); + m_item->itemText.setCursorPosition(m_replStart + repl.length()); } if (RStyle->isChecked()) { @@ -867,6 +967,11 @@ bool setter = SText->isChecked(); STextVal->setEnabled(setter); Word->setEnabled(setter); + if (m_doc->m_Selection->count() == 1 && m_SearchCurrent) + SearchCurrent->setEnabled(setter); + else + SearchCurrent->setEnabled(false); + CaseIgnore->setEnabled(setter); if (setter) STextVal->setFocus(); Index: scribus/ui/search.h =================================================================== --- scribus/ui/search.h (revision 22354) +++ scribus/ui/search.h (working copy) @@ -8,6 +8,7 @@ #define SEARCHREPLACE_H #include +#include class QVBoxLayout; class QHBoxLayout; class QGridLayout; @@ -33,7 +34,7 @@ Q_OBJECT public: - SearchReplace( QWidget* parent, ScribusDoc *doc, PageItem* ite, bool mode = true ); + SearchReplace( QWidget* parent, ScribusDoc *doc, PageItem* ite, bool mode = true, bool CurSelected = true ); ~SearchReplace() {}; virtual void slotDoSearch(); virtual void slotDoReplace(); @@ -84,6 +85,7 @@ StyleSelect* SEffVal; StyleSelect* REffVal; QCheckBox* Word; + QCheckBox* SearchCurrent; QCheckBox* CaseIgnore; QPushButton* DoSearch; QPushButton* DoReplace; @@ -133,6 +135,7 @@ bool m_notFound; bool m_itemMode; + bool m_SearchCurrent; // for search current selected text frame QVBoxLayout* SearchReplaceLayout; QHBoxLayout* SelLayout; QGridLayout* SearchLayout; @@ -145,7 +148,8 @@ /// Number of matches found thus far in a search int matchesFound; int m_firstMatchPosition; - + // to map each item to a page number + QMap> ItemsPageNum; }; #endif // SEARCHREPLACE_H