Re: Full Gettext support in KBabel

Chusslove Illich <[email protected]> Sat, 22 Oct 2005 20:54:28 +0200
Newsgroups gmane.comp.kde.devel.kbabel
Message-ID <[email protected]>
> [: Stephan Kulow :]
> We will change to standard gettext before 4.0 - if kbabel 3.5 has to be
> changed for that, be it!

This sounds like a licence for "change as needed" :)

I've added upon Nicolas' patch, making msgctxt a normal member of the 
internal data: proper support in Catalog and CatalogItem, and proper 
import and export in Gettext filter (patch_internals.diff).

I've tried to fool around with GUI, eg. make an extra tab in msgid pane, 
but it proved too much for me just by looking for analogies :) Instead, 
for debug purposes, I put msgctxt below the msgid in msgid pane, separated 
by a "Inserted by KBabel..." sort of line (patch_interface.diff). Perhaps 
it would still not be too hard to add extra GUI element for someone who 
actually knows what to do :)

-- 
Chusslove Illich (Часлав Илић)

_______________________________________________
kbabel mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kbabel
patch_interface.diff (text/x-diff, 2.5 KB)
Index: kbabel/kbabelview.cpp
===================================================================
--- kbabel/kbabelview.cpp	(revision 473115)
+++ kbabel/kbabelview.cpp	(working copy)
@@ -1822,7 +1822,14 @@
        disconnect(msgstrEdit,SIGNAL(textChanged()),this,SLOT(autoRemoveFuzzyStatus()));
    }
 
-   msgidLabel->setText(_catalog->msgid(_currentIndex));
+   QStringList tmp = _catalog->msgid(_currentIndex);
+   bool hasctxt = false;
+   if (not _catalog->msgctxt(_currentIndex).isEmpty())
+   {
+      hasctxt = true;
+      tmp.prepend(_catalog->msgctxt(_currentIndex));
+   }
+   msgidLabel->setText(tmp, hasctxt);
    msgidLabel->repaint();
 
    msgstrEdit->setText(_catalog->msgstr(_currentIndex));
Index: kbabel/hidingmsgedit.h
===================================================================
--- kbabel/hidingmsgedit.h	(revision 473115)
+++ kbabel/hidingmsgedit.h	(working copy)
@@ -99,7 +99,7 @@
   // reiplemented to return correct value
   bool hasFocus ();
 public slots: // Public slots
-  void setText(QStringList texts);
+  void setText(QStringList texts, bool hasctxt = false);
   void showSingle();
   void showMultiple();
   void showPlurals( bool on );
Index: kbabel/hidingmsgedit.cpp
===================================================================
--- kbabel/hidingmsgedit.cpp	(revision 473115)
+++ kbabel/hidingmsgedit.cpp	(working copy)
@@ -62,7 +62,7 @@
 HidingMsgEdit::~HidingMsgEdit(){
 }
 
-void HidingMsgEdit::setText(QStringList texts){
+void HidingMsgEdit::setText(QStringList texts, bool hasctxt){
   if( texts.count() == 0 )
   {
       kdWarning() << "HidingMsgEdit::setText with empty text" << endl;
@@ -70,21 +70,28 @@
       showSingle();
       return;
   }
-  
-  if( texts.count() == 1 )
+
+  QStringList::iterator text = texts.begin();
+  QString ctxt = "";
+  if (hasctxt)
   {
-      _singleEdit->setText(*texts.at(0));
+      ctxt = "\n>>>>> Do not translate below this line, context inserted by KBabel:\n" + *text;
+      text++;
+  }
+    
+  if( texts.count() == 1 or (texts.count() == 2 and hasctxt))
+  {
+      _singleEdit->setText(*text + ctxt);
       showSingle();
   }
   else
   {
       if( _numberOfPlurals )
       {
-          QStringList::iterator text = texts.begin();
 	  uint i;
           for( i=0 ; i < _numberOfPlurals && text!= texts.end() ; i++, text++ )
 	  {
-	      static_cast<MsgMultiLineEdit *>(_multipleEdit->page(i))->setText(*text);
+	      static_cast<MsgMultiLineEdit *>(_multipleEdit->page(i))->setText(*text + ctxt);
 	  }
 	  
 	  // clean the non-initialized ones
patch_internals.diff (text/x-diff, 10.1 KB)
Index: common/catalog.h
===================================================================
--- common/catalog.h	(revision 473115)
+++ common/catalog.h	(working copy)
@@ -143,6 +143,14 @@
    virtual ~Catalog();
 
    /**
+   * Get the message context for a given message.
+   *
+   * @param index  index of the requested message
+   * @return       context for the given message
+   */
+   QString msgctxt(uint index) const;
+   
+   /**
    * Get list of texts for a given message in original language. Each entry in the list
    * represents a single singular/plural form.
    *
Index: common/catalog.cpp
===================================================================
--- common/catalog.cpp	(revision 473115)
+++ common/catalog.cpp	(working copy)
@@ -87,6 +87,16 @@
     delete d;
 }
 
+QString Catalog::msgctxt(uint index) const
+{
+    if (  d->_entries.isEmpty() )
+        return QString::null;
+   uint max=d->_entries.count()-1;
+   if(index > max)
+      index=max;
+   return d->_entries[index].msgctxt();
+}
+
 QStringList Catalog::msgid(uint index, const bool noNewlines) const
 {
    if (  d->_entries.isEmpty() )
Index: common/catalogitem.h
===================================================================
--- common/catalogitem.h	(revision 473115)
+++ common/catalogitem.h	(working copy)
@@ -125,6 +125,8 @@
 
     /** returns the comment of this entry */
     QString comment() const;
+    /** returns the msgctxt of this entry */
+    QString msgctxt(const bool noNewlines = false) const;
     /** returns the msgid of the entry */
     QStringList msgid(const bool noNewlines = false) const;
     /** returns the msgstr of the entry */
@@ -139,6 +141,7 @@
     QStringList msgstrAsList(int pluralNr=0) const;
 
     void setComment(QString com);
+    void setMsgctxt(QString msg);
     void setMsgid(QString msg);
     void setMsgid(QStringList msg);
     void setMsgstr(QString msg);
Index: common/catalogitem_private.h
===================================================================
--- common/catalogitem_private.h	(revision 473115)
+++ common/catalogitem_private.h	(working copy)
@@ -56,6 +56,7 @@
 public:
 
    QString _comment;
+   QString _msgctxt;
    QStringList _msgid;
    QStringList _msgstr;
 
Index: common/catalogitem.cpp
===================================================================
--- common/catalogitem.cpp	(revision 473115)
+++ common/catalogitem.cpp	(working copy)
@@ -71,6 +71,18 @@
     return d->_comment;
 }
 
+QString CatalogItem::msgctxt(const bool noNewlines) const
+{
+    if( noNewlines )
+    {
+        QString tmp = d->_msgctxt;
+        tmp.replace("\n", " ");
+        return tmp;
+    }
+    else
+        return d->_msgctxt;
+}
+
 QStringList CatalogItem::msgid(const bool noNewlines) const
 {
     QStringList result=d->_msgid;
@@ -142,6 +154,11 @@
     return d->_valid;
 }
 
+void CatalogItem::setMsgctxt(QString msg)
+{
+    d->_msgctxt=msg;
+}
+
 void CatalogItem::setMsgid(QString msg)
 {
     d->_msgid=msg;
@@ -249,6 +266,11 @@
    {
       lines = d->_comment.contains('\n')+1;
    }
+   int msgctxtLines=0;
+   if(!d->_msgctxt.isEmpty())
+   {
+      msgctxtLines=d->_msgctxt.contains('\n')+1;
+   }
    int msgidLines=0;
    QStringList::ConstIterator it;
    for(it=d->_msgid.begin(); it != d->_msgid.end(); ++it)
@@ -261,12 +283,14 @@
       msgstrLines += (*it).contains('\n')+1;
    }
 
+   if(msgctxtLines>1)
+      msgctxtLines++;
    if(msgidLines>1)
       msgidLines++;
    if(msgstrLines>1)
       msgstrLines++;
 
-   lines+=( msgidLines+msgstrLines );
+   lines+=( msgctxtLines+msgidLines+msgstrLines );
 
    return lines;
 }
@@ -453,6 +477,7 @@
       d->_argList.clear();
    }
    d->_comment="";
+   d->_msgctxt="";
    d->_valid=true;
    d->_gettextPluralForm=false;
    d->_haveTagList=false;
@@ -465,6 +490,7 @@
 void CatalogItem::operator=(const CatalogItem& rhs)
 {
     d->_comment = rhs.d->_comment;
+    d->_msgctxt = rhs.d->_msgctxt;
     d->_msgid = rhs.d->_msgid;
     d->_msgstr = rhs.d->_msgstr;
     d->_valid = rhs.d->_valid;
Index: filters/gettext/gettextimport.h
===================================================================
--- filters/gettext/gettextimport.h	(revision 473115)
+++ filters/gettext/gettextimport.h	(working copy)
@@ -59,6 +59,7 @@
     KBabel::ConversionStatus readEntry(QTextStream& stream);
     
     // description of the last read entry
+    QString _msgctxt;
     QStringList _msgid;
     QStringList _msgstr;
     QString _comment;
Index: filters/gettext/gettextimport.cpp
===================================================================
--- filters/gettext/gettextimport.cpp	(revision 473115)
+++ filters/gettext/gettextimport.cpp	(working copy)
@@ -153,6 +153,7 @@
          else
          {
                CatalogItem tempCatItem;
+               tempCatItem.setMsgctxt( _msgctxt );
                tempCatItem.setMsgid( _msgid );
                tempCatItem.setMsgstr( _msgstr );
                tempCatItem.setComment( _comment );
@@ -172,6 +173,7 @@
          errorIndex.append(counter);
          
          CatalogItem tempCatItem;
+         tempCatItem.setMsgctxt( _msgctxt );
          tempCatItem.setMsgid( _msgid );
          tempCatItem.setMsgstr( _msgstr );
          tempCatItem.setComment( _comment );
@@ -332,12 +334,12 @@
    bool cancelLoop=false;
    bool error=false;
    bool recoverableError=false;
-   QString msgctxt;
    bool seenMsgctxt=false;
    _msgstr.clear();
    _msgstr.append(QString());
    _msgid.clear();
    _msgid.append(QString());
+   _msgctxt=QString();
    _comment=QString();
    _gettextPluralForm=false;
    _obsolete=false;
@@ -388,7 +390,7 @@
                // remove quotes at beginning and the end of the lines
                line.remove(QRegExp("^msgctxt\\s*\""));
                line.remove(QRegExp("\"$"));
-               msgctxt=line;
+               _msgctxt=line;
                seenMsgctxt=true;
            }
            else if(line.find(QRegExp("^msgid\\s*\".*\"$")) != -1)
@@ -444,7 +446,7 @@
                // remove quotes at beginning and the end of the lines
                line.remove(QRegExp("^msgctxt\\s*\""));
                line.remove(QRegExp("\"$"));
-               msgctxt=line;
+               _msgctxt=line;
                seenMsgctxt=true;
             }
             else if(line.find(QRegExp("^msgid\\s*\".*\"$")) != -1)
@@ -488,7 +490,12 @@
                // remove quotes at beginning and the end of the lines
                line.remove(QRegExp("^\""));
                line.remove(QRegExp("\"$"));
-               msgctxt+=line; // We put the context in a single line (### TODO: keep it like in the file)
+               
+               // add Msgctxt line to item
+               if(_msgctxt.isEmpty())
+                  _msgctxt=line;
+               else
+                  _msgctxt+=("\n"+line);
             }
             else if(line.find(QRegExp("^msgid\\s*\".*\"$")) != -1)
             {
@@ -516,7 +523,7 @@
             }
             else
             {
-               kdDebug(KBABEL) << "no msgid found after a msgctxt while parsing: " << msgctxt << endl;
+               kdDebug(KBABEL) << "no msgid found after a msgctxt while parsing: " << _msgctxt << endl;
 
                error=true;
                cancelLoop=true;
@@ -731,13 +738,6 @@
         }
     }
 
-    // ### HACK: Temporary hack until msgctxt is properly supported.
-    if(seenMsgctxt)
-    {
-        if (!_comment.isEmpty())
-          _comment+="\n";
-        _comment+="# MsgContext: "+msgctxt;
-    }
 /*
    if(_gettextPluralForm)
    {
Index: filters/gettext/gettextexport.h
===================================================================
--- filters/gettext/gettextexport.h	(revision 473115)
+++ filters/gettext/gettextexport.h	(working copy)
@@ -56,6 +56,7 @@
     virtual KBabel::ConversionStatus save(const QString& file, const QString& mimetype, const KBabel::Catalog* catalog);
     
 private:
+    QStringList msgctxtAsList( const KBabel::Catalog* catalog, uint item ) const;
     QStringList msgidAsList( const KBabel::Catalog* catalog, uint item, bool plural=false ) const;
     QStringList msgstrAsList( const KBabel::Catalog* catalog, uint item, uint pluralNr=0 ) const;
 };
Index: filters/gettext/gettextexport.cpp
===================================================================
--- filters/gettext/gettextexport.cpp	(revision 473115)
+++ filters/gettext/gettextexport.cpp	(working copy)
@@ -159,28 +159,25 @@
 	  
 	  // write entry
 	  QString comment = catalog->comment(counter);
-	  QString msgctxt;
-	  bool haveMsgctxt=false;
-	  // ### HACK: Temporary hack until msgctxt is properly supported.
-          // ### TODO: the user might have added a comment, so we cannot assume that the context is the end of the whole comments.
-          const int posContext=comment.find(QRegExp("# MsgContext: "));
-          if( posContext >= 0)
-	  {
-	      msgctxt=comment.mid(posContext+14);
-              kdDebug() << "MsgContext found: " << msgctxt << endl;
-              haveMsgctxt=true;
-	      comment.truncate(posContext);
-	      if(comment.endsWith("\n"))
-                  comment.truncate(posContext-1); // KDE4: use QString::chop(1)
-	  }
 	  if(!comment.isEmpty())
 	  {
 	      stream << comment << "\n";
 	  }
-	  if(haveMsgctxt)
+
+	  if(!catalog->msgctxt(counter).isEmpty())
 	  {
-	      // TODO: support multi-line contexts
-	      stream << "msgctxt \"" << msgctxt << "\"\n";
+		QStringList list=msgctxtAsList(catalog, counter);
+		QValueList<QString>::ConstIterator lit;
+
+		// if the msgctxt has more than one line
+		if(list.count() > 1)
+		  list.prepend("");
+
+		stream << "msgctxt ";
+		for( lit = list.begin(); lit != list.end(); ++lit )
+		{
+		  stream << "\"" << (*lit) << "\"\n";
+		}
 	  }
 
 	  QStringList list=msgidAsList(catalog, counter);
@@ -283,6 +280,21 @@
    return OK;
 }
 
+QStringList GettextExportPlugin::msgctxtAsList(const Catalog* catalog, uint item) const
+{
+   QString str = catalog->msgctxt(item);
+
+   QStringList list=QStringList::split("\n",str);
+			  
+   if(str.left(1)=="\n")
+	list.prepend("");
+				   
+   if(list.isEmpty())
+	list.append("");
+
+   return list;
+}
+
 QStringList GettextExportPlugin::msgidAsList(const Catalog* catalog, uint item, bool plural) const
 {
    QString str;
signature.asc (application/pgp-signature, 189 B)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (GNU/Linux)

iD8DBQBDWormMSGXgigGr3ERAtCNAJ99NIC4XarXkTqPoVK2xU++WlTnLACeL9L7
cyPHs3xHtLlVKLeWfn40IV4=
=7vmA
-----END PGP SIGNATURE-----