[prev in list] [next in list] [prev in thread] [next in thread]
List: koffice-devel
Subject: Re: DataCenterMap
From: Thomas Zander <zander () kde ! org>
Date: 2010-01-20 8:52:32
Message-ID: 201001200952.33126.zander () kde ! org
[Download RAW message or body]
On Tuesday 19. January 2010 21.51.02 Thorsten Zachmann wrote:
> The enhanced path shapes (funny/arrow category in the add shape docker)
> now all result in an cross when added to the canvas. Looks like this is
> the problem:
Fixed, see attached commits.
>
> + KoStyleManager *styleManager = static_cast<KoStyleManager *>(kwDoc()-
>
> >resourceManager()->resource(KoText::StyleManager).value<void*>(
>
> What is the reason to use a static cast instead of a dynamic one?
I'm going to check if I can use qobject_cast, which makes more sense than
static indeed, but the reason is that dynamic cast doesn't work.
> + KoResourceManager *resourceprovider = canvas->resourceManager();
>
> How about renaming the variable also to say resourceManger and no longer
> resourceprovice?
I think the reason I missed that one is because I searched for
resourceProvider, and the camelCase is not used thee.
> I only had a look during the my trainride home. More to come when I find
> more time to look at it.
The main problems are solved with the attached commits. What about I push this
to svn and we fix issues as we find them.
The important part of agreeing on approach is ok, right?
--
Thomas Zander
["0001-Fix-mem-leak-delete-the-collection-using-the-QObject.patch" (text/x-patch)]
From 725abe499cded7b61a0df3439e487b30f5cde826 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 00:32:07 +0100
Subject: [PATCH 1/7] Fix mem leak; delete the collection using the QObject concept
---
libs/flake/KoImageCollection.cpp | 5 +++--
libs/flake/KoImageCollection.h | 6 ++++--
libs/flake/KoPathShapeFactory.cpp | 2 +-
plugins/pictureshape/PictureShapeFactory.cpp | 2 +-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/libs/flake/KoImageCollection.cpp b/libs/flake/KoImageCollection.cpp
index 24b7c16..288c34f 100644
--- a/libs/flake/KoImageCollection.cpp
+++ b/libs/flake/KoImageCollection.cpp
@@ -44,8 +44,9 @@ public:
QMap<QByteArray, KoImageDataPrivate*> storeImages;
};
-KoImageCollection::KoImageCollection()
- : d(new Private())
+KoImageCollection::KoImageCollection(QObject *parent)
+ : QObject(parent),
+ d(new Private())
{
}
diff --git a/libs/flake/KoImageCollection.h b/libs/flake/KoImageCollection.h
index 012e64b..e903627 100644
--- a/libs/flake/KoImageCollection.h
+++ b/libs/flake/KoImageCollection.h
@@ -21,6 +21,7 @@
#include "flake_export.h"
+#include <QObject>
#include <KoDataCenter.h>
class QImage;
@@ -32,11 +33,12 @@ class KoImageData;
* An collection of KoImageData objects to allow loading and saving them all \
together to the KoStore.
* It also makes sure that if the same image is added to the collection that they \
share the internal data structure.
*/
-class FLAKE_EXPORT KoImageCollection : public KoDataCenter
+class FLAKE_EXPORT KoImageCollection : public QObject, public KoDataCenter
{
+ Q_OBJECT
public:
/// constructor
- KoImageCollection();
+ KoImageCollection(QObject *parent = 0);
virtual ~KoImageCollection();
/// reimplemented
diff --git a/libs/flake/KoPathShapeFactory.cpp b/libs/flake/KoPathShapeFactory.cpp
index ceb1772..9d19e4a 100644
--- a/libs/flake/KoPathShapeFactory.cpp
+++ b/libs/flake/KoPathShapeFactory.cpp
@@ -70,7 +70,7 @@ void \
KoPathShapeFactory::newDocumentResourceManager(KoResourceManager *manager) // added \
to the data center map, in case the picture shape plugin // is not loaded
if (manager->imageCollection() == 0) {
- KoImageCollection *imgCol = new KoImageCollection();
+ KoImageCollection *imgCol = new KoImageCollection(manager);
manager->setImageCollection(imgCol);
}
}
diff --git a/plugins/pictureshape/PictureShapeFactory.cpp \
b/plugins/pictureshape/PictureShapeFactory.cpp index 2a9e238..84d4a53 100644
--- a/plugins/pictureshape/PictureShapeFactory.cpp
+++ b/plugins/pictureshape/PictureShapeFactory.cpp
@@ -65,5 +65,5 @@ QList<KoShapeConfigWidgetBase*> \
PictureShapeFactory::createShapeOptionPanels() void \
PictureShapeFactory::newDocumentResourceManager(KoResourceManager *manager) {
if (!manager->imageCollection())
- manager->setImageCollection(new KoImageCollection());
+ manager->setImageCollection(new KoImageCollection(manager));
}
--
1.6.3.3
["0003-Fix-bug-when-using-more-then-one-document-in-the-sam.patch" (text/x-patch)]
From 4ade19fa1d05bf2c3e78b7b83b1033f7446bc059 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 00:38:58 +0100
Subject: [PATCH 3/7] Fix bug when using more then one document in the same process
Always use the manager to get the data, storing it locally is
not safe.
---
plugins/textshape/TextShapeFactory.cpp | 13 ++++++++-----
plugins/textshape/TextShapeFactory.h | 3 ---
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/plugins/textshape/TextShapeFactory.cpp b/plugins/textshape/TextShapeFactory.cpp
index 10ef7bd..d23cf2f 100644
--- a/plugins/textshape/TextShapeFactory.cpp
+++ b/plugins/textshape/TextShapeFactory.cpp
@@ -36,8 +36,7 @@
#include <QTextCursor>
TextShapeFactory::TextShapeFactory(QObject *parent)
- : KoShapeFactory(parent, TextShape_SHAPEID, i18n("Text")),
- m_inlineTextObjectManager(0)
+ : KoShapeFactory(parent, TextShape_SHAPEID, i18n("Text"))
{
setToolTip(i18n("A shape that shows text"));
setOdfElementNames(KoXmlNS::draw, QStringList("text-box"));
@@ -55,7 +54,12 @@ TextShapeFactory::TextShapeFactory(QObject *parent)
KoShape *TextShapeFactory::createDefaultShape(KoResourceManager *documentResources) const
{
- TextShape *text = new TextShape(m_inlineTextObjectManager);
+ KoInlineTextObjectManager *manager = 0;
+ if (documentResources && documentResources->hasResource(KoText::InlineTextObjectManager)) {
+ QVariant variant = documentResources->resource(KoText::InlineTextObjectManager);
+ manager = static_cast<KoInlineTextObjectManager*>(variant.value<void*>());
+ }
+ TextShape *text = new TextShape(manager);
KoTextDocument document(text->textShapeData()->document());
if (documentResources) {
document.setUndoStack(documentResources->undoStack());
@@ -94,9 +98,8 @@ bool TextShapeFactory::supports(const KoXmlElement & e) const
void TextShapeFactory::newDocumentResourceManager(KoResourceManager *manager)
{
- m_inlineTextObjectManager = new KoInlineTextObjectManager(manager);
QVariant variant;
- variant.setValue<void*>(m_inlineTextObjectManager);
+ variant.setValue<void*>(new KoInlineTextObjectManager(manager));
manager->setResource(KoText::InlineTextObjectManager, variant);
if (!manager->hasResource(KoDocumentResource::UndoStackResource)) {
diff --git a/plugins/textshape/TextShapeFactory.h b/plugins/textshape/TextShapeFactory.h
index 8eedd4b..724cbc4 100644
--- a/plugins/textshape/TextShapeFactory.h
+++ b/plugins/textshape/TextShapeFactory.h
@@ -40,9 +40,6 @@ public:
virtual bool supports(const KoXmlElement & e) const;
virtual void newDocumentResourceManager(KoResourceManager *manager);
-
-private:
- KoInlineTextObjectManager *m_inlineTextObjectManager;
};
#endif
--
1.6.3.3
["0004-Don-t-leak-the-page-provider.patch" (text/x-patch)]
From 2b425a05205e45c74fd282c68ac0ce7726194cb7 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 09:29:12 +0100
Subject: [PATCH 4/7] Don't leak the page provider
---
libs/kopageapp/KoPADocument.cpp | 9 ++++++---
1 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/libs/kopageapp/KoPADocument.cpp b/libs/kopageapp/KoPADocument.cpp
index 30f7b08..038eb7f 100644
--- a/libs/kopageapp/KoPADocument.cpp
+++ b/libs/kopageapp/KoPADocument.cpp
@@ -65,6 +65,7 @@ public:
QList<KoPAPageBase*> masterPages;
KoInlineTextObjectManager *inlineTextObjectManager;
bool rulersVisible;
+ KoPAPageProvider *pageProvider;
};
KoPADocument::KoPADocument( QWidget* parentWidget, QObject* parent, bool singleViewMode )
@@ -75,7 +76,9 @@ KoPADocument::KoPADocument( QWidget* parentWidget, QObject* parent, bool singleV
resourceManager()->setUndoStack(undoStack());
QVariant variant;
- variant.setValue<void*>(new KoPAPageProvider());
+
+ d->pageProvider = new KoPAPageProvider();
+ variant.setValue<void*>(d->pageProvider);
resourceManager()->setResource(KoText::PageProvider, variant);
loadConfig();
}
@@ -85,6 +88,7 @@ KoPADocument::~KoPADocument()
saveConfig();
qDeleteAll( d->pages );
qDeleteAll( d->masterPages );
+ delete d->pageProvider;
delete d;
}
@@ -522,8 +526,7 @@ KoPageApp::PageType KoPADocument::pageType() const
QPixmap KoPADocument::pageThumbnail(KoPAPageBase* page, const QSize& size)
{
int pageNumber = pageIndex(page) + 1;
- QVariant var = resourceManager()->resource(KoText::PageProvider);
- static_cast<KoPAPageProvider*>(var.value<void*>())->setMasterPageNumber(pageNumber);
+ d->pageProvider->setMasterPageNumber(pageNumber);
return page->thumbnail(size);
}
--
1.6.3.3
["0006-Avoid-leaking-text-objects.patch" (text/x-patch)]
From 3f619f4f3d20dda81f91dfb1337b6e04a7d5b8c0 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 09:36:13 +0100
Subject: [PATCH 6/7] Avoid leaking text objects
---
plugins/textshape/TextShapeFactory.cpp | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/plugins/textshape/TextShapeFactory.cpp b/plugins/textshape/TextShapeFactory.cpp
index d23cf2f..a36dcd8 100644
--- a/plugins/textshape/TextShapeFactory.cpp
+++ b/plugins/textshape/TextShapeFactory.cpp
@@ -106,9 +106,9 @@ void TextShapeFactory::newDocumentResourceManager(KoResourceManager *manager)
kWarning(32500) << "No KUndoStack found in the document resource manager, creating a new one";
manager->setUndoStack(new KUndoStack(manager));
}
- variant.setValue<void*>(new KoChangeTracker());
+ variant.setValue<void*>(new KoChangeTracker(manager));
manager->setResource(KoText::ChangeTrackerResource, variant);
- variant.setValue<void*>(new KoStyleManager());
+ variant.setValue<void*>(new KoStyleManager(manager));
manager->setResource(KoText::StyleManager, variant);
}
--
1.6.3.3
["0002-More-cleanups-of-unused-dataCenters.patch" (text/x-patch)]
From aa1da9bf0cb56fd814127325b4e0ae699f787014 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 00:38:09 +0100
Subject: [PATCH 2/7] More cleanups of unused dataCenters
---
kword/part/KWDLoader.cpp | 5 +++--
kword/part/KWDocument.cpp | 1 -
kword/part/KWDocument.h | 7 -------
libs/flake/KoShape.cpp | 6 ------
libs/flake/KoShape.h | 7 -------
libs/flake/KoShapeLoadingContext.h | 3 +--
libs/flake/tests/MockShapes.h | 3 ---
.../enhancedpath/EnhancedPathShapeFactory.cpp | 2 +-
.../enhancedpath/EnhancedPathShapeFactory.h | 2 +-
9 files changed, 6 insertions(+), 30 deletions(-)
diff --git a/kword/part/KWDLoader.cpp b/kword/part/KWDLoader.cpp
index 4a5304e..becd5e1 100644
--- a/kword/part/KWDLoader.cpp
+++ b/kword/part/KWDLoader.cpp
@@ -576,7 +576,7 @@ void KWDLoader::fill(KWTextFrameSet *fs, const KoXmlElement \
&framesetElem) cursor.insertBlock(emptyTbf, emptyCf);
}
- KoStyleManager * styleManager = dynamic_cast<KoStyleManager \
*>(m_document->dataCenterMap()["StyleManager"]); + KoStyleManager \
*styleManager = static_cast<KoStyleManager \
*>(m_document->resourceManager()->resource(KoText::StyleManager).value<void*>()); \
Q_ASSERT(styleManager);
firstParag = false;
@@ -1114,7 +1114,8 @@ void KWDLoader::fill(ImageKey *key, const KoXmlElement \
&keyElement)
void KWDLoader::loadStyleTemplates(const KoXmlElement &stylesElem)
{
- KoStyleManager *styleManager = dynamic_cast<KoStyleManager \
*>(m_document->dataCenterMap()["StyleManager"]); + KoStyleManager *styleManager = \
static_cast<KoStyleManager \
*>(m_document->resourceManager()->resource(KoText::StyleManager).value<void*>()); +
Q_ASSERT(styleManager);
KoXmlElement style;
diff --git a/kword/part/KWDocument.cpp b/kword/part/KWDocument.cpp
index 6a4bf57..6b85d1a 100644
--- a/kword/part/KWDocument.cpp
+++ b/kword/part/KWDocument.cpp
@@ -160,7 +160,6 @@ KWDocument::~KWDocument()
delete m_magicCurtain;
saveConfig();
qDeleteAll(m_frameSets);
- qDeleteAll(m_dataCenterMap);
}
void KWDocument::addShape(KoShape *shape)
diff --git a/kword/part/KWDocument.h b/kword/part/KWDocument.h
index d02d950..876456f 100644
--- a/kword/part/KWDocument.h
+++ b/kword/part/KWDocument.h
@@ -97,11 +97,6 @@ public:
return &m_pageManager;
}
- /// @return the data center map for this document.
- QMap<QString, KoDataCenter *> dataCenterMap() const {
- return m_dataCenterMap;
- }
-
/**
* Insert a new page after another,
* creating followup frames (but not headers/footers),
@@ -228,8 +223,6 @@ private:
KWFrameLayout m_frameLayout;
KWApplicationConfig m_config;
- QMap<QString, KoDataCenter *> m_dataCenterMap;
-
MagicCurtain *m_magicCurtain; ///< all things we don't want to show are behind \
this one bool m_mainFramesetEverFinished;
};
diff --git a/libs/flake/KoShape.cpp b/libs/flake/KoShape.cpp
index 654afb4..1ef1aec 100644
--- a/libs/flake/KoShape.cpp
+++ b/libs/flake/KoShape.cpp
@@ -1329,12 +1329,6 @@ void KoShape::saveOdfCommonChildElements(KoShapeSavingContext \
&context) const
// end loading & saving methods
-void KoShape::init(const QMap<QString, KoDataCenter *> & dataCenterMap)
-{
- Q_UNUSED(dataCenterMap);
-}
-
-
// static
void KoShape::applyConversion(QPainter &painter, const KoViewConverter &converter)
{
diff --git a/libs/flake/KoShape.h b/libs/flake/KoShape.h
index c73133f..02d3dc1 100644
--- a/libs/flake/KoShape.h
+++ b/libs/flake/KoShape.h
@@ -200,13 +200,6 @@ public:
void saveOdfCommonChildElements(KoShapeSavingContext &context) const;
/**
- * After the shape has been created this method is called so it can get access \
to any DataCenter it
- * might want.
- * The default implementation does nothing.
- */
- virtual void init(const QMap<QString, KoDataCenter*> &dataCenterMap);
-
- /**
* @brief Scale the shape using the zero-point which is the top-left corner.
* @see position()
*
diff --git a/libs/flake/KoShapeLoadingContext.h b/libs/flake/KoShapeLoadingContext.h
index 91323c1..875fd4c 100644
--- a/libs/flake/KoShapeLoadingContext.h
+++ b/libs/flake/KoShapeLoadingContext.h
@@ -70,8 +70,7 @@ public:
/**
* constructor
* @param context the context created for generic ODF loading.
- * @param dataCenterMap the data center map of the shape controller. This is \
used in calling KoShape::init
- * during loading.
+ * @param documentResources the data of the shape controller.
*/
KoShapeLoadingContext(KoOdfLoadingContext &context, KoResourceManager \
*documentResources);
diff --git a/libs/flake/tests/MockShapes.h b/libs/flake/tests/MockShapes.h
index 4ac4f96..5cb5ac5 100644
--- a/libs/flake/tests/MockShapes.h
+++ b/libs/flake/tests/MockShapes.h
@@ -101,9 +101,6 @@ public:
bool contains(KoShape* shape) {
return m_shapes.contains(shape);
}
- QMap<QString, KoDataCenter *> dataCenterMap() const {
- return QMap<QString, KoDataCenter *>();
- }
private:
QSet<KoShape * > m_shapes;
};
diff --git a/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.cpp \
b/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.cpp index d6c3d9c..e0a0f50 \
100644
--- a/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.cpp
+++ b/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.cpp
@@ -75,7 +75,7 @@ KoShape \
*EnhancedPathShapeFactory::createDefaultShape(KoResourceManager *) const return \
shape; }
-KoShape *EnhancedPathShapeFactory::createShape(const KoProperties *params, const \
QMap<QString, KoDataCenter *> &, KoResourceManager *) const +KoShape \
*EnhancedPathShapeFactory::createShape(const KoProperties *params, KoResourceManager \
*) const {
QRectF viewBox(0, 0, 100, 100);
QVariant viewboxData;
diff --git a/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.h \
b/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.h index 9a7e4be..d1e3d4e \
100644
--- a/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.h
+++ b/plugins/pathshapes/enhancedpath/EnhancedPathShapeFactory.h
@@ -33,7 +33,7 @@ public:
/// constructor
explicit EnhancedPathShapeFactory(QObject *parent);
~EnhancedPathShapeFactory() {}
- virtual KoShape *createShape(const KoProperties *params, const QMap<QString, \
KoDataCenter *> &dataCenterMap, KoResourceManager *documentResources = 0) const; + \
virtual KoShape *createShape(const KoProperties *params, KoResourceManager \
*documentResources = 0) const;
virtual KoShape *createDefaultShape(KoResourceManager *documentResources = 0) \
const; virtual bool supports(const KoXmlElement &e) const;
private:
--
1.6.3.3
["0005-Avoid-leaking-memory-on-document-delete.patch" (text/x-patch)]
From 6c8dc7801033f6a1ca3b39ba239b7af7558669e3 Mon Sep 17 00:00:00 2001
From: Thomas Zander <zander@kde.org>
Date: Tue, 19 Jan 2010 09:33:02 +0100
Subject: [PATCH 5/7] Avoid leaking memory on document delete
---
kpresenter/part/KPrDocument.cpp | 4 ++--
kpresenter/part/KPrSoundCollection.cpp | 5 +++--
kpresenter/part/KPrSoundCollection.h | 5 +++--
kpresenter/part/pagelayout/KPrPageLayouts.cpp | 3 ++-
kpresenter/part/pagelayout/KPrPageLayouts.h | 5 +++--
5 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/kpresenter/part/KPrDocument.cpp b/kpresenter/part/KPrDocument.cpp
index a99b543..5bddd8a 100644
--- a/kpresenter/part/KPrDocument.cpp
+++ b/kpresenter/part/KPrDocument.cpp
@@ -83,10 +83,10 @@ KPrDocument::KPrDocument( QWidget* parentWidget, QObject* parent, \
bool singleVie
"presentation:class" ) );
QVariant variant;
- variant.setValue<void*>(new KPrSoundCollection());
+ variant.setValue<void*>(new KPrSoundCollection(this));
resourceManager()->setResource(KPresenter::SoundCollection, variant);
- variant.setValue<void*>(new KPrPageLayouts());
+ variant.setValue<void*>(new KPrPageLayouts(this));
resourceManager()->setResource(KPresenter::PageLayouts, variant);
loadKPrConfig();
diff --git a/kpresenter/part/KPrSoundCollection.cpp \
b/kpresenter/part/KPrSoundCollection.cpp index bf88afb..8319e3d 100644
--- a/kpresenter/part/KPrSoundCollection.cpp
+++ b/kpresenter/part/KPrSoundCollection.cpp
@@ -31,8 +31,9 @@ public:
QList<KPrSoundData*> sounds;
};
-KPrSoundCollection::KPrSoundCollection()
- : d(new Private())
+KPrSoundCollection::KPrSoundCollection(QObject *parent)
+ : QObject(parent),
+ d(new Private())
{
}
diff --git a/kpresenter/part/KPrSoundCollection.h \
b/kpresenter/part/KPrSoundCollection.h index 74eff45..a23b63c 100644
--- a/kpresenter/part/KPrSoundCollection.h
+++ b/kpresenter/part/KPrSoundCollection.h
@@ -21,6 +21,7 @@
#include <KoDataCenter.h>
#include <QStringList>
+#include <QObject>
#include "kpresenter_export.h"
@@ -30,10 +31,10 @@ class KoStore;
/**
* An collection of KPrSoundData objects to allow loading and saving them all \
together to the KoStore.
*/
-class KPRESENTER_EXPORT KPrSoundCollection : public KoDataCenter {
+class KPRESENTER_EXPORT KPrSoundCollection : public QObject, KoDataCenter {
public:
/// constructor
- KPrSoundCollection();
+ KPrSoundCollection(QObject *parent = 0);
~KPrSoundCollection();
/**
diff --git a/kpresenter/part/pagelayout/KPrPageLayouts.cpp \
b/kpresenter/part/pagelayout/KPrPageLayouts.cpp index 49ff114..0d23768 100644
--- a/kpresenter/part/pagelayout/KPrPageLayouts.cpp
+++ b/kpresenter/part/pagelayout/KPrPageLayouts.cpp
@@ -44,7 +44,8 @@ public:
KPrPageLayout * layout;
};
-KPrPageLayouts::KPrPageLayouts()
+KPrPageLayouts::KPrPageLayouts(QObject *parent)
+ : QObject(parent)
{
}
diff --git a/kpresenter/part/pagelayout/KPrPageLayouts.h \
b/kpresenter/part/pagelayout/KPrPageLayouts.h index aa55d87..7eed228 100644
--- a/kpresenter/part/pagelayout/KPrPageLayouts.h
+++ b/kpresenter/part/pagelayout/KPrPageLayouts.h
@@ -22,6 +22,7 @@
#include <QMap>
#include <QString>
+#include <QObject>
class QRectF;
class KPrPageLayout;
@@ -29,10 +30,10 @@ class KPrPageLayoutWrapper;
class KoPALoadingContext;
class KoPASavingContext;
-class KPrPageLayouts
+class KPrPageLayouts : public QObject
{
public:
- KPrPageLayouts();
+ KPrPageLayouts(QObject *parent = 0);
~KPrPageLayouts();
bool saveOdf( KoPASavingContext & context );
--
1.6.3.3
_______________________________________________
koffice-devel mailing list
koffice-devel@kde.org
https://mail.kde.org/mailman/listinfo/koffice-devel
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic