You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
356 lines
10 KiB
356 lines
10 KiB
//
|
|
// C++ Implementation: annotationoutput
|
|
//
|
|
// Description:
|
|
//
|
|
//
|
|
// Author: Andras Mantia <amantia@kde.org>, (C) 2005
|
|
//
|
|
// Copyright: See COPYING file that comes with this distribution
|
|
//
|
|
//
|
|
|
|
#include <tqdict.h>
|
|
#include <tqdom.h>
|
|
#include <tqfile.h>
|
|
#include <tqheader.h>
|
|
#include <tqmap.h>
|
|
#include <tqregexp.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqtextstream.h>
|
|
#include <tqtimer.h>
|
|
|
|
#include <kdebug.h>
|
|
#include <kio/netaccess.h>
|
|
#include <klistview.h>
|
|
#include <klocale.h>
|
|
#include <kmessagebox.h>
|
|
#include <kurl.h>
|
|
|
|
#include "annotationoutput.h"
|
|
#include "messageoutput.h"
|
|
#include "project.h"
|
|
#include "projectlist.h"
|
|
#include "qextfileinfo.h"
|
|
#include "quantacommon.h"
|
|
#include "viewmanager.h"
|
|
|
|
AnnotationOutput::AnnotationOutput(TQWidget *parent, const char *name)
|
|
: KTabWidget(parent, name)
|
|
{
|
|
m_currentFileAnnotations = new MessageOutput(this);
|
|
addTab(m_currentFileAnnotations, i18n("Current File"));
|
|
|
|
m_yourAnnotations = new KListView(this);
|
|
m_yourAnnotations->addColumn("1", -1);
|
|
m_yourAnnotations->addColumn("2", 0);
|
|
m_yourAnnotations->setRootIsDecorated(true);
|
|
m_yourAnnotations->header()->hide();
|
|
m_yourAnnotations->setSorting(1);
|
|
m_yourAnnotations->setLineWidth(2);
|
|
addTab(m_yourAnnotations, i18n("For You"));
|
|
|
|
connect(m_yourAnnotations, TQT_SIGNAL(executed(TQListViewItem*)), TQT_SLOT(yourAnnotationsItemExecuted(TQListViewItem *)));
|
|
|
|
m_allAnnotations = new KListView(this);
|
|
m_allAnnotations->addColumn("1", -1);
|
|
m_allAnnotations->addColumn("2", 0);
|
|
m_allAnnotations->setRootIsDecorated(true);
|
|
m_allAnnotations->header()->hide();
|
|
m_allAnnotations->setSorting(1);
|
|
m_allAnnotations->setLineWidth(2);
|
|
connect(m_allAnnotations, TQT_SIGNAL(executed(TQListViewItem*)), TQT_SLOT(allAnnotationsItemExecuted(TQListViewItem *)));
|
|
addTab(m_allAnnotations, i18n("All Files"));
|
|
|
|
|
|
connect(this, TQT_SIGNAL(currentChanged(TQWidget*)), TQT_SLOT(tabChanged(TQWidget*)));
|
|
|
|
m_updateTimer = new TQTimer(this);
|
|
connect(m_updateTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotUpdateNextFile()));
|
|
|
|
m_yourAnnotationsNum = 0;
|
|
}
|
|
|
|
AnnotationOutput::~AnnotationOutput()
|
|
{
|
|
}
|
|
|
|
void AnnotationOutput::tabChanged(TQWidget *w)
|
|
{
|
|
if (w == m_allAnnotations || w == m_yourAnnotations)
|
|
readAnnotations();
|
|
}
|
|
|
|
void AnnotationOutput::insertAnnotation(uint line, const TQString& fileName, const TQPair<TQString, TQString>& annotation)
|
|
{
|
|
line++;
|
|
TQString s = i18n("Line %1: %2").arg(line).arg(annotation.first);
|
|
s.replace('\n', ' ');
|
|
m_currentFileAnnotations->showMessage(line, 1, fileName, s);
|
|
}
|
|
|
|
void AnnotationOutput::clearAnnotations()
|
|
{
|
|
m_currentFileAnnotations->clear();
|
|
}
|
|
|
|
void AnnotationOutput::readAnnotations()
|
|
{
|
|
if (!Project::ref()->hasProject())
|
|
{
|
|
m_allAnnotations->clear();
|
|
m_yourAnnotations->clear();
|
|
m_yourAnnotationsNum = 0;
|
|
setTabLabel(m_yourAnnotations, i18n("For You"));
|
|
return;
|
|
}
|
|
|
|
KURL baseURL = Project::ref()->projectBaseURL();
|
|
TQStringList openedItems;
|
|
TQListViewItem *item = m_allAnnotations->firstChild();
|
|
while (item)
|
|
{
|
|
if (item->isOpen())
|
|
openedItems += item->text(0);
|
|
item = item->nextSibling();
|
|
}
|
|
m_allAnnotations->clear();
|
|
m_annotatedFileItems.clear();
|
|
m_fileNames.clear();
|
|
m_lines.clear();
|
|
|
|
TQStringList yourOpenedItems;
|
|
item = m_yourAnnotations->firstChild();
|
|
while (item)
|
|
{
|
|
if (item->isOpen())
|
|
yourOpenedItems += item->text(0);
|
|
item = item->nextSibling();
|
|
}
|
|
|
|
m_yourAnnotations->clear();
|
|
m_yourFileItems.clear();
|
|
m_yourFileNames.clear();
|
|
m_yourLines.clear();
|
|
m_yourAnnotationsNum = 0;
|
|
|
|
TQDomElement annotationElement = Project::ref()->dom()->firstChild().firstChild().namedItem("annotations").toElement();
|
|
if (annotationElement.isNull())
|
|
return;
|
|
TQString yourself = Project::ref()->yourself().lower();
|
|
TQStringList roles = Project::ref()->yourRoles();
|
|
TQDomNodeList nodes = annotationElement.childNodes();
|
|
int count = nodes.count();
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
TQDomElement el = nodes.item(i).toElement();
|
|
TQString fileName = el.attribute("url");
|
|
KURL u = baseURL;
|
|
QuantaCommon::setUrl(u, fileName);
|
|
u = QExtFileInfo::toAbsolute(u, baseURL);
|
|
if (Project::ref()->contains(u))
|
|
{
|
|
bool ok;
|
|
int line = el.attribute("line").toInt(&ok, 10);
|
|
TQString text = el.attribute("text");
|
|
TQString receiver = el.attribute("receiver");
|
|
text.replace('\n',' ');
|
|
TQString lineText = TQString("%1").arg(line);
|
|
if (lineText.length() < 20)
|
|
{
|
|
TQString s;
|
|
s.fill('0', 20 - lineText.length());
|
|
lineText.prepend(s);
|
|
}
|
|
KListViewItem *fileIt = m_annotatedFileItems[fileName];
|
|
if (!fileIt)
|
|
{
|
|
fileIt = new KListViewItem(m_allAnnotations, fileName);
|
|
m_annotatedFileItems.insert(fileName, fileIt);
|
|
m_fileNames[fileIt] = u.url();
|
|
}
|
|
KListViewItem *it = new KListViewItem(fileIt, fileIt, text, lineText);
|
|
if (openedItems.contains(fileName))
|
|
fileIt->setOpen(true);
|
|
m_fileNames[it] = u.url();
|
|
m_lines[it] = line;
|
|
|
|
if (!yourself.isEmpty() && (receiver == yourself || roles.contains(receiver)))
|
|
{
|
|
m_yourAnnotationsNum++;
|
|
KListViewItem *fileIt = m_yourFileItems[fileName];
|
|
if (!fileIt)
|
|
{
|
|
fileIt = new KListViewItem(m_yourAnnotations, fileName);
|
|
m_yourFileItems.insert(fileName, fileIt);
|
|
m_yourFileNames[fileIt] = u.url();
|
|
}
|
|
KListViewItem *it = new KListViewItem(fileIt, fileIt, text, lineText);
|
|
if (yourOpenedItems.contains(fileName))
|
|
fileIt->setOpen(true);
|
|
m_yourFileNames[it] = u.url();
|
|
m_yourLines[it] = line;
|
|
}
|
|
} else
|
|
{
|
|
annotationElement.removeChild(el);
|
|
}
|
|
}
|
|
if (m_yourAnnotationsNum > 0)
|
|
{
|
|
setTabLabel(m_yourAnnotations, i18n("For You: %1").arg(m_yourAnnotationsNum));
|
|
} else
|
|
{
|
|
setTabLabel(m_yourAnnotations, i18n("For You"));
|
|
}
|
|
}
|
|
|
|
void AnnotationOutput::writeAnnotations(const TQString &fileName, const TQMap<uint, TQPair<TQString, TQString> > &a_annotations)
|
|
{
|
|
m_annotatedFileItems.clear();
|
|
m_fileNames.clear();
|
|
m_lines.clear();
|
|
m_yourFileItems.clear();
|
|
m_yourFileNames.clear();
|
|
m_yourLines.clear();
|
|
|
|
bool modified = false;
|
|
TQMap<uint, TQPair<TQString, TQString> > annotations = a_annotations;
|
|
TQDomDocument *dom = Project::ref()->dom();
|
|
TQDomElement annotationElement = dom->firstChild().firstChild().namedItem("annotations").toElement();
|
|
if (annotationElement.isNull())
|
|
{
|
|
annotationElement = dom->createElement("annotations");
|
|
dom->firstChild().firstChild().appendChild(annotationElement);
|
|
}
|
|
TQDomNode n = annotationElement.firstChild();
|
|
while ( !n.isNull() )
|
|
{
|
|
TQDomElement el = n.toElement();
|
|
TQString fName = el.attribute("url");
|
|
TQDomNode n2 = n.nextSibling();
|
|
if (fileName == fName)
|
|
{
|
|
TQString text = el.attribute("text");
|
|
bool ok;
|
|
int line = el.attribute("line").toInt(&ok, 10);
|
|
if (!annotations.contains(line) || (annotations[line].first != text))
|
|
{
|
|
n.parentNode().removeChild(n);
|
|
modified = true;
|
|
} else
|
|
annotations.remove(line);
|
|
}
|
|
n = n2;
|
|
}
|
|
for (TQMap<uint, TQPair<TQString, TQString> >::ConstIterator it = annotations.constBegin(); it != annotations.constEnd(); ++it)
|
|
{
|
|
TQDomElement el = dom->createElement("annotation");
|
|
el.setAttribute("url", fileName);
|
|
el.setAttribute("line", it.key());
|
|
el.setAttribute("text", it.data().first);
|
|
el.setAttribute("receiver", it.data().second.lower());
|
|
annotationElement.appendChild(el);
|
|
modified = true;
|
|
}
|
|
if (modified)
|
|
Project::ref()->setModified(true);
|
|
if (m_allAnnotations->isVisible() || m_yourAnnotations->isVisible())
|
|
readAnnotations();
|
|
}
|
|
|
|
void AnnotationOutput::allAnnotationsItemExecuted(TQListViewItem *item)
|
|
{
|
|
if (dynamic_cast<KListView*> (item->parent()) != m_allAnnotations)
|
|
{
|
|
emit clicked(m_fileNames[item], m_lines[item], 0);
|
|
} else
|
|
emit clicked(m_fileNames[item], 0, 0);
|
|
}
|
|
|
|
void AnnotationOutput::yourAnnotationsItemExecuted(TQListViewItem *item)
|
|
{
|
|
if (dynamic_cast<KListView*> (item->parent()) != m_yourAnnotations)
|
|
{
|
|
emit clicked(m_yourFileNames[item], m_yourLines[item], 0);
|
|
} else
|
|
emit clicked(m_yourFileNames[item], 0, 0);
|
|
}
|
|
|
|
void AnnotationOutput::updateAnnotations()
|
|
{
|
|
m_updateTimer->stop();
|
|
m_currentFileAnnotations->clear();
|
|
readAnnotations();
|
|
if (Project::ref()->hasProject() && Project::ref()->projectBaseURL().isLocalFile())
|
|
{
|
|
m_files = Project::ref()->files();
|
|
m_fileIndex = 0;
|
|
m_updateTimer->start(0, true);
|
|
}
|
|
}
|
|
|
|
void AnnotationOutput::updateAnnotationForFile(const KURL& url)
|
|
{
|
|
static const TQRegExp rx("-->|\\*/");
|
|
if (!ViewManager::ref()->isOpened(url) && QuantaCommon::checkMimeGroup(url, "text" ))
|
|
{
|
|
// kdDebug(24000) << "Testing " << url << endl;
|
|
TQFile f(url.path());
|
|
if (f.open(IO_ReadOnly))
|
|
{
|
|
TQMap<uint, TQPair<TQString, TQString> > annotations;
|
|
uint i = 0;
|
|
TQTextStream stream(&f);
|
|
stream.setEncoding(TQTextStream::UnicodeUTF8);
|
|
TQString line;
|
|
while (!stream.atEnd())
|
|
{
|
|
line = stream.readLine();
|
|
int pos = line.find("@annotation");
|
|
if (pos != -1)
|
|
{
|
|
TQString receiver;
|
|
pos += 11;
|
|
if (line[pos] == '(')
|
|
{
|
|
int p = pos;
|
|
pos = line.find(')');
|
|
if (pos != -1)
|
|
{
|
|
receiver = line.mid(p + 1, pos - p - 1);
|
|
pos += 2;
|
|
}
|
|
} else
|
|
pos++;
|
|
int pos2 = line.find(rx);
|
|
annotations.insert(i, tqMakePair(line.mid(pos, pos2 - pos).stripWhiteSpace(), receiver));
|
|
}
|
|
++i;
|
|
}
|
|
f.close();
|
|
if (!annotations.isEmpty())
|
|
{
|
|
KURL u = QExtFileInfo::toRelative(url, Project::ref()->projectBaseURL());
|
|
writeAnnotations(QuantaCommon::qUrl(u), annotations);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void AnnotationOutput::slotUpdateNextFile()
|
|
{
|
|
updateAnnotationForFile(m_files[m_fileIndex]);
|
|
if (m_fileIndex < m_files.count())
|
|
{
|
|
m_fileIndex++;
|
|
m_updateTimer->start(2, true);
|
|
} else
|
|
if (m_yourAnnotationsNum > 0)
|
|
{
|
|
KMessageBox::information(this, i18n("<qt>There are annotations addressed for you.<br> To view them select the <i>For You</i> tab in the <i>Annotations</i> toolview.</qt>"), i18n("New Annotations"), "Show Your Annotations");
|
|
}
|
|
}
|
|
|
|
#include "annotationoutput.moc"
|