Back to index

scribus-ng  1.3.4.dfsg+svn20071115
parse.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 /* This is the Scribus Short Words plugin main mechanism.
00008 
00009 This code is based on the Scribus-Vlna plug in rewritten for
00010 international use.
00011 
00012 2004 Petr Vanek <petr@yarpen.cz>
00013 with contributors.
00014 
00015 This program is free software - see LICENSE file in the distribution
00016 or documentation
00017 */
00018 
00019 #include <qregexp.h>
00020 
00021 #include "shortwords.h"
00022 #include "parse.h"
00023 #include "parse.moc"
00024 #include "version.h"
00025 #include "configuration.h"
00026 
00027 #include "scribus.h"
00028 #include "page.h"
00029 #include "pageitem.h"
00030 #include "selection.h"
00031 
00032 SWParse::SWParse()
00033 {
00034        modify = 0;
00035 }
00036 
00037 void SWParse::parseItem(PageItem *aFrame)
00038 {
00039        // the content of the frame - text itself
00040        QString content = QString();
00041        int changes = 0;
00042        // language of the frame
00043        QString lang;
00044        // list of the short words
00045        QStringList shorts;
00046        // text with special space
00047        QString unbreak;
00048        // the regexp
00049        QRegExp rx(" ");
00050        // cfg
00051        SWConfig *cfg = new SWConfig();
00052 
00053        // just textframes processed
00054        if (!aFrame->asTextFrame())
00055               return;
00056 
00057        // an ugly hack to get the language code from the item language property
00058        lang = aFrame->itemText.charStyle(0).language();
00059        if (aFrame->doc()->scMW()->Sprachen.contains(lang))
00060               lang = cfg->getLangCodeFromHyph(aFrame->doc()->scMW()->Sprachen[lang]);
00061        // apply spaces after shorts
00062        shorts = cfg->getShortWords(lang);
00063        if (shorts.count()==0)
00064               return; // no changes
00065 
00066        // get text from frame
00067        int i;
00068        for (i=0; i < aFrame->itemText.length() && ! aFrame->frameDisplays(i); ++i)
00069               ;
00070        for (; i < aFrame->itemText.length() && aFrame->frameDisplays(i); ++i)
00071               content += aFrame->itemText.text(i,1);
00072        changes = content.contains(UNBREAKABLE_SPACE);
00073 
00074        // for every config string, replace its spaces by nbsp's.
00075        for (QStringList::Iterator it = shorts.begin(); it != shorts.end(); ++it)
00076        {
00077               unbreak = (*it);
00078               // replace ' ' from cfg with '~' in the replacement string
00079               unbreak = unbreak.replace(SPACE, UNBREAKABLE_SPACE);
00080               /*
00081               Regexp used to find the config string (*it) in content.
00082               Cheat sheet:
00083               - \b is a "word boundary"; it matches at a *position*
00084               not a *character*
00085               - \W is a "non-word character"; it matches every character
00086               that is neither a letter, nor a number, nor '_';
00087               for example, it matches all kind of whitespace
00088               (including carriage return) and punctuation
00089               Example occurrences when (*it) == "Mr ":
00090                      - "Mr Bla etc." : there's one of the word boundaries
00091                      of the word "Mr" before the pattern, and one of the
00092                      word boundaries of the word "Bla" after.
00093               Example occurrences when (*it) == " !":
00094                      - "ugly hack ! No." : there's a word boundary before,
00095                      and a whitespace is matched by \W after.
00096                      - "» !" : '«' is matched by \W before, newline is
00097                      matched by \W after.
00098               */
00099               rx.setPattern("(\\b|\\W)" + rx.escape(*it) + "(\\b|\\W)");
00100               /*
00101               QString::replace works on the whole string in one pass.
00102               On every occurrence of our regexp, \1 and \2 are replaced
00103               by what has been matched (captured characters) in,
00104               respectively, the first and second capturing parentheses.
00105               */
00106               content.replace(rx, "\\1" + unbreak + "\\2");
00107        }
00108        // return text into frame
00109        for (i=0; i < aFrame->itemText.length() && ! aFrame->frameDisplays(i); ++i)
00110               ;
00111        for (; i < aFrame->itemText.length() && aFrame->frameDisplays(i); ++i)
00112               aFrame->itemText.replaceChar(i, content.at(i));
00113        if (content.contains(UNBREAKABLE_SPACE) > changes)
00114               ++modify;
00115 
00116        delete(cfg);
00117 } // end of method
00118 
00119 void SWParse::parseSelection(ScribusDoc* doc)
00120 {
00121        uint docSelectionCount = doc->m_Selection->count();
00122        doc->scMW()->mainWindowProgressBar->setTotalSteps(docSelectionCount);
00123        for (uint i=0; i < docSelectionCount; ++i)
00124        {
00125        doc->scMW()->mainWindowProgressBar->setProgress(i);
00126               parseItem(doc->m_Selection->itemAt(i));
00127        } // for items
00128        doc->scMW()->mainWindowProgressBar->setProgress(docSelectionCount);
00129 }
00130 
00131 
00132 void SWParse::parsePage(ScribusDoc* doc)
00133 {
00134        parsePage(doc, doc->currentPageNumber());
00135 }
00136 
00137 void SWParse::parsePage(ScribusDoc* doc, int page)
00138 {
00139        uint cnt = 0;
00140        uint docItemsCount=doc->Items->count();
00141        for (uint a = 0; a < docItemsCount; ++a)
00142        {
00143               PageItem* b = doc->Items->at(a);
00144               if (b->OwnPage == page)
00145                      ++cnt;
00146        }
00147        doc->scMW()->mainWindowProgressBar->setTotalSteps(cnt);
00148        doc->view()->GotoPage(page);
00149        uint i = 0;
00150        for (uint a = 0; a < docItemsCount; ++a)
00151        {
00152               PageItem* b = doc->Items->at(a);
00153               if (b->OwnPage == page)
00154               {
00155                      doc->scMW()->mainWindowProgressBar->setProgress(++i);
00156                      parseItem(b);
00157               }
00158        }
00159        doc->scMW()->mainWindowProgressBar->setProgress(cnt);
00160 }
00161 
00162 void SWParse::parseAll(ScribusDoc* doc)
00163 {
00164        for (uint i=0; i < doc->Pages->count(); ++i)
00165               parsePage(doc, i);
00166 }