------=_Part_2267_10903732.1208293490984 Content-Type: multipart/alternative; boundary="----=_Part_2268_20595983.1208293490985" ------=_Part_2268_20595983.1208293490985 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi. Yes, according to QDir docs: Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system. Also, looking at this again, I realized that using QString::remove might have the corner case where your path repeats (eg, if scanning /home/user/ and /home/user/stuff/home/user/file.txt matches, it would show up as stufffile.txt [and I tested it, it does]). So attached is a new version of the patch that doesn't cause that. I also just noticed a bug, but couldn't find where it's coming from: the last line on a file is never matched. E.g. I had created a file with just "test" inside, and it wasn't matching. Adding two \n to the end of the file made it match. Should I open the bug on b.k.o? Ivo P.s.: Please CC me directly as I have mail delivery for the list off. On Tue, Apr 15, 2008 at 9:54 PM, Christian Ehrlicher wrote: > Dominik Haumann schrieb: > > Hi, > > > > looks good, but one question though, see below. > > > > On Monday 14 April 2008, Ivo Anjo wrote: > > > > > Hi. > > > > > > This patch adds the relative path (from the root folder of the grep) > > > to > > > the filename shown on the file in files plugin. > > > So if I have /somedir/text/boo.txt and I grep with /somedir as root, > > > and > > > boo.txt matches, instead of appearing "boo.txt", it appears > > > "text/boo.txt". > > > > > > This is specially useful in java projects, where you have tons of > > > classes > > > in different dirs, and this helps to know what things are without > > > opening > > > them and looking at the package. > > > > > > Ivo Anjo > > > > > > P.s.: Please CC me directly as I have mail delivery for the list off. > > > kate_find_in_files_relpath.patch > > > Index: plugins/findinfiles/kategrepthread.h > > > =================================================================== > > > --- plugins/findinfiles/kategrepthread.h (revision 795790) > > > +++ plugins/findinfiles/kategrepthread.h (working copy) > > > @@ -51,7 +51,7 @@ > > > void grepInFile (const QString &fileName, const QString > > > &baseName); > > > Q_SIGNALS: > > > - void foundMatch (const QString &filename, int line, int column, > > > const QString &basename, const QString &lineContent, QWidget > > > *parentTab); > > > + void foundMatch (const QString &filename, const QString &relname, > > > int line, int column, const QString &basename, const QString > > > &lineContent, QWidget *parentTab); private: > > > QWidget* m_parentTab; > > > @@ -60,6 +60,7 @@ > > > bool m_recursive; > > > QStringList m_fileWildcards; > > > QList m_searchPattern; > > > + QString m_dir; > > > }; > > > #endif > > > Index: plugins/findinfiles/kategrepdialog.cpp > > > =================================================================== > > > --- plugins/findinfiles/kategrepdialog.cpp (revision 795790) > > > +++ plugins/findinfiles/kategrepdialog.cpp (working copy) > > > @@ -296,8 +296,8 @@ > > > connect(lbResult, SIGNAL(destroyed()), m_grepThread, > > > SLOT(cancel())); > > > connect(lbResult, SIGNAL(destroyed()), this, > > > SLOT(searchFinished())); > > > connect (m_grepThread, SIGNAL(finished()), this, > > > SLOT(searchFinished())); - connect (m_grepThread, SIGNAL(foundMatch > > > (const QString &, int, int, const QString &, const QString &, QWidget > > > *)), - this, SLOT(searchMatchFound(const QString &, int, > > > int, > > > const QString &, const QString &, QWidget *))); + connect > > > (m_grepThread, > > > SIGNAL(foundMatch (const QString &, const QString &, int, int, const > > > QString &, const QString &, QWidget *)), + this, > > > SLOT(searchMatchFound(const QString &, const QString &, int, int, > > > const > > > QString &, const QString &, QWidget *))); // grep > > > m_grepThread->start(); > > > @@ -369,7 +369,7 @@ > > > } > > > } > > > -void KateGrepDialog::searchMatchFound(const QString &filename, int > > > line, > > > int column, const QString &basename, const QString &lineContent, > > > QWidget > > > *parentTab) +void KateGrepDialog::searchMatchFound(const QString > > > &filename, const QString &relname, int line, int column, const QString > > > &basename, const QString &lineContent, QWidget *parentTab) { > > > // should never happen > > > if(lbResult->indexOf(parentTab) < 0) > > > @@ -379,7 +379,7 @@ > > > QTreeWidgetItem* item = new QTreeWidgetItem(w); > > > // visible text > > > - item->setText(0, basename); > > > + item->setText(0, relname); > > > item->setText(1, QString::number (line + 1)); > > > item->setText(2, lineContent.trimmed()); > > > Index: plugins/findinfiles/kategrepdialog.h > > > =================================================================== > > > --- plugins/findinfiles/kategrepdialog.h (revision 795790) > > > +++ plugins/findinfiles/kategrepdialog.h (working copy) > > > @@ -63,7 +63,7 @@ > > > void slotClear(); > > > void patternTextChanged( const QString &); > > > void searchFinished (); > > > - void searchMatchFound(const QString &filename, int line, int > > > column, > > > const QString &basename, const QString &lineContent, QWidget > > > *parentTab); > > > + void searchMatchFound(const QString &filename, const QString > > > &relname, int line, int column, const QString &basename, const QString > > > &lineContent, QWidget *parentTab); void syncDir(); > > > private: > > > Index: plugins/findinfiles/kategrepthread.cpp > > > =================================================================== > > > --- plugins/findinfiles/kategrepthread.cpp (revision 795790) > > > +++ plugins/findinfiles/kategrepthread.cpp (working copy) > > > @@ -36,6 +36,8 @@ > > > , m_searchPattern (searchPattern) > > > { > > > m_workQueue << dir; > > > + QDir baseDir(dir); > > > + m_dir = baseDir.absolutePath() + '/'; > > > > > > > Does this work on Windows, too? > > > > Yes, why not :) > In Qt all internal paths have '/' as path separator. > > > Christian > ------=_Part_2268_20595983.1208293490985 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi.

Yes, according to QDir docs:

Qt uses "/" as a universal directory separator in the same way that "/" is used as a path separator in URLs. If you always use "/" as a directory separator, Qt will translate your paths to conform to the underlying operating system.


Also, looking at this again, I realized that using QString::remove might have the corner case where your path repeats (eg, if scanning /home/user/ and /home/user/stuff/home/user/file.txt matches, it would show up as stufffile.txt [and I tested it, it does]).

So attached is a new version of the patch that doesn't cause that.

I also just noticed a bug, but couldn't find where it's coming from: the last line on a file is never matched. E.g. I had created a file with just "test" inside, and it wasn't matching. Adding two \n to the end of the file made it match. Should I open the bug on b.k.o?

Ivo

P.s.: Please CC me directly as I have mail delivery for the list off.

On Tue, Apr 15, 2008 at 9:54 PM, Christian Ehrlicher <Ch.Ehrlicher@gmx.de> wrote:
Dominik Haumann schrieb:

Hi,

looks good, but one question though, see below.

On Monday 14 April 2008, Ivo Anjo wrote:
Hi.

This patch adds the relative path (from the root folder of the grep) to
the filename shown on the file in files plugin.
So if I have /somedir/text/boo.txt and I grep with /somedir as root, and
boo.txt matches, instead of appearing "boo.txt", it appears
"text/boo.txt".

This is specially useful in java projects, where you have tons of classes
in different dirs, and this helps to know what things are without opening
them and looking at the package.

Ivo Anjo

P.s.: Please CC me directly as I have mail delivery for the list off.
kate_find_in_files_relpath.patch
 Index: plugins/findinfiles/kategrepthread.h
===================================================================
--- plugins/findinfiles/kategrepthread.h        (revision 795790)
+++ plugins/findinfiles/kategrepthread.h        (working copy)
@@ -51,7 +51,7 @@
    void grepInFile (const QString &fileName, const QString &baseName);
    Q_SIGNALS:
-    void foundMatch (const QString &filename, int line, int column,
const QString &basename, const QString &lineContent, QWidget *parentTab);
+    void foundMatch (const QString &filename, const QString &relname,
int line, int column, const QString &basename, const QString
&lineContent, QWidget *parentTab);   private:
    QWidget* m_parentTab;
@@ -60,6 +60,7 @@
    bool m_recursive;
    QStringList m_fileWildcards;
    QList<QRegExp> m_searchPattern;
+    QString m_dir;
 };
  #endif
Index: plugins/findinfiles/kategrepdialog.cpp
===================================================================
--- plugins/findinfiles/kategrepdialog.cpp      (revision 795790)
+++ plugins/findinfiles/kategrepdialog.cpp      (working copy)
@@ -296,8 +296,8 @@
  connect(lbResult, SIGNAL(destroyed()), m_grepThread, SLOT(cancel()));
  connect(lbResult, SIGNAL(destroyed()), this, SLOT(searchFinished()));
  connect (m_grepThread, SIGNAL(finished()), this,
SLOT(searchFinished())); -  connect (m_grepThread, SIGNAL(foundMatch
(const QString &, int, int, const QString &, const QString &, QWidget
*)), -           this, SLOT(searchMatchFound(const QString &, int, int,
const QString &, const QString &, QWidget *))); +  connect (m_grepThread,
SIGNAL(foundMatch (const QString &, const QString &, int, int, const
QString &, const QString &, QWidget *)), +           this,
SLOT(searchMatchFound(const QString &, const QString &, int, int, const
QString &, const QString &, QWidget *)));   // grep
  m_grepThread->start();
@@ -369,7 +369,7 @@
  }
 }
 -void KateGrepDialog::searchMatchFound(const QString &filename, int line,
int column, const QString &basename, const QString &lineContent, QWidget
*parentTab) +void KateGrepDialog::searchMatchFound(const QString
&filename, const QString &relname, int line, int column, const QString
&basename, const QString &lineContent, QWidget *parentTab) {
  // should never happen
  if(lbResult->indexOf(parentTab) < 0)
@@ -379,7 +379,7 @@
    QTreeWidgetItem* item = new QTreeWidgetItem(w);
  // visible text
-  item->setText(0, basename);
+  item->setText(0, relname);
  item->setText(1, QString::number (line + 1));
  item->setText(2, lineContent.trimmed());
 Index: plugins/findinfiles/kategrepdialog.h
===================================================================
--- plugins/findinfiles/kategrepdialog.h        (revision 795790)
+++ plugins/findinfiles/kategrepdialog.h        (working copy)
@@ -63,7 +63,7 @@
    void slotClear();
    void patternTextChanged( const QString &);
    void searchFinished ();
-    void searchMatchFound(const QString &filename, int line, int column,
const QString &basename, const QString &lineContent, QWidget *parentTab);
+    void searchMatchFound(const QString &filename, const QString
&relname, int line, int column, const QString &basename, const QString
&lineContent, QWidget *parentTab); void syncDir();
    private:
Index: plugins/findinfiles/kategrepthread.cpp
===================================================================
--- plugins/findinfiles/kategrepthread.cpp      (revision 795790)
+++ plugins/findinfiles/kategrepthread.cpp      (working copy)
@@ -36,6 +36,8 @@
    , m_searchPattern (searchPattern)
 {
  m_workQueue << dir;
+  QDir baseDir(dir);
+  m_dir = baseDir.absolutePath() + '/';

Does this work on Windows, too?

Yes, why not :)
In Qt all internal paths have '/' as path separator.


Christian

------=_Part_2268_20595983.1208293490985-- ------=_Part_2267_10903732.1208293490984 Content-Type: text/x-patch; name=kate_find_in_files_relpath_v2.patch Content-Transfer-Encoding: base64 X-Attachment-Id: f_ff2ypli50 Content-Disposition: attachment; filename=kate_find_in_files_relpath_v2.patch SW5kZXg6IHBsdWdpbnMvZmluZGluZmlsZXMva2F0ZWdyZXB0aHJlYWQuaAo9PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci0t LSBwbHVnaW5zL2ZpbmRpbmZpbGVzL2thdGVncmVwdGhyZWFkLmgJKHJldmlzaW9uIDc5NTc5MCkK KysrIHBsdWdpbnMvZmluZGluZmlsZXMva2F0ZWdyZXB0aHJlYWQuaAkod29ya2luZyBjb3B5KQpA QCAtNTEsNyArNTEsNyBAQAogICAgIHZvaWQgZ3JlcEluRmlsZSAoY29uc3QgUVN0cmluZyAmZmls ZU5hbWUsIGNvbnN0IFFTdHJpbmcgJmJhc2VOYW1lKTsKIAogICBRX1NJR05BTFM6Ci0gICAgdm9p ZCBmb3VuZE1hdGNoIChjb25zdCBRU3RyaW5nICZmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1 bW4sIGNvbnN0IFFTdHJpbmcgJmJhc2VuYW1lLCBjb25zdCBRU3RyaW5nICZsaW5lQ29udGVudCwg UVdpZGdldCAqcGFyZW50VGFiKTsKKyAgICB2b2lkIGZvdW5kTWF0Y2ggKGNvbnN0IFFTdHJpbmcg JmZpbGVuYW1lLCBjb25zdCBRU3RyaW5nICZyZWxuYW1lLCBpbnQgbGluZSwgaW50IGNvbHVtbiwg Y29uc3QgUVN0cmluZyAmYmFzZW5hbWUsIGNvbnN0IFFTdHJpbmcgJmxpbmVDb250ZW50LCBRV2lk Z2V0ICpwYXJlbnRUYWIpOwogCiAgIHByaXZhdGU6CiAgICAgUVdpZGdldCogbV9wYXJlbnRUYWI7 CkBAIC02MCw2ICs2MCw3IEBACiAgICAgYm9vbCBtX3JlY3Vyc2l2ZTsKICAgICBRU3RyaW5nTGlz dCBtX2ZpbGVXaWxkY2FyZHM7CiAgICAgUUxpc3Q8UVJlZ0V4cD4gbV9zZWFyY2hQYXR0ZXJuOwor ICAgIFFTdHJpbmcgbV9kaXI7CiB9OwogCiAjZW5kaWYKSW5kZXg6IHBsdWdpbnMvZmluZGluZmls ZXMva2F0ZWdyZXBkaWFsb2cuY3BwCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIHBsdWdpbnMvZmluZGluZmlsZXMv a2F0ZWdyZXBkaWFsb2cuY3BwCShyZXZpc2lvbiA3OTU3OTApCisrKyBwbHVnaW5zL2ZpbmRpbmZp bGVzL2thdGVncmVwZGlhbG9nLmNwcAkod29ya2luZyBjb3B5KQpAQCAtMjk2LDggKzI5Niw4IEBA CiAgIGNvbm5lY3QobGJSZXN1bHQsIFNJR05BTChkZXN0cm95ZWQoKSksIG1fZ3JlcFRocmVhZCwg U0xPVChjYW5jZWwoKSkpOwogICBjb25uZWN0KGxiUmVzdWx0LCBTSUdOQUwoZGVzdHJveWVkKCkp LCB0aGlzLCBTTE9UKHNlYXJjaEZpbmlzaGVkKCkpKTsKICAgY29ubmVjdCAobV9ncmVwVGhyZWFk LCBTSUdOQUwoZmluaXNoZWQoKSksIHRoaXMsIFNMT1Qoc2VhcmNoRmluaXNoZWQoKSkpOwotICBj b25uZWN0IChtX2dyZXBUaHJlYWQsIFNJR05BTChmb3VuZE1hdGNoIChjb25zdCBRU3RyaW5nICYs IGludCwgaW50LCBjb25zdCBRU3RyaW5nICYsIGNvbnN0IFFTdHJpbmcgJiwgUVdpZGdldCAqKSks Ci0gICAgICAgICAgIHRoaXMsIFNMT1Qoc2VhcmNoTWF0Y2hGb3VuZChjb25zdCBRU3RyaW5nICYs IGludCwgaW50LCBjb25zdCBRU3RyaW5nICYsIGNvbnN0IFFTdHJpbmcgJiwgUVdpZGdldCAqKSkp OworICBjb25uZWN0IChtX2dyZXBUaHJlYWQsIFNJR05BTChmb3VuZE1hdGNoIChjb25zdCBRU3Ry aW5nICYsIGNvbnN0IFFTdHJpbmcgJiwgaW50LCBpbnQsIGNvbnN0IFFTdHJpbmcgJiwgY29uc3Qg UVN0cmluZyAmLCBRV2lkZ2V0ICopKSwKKyAgICAgICAgICAgdGhpcywgU0xPVChzZWFyY2hNYXRj aEZvdW5kKGNvbnN0IFFTdHJpbmcgJiwgY29uc3QgUVN0cmluZyAmLCBpbnQsIGludCwgY29uc3Qg UVN0cmluZyAmLCBjb25zdCBRU3RyaW5nICYsIFFXaWRnZXQgKikpKTsKIAogICAvLyBncmVwCiAg IG1fZ3JlcFRocmVhZC0+c3RhcnQoKTsKQEAgLTM2OSw3ICszNjksNyBAQAogICB9CiB9CiAKLXZv aWQgS2F0ZUdyZXBEaWFsb2c6OnNlYXJjaE1hdGNoRm91bmQoY29uc3QgUVN0cmluZyAmZmlsZW5h bWUsIGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBRU3RyaW5nICZiYXNlbmFtZSwgY29uc3Qg UVN0cmluZyAmbGluZUNvbnRlbnQsIFFXaWRnZXQgKnBhcmVudFRhYikKK3ZvaWQgS2F0ZUdyZXBE aWFsb2c6OnNlYXJjaE1hdGNoRm91bmQoY29uc3QgUVN0cmluZyAmZmlsZW5hbWUsIGNvbnN0IFFT dHJpbmcgJnJlbG5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBRU3RyaW5nICZiYXNl bmFtZSwgY29uc3QgUVN0cmluZyAmbGluZUNvbnRlbnQsIFFXaWRnZXQgKnBhcmVudFRhYikKIHsK ICAgLy8gc2hvdWxkIG5ldmVyIGhhcHBlbgogICBpZihsYlJlc3VsdC0+aW5kZXhPZihwYXJlbnRU YWIpIDwgMCkKQEAgLTM3OSw3ICszNzksNyBAQAogCiAgIFFUcmVlV2lkZ2V0SXRlbSogaXRlbSA9 IG5ldyBRVHJlZVdpZGdldEl0ZW0odyk7CiAgIC8vIHZpc2libGUgdGV4dAotICBpdGVtLT5zZXRU ZXh0KDAsIGJhc2VuYW1lKTsKKyAgaXRlbS0+c2V0VGV4dCgwLCByZWxuYW1lKTsKICAgaXRlbS0+ c2V0VGV4dCgxLCBRU3RyaW5nOjpudW1iZXIgKGxpbmUgKyAxKSk7CiAgIGl0ZW0tPnNldFRleHQo MiwgbGluZUNvbnRlbnQudHJpbW1lZCgpKTsKIApJbmRleDogcGx1Z2lucy9maW5kaW5maWxlcy9r YXRlZ3JlcGRpYWxvZy5oCj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIHBsdWdpbnMvZmluZGluZmlsZXMva2F0ZWdy ZXBkaWFsb2cuaAkocmV2aXNpb24gNzk1NzkwKQorKysgcGx1Z2lucy9maW5kaW5maWxlcy9rYXRl Z3JlcGRpYWxvZy5oCSh3b3JraW5nIGNvcHkpCkBAIC02Myw3ICs2Myw3IEBACiAgICAgdm9pZCBz bG90Q2xlYXIoKTsKICAgICB2b2lkIHBhdHRlcm5UZXh0Q2hhbmdlZCggY29uc3QgUVN0cmluZyAm KTsKICAgICB2b2lkIHNlYXJjaEZpbmlzaGVkICgpOwotICAgIHZvaWQgc2VhcmNoTWF0Y2hGb3Vu ZChjb25zdCBRU3RyaW5nICZmaWxlbmFtZSwgaW50IGxpbmUsIGludCBjb2x1bW4sIGNvbnN0IFFT dHJpbmcgJmJhc2VuYW1lLCBjb25zdCBRU3RyaW5nICZsaW5lQ29udGVudCwgUVdpZGdldCAqcGFy ZW50VGFiKTsKKyAgICB2b2lkIHNlYXJjaE1hdGNoRm91bmQoY29uc3QgUVN0cmluZyAmZmlsZW5h bWUsIGNvbnN0IFFTdHJpbmcgJnJlbG5hbWUsIGludCBsaW5lLCBpbnQgY29sdW1uLCBjb25zdCBR U3RyaW5nICZiYXNlbmFtZSwgY29uc3QgUVN0cmluZyAmbGluZUNvbnRlbnQsIFFXaWRnZXQgKnBh cmVudFRhYik7CiAgICAgdm9pZCBzeW5jRGlyKCk7CiAKICAgcHJpdmF0ZToKSW5kZXg6IHBsdWdp bnMvZmluZGluZmlsZXMva2F0ZWdyZXB0aHJlYWQuY3BwCj09PT09PT09PT09PT09PT09PT09PT09 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KLS0tIHBsdWdpbnMv ZmluZGluZmlsZXMva2F0ZWdyZXB0aHJlYWQuY3BwCShyZXZpc2lvbiA3OTU3OTApCisrKyBwbHVn aW5zL2ZpbmRpbmZpbGVzL2thdGVncmVwdGhyZWFkLmNwcAkod29ya2luZyBjb3B5KQpAQCAtMzYs NiArMzYsOCBAQAogICAgICwgbV9zZWFyY2hQYXR0ZXJuIChzZWFyY2hQYXR0ZXJuKQogewogICBt X3dvcmtRdWV1ZSA8PCBkaXI7CisgIFFEaXIgYmFzZURpcihkaXIpOworICBtX2RpciA9IGJhc2VE aXIuYWJzb2x1dGVQYXRoKCkgKyAnLyc7CiB9CiAKIEthdGVHcmVwVGhyZWFkOjp+S2F0ZUdyZXBU aHJlYWQgKCkKQEAgLTEwNyw3ICsxMDksMTEgQEAKICAgICAgIGlmIChmaXJzdENvbHVtbiAhPSAt MSkKICAgICAgIHsKICAgICAgICAga0RlYnVnICgpIDw8ICJmb3VuZCBtYXRjaDogIiA8PCBmaWxl TmFtZSA8PCAiIDogIiA8PCBsaW5lTnVtYmVyOwotICAgICAgICBlbWl0IGZvdW5kTWF0Y2ggKGZp bGVOYW1lLCBsaW5lTnVtYmVyLCBmaXJzdENvbHVtbiwgYmFzZU5hbWUsIGxpbmVzLmF0ICgwKSwg bV9wYXJlbnRUYWIpOworICAgICAgICBRU3RyaW5nIHJlbE5hbWUgPSBmaWxlTmFtZTsKKyAgICAg ICAgaWYgKHJlbE5hbWUuc3RhcnRzV2l0aChtX2RpcikpIHsKKyAgICAgICAgICByZWxOYW1lLnJl bW92ZSgwLCBtX2Rpci5zaXplKCkpOworICAgICAgICB9CisgICAgICAgIGVtaXQgZm91bmRNYXRj aCAoZmlsZU5hbWUsIHJlbE5hbWUsIGxpbmVOdW1iZXIsIGZpcnN0Q29sdW1uLCBiYXNlTmFtZSwg bGluZXMuYXQgKDApLCBtX3BhcmVudFRhYik7CiAgICAgICB9CiAKICAgICAgIC8vIHJlbW92ZSBm aXJzdCBsaW5lLi4uCg== ------=_Part_2267_10903732.1208293490984 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ KWrite-Devel mailing list KWrite-Devel@kde.org https://mail.kde.org/mailman/listinfo/kwrite-devel ------=_Part_2267_10903732.1208293490984--