summaryrefslogtreecommitdiffstats
path: root/quanta/messages
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commite9ae80694875f869892f13f4fcaf1170a00dea41 (patch)
treeaa2f8d8a217e2d376224c8d46b7397b68d35de2d /quanta/messages
downloadtdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.tar.gz
tdewebdev-e9ae80694875f869892f13f4fcaf1170a00dea41.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdewebdev@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'quanta/messages')
-rw-r--r--quanta/messages/Makefile.am13
-rw-r--r--quanta/messages/annotationoutput.cpp355
-rw-r--r--quanta/messages/annotationoutput.h90
-rw-r--r--quanta/messages/messageitem.cpp92
-rw-r--r--quanta/messages/messageitem.h54
-rw-r--r--quanta/messages/messageoutput.cpp179
-rw-r--r--quanta/messages/messageoutput.h90
7 files changed, 873 insertions, 0 deletions
diff --git a/quanta/messages/Makefile.am b/quanta/messages/Makefile.am
new file mode 100644
index 00000000..625869eb
--- /dev/null
+++ b/quanta/messages/Makefile.am
@@ -0,0 +1,13 @@
+noinst_LTLIBRARIES = libmessages.la
+
+libmessages_la_SOURCES = messageoutput.cpp messageitem.cpp annotationoutput.cpp
+METASOURCES = AUTO
+
+AM_CPPFLAGS = -I$(top_srcdir)/quanta/utility \
+ -I$(top_srcdir)/quanta/src \
+ -I$(top_srcdir)/quanta/project \
+ -I$(top_srcdir)/quanta/parsers \
+ -I$(top_srcdir)/lib \
+ $(all_includes)
+
+noinst_HEADERS = annotationoutput.h
diff --git a/quanta/messages/annotationoutput.cpp b/quanta/messages/annotationoutput.cpp
new file mode 100644
index 00000000..8c8d7d90
--- /dev/null
+++ b/quanta/messages/annotationoutput.cpp
@@ -0,0 +1,355 @@
+//
+// C++ Implementation: annotationoutput
+//
+// Description:
+//
+//
+// Author: Andras Mantia <amantia@kde.org>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+
+#include <qdict.h>
+#include <qdom.h>
+#include <qfile.h>
+#include <qheader.h>
+#include <qmap.h>
+#include <qregexp.h>
+#include <qstringlist.h>
+#include <qtextstream.h>
+#include <qtimer.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(QWidget *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, SIGNAL(executed(QListViewItem*)), SLOT(yourAnnotationsItemExecuted(QListViewItem *)));
+
+ 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, SIGNAL(executed(QListViewItem*)), SLOT(allAnnotationsItemExecuted(QListViewItem *)));
+ addTab(m_allAnnotations, i18n("All Files"));
+
+
+ connect(this, SIGNAL(currentChanged(QWidget*)), SLOT(tabChanged(QWidget*)));
+
+ m_updateTimer = new QTimer(this);
+ connect(m_updateTimer, SIGNAL(timeout()), this, SLOT(slotUpdateNextFile()));
+
+ m_yourAnnotationsNum = 0;
+}
+
+AnnotationOutput::~AnnotationOutput()
+{
+}
+
+void AnnotationOutput::tabChanged(QWidget *w)
+{
+ if (w == m_allAnnotations || w == m_yourAnnotations)
+ readAnnotations();
+}
+
+void AnnotationOutput::insertAnnotation(uint line, const QString& fileName, const QPair<QString, QString>& annotation)
+{
+ line++;
+ QString 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();
+ QStringList openedItems;
+ QListViewItem *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();
+
+ QStringList 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;
+
+ QDomElement annotationElement = Project::ref()->dom()->firstChild().firstChild().namedItem("annotations").toElement();
+ if (annotationElement.isNull())
+ return;
+ QString yourself = Project::ref()->yourself().lower();
+ QStringList roles = Project::ref()->yourRoles();
+ QDomNodeList nodes = annotationElement.childNodes();
+ int count = nodes.count();
+ for (int i = 0; i < count; i++)
+ {
+ QDomElement el = nodes.item(i).toElement();
+ QString 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);
+ QString text = el.attribute("text");
+ QString receiver = el.attribute("receiver");
+ text.replace('\n',' ');
+ QString lineText = QString("%1").arg(line);
+ if (lineText.length() < 20)
+ {
+ QString 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 QString &fileName, const QMap<uint, QPair<QString, QString> > &a_annotations)
+{
+ m_annotatedFileItems.clear();
+ m_fileNames.clear();
+ m_lines.clear();
+ m_yourFileItems.clear();
+ m_yourFileNames.clear();
+ m_yourLines.clear();
+
+ bool modified = false;
+ QMap<uint, QPair<QString, QString> > annotations = a_annotations;
+ QDomDocument *dom = Project::ref()->dom();
+ QDomElement annotationElement = dom->firstChild().firstChild().namedItem("annotations").toElement();
+ if (annotationElement.isNull())
+ {
+ annotationElement = dom->createElement("annotations");
+ dom->firstChild().firstChild().appendChild(annotationElement);
+ }
+ QDomNode n = annotationElement.firstChild();
+ while ( !n.isNull() )
+ {
+ QDomElement el = n.toElement();
+ QString fName = el.attribute("url");
+ QDomNode n2 = n.nextSibling();
+ if (fileName == fName)
+ {
+ QString 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 (QMap<uint, QPair<QString, QString> >::ConstIterator it = annotations.constBegin(); it != annotations.constEnd(); ++it)
+ {
+ QDomElement 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(QListViewItem *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(QListViewItem *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 QRegExp rx("-->|\\*/");
+ if (!ViewManager::ref()->isOpened(url) && QuantaCommon::checkMimeGroup(url, "text" ))
+ {
+ // kdDebug(24000) << "Testing " << url << endl;
+ QFile f(url.path());
+ if (f.open(IO_ReadOnly))
+ {
+ QMap<uint, QPair<QString, QString> > annotations;
+ uint i = 0;
+ QTextStream stream(&f);
+ stream.setEncoding(QTextStream::UnicodeUTF8);
+ QString line;
+ while (!stream.atEnd())
+ {
+ line = stream.readLine();
+ int pos = line.find("@annotation");
+ if (pos != -1)
+ {
+ QString 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, qMakePair(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"
diff --git a/quanta/messages/annotationoutput.h b/quanta/messages/annotationoutput.h
new file mode 100644
index 00000000..0c5ab748
--- /dev/null
+++ b/quanta/messages/annotationoutput.h
@@ -0,0 +1,90 @@
+//
+// C++ Interface: annotationoutput
+//
+// Description:
+//
+//
+// Author: Andras Mantia <amantia@kde.org>, (C) 2005
+//
+// Copyright: See COPYING file that comes with this distribution
+//
+//
+#ifndef ANNOTATIONOUTPUT_H
+#define ANNOTATIONOUTPUT_H
+
+#include <kurl.h>
+#include <ktabwidget.h>
+
+/**
+@author Andras Mantia
+*/
+
+class QDomDocument;
+class QListViewItem;
+class QTimer;
+
+class KListView;
+class KListViewItem;
+
+class MessageOutput;
+
+enum AnnotationScope
+{
+ CurrentFile = 0,
+ AllFiles
+};
+
+class AnnotationOutput : public KTabWidget
+{
+Q_OBJECT
+public:
+ AnnotationOutput(QWidget *parent = 0, const char *name = 0);
+
+ ~AnnotationOutput();
+ MessageOutput *currentFileAnnotations() const {return m_currentFileAnnotations;}
+ KListView *allAnnotations() const {return m_allAnnotations;}
+ void writeAnnotations(const QString &fileName, const QMap<uint, QPair<QString, QString> > &annotations);
+
+public slots:
+ /**
+ * Scans the project files to see if there were annotations added or modified outside of Quanta. The scan is done in background.
+ */
+ void updateAnnotations();
+ void readAnnotations();
+ void clearAnnotations();
+ void insertAnnotation(uint line, const QString& fileName, const QPair<QString, QString>& annotation);
+
+private slots:
+ void tabChanged(QWidget *w);
+ void allAnnotationsItemExecuted(QListViewItem *item);
+ void yourAnnotationsItemExecuted(QListViewItem *item);
+ void slotUpdateNextFile();
+
+signals:
+ void clicked(const QString& fname, int line, int col);
+
+private:
+ /**
+ * Updates the annotation for a file.
+ * @param url
+ */
+ void updateAnnotationForFile(const KURL& url);
+
+ MessageOutput *m_currentFileAnnotations;
+ KListView *m_allAnnotations;
+ QDict<KListViewItem> m_annotatedFileItems;
+ QMap<QListViewItem*, QString> m_fileNames;
+ QMap<QListViewItem*, uint> m_lines;
+ uint m_yourAnnotationsNum;
+
+ KListView *m_yourAnnotations;
+ QDict<KListViewItem> m_yourFileItems;
+ QMap<QListViewItem*, QString> m_yourFileNames;
+ QMap<QListViewItem*, uint> m_yourLines;
+
+ QTimer *m_updateTimer;
+ KURL::List m_files;
+ uint m_fileIndex;
+};
+
+#endif
diff --git a/quanta/messages/messageitem.cpp b/quanta/messages/messageitem.cpp
new file mode 100644
index 00000000..7f906041
--- /dev/null
+++ b/quanta/messages/messageitem.cpp
@@ -0,0 +1,92 @@
+/***************************************************************************
+ messageoutput.cpp - description
+ -------------------
+ begin : Jan 12 2001
+ copyright : (C) 2001 by Dmitry Poplavsky <dima@kde.org>
+ (C) 2002-2005 Andras Mantia <amantia@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "messageitem.h"
+#include <qregexp.h>
+#include <klocale.h>
+
+MessageItem::MessageItem( QListBox * listbox, const QString &text, int line, int column, const QString &fname )
+ :QListBoxText(listbox,text),lineNumber(line),columnNumber(column),filename(fname)
+{
+}
+
+int MessageItem::line()
+{
+ if ( lineNumber != -1 ) {
+ return lineNumber;
+ }
+ else { // try to find first number in text
+ QString s = text();
+ int pos = s.find( QRegExp("[0-9]"));
+ if ( pos == -1 )
+ return lineNumber;
+ int pos2 = pos;
+ while ( s[pos2].isDigit() ) pos2++;
+
+ QString snum = s.mid(pos, pos2-pos);
+ return snum.toInt();
+
+ }
+}
+
+int MessageItem::column()
+{
+ if (columnNumber != -1)
+ {
+ return columnNumber;
+ } else
+ {
+ QString s = text();
+ QRegExp exp("(?:\\D|^)(\\d{1,4})(?:\\D|$)");
+
+ int pos = exp.search(s);
+ if ( pos == -1 )
+ return 0;
+ pos = exp.search(s, pos + exp.cap(1).length());
+ if ( pos == -1 )
+ return 0;
+ s = exp.cap(1);
+ return s.toInt();
+ }
+}
+
+QString MessageItem::fileName()
+{
+ if (filename.isEmpty())
+ {
+ QString fname;
+ QString s = text();
+ int pos = s.find(i18n("File: "));
+ if (pos != -1)
+ {
+ int pos2 = s.find(i18n(", "), pos);
+ if (pos2 != -1)
+ fname = s.mid(pos, pos2-pos);
+ else
+ fname = s.mid(pos);
+ fname.remove(i18n("File: "));
+ }
+ return fname;
+ } else
+ return filename;
+}
+
+void MessageItem::addText(const QString &t)
+{
+ setText( text() + t );
+}
+
diff --git a/quanta/messages/messageitem.h b/quanta/messages/messageitem.h
new file mode 100644
index 00000000..01e04b35
--- /dev/null
+++ b/quanta/messages/messageitem.h
@@ -0,0 +1,54 @@
+/***************************************************************************
+ messageoutput.h - description
+ -------------------
+ begin : Jan 12 2001
+ copyright : (C) 2001 by Dmitry Poplavsky <dima@kde.org>
+ (C) 2002-2005 Andras Mantia <amantia@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+
+#ifndef MESSAGEITEM_H
+#define MESSAGEITEM_H
+
+#include <qlistbox.h>
+
+/**
+ Like QListBoxText with storing of filename and line in it.
+*/
+
+class MessageItem : public QListBoxText {
+ public:
+
+ MessageItem( QListBox *listbox, const QString &text = QString::null, int line = -1, int column = -1, const QString &fname = QString::null);
+
+ /** return line number for file , associated with this message */
+ int line();
+ /** return column number for file , associated with this message */
+ int column();
+ /** return name of file , associated with this message */
+ QString fileName();
+
+ void setLine(int line) { lineNumber = line; }
+ void setColumn(int line) { columnNumber = line; }
+ void setFileName(const QString &fileName ) { filename = fileName; }
+ void addText(const QString &text);
+ private:
+
+ // line number and filename , associated with this line
+ int lineNumber; ///< the line of the item. -1 if not defined
+ int columnNumber; ///< the column of the item. -1 if not defined
+ QString filename; ///< the filename (URL) of the item. Empty if not defined
+
+};
+
+#endif
+
diff --git a/quanta/messages/messageoutput.cpp b/quanta/messages/messageoutput.cpp
new file mode 100644
index 00000000..6b89aaa9
--- /dev/null
+++ b/quanta/messages/messageoutput.cpp
@@ -0,0 +1,179 @@
+/***************************************************************************
+ messageoutput.cpp - description
+ -------------------
+ begin : Thu Feb 24 2000
+ copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavski <pdima@mail.univ.kiev.ua>
+ (C) 2003-2005 Andras Mantia <amantia@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+// KDE includes
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kfiledialog.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kpopupmenu.h>
+#include <kiconloader.h>
+
+// Qt includes
+#include <qclipboard.h>
+#include <qfile.h>
+#include <qtextstream.h>
+
+#include "messageoutput.h"
+#include "messageitem.h"
+
+MessageOutput::MessageOutput(QWidget *parent, const char *name )
+ : QListBox(parent,name)
+{
+ m_maxItems = 2000;
+
+ QPalette pal = palette();
+ pal.setColor(QColorGroup::HighlightedText, pal.color(QPalette::Normal, QColorGroup::Text));
+ pal.setColor(QColorGroup::Highlight, pal.color(QPalette::Normal, QColorGroup::Mid));
+ setPalette(pal);
+ setFocusPolicy( NoFocus );
+
+ m_popupMenu = new KPopupMenu(this);
+ connect(this, SIGNAL(contextMenuRequested(QListBoxItem*, const QPoint&)),
+ this, SLOT(showMenu(QListBoxItem*, const QPoint&)));
+ m_popupMenu->insertItem( SmallIconSet("editcopy"), i18n("&Copy"), this, SLOT(copyContent()) ) ;
+ m_popupMenu->insertItem( SmallIconSet("filesaveas"), i18n("&Save As..."), this, SLOT(saveContent()) ) ;
+ m_popupMenu->insertSeparator();
+ m_popupMenu->insertItem( SmallIconSet("editclear"), i18n("Clear"), this, SLOT(clear()) ) ;
+
+ connect( this, SIGNAL(clicked(QListBoxItem*)), SLOT(clickItem(QListBoxItem*)) );
+}
+
+MessageOutput::~MessageOutput()
+{
+}
+
+MessageItem *MessageOutput::insertItem(const QString& s)
+{
+ checkMaxItems();
+ MessageItem *it = new MessageItem(this, s);
+ setBottomItem(count()>0?count()-1:0);
+ return it;
+}
+
+void MessageOutput::addToLastItem(const QString& s)
+{
+ int ind = count() - 1;
+ if ( ind != -1 ) {
+ MessageItem *it = dynamic_cast<MessageItem*>( item(ind) );
+ if ( it )
+ it->addText( s );
+ else
+ changeItem( text( ind )+ s, ind );
+ }
+}
+
+void MessageOutput::showMessage(int line, int col, const QString &fileName, const QString& s, bool append)
+{
+ MessageItem *it = 0L;
+ QString message = s;
+ int endPos;
+ if ( !count() || (!append && !text(count()-1).stripWhiteSpace().isEmpty()) )
+ it = insertItem("");
+ while ( ( endPos = message.find('\n') ) != -1 ) {
+ if (it)
+ {
+ it->setLine(line);
+ it->setColumn(col);
+ it->setFileName(fileName);
+ }
+ addToLastItem( message.left(endPos) );
+ it = insertItem("");
+ message.remove(0,endPos+1);
+ }
+ if (!message.isEmpty())
+ {
+ if (it)
+ {
+ it->setLine(line);
+ it->setColumn(col);
+ it->setFileName(fileName);
+ }
+ addToLastItem( message);
+ }
+ setBottomItem(count()>0?count()-1:0);
+}
+
+void MessageOutput::showMessage(const QString& s, bool append)
+{
+ showMessage(-1, -1, "", s, append);
+}
+
+
+void MessageOutput::checkMaxItems()
+{
+ if ( count() >= m_maxItems )
+ removeItem( index(firstItem()) );
+}
+
+void MessageOutput::clickItem( QListBoxItem * l_item )
+{
+ MessageItem *item = dynamic_cast<MessageItem*>(l_item);
+ if ( item ) {
+// kdDebug(24000) << "Column: " << item->column() << endl;
+ if ( item->line() != -1 )
+ emit clicked( item->fileName(), item->line() - 1, item->column() - 1);
+ }
+}
+
+void MessageOutput::showMenu( QListBoxItem*, const QPoint& l_point )
+{
+ m_popupMenu->exec(l_point);
+}
+
+QString MessageOutput::content()
+{
+ QString p_content;
+ for (uint i=0; i<count(); i++)
+ p_content.append(text(i) + "\n");
+ return p_content;
+}
+
+void MessageOutput::copyContent()
+{
+ kapp->clipboard()->setText(content(), QClipboard::Clipboard);
+}
+
+void MessageOutput::saveContent()
+{
+ KURL url=KFileDialog::getSaveURL(QDir::currentDirPath(),
+ i18n("*.log|Log Files (*.log)\n*|All Files"), this, i18n("Save Log File"));
+ if (url.isEmpty())
+ return;
+
+ QFileInfo fileinfo(url.path());
+ if (fileinfo.exists() && KMessageBox::warningContinueCancel(0,
+ i18n("<qt>File<br><b>%1</b><br>already exists. Overwrite it?</qt>")
+ .arg(url.path()), QString::null, i18n("Overwrite")) == KMessageBox::Cancel)
+ return;
+
+ QFile file(url.path());
+ if (!file.open(IO_WriteOnly)) {
+ KMessageBox::error(0, i18n("<qt>Cannot save log file<br><b>%1</b></qt>")
+ .arg(url.url()));
+ return;
+ }
+
+ QTextStream textfile(&file);
+ textfile << content();
+ file.close();
+
+}
+
+
+#include "messageoutput.moc"
diff --git a/quanta/messages/messageoutput.h b/quanta/messages/messageoutput.h
new file mode 100644
index 00000000..223470bd
--- /dev/null
+++ b/quanta/messages/messageoutput.h
@@ -0,0 +1,90 @@
+/***************************************************************************
+ messageoutput.h - description
+ -------------------
+ begin : Thu Feb 24 2000
+ copyright : (C) 2000 by Yacovlev Alexander & Dmitry Poplavski <pdima@mail.univ.kiev.ua>
+ (C) 2002-2005 Andras Mantia <amantia@kde.org>
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#ifndef MESSAGEOUTPUT_H
+#define MESSAGEOUTPUT_H
+
+#include <qlistbox.h>
+
+class KProcess;
+class KPopupMenu;
+
+class MessageItem;
+
+/**class for displaing of
+weblint output
+ *@author Yacovlev Alexander & Dmitry Poplavski
+ */
+
+class MessageOutput : public QListBox {
+ Q_OBJECT
+public:
+ MessageOutput(QWidget *parent=0, const char *name=0);
+ ~MessageOutput();
+ // Return whole content as a single string with EOLs
+ QString content();
+
+public slots:
+ /** Inserts an item with the content s to the end of the list*/
+ MessageItem *insertItem(const QString& s);
+
+ /** Insert message for each line of string (EOL-separated).
+ @param line The line this message refers to. -1 if it's not specified (the first number is taken from the message string)
+ @param column The column this message refers to. -1 if it's not specified (the second number is taken from the message string)
+ @param fileName The URL of the file this message refers to. If empty, the string following the "File: " string in the message is used.
+ @param message The message itself
+ @param append Append the message to the previous one or start a new line. Default is false, start a new line.
+ */
+ void showMessage(int line, int column, const QString &fileName, const QString& message, bool append = false);
+ /** Insert message for each line of string (EOL-separated).
+ @param message The message itself
+ @param append Append the message to the previous one or start a new line. Default is false, start a new line.
+ */
+ void showMessage(const QString& message, bool append = false);
+ /** Append message string to the last item
+ @param line The line this message refers to. -1 if it's not specified (the first number is taken from the message string)
+ @param column The column this message refers to. -1 if it's not specified (the second number is taken from the message string)
+ @param fileName The URL of the file this message refers to. If empty, the string following the "File: " string in the message is used.
+ @param message The message itself
+ */
+ void addToLastItem(const QString& message);
+ // Copy message content to clipboard
+ void copyContent();
+ // Save message content to clipboard
+ void saveContent();
+
+
+public:
+ uint maxItems() const { return m_maxItems; }
+ void setMaxItems( uint items ) { m_maxItems = items; }
+ /** remove first items , if count > m_maxItem */
+ void checkMaxItems();
+
+signals:
+ void clicked(const QString& fname, int line, int col);
+
+protected slots:
+ void clickItem( QListBoxItem *);
+ // Show context menu
+ void showMenu(QListBoxItem*, const QPoint&);
+
+private:
+ uint m_maxItems;
+ KPopupMenu* m_popupMenu;
+};
+
+#endif