/* **************************************************************************** This file is part of KBabel Copyright (C) 1999-2000 by Matthias Kiefer 2001-2003 by Stanislav Visnovsky This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. In addition, as a special exception, the copyright holders give permission to link the code of this program with any edition of the TQt library by Trolltech AS, Norway (or with modified versions of TQt that use the same license as TQt), and distribute linked combinations including the two. You must obey the GNU General Public License in all respects for all of the code used other than TQt. If you modify this file, you may extend this exception to your version of the file, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. **************************************************************************** */ #include "catmanresource.h" #include "catmanlistitem.h" #include "catalogmanagerview.h" #include "catalog.h" #include "resources.h" #include #include #include #include #include #include #include #include using namespace KBabel; CatManListItem::CatManListItem(CatalogManagerView *view, TQListViewItem* parent,TQString fullPath,TQString fullPotPath,TQString package) : TQListViewItem(parent) { _view = view; init(fullPath,fullPotPath,package); } CatManListItem::CatManListItem(CatalogManagerView *view, TQListView* parent,TQString fullPath,TQString fullPotPath) : TQListViewItem(parent) { _primary=TQFileInfo(fullPath); _template=TQFileInfo(fullPotPath); _package="/"; _type=Dir; _marked=false; _view = view; _hasPo=false; _hasPot=false; _hasErrors=false; _primary.setCaching(false); _template.setCaching(false); setText(COL_NAME,i18n("Message Catalogs")); setPixmap(COL_NAME,ICON_FOLDER_CLOSED_OK); } void CatManListItem::init(const TQString& fullPath, const TQString& fullPotPath, const TQString& package) { _primary=TQFileInfo(fullPath); _template=TQFileInfo(fullPotPath); _package=package; _marked=false; _hasPo=false; _hasPot=false; _hasErrors=false; _primary.setCaching(false); _template.setCaching(false); // set _lastUpdated=TQDate(1900,1,1); _wordList.clear(); _wordListUpdated = false; update(parent()->isOpen(),false,true); if( !isDir() ) setPixmap(COL_MARKER,ICON_NOFLAG); } void CatManListItem::setMarked(bool on) { if(on) { setPixmap(COL_MARKER,ICON_FLAG); } else { setPixmap(COL_MARKER,ICON_NOFLAG); } _marked=on; } bool CatManListItem::marked() const { if( isFile() ) return _marked; else if( isDir() ) { CatManListItem * myChild = (CatManListItem*)firstChild(); while( myChild ) { if(myChild->isFile() && myChild->marked() ) return true; else if(myChild->isDir() && myChild->marked() ) return true; myChild = (CatManListItem*)myChild->nextSibling(); } } return false; } void CatManListItem::setOpen(bool open) { bool needWork = needsWork(); TQListViewItem::setOpen(open); if(open && _type==Dir) { TQPixmap icon; icon = needWork ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK; if(!_template.exists()) { icon=paintExclamation(&icon); } setPixmap(COL_NAME,icon); CatManListItem * myChild = (CatManListItem*)firstChild(); while( myChild ) { myChild->checkUpdate(); myChild = (CatManListItem*)myChild->nextSibling(); } } else { TQPixmap icon; if(needsWork()) icon = ICON_FOLDER_CLOSED_WORK; else icon = ICON_FOLDER_CLOSED_OK; if(!_template.exists()) { icon=paintExclamation(&icon); } setPixmap(COL_NAME,icon); } } TQStringList CatManListItem::allChildrenList(bool onlyFiles) const { TQStringList childrenList; CatManListItem * myChild = (CatManListItem*)firstChild(); while( myChild ) { TQString name=myChild->package(); if(myChild->isFile()) { childrenList.append(name); } else if(myChild->isDir()) { if(!onlyFiles) childrenList.append(name); childrenList+=myChild->allChildrenList(onlyFiles); } myChild = (CatManListItem*)myChild->nextSibling(); } return childrenList; } TQStringList CatManListItem::allChildrenFileList(bool onlyFiles, bool emptyDirs, bool onlyModified) const { TQStringList childrenList; CatManListItem * myChild = (CatManListItem*)firstChild(); while( myChild ) { if(myChild->isFile() && myChild->hasPo() && !(!myChild->isModified() && onlyModified)) { childrenList.append(myChild->poFile()); } else if(myChild->isDir()) { if(!onlyFiles && (emptyDirs || myChild->_primary.exists() )) { childrenList.append(myChild->poFile()); } childrenList+=myChild->allChildrenFileList(onlyFiles,false,onlyModified); } myChild = (CatManListItem*)myChild->nextSibling(); } return childrenList; } TQStringList CatManListItem::contentsList(bool onlyFiles) const { TQStringList childList; CatManListItem * myChild = (CatManListItem*)firstChild(); while( myChild ) { TQString name=myChild->package(); if(onlyFiles) { if(myChild->isFile()) { childList.append(name); } } else { childList.append(name); } myChild = (CatManListItem*)myChild->nextSibling(); } return childList; } void CatManListItem::forceUpdate() { update(true,true,false); } void CatManListItem::checkUpdate(bool noParents) { // if a file has disappeared or is new if(_hasPo != hasPo() || _hasPot != hasPot()) { update(true,false,noParents); } else if(!isFile()) { update(true,false,noParents); } else if(_hasPo && _lastUpdated < _primary.lastModified()) { update(true,false,noParents); } else if(_hasPot && _lastUpdated < _template.lastModified()) { update(true,false,noParents); } } TQString CatManListItem::key(int col, bool) const { // show directories first TQString key=text(col); if(col==COL_NAME) { if(_type==Dir) { key="a"+key; } else { key="b"+key; } } // fuzzy, untranslated, total else if(col==COL_FUZZY || col ==COL_TOTAL || col==COL_UNTRANS) { key=key.rightJustify(10,'0'); } // marked po's else if(col==COL_MARKER) { if(_marked) { key="1"; } else { key="0"; } } return key; } void CatManListItem::update(bool showPoInfo,bool includeChildren , bool noParents) { if( _view->isStopped() ) return; // if parent view is stopped, we should stop as well bool updateWordList = _view->settings().indexWords; // flag, if something has changed and parent has to be updated bool updateParent=false; // update flags for files... const bool hadPo=_hasPo; _hasPo = hasPo(); const bool hadPot = _hasPot; _hasPot = hasPot(); // and check if something changed if(hadPo != _hasPo || hadPot != _hasPot) updateParent=true; if(_package!="/") // don't update root item { if(_primary.exists()) { if(_primary.isDir()) { TQDir dir=_primary.dir(); setText(COL_NAME,dir.dirName()); // count the childen numbers int fuzzy = 0; int untrans = 0; int total = 0; CatManListItem* ch = static_cast(firstChild ()); while (ch) { fuzzy += ch->fuzzy (); untrans += ch->untranslated (); total += ch->total (); ch = static_cast(ch->nextSibling()); } setText(COL_FUZZY,TQString::number(fuzzy)); setText(COL_UNTRANS,TQString::number(untrans)); setText(COL_TOTAL,TQString::number(total)); //setSelectable(false); _type=Dir; bool needWork = needsWork(); TQPixmap icon; if(!isOpen()) { if( needWork ) icon = ICON_FOLDER_CLOSED_WORK; else icon = ICON_FOLDER_CLOSED_OK; } else { icon = needWork ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK; } // check if the same directory exists also in the // template directory if(_template.isDir()) { setPixmap( COL_NAME, icon ); } else { TQPixmap folder = icon; icon=paintExclamation(&folder); setPixmap(COL_NAME,folder); } } else // primary is file { _type=File; TQString name=_primary.fileName(); setText(COL_NAME,name.left(name.length()-3)); if(showPoInfo) { _lastUpdated=TQDateTime::currentDateTime(); bool neededWork=needsWork(); bool needWork=false; PoInfo poInfo; TQPixmap icon = ICON_UPDATING; setPixmap(COL_NAME,icon); if ( PoInfo::info( _primary.absFilePath(), poInfo, _wordList, updateWordList, true, true ) == OK ) { if( _view->isStopped() ) return; if( updateWordList) _wordListUpdated = true; _hasErrors=false; const CVSHandler* cvsHandler = _view->cvsHandler(); const SVNHandler* svnHandler = _view->svnHandler(); const CVSHandler::FileStatus cvsFileStatus = cvsHandler->fstatus( poFile() ); const SVNHandler::FileStatus svnFileStatus = svnHandler->fstatus( poFile() ); _isModified = cvsHandler->isConsideredModified( cvsFileStatus ) || svnHandler->isConsideredModified( svnFileStatus ); TQString versionControl; if ( cvsFileStatus != CVSHandler::NO_REPOSITORY ) versionControl = cvsHandler->fileStatus( cvsFileStatus ); else if ( svnFileStatus != SVNHandler::NO_REPOSITORY ) versionControl = svnHandler->fileStatus( svnFileStatus ); else versionControl = i18n("No version control"); setText(COL_FUZZY,TQString::number(poInfo.fuzzy)); setText(COL_UNTRANS,TQString::number(poInfo.untranslated)); setText(COL_TOTAL,TQString::number(poInfo.total)); setText( COL_CVS_OR_SVN, versionControl ); setText(COL_REVISION,poInfo.revision); setText(COL_TRANSLATOR,poInfo.lastTranslator); if(needsWork()) { icon=ICON_NEEDWORK; needWork = true; } else { icon = ICON_OK; needWork=false; } } else { kdDebug(KBABEL_CATMAN) << "This file is broken" << endl; if( _view->isStopped() ) return; _hasErrors=true; icon = ICON_BROKEN; needWork=true; } if(!_template.exists()) { icon=paintExclamation(&icon); } setPixmap(COL_NAME,icon); updateParent=true; } } } // only the template exists else if(_template.exists()) { if(_template.isDir()) { TQDir dir=_template.dir(); setText(COL_NAME,dir.dirName()); //setSelectable(false); _type=Dir; // count the childen numbers int total = 0; CatManListItem* ch = static_cast(firstChild ()); while (ch) { total += ch->total (); ch = static_cast(ch->nextSibling()); } setText(COL_TOTAL,TQString::number(total)); TQPixmap icon; if(!isOpen()) { icon = ICON_FOLDER_CLOSED_WORK; } else { icon = needsWork() ? ICON_FOLDER_OPEN_WORK : ICON_FOLDER_OPEN_OK; } setPixmap(COL_NAME, icon ); } // item is file else { _type=File; TQString name=_primary.fileName(); setText(COL_NAME,name.left(name.length()-3)); if(showPoInfo) { _lastUpdated=TQDateTime::currentDateTime(); // clean previous state information setText(COL_FUZZY,TQString()); setText(COL_UNTRANS,TQString()); setText(COL_TOTAL,TQString()); setText(COL_CVS_OR_SVN, TQString()); setText(COL_REVISION, TQString()); setText(COL_TRANSLATOR, TQString()); setPixmap(COL_NAME,ICON_UPDATING); PoInfo poInfo; if ( PoInfo::info( _template.absFilePath(), poInfo, _wordList, false, true, true ) == OK ) { if( _view->isStopped() ) return; setText(COL_TOTAL,TQString::number(poInfo.total)); } if( _view->isStopped() ) return; } setPixmap(COL_NAME,ICON_MISSING); updateParent = true; } } else { kdWarning(KBABEL_CATMAN) << "whether po nor pot exists: " << _package << endl; } } _view->fileInfoRead( package() ); if( _view->isStopped() ) return; if(updateParent && !noParents) { updateParents(); } if( _view->isStopped() ) return; if(includeChildren) { CatManListItem *myChild = (CatManListItem*)firstChild(); while( myChild ) { myChild->update(showPoInfo,includeChildren); myChild = (CatManListItem*)myChild->nextSibling(); } } // HACK to get the signal emitted if (isSelected( )) { listView( )->setSelected(this, false); listView( )->setSelected(this, true); } } // we know that this item was saved and PoInfo contains new information // about this item, the item is file // however, is can be saved template or translation!!! - only translation is handled??? void CatManListItem::updateAfterSave( PoInfo &poInfo ) { // flag, if something has changed and parent has to be updated bool updateParent=false; // update flags for files... const bool hadPo=_hasPo; _hasPo = hasPo(); const bool hadPot = _hasPot; _hasPot = hasPot(); // and check if something changed if(hadPo != _hasPo || hadPot != _hasPot) updateParent=true; if(_primary.exists()) { // primary is existent file _type=File; TQString name=_primary.fileName(); setText(COL_NAME,name.left(name.length()-3)); _lastUpdated=TQDateTime::currentDateTime(); bool neededWork=needsWork(); bool needWork=false; TQPixmap icon; _hasErrors=false; const CVSHandler::FileStatus cvsFileStatus = _view->cvsHandler()->fstatus(poFile()); const SVNHandler::FileStatus svnFileStatus = _view->svnHandler()->fstatus(poFile()); TQString versionControl; if ( cvsFileStatus != CVSHandler::NO_REPOSITORY ) versionControl = _view->cvsHandler()->fileStatus( cvsFileStatus ); else if ( svnFileStatus != SVNHandler::NO_REPOSITORY ) versionControl = _view->svnHandler()->fileStatus( svnFileStatus ); else versionControl = i18n("No version control"); setText(COL_FUZZY,TQString::number(poInfo.fuzzy)); setText(COL_UNTRANS,TQString::number(poInfo.untranslated)); setText(COL_TOTAL,TQString::number(poInfo.total)); setText( COL_CVS_OR_SVN, versionControl ); setText(COL_REVISION,poInfo.revision); setText(COL_TRANSLATOR,poInfo.lastTranslator); if(needsWork()) { icon=ICON_NEEDWORK; needWork = true; } else { icon = ICON_OK; needWork=false; } if(!_template.exists()) { icon=paintExclamation(&icon); } setPixmap(COL_NAME,icon); // if the status changed, update the parent item if(needWork != neededWork) { updateParent=true; } } if(updateParent) { updateParents(); } } void CatManListItem::updateParents() { CatManListItem *item = (CatManListItem*)parent(); while( item && !_view->isStopped()) { item->update(false,false); item = (CatManListItem*)item->parent(); } } bool CatManListItem::hasPo() const { return _primary.exists(); } bool CatManListItem::hasPot() const { return _template.exists(); } bool CatManListItem::isModified() const { return _isModified; } int CatManListItem::fuzzy() const { bool success; int number=text(COL_FUZZY).toInt(&success); if(!success) number=0; return number; } int CatManListItem::untranslated() const { bool success; int number; if( !hasPo() ) { number=total(); } else { number=text(COL_UNTRANS).toInt(&success); if(!success) number=0; } return number; } int CatManListItem::total() const { bool success; int number=text(COL_TOTAL).toInt(&success); if(!success) number=0; return number; } bool CatManListItem::needsWork() const { bool flag=false; if(isFile()) { if(!hasPo() || fuzzy() > 0 || untranslated() > 0 || _hasErrors) flag=true; } else { CatManListItem *myChild = (CatManListItem*)firstChild(); while( myChild ) { if( myChild->needsWork() ) { flag=true; myChild=0; } else { myChild = (CatManListItem*)myChild->nextSibling(); } } } return flag; } bool CatManListItem::isDir() const { return type()==Dir; } bool CatManListItem::isFile() const { return type()==File; } TQString CatManListItem::poFile() const { return _primary.absFilePath(); } TQString CatManListItem::potFile() const { return _template.absFilePath(); } TQString CatManListItem::package(bool rootSlash) const { if(rootSlash) return _package; else { return _package.right(_package.length()-1); } } TQString CatManListItem::packageDir( ) const { return ( _type == Dir ? _package : TQString() ); } TQString CatManListItem::name() const { int index = _package.findRev("/"); return _package.right(_package.length()-index-1); } TQPixmap CatManListItem::paintExclamation(TQPixmap* pixmap) { if(!pixmap || pixmap->isNull()) return TQPixmap(0,0); if(_package=="/" && _template.filePath().isEmpty()) return *pixmap; if(isDir() && _package == _template.filePath()) return *pixmap; if(isFile() && _package+".pot" == _template.filePath()) return *pixmap; int width=pixmap->width(); int height=pixmap->height(); int diameter=TQMIN(width,height); TQBitmap mask=pixmap->createHeuristicMask(); TQPainter mp(&mask); mp.setPen(TQPen(TQt::color1,1)); mp.drawEllipse(width-diameter,height-diameter,diameter,diameter); TQPixmap result(width,height); TQPainter p(&result); p.drawPixmap(0,0,*pixmap); p.setPen( TQPen(red,1) ); p.drawEllipse(width-diameter,height-diameter,diameter,diameter); result.setMask(mask); return result; } TQListViewItem *CatManListItem::previousSibling() { TQListViewItem * i = parent(); if( !i ) return i; i = i->firstChild(); if( !i ) return i; if( i == this ) return 0; while( i->nextSibling()!=this ) i = i->nextSibling(); return i; } TQListViewItem *CatManListItem::lastChild() { TQListViewItem * i = firstChild(); if( !i ) return i; while( i->nextSibling() ) i = i->nextSibling(); return i; } void CatManListItem::checkErrors(KDataTool* tool, TQObject* progressSignalHandler, bool ignoreFuzzy, bool markAsFuzzy) { bool hasError=false; _errors.clear(); Catalog* cat = new Catalog(); TQObject::connect( cat, TQ_SIGNAL( signalProgress(int) ), progressSignalHandler, TQ_SIGNAL( setValidationProgressBar(int))); TQObject::connect( cat, TQ_SIGNAL( signalResetProgressBar(TQString, int) ), progressSignalHandler, TQ_SLOT( setupFileProgressBar(TQString, int))); if( cat->openURL(KURL( poFile() )) == OK ) { kdDebug(KBABEL_CATMAN) << "File opened succesfully" << endl; if( !cat->checkUsingTool(tool,true) ) { hasError = true; } else forceUpdate(); // no error, find out the new state } else { kdDebug(KBABEL_CATMAN) << "File not opened !!!!!" << endl; hasError=true; } if( hasError ) { TQString errortext; _hasErrors = true; DocPosition dummy; IgnoreItem i; i.fileURL = poFile(); if( cat->hasError(0,dummy) && (!ignoreFuzzy || !cat->isFuzzy(0))) { i.msgid = cat->msgid(0); i.msgstr = cat->msgstr(0); i.index = 0; _errors.append( i ); if( markAsFuzzy ) cat->setFuzzy(0, true); } int index=0; do { index=cat->nextError(index,dummy); if( index != -1 && (!ignoreFuzzy || !cat->isFuzzy(index) ) ) { i.msgid = cat->msgid(index); i.msgstr = cat->msgstr(index); i.index = index; _errors.append( i ); if( markAsFuzzy ) cat->setFuzzy(index, true); } } while(index>=0); // change icon only if there were non-ignored errors if( !_errors.isEmpty() ) { setPixmap(COL_NAME, ICON_ERROR); } // if we changed fuzzy flags, save the result if( cat->isModified() ) cat->saveFile(); } delete cat; }