[prev in list] [next in list] [prev in thread] [next in thread] 

List:       mapguide-commits
Subject:    [mapguide-commits] r8267 - in sandbox/jng/convenience_apis: Common/MapGuideCommon/MapLayer Server/sr
From:       svn_mapguide () osgeo ! org
Date:       2014-06-27 9:35:56
Message-ID: 20140627093556.74648390412 () trac ! osgeo ! org
[Download RAW message or body]

Author: jng
Date: 2014-06-27 02:35:56 -0700 (Fri, 27 Jun 2014)
New Revision: 8267

Modified:
   sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp
   sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h
   sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp
   sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h
Log:
For layers with multiple composite styles, the current set of APIs won't cut it, as \
theme category for composite styles needs to be offset by the number of rules in \
other styles before it in order for the right icon to be rendered.

This submission adds a GetCompositeThemeCategoryCount method to support this \
scenario. Also included is unit tests for exercising this particular case, and \
demonstrating how composite theme icons would be generated.

Modified: sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp
===================================================================
--- sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp	2014-06-26 \
                15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.cpp	2014-06-27 \
09:35:56 UTC (rev 8267) @@ -628,8 +628,7 @@
                             }
                             else if (cts != NULL)
                             {
-                                if (ret->IndexOf(4) < 0)
-                                    ret->Add(4);
+                                ret->Add(4);
                             }
                         }
                     }
@@ -700,6 +699,51 @@
     return ret;
 }
 
+INT32 MgLayer::GetCompositeThemeCategoryCount(INT32 compositeOffset)
+{
+    return GetCompositeThemeCategoryCount(GetMap()->GetViewScale(), \
compositeOffset); +}
+
+INT32 MgLayer::GetCompositeThemeCategoryCount(double scale, INT32 compositeOffset)
+{
+    INT32 ret = -1;
+
+    Ptr<MgResourceService> resSvc = \
dynamic_cast<MgResourceService*>(GetMap()->GetService(MgServiceType::ResourceService));
 +    std::auto_ptr<MdfModel::LayerDefinition> \
ldf(MgLayerBase::GetLayerDefinition(resSvc, m_definition)); +    if (ldf.get() != \
NULL) +    {
+        MdfModel::VectorLayerDefinition* vl = \
dynamic_cast<MdfModel::VectorLayerDefinition*>(ldf.get()); +        if(vl != NULL)
+        {
+            MdfModel::VectorScaleRangeCollection* scaleRanges = \
vl->GetScaleRanges(); +            if (scaleRanges != NULL)
+            {
+                for (INT32 i = 0; i < scaleRanges->GetCount(); i++)
+                {
+                    MdfModel::VectorScaleRange* vsr = scaleRanges->GetAt(i);
+                    if (scale >= vsr->GetMinScale() && scale < vsr->GetMaxScale())
+                    {
+                        MdfModel::FeatureTypeStyleCollection* ftsc = \
vsr->GetFeatureTypeStyles(); +                        //NOTE: If a Layer Definition \
has basic and composite types, then this offset will probably be wrong +              \
//but such layers are technically illegal and we shouldn't try to be catering to such \
layers +                        if (compositeOffset < ftsc->GetCount())
+                        {
+                            MdfModel::CompositeTypeStyle* cts = \
dynamic_cast<MdfModel::CompositeTypeStyle*>(ftsc->GetAt(compositeOffset)); +          \
if (cts != NULL) +                            {
+                                ret = cts->GetRules()->GetCount();
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    return ret;
+}
+
 MgByteReader* MgLayer::GenerateLegendImage(double scale, INT32 width, INT32 height, \
CREFSTRING format, INT32 geomType, INT32 themeCategory)  {
     Ptr<MgByteReader> ret;

Modified: sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h
===================================================================
--- sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h	2014-06-26 \
                15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Common/MapGuideCommon/MapLayer/Layer.h	2014-06-27 \
09:35:56 UTC (rev 8267) @@ -377,7 +377,8 @@
     /// \htmlinclude SyntaxBottom.html
     ///
     /// \remarks
-    /// The map's current scale is used to determine what scale range in the layer \
definition to search for +    /// The map's current scale is used to determine what \
scale range in the layer definition to search for. +    /// For a scale range with \
multiple composite styles, multiple instances of (4 = composite) will be in the \
resulting collection  ///
     /// \return
     /// The list of geometry type styles for this layer at the map's current scale. \
Returns NULL if there are no applicable geometry types @@ -404,7 +405,9 @@
     /// The geometry type
     ///
     /// \remarks
-    /// The map's current scale is used to determine what scale range in the layer \
definition to search for +    /// The map's current scale is used to determine what \
scale range in the layer definition to search for. +    /// When geomType = 4, it \
will only count the number of the theme categories for the first composite style it \
finds. For a scale range +    /// with multiple composite type styles, you should use \
GetCompositeThemeCategoryCount() instead  ///
     /// \return
     /// The number of theme categories for this layer at the map's current scale for \
the given geometry type style. A count greater than 1 indicates a themed layer. \
Returns -1 if there are no applicable styles at the current scale @@ -412,6 +415,30 \
@@  /// \since 3.0
     INT32 GetThemeCategoryCount(INT32 geomType);
 
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +    /// \brief
+    /// Gets the number of composite theme categories for this layer at the map's \
current scale for the given composite style. A count greater than 1 indicates a \
themed layer. Returns -1 if there are no applicable styles at the current scale +    \
/// +    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \param compositeOffset (int)
+    /// The zero-based index denoting the particular composite style to count from. \
0 = 1st composite style, 1 = 2nd composite style +    ///
+    /// \return
+    /// The number of theme categories for this layer at the map's current scale for \
the given composite style. A count greater than 1 indicates a themed layer. Returns \
-1 if there are no applicable styles at the current scale +    ///
+    /// \since 3.0
+    INT32 GetCompositeThemeCategoryCount(INT32 compositeOffset);
+
     ////////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the legend image for the specified geometry type and theme category
@@ -486,6 +513,9 @@
     /// \param scale (double)
     /// The scale at which to retrive the list of applicable geometry types
     ///
+    /// \remarks
+    /// For a scale range with multiple composite styles, multiple instances of (4 = \
composite) will be in the resulting collection +    ///
     /// \return
     /// The list of geometry type styles for this layer at the map's current scale. \
Returns NULL if there are no applicable geometry types  ///
@@ -512,12 +542,42 @@
     /// \param geomType (int)
     /// The geometry type
     ///
+    /// \remarks
+    /// When geomType = 4, it will only count the number of the theme categories for \
the first composite style it finds. For a scale range +    /// with multiple \
composite type styles, you should use GetCompositeThemeCategoryCount() instead +    \
///  /// \return
     /// The number of theme categories for this layer at the map's current scale for \
the given geometry type style. A count greater than 1 indicates a themed layer. \
Returns -1 if there are no applicable styles at the current scale  ///
     /// \since 3.0
     INT32 GetThemeCategoryCount(double scale, INT32 geomType);
 
+    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 +    /// \brief
+    /// Gets the number of composite theme categories for this layer at the map's \
current scale for the given composite style. A count greater than 1 indicates a \
themed layer. Returns -1 if there are no applicable styles at the current scale +    \
/// +    /// <!-- Syntax in .Net, Java, and PHP -->
+    /// \htmlinclude DotNetSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude JavaSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    /// \htmlinclude PHPSyntaxTop.html
+    /// virtual int GetThemeCategoryCount(double scale, int geomType);
+    /// \htmlinclude SyntaxBottom.html
+    ///
+    /// \param scale (double)
+    /// The scale at which to count the number of applicable theme categories
+    /// \param compositeOffset (int)
+    /// The zero-based index denoting the particular composite style to count from. \
0 = 1st composite style, 1 = 2nd composite style +    ///
+    /// \return
+    /// The number of theme categories for this layer at the map's current scale for \
the given composite style. A count greater than 1 indicates a themed layer. Returns \
-1 if there are no applicable styles at the current scale +    ///
+    /// \since 3.0
+    INT32 GetCompositeThemeCategoryCount(double scale, INT32 compositeOffset);
+
     ////////////////////////////////////////////////////////////////////////////////
     /// \brief
     /// Returns the legend image for the specified geometry type and theme category

Modified: sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp
===================================================================
--- sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp	2014-06-26 \
                15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.cpp	2014-06-27 \
09:35:56 UTC (rev 8267) @@ -128,6 +128,16 @@
         Ptr<MgByteReader> ldfrdr4 = ldfsrc4->GetReader();
         m_svcResource->SetResource(ldfres4, ldfrdr4, NULL);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition"); +       \
Ptr<MgByteSource> ldfsrc5 = new MgByteSource(L"../UnitTestFiles/UT_MultiCTS.ldf", \
false); +        Ptr<MgByteReader> ldfrdr5 = ldfsrc5->GetReader();
+        m_svcResource->SetResource(ldfres5, ldfrdr5, NULL);
+
+        Ptr<MgResourceIdentifier> ldfres6 = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
 +        Ptr<MgByteSource> ldfsrc6 = new \
MgByteSource(L"../UnitTestFiles/UT_MultiCTSWithTheme.ldf", false); +        \
Ptr<MgByteReader> ldfrdr6 = ldfsrc6->GetReader(); +        \
m_svcResource->SetResource(ldfres6, ldfrdr6, NULL); +
         //publish the feature sources
         Ptr<MgResourceIdentifier> fsres1 = new \
                MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource");
                
         Ptr<MgByteSource> fssrc1 = new \
MgByteSource(L"../UnitTestFiles/UT_HydrographicPolygons.fs", false); @@ -216,6 \
                +226,12 @@
         Ptr<MgResourceIdentifier> ldfres4 = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/RotatedPointStyles.LayerDefinition");
  m_svcResource->DeleteResource(ldfres4);
 
+        Ptr<MgResourceIdentifier> ldfres5 = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition"); +       \
m_svcResource->DeleteResource(ldfres5); +
+        Ptr<MgResourceIdentifier> ldfres6 = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
 +        m_svcResource->DeleteResource(ldfres6);
+
         //delete the feature sources
         Ptr<MgResourceIdentifier> fsres1 = new \
MgResourceIdentifier(L"Library://UnitTests/Data/HydrographicPolygons.FeatureSource"); \
m_svcResource->DeleteResource(fsres1); @@ -1082,6 +1098,181 @@
     }
 }
 
+void TestMappingService::TestCase_GetLegendImageCompositeConvenience()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> mapres = new \
MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition"); +        \
Ptr<MgMap> map = new MgMap(m_siteConnection); +        map->Create(mapres, \
L"TestCase_GetLegendImageCompositeConvenience"); +
+        Ptr<MgResourceIdentifier> ldf = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTS.LayerDefinition"); +       \
Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource); +        \
layer->SetName(L"TestCase_GetLegendImageCompositeConvenience"); +        \
Ptr<MgLayerCollection> layers = map->GetLayers(); +        layers->Insert(0, layer);
+
+        Ptr<MgIntCollection> types = layer->GetGeometryTypeStyles(10000.0);
+        CPPUNIT_ASSERT(3 == types->GetCount());
+        CPPUNIT_ASSERT(types->IndexOf(1) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(2) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(3) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(4) >= 0);
+        for (INT32 i = 0; i < types->GetCount(); i++)
+        {
+            CPPUNIT_ASSERT(4 == types->GetItem(i));
+        }
+
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 3));
+        CPPUNIT_ASSERT(1 == layer->GetThemeCategoryCount(10000.0, 4));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 0));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetCompositeThemeCategoryCount(10000.0, 3));
+
+        INT32 rulesProcessed = 0;
+        for (INT32 ctype = 0; ctype < 3; ctype++)
+        {
+            INT32 rules = layer->GetCompositeThemeCategoryCount(10000.0, ctype);
+            for (INT32 offset = rulesProcessed; offset < (rulesProcessed + rules); \
offset++) +            {
+                STRING prefix = \
L"../UnitTestFiles/GenerateLegendImageConvenience_MultiCTS_type"; +                \
STRING sNum; +                MgUtil::Int32ToString(ctype, sNum);
+                prefix += sNum;
+                prefix += L"_offset";
+                MgUtil::Int32ToString(offset, sNum);
+                prefix += sNum;
+
+                STRING fileNamePNG = prefix;
+                fileNamePNG += L"_16x16_PNG.png";
+                Ptr<MgByteReader> rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Png, 4, offset); +                Ptr<MgByteSink> sink = new \
MgByteSink(rdr); +                sink->ToFile(fileNamePNG);
+
+                STRING fileNamePNG8 = prefix;
+                fileNamePNG8 += L"_16x16_PNG8.png";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Png8, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG8);
+
+                STRING fileNameJPG = prefix;
+                fileNameJPG += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Jpeg, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameJPG);
+
+                STRING fileNameGIF = prefix;
+                fileNameGIF += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Gif, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameGIF);
+            }
+            rulesProcessed += rules;
+        }
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
+void TestMappingService::TestCase_GetLegendImageCompositeThemedConvenience()
+{
+    try
+    {
+        Ptr<MgResourceIdentifier> mapres = new \
MgResourceIdentifier(L"Library://UnitTests/Maps/Sheboygan.MapDefinition"); +        \
Ptr<MgMap> map = new MgMap(m_siteConnection); +        map->Create(mapres, \
L"TestCase_GetLegendImageCompositeThemedConvenience"); +
+        Ptr<MgResourceIdentifier> ldf = new \
MgResourceIdentifier(L"Library://UnitTests/Layers/MultiCTSWithTheme.LayerDefinition");
 +        Ptr<MgLayer> layer = new MgLayer(ldf, m_svcResource);
+        layer->SetName(L"TestCase_GetLegendImageCompositeThemedConvenience");
+        Ptr<MgLayerCollection> layers = map->GetLayers();
+        layers->Insert(0, layer);
+
+        Ptr<MgIntCollection> types = layer->GetGeometryTypeStyles(10000.0);
+        CPPUNIT_ASSERT(3 == types->GetCount());
+        CPPUNIT_ASSERT(types->IndexOf(1) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(2) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(3) < 0);
+        CPPUNIT_ASSERT(types->IndexOf(4) >= 0);
+        for (INT32 i = 0; i < types->GetCount(); i++)
+        {
+            CPPUNIT_ASSERT(4 == types->GetItem(i));
+        }
+
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetThemeCategoryCount(10000.0, 3));
+        CPPUNIT_ASSERT(1 == layer->GetThemeCategoryCount(10000.0, 4));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 0));
+        CPPUNIT_ASSERT(3 == layer->GetCompositeThemeCategoryCount(10000.0, 1));
+        CPPUNIT_ASSERT(1 == layer->GetCompositeThemeCategoryCount(10000.0, 2));
+        CPPUNIT_ASSERT(-1 == layer->GetCompositeThemeCategoryCount(10000.0, 3));
+
+        INT32 rulesProcessed = 0;
+        for (INT32 ctype = 0; ctype < 3; ctype++)
+        {
+            INT32 rules = layer->GetCompositeThemeCategoryCount(10000.0, ctype);
+            for (INT32 offset = rulesProcessed; offset < (rulesProcessed + rules); \
offset++) +            {
+                STRING prefix = \
L"../UnitTestFiles/GenerateLegendImageConvenience_MultiCTSWithTheme_type"; +          \
STRING sType; +                MgUtil::Int32ToString(ctype, sType);
+                prefix += sType;
+                prefix += L"_offset";
+                STRING sOffset;
+                MgUtil::Int32ToString(offset, sOffset);
+                prefix += sOffset;
+
+                STRING fileNamePNG = prefix;
+                fileNamePNG += L"_16x16_PNG.png";
+                Ptr<MgByteReader> rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Png, 4, offset); +                Ptr<MgByteSink> sink = new \
MgByteSink(rdr); +                sink->ToFile(fileNamePNG);
+
+                STRING fileNamePNG8 = prefix;
+                fileNamePNG8 += L"_16x16_PNG8.png";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Png8, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNamePNG8);
+
+                STRING fileNameJPG = prefix;
+                fileNameJPG += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Jpeg, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameJPG);
+
+                STRING fileNameGIF = prefix;
+                fileNameGIF += L"_16x16_JPG.jpg";
+                rdr = layer->GenerateLegendImage(10000.0, 16, 16, \
MgImageFormats::Gif, 4, offset); +                sink = new MgByteSink(rdr);
+                sink->ToFile(fileNameGIF);
+            }
+            rulesProcessed += rules;
+        }
+    }
+    catch (MgException* e)
+    {
+        STRING message = e->GetDetails(TEST_LOCALE);
+        SAFE_RELEASE(e);
+        CPPUNIT_FAIL(MG_WCHAR_TO_CHAR(message.c_str()));
+    }
+    catch (...)
+    {
+        throw;
+    }
+}
+
 void TestMappingService::TestCase_GetLegendImagePointStyleWithConstRotationsConvenience()
  {
     try

Modified: sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h
===================================================================
--- sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h	2014-06-26 \
                15:33:51 UTC (rev 8266)
+++ sandbox/jng/convenience_apis/Server/src/UnitTesting/TestMappingService.h	2014-06-27 \
09:35:56 UTC (rev 8267) @@ -37,6 +37,8 @@
     CPPUNIT_TEST(TestCase_GetLegendImage);
     CPPUNIT_TEST(TestCase_GetLegendImagePointStyleWithConstRotations);
     CPPUNIT_TEST(TestCase_GetLegendImageConvenience);
+    CPPUNIT_TEST(TestCase_GetLegendImageCompositeConvenience);
+    CPPUNIT_TEST(TestCase_GetLegendImageCompositeThemedConvenience);
     CPPUNIT_TEST(TestCase_GetLegendImagePointStyleWithConstRotationsConvenience);
     CPPUNIT_TEST(TestCase_CreateRuntimeMap);
     CPPUNIT_TEST(TestCase_DescribeRuntimeMap);
@@ -70,6 +72,8 @@
     void TestCase_GetLegendImage();
     void TestCase_GetLegendImagePointStyleWithConstRotations();
     void TestCase_GetLegendImageConvenience();
+    void TestCase_GetLegendImageCompositeConvenience();
+    void TestCase_GetLegendImageCompositeThemedConvenience();
     void TestCase_GetLegendImagePointStyleWithConstRotationsConvenience();
     void TestCase_QueryFeaturesImageMap();
 

_______________________________________________
mapguide-commits mailing list
mapguide-commits@lists.osgeo.org
http://lists.osgeo.org/mailman/listinfo/mapguide-commits


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic