# # # add_dir "libs/qanava/build/vc8" # # add_file "libs/qanava/build/qan/qanava.vcproj" # content [a7e32ae7e57a483615fdec42ad34bbc8106df423] # # add_file "libs/qanava/build/qanava.sln" # content [90aedd92cd5905b131f978b4d4ca5821a0f405f3] # # add_file "libs/qanava/build/vc8/qanava.sln" # content [90aedd92cd5905b131f978b4d4ca5821a0f405f3] # # add_file "libs/qanava/src/qanEdgeItem.cpp" # content [0caac7b7d4027c08862fd8a40053f4b418e27ee1] # # add_file "libs/qanava/src/qanEdgeItem.h" # content [a6faccbca3c47dc3167a9941bac2b260b62efa6b] # # add_file "libs/qanava/src/qanNodeItem.cpp" # content [004012aa32e2d2b99e8ffbc8c726796732e8be3e] # # add_file "libs/qanava/src/qanNodeItem.h" # content [a1e0b3eb14d69a41be0b3fb7df0bba3707a54f39] # # add_file "libs/qanava/src/qanSimpleLayout.cpp" # content [eafcb23254d70a6cdeb04ff096f5d0091866b07c] # # add_file "libs/qanava/src/qanSimpleLayout.h" # content [ccfd04f8476073033255406182385f6e391e7a80] # # add_file "libs/qanava/src/qanTreeLayout.cpp" # content [836a7b1ecc11de2d242d63a45c72cc9e437b456e] # # add_file "libs/qanava/src/qanTreeLayout.h" # content [f6e7e5e89f64711c30443ed60bdc794902f79aa3] # # patch "guitone/res/i18n/guitone_de.ts" # from [e97280e3c67f5b0693547d7d9eae8fc7b1022343] # to [eea6b551bbd68e41ad3bc1e2f02cd1e9f3a0e7d9] # # patch "guitone/src/view/dialogs/AncestryGraph.cpp" # from [2d96f818ed011d6ff7002182a63d54ece76b96eb] # to [9694391673a672540dfd7af1a173f9149d98eef6] # # patch "guitone/src/view/dialogs/AncestryGraph.h" # from [8b3764f98c90d5c7fab0d8c529e97b92b92e4fc6] # to [9c16c34d9eb82a6c4c7cd99c9f03446cf363a621] # # patch "libs/qanava/build/qan/qan.pro" # from [d5ef733dbb9849633e57e042ad112df5df9185c9] # to [c4e3c2e0bba796aae727c6f7cf3a7aaab6923d85] # # patch "libs/qanava/src/qanGraphItemView.cpp" # from [2650092cb13e790fe4e6e81a7476978b0fa8a2b6] # to [5b4cb3773030bf708e1deb4374b4f42e87b91044] # # patch "libs/qanava/src/qanGraphItemView.h" # from [4ff6a1e3a993c364ed5dfb4eaee72c8919814ad0] # to [99f9cda323fa15286177a3277578dce9f90e5e55] # # patch "libs/qanava/src/qanGraphicsView.cpp" # from [97aaefe368fdc15c63d293e9d40ef1630414fbea] # to [7e38735bec8ddf769e356b9c27d037806f57050f] # # patch "libs/qanava/src/qanGridItem.cpp" # from [a521aaca80231c4a3cc1cad98105e155687d6ec2] # to [861ccf7f2cdf191bf535eb40e9cabb49613869a3] # # patch "libs/qanava/src/qanGridItem.h" # from [14da4617240de3277b84e376e7652288b1e6ab07] # to [79b8cd3d9adb20718b0dc0d862849c2c42980b22] # # patch "libs/qanava/src/qanLayout.cpp" # from [511aa22d12419f13286818772fc60ed1968f49a9] # to [bc1ecd1af36c3a75f6efc1306b3d52da7a862f12] # # patch "libs/qanava/src/qanLayout.h" # from [2f96b5189a86b669e54c072e9c621074ef76654f] # to [85537ab50a01625b3b95ed98b3ab237125466e74] # # patch "libs/qanava/src/qanNode.h" # from [5db78823a601423d53024a55532763ee5babcecd] # to [48c13d1b0cbbf8703568114725bc0d5a5ed83da3] # ============================================================ --- libs/qanava/build/qan/qanava.vcproj a7e32ae7e57a483615fdec42ad34bbc8106df423 +++ libs/qanava/build/qan/qanava.vcproj a7e32ae7e57a483615fdec42ad34bbc8106df423 @@ -0,0 +1,810 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ============================================================ --- libs/qanava/build/qanava.sln 90aedd92cd5905b131f978b4d4ca5821a0f405f3 +++ libs/qanava/build/qanava.sln 90aedd92cd5905b131f978b4d4ca5821a0f405f3 @@ -0,0 +1,144 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_qtmodel", "..\..\tests\qtmodel\test_qtmodel.vcproj", "{D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_basic", "..\..\tests\basic\test_basic.vcproj", "{0B9FE8EB-0588-3B7F-81C8-451D88AA7763}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_logo", "..\..\tests\logo\test_logo.vcproj", "{BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_layout", "..\..\tests\layout\test_layout.vcproj", "{5B612C24-0FC9-3959-B0B9-2582E50B5004}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_simpleqtmodel", "..\..\tests\simpleqtmodel\test_simpleqtmodel.vcproj", "{27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_styles", "..\..\tests\styles\test_styles.vcproj", "{5946E743-5ECA-301C-B7E8-8F3492138804}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_terror", "..\..\tests\terror\test_terror.vcproj", "{71DBBA2A-10D1-3DA3-888E-BB4B134939FA}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_customnodes", "..\..\tests\customnodes\test_customnodes.vcproj", "{A53A62E0-F302-3AC8-95D7-EB695FF71D49}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_large", "..\..\tests\large\test_large.vcproj", "{061024EB-0D88-339D-BCF9-93A7C6DD4CD7}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qanava", "..\qan\qanava.vcproj", "{D98C1DD4-008F-34B2-A980-0998ECF8427E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_trees", "..\..\tests\trees\test_trees.vcproj", "{AB2726B5-A220-4FB9-8951-B87A9F5FBC00}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Debug|Win32.Build.0 = Debug|Win32 + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Release|Win32.ActiveCfg = Release|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Debug|Win32.ActiveCfg = Debug|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Debug|Win32.Build.0 = Debug|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Release|Win32.ActiveCfg = Release|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Release|Win32.Build.0 = Release|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Debug|Win32.ActiveCfg = Debug|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Debug|Win32.Build.0 = Debug|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Release|Win32.ActiveCfg = Release|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Debug|Win32.Build.0 = Debug|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Release|Win32.ActiveCfg = Release|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Debug|Win32.ActiveCfg = Debug|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Debug|Win32.Build.0 = Debug|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Release|Win32.ActiveCfg = Release|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Release|Win32.Build.0 = Release|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Debug|Win32.ActiveCfg = Debug|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Debug|Win32.Build.0 = Debug|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Release|Win32.ActiveCfg = Release|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Release|Win32.Build.0 = Release|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Debug|Win32.ActiveCfg = Debug|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Debug|Win32.Build.0 = Debug|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Release|Win32.ActiveCfg = Release|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Release|Win32.Build.0 = Release|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Debug|Win32.ActiveCfg = Debug|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Debug|Win32.Build.0 = Debug|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Release|Win32.ActiveCfg = Release|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Release|Win32.Build.0 = Release|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Debug|Win32.Build.0 = Debug|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Release|Win32.ActiveCfg = Release|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Release|Win32.Build.0 = Release|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Debug|Win32.ActiveCfg = Debug|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Debug|Win32.Build.0 = Debug|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Release|Win32.ActiveCfg = Release|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Release|Win32.Build.0 = Release|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Debug|Win32.ActiveCfg = Debug|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Debug|Win32.Build.0 = Debug|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Release|Win32.ActiveCfg = Release|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal ============================================================ --- libs/qanava/build/vc8/qanava.sln 90aedd92cd5905b131f978b4d4ca5821a0f405f3 +++ libs/qanava/build/vc8/qanava.sln 90aedd92cd5905b131f978b4d4ca5821a0f405f3 @@ -0,0 +1,144 @@ +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_qtmodel", "..\..\tests\qtmodel\test_qtmodel.vcproj", "{D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_basic", "..\..\tests\basic\test_basic.vcproj", "{0B9FE8EB-0588-3B7F-81C8-451D88AA7763}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_logo", "..\..\tests\logo\test_logo.vcproj", "{BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_layout", "..\..\tests\layout\test_layout.vcproj", "{5B612C24-0FC9-3959-B0B9-2582E50B5004}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_simpleqtmodel", "..\..\tests\simpleqtmodel\test_simpleqtmodel.vcproj", "{27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_styles", "..\..\tests\styles\test_styles.vcproj", "{5946E743-5ECA-301C-B7E8-8F3492138804}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_terror", "..\..\tests\terror\test_terror.vcproj", "{71DBBA2A-10D1-3DA3-888E-BB4B134939FA}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_customnodes", "..\..\tests\customnodes\test_customnodes.vcproj", "{A53A62E0-F302-3AC8-95D7-EB695FF71D49}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_large", "..\..\tests\large\test_large.vcproj", "{061024EB-0D88-339D-BCF9-93A7C6DD4CD7}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "qanava", "..\qan\qanava.vcproj", "{D98C1DD4-008F-34B2-A980-0998ECF8427E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_trees", "..\..\tests\trees\test_trees.vcproj", "{AB2726B5-A220-4FB9-8951-B87A9F5FBC00}" + ProjectSection(ProjectDependencies) = postProject + {D98C1DD4-008F-34B2-A980-0998ECF8427E} = {D98C1DD4-008F-34B2-A980-0998ECF8427E} + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Debug|Win32.ActiveCfg = Debug|Win32 + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Debug|Win32.Build.0 = Debug|Win32 + {D769CC4A-F8B5-3D36-8D2B-A0B7E221D5F6}.Release|Win32.ActiveCfg = Release|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Debug|Win32.ActiveCfg = Debug|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Debug|Win32.Build.0 = Debug|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Release|Win32.ActiveCfg = Release|Win32 + {0B9FE8EB-0588-3B7F-81C8-451D88AA7763}.Release|Win32.Build.0 = Release|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Debug|Win32.ActiveCfg = Debug|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Debug|Win32.Build.0 = Debug|Win32 + {BBCDCF1F-2033-3350-9B07-FFF3D852B3E3}.Release|Win32.ActiveCfg = Release|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Debug|Win32.ActiveCfg = Debug|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Debug|Win32.Build.0 = Debug|Win32 + {5B612C24-0FC9-3959-B0B9-2582E50B5004}.Release|Win32.ActiveCfg = Release|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Debug|Win32.ActiveCfg = Debug|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Debug|Win32.Build.0 = Debug|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Release|Win32.ActiveCfg = Release|Win32 + {27409704-FB8E-39EF-AB9B-57B2A2E8FC7C}.Release|Win32.Build.0 = Release|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Debug|Win32.ActiveCfg = Debug|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Debug|Win32.Build.0 = Debug|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Release|Win32.ActiveCfg = Release|Win32 + {5946E743-5ECA-301C-B7E8-8F3492138804}.Release|Win32.Build.0 = Release|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Debug|Win32.ActiveCfg = Debug|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Debug|Win32.Build.0 = Debug|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Release|Win32.ActiveCfg = Release|Win32 + {71DBBA2A-10D1-3DA3-888E-BB4B134939FA}.Release|Win32.Build.0 = Release|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Debug|Win32.ActiveCfg = Debug|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Debug|Win32.Build.0 = Debug|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Release|Win32.ActiveCfg = Release|Win32 + {A53A62E0-F302-3AC8-95D7-EB695FF71D49}.Release|Win32.Build.0 = Release|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Debug|Win32.ActiveCfg = Debug|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Debug|Win32.Build.0 = Debug|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Release|Win32.ActiveCfg = Release|Win32 + {061024EB-0D88-339D-BCF9-93A7C6DD4CD7}.Release|Win32.Build.0 = Release|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Debug|Win32.ActiveCfg = Debug|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Debug|Win32.Build.0 = Debug|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Release|Win32.ActiveCfg = Release|Win32 + {D98C1DD4-008F-34B2-A980-0998ECF8427E}.Release|Win32.Build.0 = Release|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Debug|Win32.ActiveCfg = Debug|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Debug|Win32.Build.0 = Debug|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Release|Win32.ActiveCfg = Release|Win32 + {AB2726B5-A220-4FB9-8951-B87A9F5FBC00}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal ============================================================ --- libs/qanava/src/qanEdgeItem.cpp 0caac7b7d4027c08862fd8a40053f4b418e27ee1 +++ libs/qanava/src/qanEdgeItem.cpp 0caac7b7d4027c08862fd8a40053f4b418e27ee1 @@ -0,0 +1,180 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanEdgeItem.cpp +// \author Benoit Autheman (address@hidden) +// \date 2007 February 08 +//----------------------------------------------------------------------------- + + +// Qanava headers +#include "./qanNodeItem.h" +#include "./qanEdgeItem.h" + + +// QT headers +#include +#include + + +namespace qan { // ::qan + + +/* Arrow Constructor/Destructor *///------------------------------------------- +EdgeItem::EdgeItem( QGraphicsItem* parent, QGraphicsScene* scene, NodeItem* src, NodeItem* dst ) : + QGraphicsItem( parent, scene ), + _src( src ), + _dst( dst ), + _hasArrow( true ) +{ + setZValue( 1. ); + + if ( src != 0 && dst != 0 ) + { + src->addEdge( this ); + dst->addEdge( this ); + updateEdge( ); + } + + setVisible( true ); +} + +EdgeItem::~EdgeItem( ) +{ + // FIXME: segfault with node dtor + /*if ( _src != 0 ) + _src->removeEdge( this ); + if ( _dst != 0 ) + _dst->removeEdge( this );*/ +} + +QRectF EdgeItem::boundingRect( ) const +{ + if ( _src == 0 || _dst == 0 ) + return QRectF( ); + + QPointF src = _src->mapToScene( _src->boundingRect( ).center( ) ); + QPointF dst = _dst->mapToScene( _dst->boundingRect( ).center( ) ); + + QPointF topLeft( qMin( src.x( ), dst.x( ) ), // tl=(minx, miny) + qMin( src.y( ), dst.y( ) ) ); + QPointF bottomRight( qMax( src.x( ), dst.x( ) ), // br=(maxx, maxy) + qMax( src.y( ), dst.y( ) ) ); + + return QRectF( 0., 0., qAbs( bottomRight.x( ) - topLeft.x( ) ), qAbs( bottomRight.y( ) - topLeft.y( ) ) ); +} + +void EdgeItem::updateEdge( ) +{ + if ( _src == 0 || _dst == 0 ) + return; + + QPointF srcF = _src->mapToScene( _src->boundingRect( ).center( ) ); + QPointF dstF = _dst->mapToScene( _dst->boundingRect( ).center( ) ); + QPointF topLeft( qMin( srcF.x( ), dstF.x( ) ), // tl=(minx, miny) + qMin( srcF.y( ), dstF.y( ) ) ); + + setPos( topLeft ); // setPos should have been called update on the old garbage area ? + + QGraphicsItem::update( ); +} + +void EdgeItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) +{ + if ( _src == 0 || _dst == 0 ) + return; + + QPointF srcF = _src->mapToScene( _src->boundingRect( ).center( ) ); + QPointF dstF = _dst->mapToScene( _dst->boundingRect( ).center( ) ); + QLineF line( mapFromScene( srcF ), mapFromScene( dstF ) ); + + if ( /*option->levelOfDetail > 0.25 && */ + _hasArrow ) + { + const double Pi = 3.141592653; + double TwoPi = 2.0 * Pi; + double angle = ::acos(line.dx() / line.length()); + if (line.dy() >= 0) + angle = TwoPi - angle; + + // Get the intersection between arrow and dst node + QRectF br = mapFromItem( _dst, _dst->boundingRect( ) ).boundingRect( ); + + // Test intersection with all borders + QLineF top( br.topLeft( ), br.topRight( ) ); + QLineF right( br.topRight( ), br.bottomRight( ) ); + QLineF bottom( br.bottomLeft( ), br.bottomRight( ) ); + QLineF left( br.topLeft( ), br.bottomLeft( ) ); + + QPointF i; + if ( line.intersect( top, &i ) == QLineF::BoundedIntersection || + line.intersect( right, &i ) == QLineF::BoundedIntersection || + line.intersect( bottom, &i ) == QLineF::BoundedIntersection || + line.intersect( left, &i ) == QLineF::BoundedIntersection ) + { + QLineF shortLine( mapFromScene( srcF ), i ); + painter->setPen( QPen( Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) ); + painter->drawLine( shortLine ); + + painter->setRenderHint( QPainter::Antialiasing ); + painter->setPen( QPen( Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) ); + painter->setBrush( QBrush( QColor( 0, 0, 0 ) ) ); + + double angle = ::acos( line.dx( ) / line.length( ) ); + if ( line.dy( ) <= 0 ) + angle = TwoPi - angle; + painter->save( ); + painter->translate( i ); + painter->rotate( angle * 180. / Pi ); + + double arrowSize = 4.; + double arrowLength = 8.; + i = QPointF( -arrowLength - 1., 0. ); + QPolygonF poly; + poly << QPointF( i.x( ), i.y( ) - arrowSize ) + << QPointF( i.x( ) + arrowLength, i.y( ) ) + << QPointF( i.x( ), i.y( ) + arrowSize ) << QPointF( i.x( ), i.y( ) - arrowSize ); + painter->drawPolygon( poly ); + painter->restore( ); + } + } + else + { + painter->setPen( QPen( Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin ) ); + painter->drawLine( line ); + } +} + +void EdgeItem::disconnectEdge( ) +{ + _src = 0; + _dst = 0; +} + +void EdgeItem::nodeDestroyed( ) +{ + disconnectEdge( ); +} +//----------------------------------------------------------------------------- + +} // ::qan + ============================================================ --- libs/qanava/src/qanEdgeItem.h a6faccbca3c47dc3167a9941bac2b260b62efa6b +++ libs/qanava/src/qanEdgeItem.h a6faccbca3c47dc3167a9941bac2b260b62efa6b @@ -0,0 +1,91 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanEdgeItem.h +// \author Benoit Autheman (address@hidden) +// \date 2007 February 08 +//----------------------------------------------------------------------------- + + +#ifndef qanEdgeItem_h +#define qanEdgeItem_h + + +// Qanava headers +#include "./qanNode.h" +#include "./qanStyle.h" + + +// QT headers +#include + + +//----------------------------------------------------------------------------- +namespace qan { // ::qan + + class NodeItem; + + class EdgeItem : public QObject, public QGraphicsItem + { + Q_OBJECT + + public: + + EdgeItem( QGraphicsItem* parent, QGraphicsScene* scene, + NodeItem* src, NodeItem* dst ); + + virtual ~EdgeItem( ); + + QRectF boundingRect( ) const; + + void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0 ); + + virtual void updateEdge( ); + + void disconnectEdge( ); + + NodeItem* getSrc( ) { return _src; } + + NodeItem* getDst( ) { return _dst; } + + public slots: + + void nodeDestroyed( ); + + private: + + NodeItem* _src; + + NodeItem* _dst; + + QPointF _sourcePoint; + + QPointF _destinationPoint; + + bool _hasArrow; + }; +} // ::qan +//----------------------------------------------------------------------------- + + +#endif // qanEdgeItem_h + ============================================================ --- libs/qanava/src/qanNodeItem.cpp 004012aa32e2d2b99e8ffbc8c726796732e8be3e +++ libs/qanava/src/qanNodeItem.cpp 004012aa32e2d2b99e8ffbc8c726796732e8be3e @@ -0,0 +1,283 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanNodeItem.cpp +// \author Benoit Autheman (address@hidden) +// \date 2004 October 13 +//----------------------------------------------------------------------------- + + +// Qanava headers +#include "./qanNodeItem.h" + + +// QT headers +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace qan { // ::qan + + +/* Node Constructor/Destructor *///-------------------------------------------- +/*! + The following style options are supported: +
    +
  • 'backcolor': Background color, when there is no background image defined. +
  • 'bordercolor': Color of the item border. +
  • 'backimage': Background image (scaled to fit the item size). +
  • 'maximumwidth': Maximum width of the item, content is cropped to fit this with limit. +
  • 'maximumheight': Maximum height of the item, content is cropped to fit this height limit. +
  • 'fontsize': Base size for the font used to display the item label. +
  • 'icon': Display an icon centered in the left of the item. +
  • 'hasshadow': Set this value to false to supress the node shadow. +
+ + An item with an empty style is transparent with no background nor border. + + \param origin Uper left corner of the rectangular item. + \param label Text label to be displayed in the node text area (can be multi line HTML tagged text). + \param style Advanced style to pass optionnal display parameters. + */ +NodeItem::NodeItem( Node& node, Style::Manager& styleManager, Style& style, + QGraphicsItem* parent, QGraphicsScene* scene, + QPointF origin, const QString& label ) : + AbstractNodeItem( node, styleManager, &style ), + QGraphicsRectItem( parent, scene ), + _dimension( 170.0, 45.0 ), + _label( label ), + _shadowColor( ), + _shadowOffset( 1.0 ), + _labelItem( 0 ) +{ + setRect( origin.x( ), origin.y( ), _dimension.x( ), _dimension.y( ) ); + setFlag( QGraphicsItem::ItemIsMovable ); + setZValue( 2.0 ); + + updateNode( ); +} + +NodeItem::~NodeItem( ) +{ + foreach ( EdgeItem* edge, _edges ) + edge->disconnectEdge( ); +} + +void NodeItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget ) +{ + { + QBrush b; + b.setStyle( Qt::SolidPattern ); + b.setColor( _shadowColor ); + painter->setBrush( b ); + + QPen p( Qt::red ); + painter->setPen( p ); + + QRectF r = boundingRect( ); + painter->drawRect( r ); + } + + // Draw background pixmap + if ( !_backPixmap.isNull( ) ) + { + QBrush b = brush( ); + b.setStyle( Qt::NoBrush ); + setBrush( b ); // Remove default backcolor (usefull if we have an alpha channel) + + QRectF backRect = boundingRect( ); + //backRect.adjust( 0., 0., 1., 1. ); + QRectF srcRect( 0., 0., _backPixmap.width( ), _backPixmap.height( ) ); + painter->drawPixmap( backRect, _backPixmap, srcRect ); + } + + QGraphicsRectItem::paint( painter, option, widget ); + + // Draw the item icon centered vertically + if ( !_icon.isNull( ) ) + { + QPointF iconPos( 1.0, 1.0 ); + if ( _dimension.y( ) > _icon.height( ) ) + iconPos.ry( ) += ( _dimension.y( ) - _icon.height( ) ) / 2.; + painter->drawPixmap( iconPos, _icon ); + } +} + +void NodeItem::updateNode( ) +{ + if ( getStyle( ) == 0 ) + return; + + QColor backColor = QColor( 255, 255, 255 ); + + if ( !getStyle( )->has( "nobackground" ) ) + { + QBrush b = brush( ); + b.setStyle( Qt::NoBrush ); + setBrush( b ); + } + + if ( getStyle( )->has( "backcolor" ) ) + { + backColor = getStyle( )->getColor( "backcolor" ); + QBrush b = brush( ); + b.setStyle( Qt::SolidPattern ); + b.setColor( backColor ); + setBrush( b ); + } + else + setBrush( QColor( 255, 255, 255 ) ); + + QColor borderColor = QColor( 0, 0, 0 ); + if ( getStyle( )->has( "bordercolor" ) ) + { + borderColor = getStyle( )->getColor( "bordercolor" ); + setPen( borderColor ); + } + + // Compute the _label size once it is laid out as rich text html + if ( _label.size( ) > 0 ) + { + QFont font; + if ( getStyle( )->has( "fontsize" ) ) + { + int fontSize = getStyle( )->getT< int >( "fontsize" ); + font.setPointSize( fontSize > 0 ? fontSize : 11 ); + } + _labelItem = new QGraphicsTextItem( this, scene( ) ); + _labelItem->setHtml( _label ); + _labelItem->setFont( font ); + } + + + // Updating node geometry and content + { + // Check for item maximum dimension (if specified) + double maximumWidth = -1.; + double maximumHeight = -1.; + if ( getStyle( )->has( "maximumwidth" ) ) + maximumWidth = getStyle( )->getT< int >( "maximumwidth" ); + if ( getStyle( )->has( "maximumheight" ) ) + maximumHeight = getStyle( )->getT< int >( "maximumheight" ); + + // Compute the item height according to the _label size once formatted and displayed + if ( _labelItem != 0 /*_labelDocument != 0 && _labelLayout != 0*/ ) + { + // Do not resize the item larger than its maximum allowed size + double textLayoutWidth = _labelItem->boundingRect( ).width( ) + 2.; + double textLayoutHeight = _labelItem->boundingRect( ).height( ) + 2.; + _dimension.setX( maximumWidth > 0. ? std::min( textLayoutWidth, maximumWidth ) : textLayoutWidth ); + _dimension.setY( maximumHeight > 0. ? std::min( textLayoutHeight, maximumHeight ) : textLayoutHeight ); + } + + // Resize the whole item to fit (eventual) icon size + if ( getStyle( )->has( "icon" ) ) + { + QImage icon = getStyleManager( ).getImage( getStyle( )->getImageName( "icon" ) ); + if ( !icon.isNull( ) ) + _icon = QPixmap::fromImage( icon, Qt::OrderedAlphaDither ); + } + + if ( !_icon.isNull( ) ) + { + double w = _dimension.x( ) + _icon.width( ) + 1.; + _dimension.setX( maximumWidth != -1 ? std::min( w, maximumWidth ) : w ); + + double h = std::max( _icon.height( ) + 1., _dimension.y( ) ); + _dimension.setY( maximumHeight != -1 ? std::min( h, maximumHeight ) : h ); + + double textMarginX = 2; + double textMarginY = 0; + double textX = textMarginX; + if ( !_icon.isNull( ) ) // Draw the text right of the icon + textX += _icon.width( ); + double textY = textMarginY; + + QRectF clipRect( textX, textY, _dimension.x( ) - textMarginX, _dimension.y( ) - textMarginY ); + _labelItem->translate( textX, textY ); + } + + // Update the background image + if ( getStyle( )->has( "backimage" ) ) + { + QImage backImage = getStyleManager( ).getImage( getStyle( )->getImageName( "backimage" ) ); + if ( !backImage.isNull( ) ) + { + QImage image = backImage.scaled( ( int )_dimension.x( ) - 1, ( int )_dimension.y( ) - 1 ); // -1 for the border + if ( !image.isNull( ) ) + _backPixmap = QPixmap::fromImage( image, Qt::OrderedAlphaDither ); + } + } + + if ( getStyle( )->has( "hasshadow" ) && getStyle( )->getT< bool >( "hasshadow" ) ) + { + if ( getStyle( )->has( "shadowcolor" ) ) + _shadowColor = getStyle( )->getColor( "shadowcolor" ); + else + _shadowColor = QColor( 105, 105, 105 ); + if ( getStyle( )->has( "shadowoffset" ) ) + _shadowOffset = getStyle( )->getT< int >( "shadowoffset" ); + else + _shadowOffset = 3.; + + // Setup the two rectangle sub items who are modelling shadow + // Two rect are needed, because a unique subitem modelling shadow cannot have + // a zvalue inferior to the rect item modelling the node (BTW, it may be faster + // to render two small rect than a big one) + QGraphicsRectItem* shadowBottom = new QGraphicsRectItem( this, scene( ) ); + shadowBottom->setRect( _shadowOffset, _dimension.y( ) + 1.0, _dimension.x( ), _shadowOffset ); + QBrush b; + b.setStyle( Qt::SolidPattern ); + b.setColor( _shadowColor ); + shadowBottom->setBrush( b ); + shadowBottom->setPen( QPen( _shadowColor ) ); + + QGraphicsRectItem* shadowRight = new QGraphicsRectItem( this, scene( ) ); + shadowRight->setRect( _dimension.x( ) + 1.0, _shadowOffset, _shadowOffset, _dimension.y( ) + 1.0 ); + shadowRight->setBrush( b ); + shadowRight->setPen( QPen( _shadowColor ) ); + } + else + _shadowColor = QColor( ); // Invalid color since there is no shadow + + // Set item geometry + setRect( 0., 0., _dimension.x( ), _dimension.y( ) ); + getNode( ).setDimension( _dimension.x( ), _dimension.y( ) ); + } +} + +QVariant NodeItem::itemChange( GraphicsItemChange change, const QVariant& value ) +{ + if ( change == ItemPositionChange || change == ItemMatrixChange ) + updateEdges( ); + return QGraphicsItem::itemChange( change, value ); +} +//----------------------------------------------------------------------------- + +} // ::qan + ============================================================ --- libs/qanava/src/qanNodeItem.h a1e0b3eb14d69a41be0b3fb7df0bba3707a54f39 +++ libs/qanava/src/qanNodeItem.h a1e0b3eb14d69a41be0b3fb7df0bba3707a54f39 @@ -0,0 +1,222 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanNodeItem.h +// \author Benoit Autheman (address@hidden) +// \date 2004 October 13 +//----------------------------------------------------------------------------- + + +#ifndef canNodeItem_h +#define canNodeItem_h + + +// Qanava headers +#include "./qanNode.h" +#include "./qanStyle.h" +#include "./qanEdgeItem.h" + + +// QT headers +#include +#include +#include + + +//----------------------------------------------------------------------------- +namespace qan { // ::qan + + class AbstractNodeItem : public QObject + { + Q_OBJECT + + public: + + AbstractNodeItem( Node& node, Style::Manager& styleManager, Style* style ) : + _node( node ), + _styleManager( styleManager ), + _style( style ) + { + if ( style != 0 ) + connect( style, SIGNAL( modified() ), this, SLOT( updateNode() ) ); + } + + virtual ~AbstractNodeItem( ) + { + } + + //! Usually, return this casted to QGraphicsItem. + virtual QGraphicsItem* getGraphicsItem( ) = 0; + + public slots: + + virtual void updateNode( ) = 0; + + public: + + Node& getNode( ) { return _node; } + + Style::Manager& getStyleManager( ) { return _styleManager; } + + void setStyle( Style* style ) { _style = style; updateNode( ); } + + Style* getStyle( ) { return _style; } + + private: + + Node& _node; + + Style::Manager& _styleManager; + + Style* _style; + + public: + + void addEdge( EdgeItem* edge ) + { + _edges << edge; + connect( this, SIGNAL( destroyed( ) ), edge, SLOT( nodeDestroyed( ) ) ); + } + + void removeEdge( EdgeItem* edge ) { _edges.removeAll( edge ); } + + void updateEdges( ) + { + foreach ( EdgeItem* edge, _edges ) + edge->updateEdge( ); + } + + protected: + + QList< EdgeItem* > _edges; + + public: + + class AbstractFactory + { + public: + + AbstractFactory( int nodeType, bool defaultFactory = false ) : + _nodeType( nodeType ), _defaultFactory( defaultFactory ) { }; + + virtual ~AbstractFactory( ) { } + + virtual AbstractNodeItem* create( Node& node, Style::Manager& styleManager, Style& style, + QGraphicsItem* parent, QGraphicsScene* scene, + QPoint origin, const QString& label) = 0; + + int getNodeType( ) const { return _nodeType; } + + bool isDefaultFactory( ) const { return _defaultFactory; } + + typedef QList< AbstractFactory* > List; + + private: + + int _nodeType; + + bool _defaultFactory; + }; + + template < typename T > + class Factory : public AbstractFactory + { + public: + + Factory( int nodeType, bool defaultFactory = false ) : + AbstractFactory( nodeType, defaultFactory ) { } + + virtual AbstractNodeItem* create( Node& node, Style::Manager& styleManager, Style& style, + QGraphicsItem* parent, QGraphicsScene* scene, + QPoint origin, const QString& label ) + { return new T( node, styleManager, style, parent, scene, origin, label ); } + }; + }; + + + + //! Model a rectangular node item on a QT graphics view. + /*! + The following style options are supported: +
    +
  • 'backcolor': Background color, when there is no background image defined. +
  • 'bordercolor': Color of the item border. +
  • 'backimage': Background image (scaled to fit the item size). +
  • 'maximumwidth': Maximum width of the item, content is cropped to fit this with limit. +
  • 'maximumheight': Maximum height of the item, content is cropped to fit this height limit. +
  • 'fontsize': Base size for the font used to display the item label. +
  • 'icon': Display an icon centered in the left of the item. +
  • 'hasshadow': Set this value to false to supress the node shadow. +
+ \nosubgrouping + */ + class NodeItem : public AbstractNodeItem, public QGraphicsRectItem + { + Q_OBJECT + + public: + + NodeItem( Node& node, Style::Manager& styleManager, Style& style, + QGraphicsItem* parent, QGraphicsScene* scene, + QPointF origin, const QString& label ); + + virtual ~NodeItem( ); + + void paint( QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget = 0 ); + + struct DefaultFactory : public AbstractNodeItem::Factory< NodeItem > + { + DefaultFactory( ) : AbstractNodeItem::Factory< NodeItem >( -1, true ) { } + }; + + public slots: + + virtual void updateNode( ); + + virtual QGraphicsItem* getGraphicsItem( ) { return static_cast< QGraphicsItem* >( this ); } + + private: + + QPointF _dimension; + + QString _label; + + QPixmap _backPixmap; + + QColor _shadowColor; + + double _shadowOffset; + + QGraphicsTextItem* _labelItem; + + QPixmap _icon; + + protected: + + QVariant itemChange( GraphicsItemChange change, const QVariant& value ); + }; +} // ::qan +//----------------------------------------------------------------------------- + + +#endif // qanNodeItem_h + ============================================================ --- libs/qanava/src/qanSimpleLayout.cpp eafcb23254d70a6cdeb04ff096f5d0091866b07c +++ libs/qanava/src/qanSimpleLayout.cpp eafcb23254d70a6cdeb04ff096f5d0091866b07c @@ -0,0 +1,106 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanSimpleLayout.cpp +// \author Benoit Autheman (address@hidden) +// \date 2006 January 06 +//----------------------------------------------------------------------------- + + +// Qanava headers +#include "./qanSimpleLayout.h" + + +namespace qan { // ::qan + + +/* Concentric Layout Management *///------------------------------------------- +void Concentric::layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress, int step ) +{ + // Configure the progress monitor + if ( progress != 0 ) + { + progress->setMaximum( graph.getNodeCount( ) ); + progress->setValue( 0 ); + } + + QPointF center = r.center( ); + int nodesPerCircle = ( int )( 360. / _azimutDelta ); + Node::List::iterator nodeIter = graph.getNodes( ).begin( ); + for ( int n = 0; n < ( int )graph.getNodes( ).size( ); n++, nodeIter++ ) + { + Node& node = **nodeIter; + double azimutIndex = ( n % nodesPerCircle ); + double azimut = azimutIndex * _azimutDelta; + + int circleIndex = 1 + ( n / nodesPerCircle ); + double cx = sin( azimut * 3.14156 / 180. ) * ( circleIndex * _circleInterval ); + double cy = cos( azimut * 3.14156 / 180. ) * ( circleIndex * _circleInterval ); + + node.getPosition( )( 0 ) = center.x( ) + cx; + node.getPosition( )( 1 ) = center.y( ) + cy; + if ( progress != 0 ) + progress->setValue( n ); + } + if ( progress != 0 ) + progress->close( ); +} +//----------------------------------------------------------------------------- + + + +/* Colimacon Layout Management *///-------------------------------------------- +void Colimacon::layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress, int step ) +{ + // Configure the progress monitor + if ( progress != 0 ) + { + progress->setMaximum( graph.getNodeCount( ) ); + progress->setValue( 0 ); + } + + QPointF center = r.center( ); + int nodesPerCircle = ( int )( 360. / _azimutDelta ); + Node::List::iterator nodeIter = graph.getNodes( ).begin( ); + for ( int n = 0; n < ( int )graph.getNodes( ).size( ); n++, nodeIter++ ) + { + Node& node = **nodeIter; + //double azimutIndex = ( double )( n % nodesPerCircle ); + double azimut = n * _azimutDelta; + + //int circleIndex = 1 + ( int )( n / nodesPerCircle ); + double cx = sin( azimut * 3.14156 / 180. ) * ( log( 1. + n ) * 10 * _circleInterval ); + double cy = cos( azimut * 3.14156 / 180. ) * ( log( 1. + n ) * 10 * _circleInterval ); + + node.getPosition( )( 0 ) = center.x( ) + cx; + node.getPosition( )( 1 ) = center.y( ) + cy; + + if ( progress != 0 ) + progress->setValue( n ); + } + if ( progress != 0 ) + progress->close( ); +} +//----------------------------------------------------------------------------- + + +} // ::qan ============================================================ --- libs/qanava/src/qanSimpleLayout.h ccfd04f8476073033255406182385f6e391e7a80 +++ libs/qanava/src/qanSimpleLayout.h ccfd04f8476073033255406182385f6e391e7a80 @@ -0,0 +1,115 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanSimpleLayout.h +// \author Benoit Autheman (address@hidden) +// \date 2007 January 06 +//----------------------------------------------------------------------------- + + +#ifndef qanSimpleLayout_h +#define qanSimpleLayout_h + + +// Qanava headers +#include "./qanLayout.h" + + +//----------------------------------------------------------------------------- +namespace qan { // ::qan + + //! Layout a graph as concentric circles of nodes. + /*! + \nosubgrouping + */ + class Concentric : public Layout + { + /*! \name Concentric Constructor/Destructor *///----------------------- + //@{ + public: + + //! Concentric constructor. + Concentric( double azimutDelta = 45., double circleInterval = 50. ) : + Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { } + + private: + + double _azimutDelta; + + double _circleInterval; + //@} + //--------------------------------------------------------------------- + + + + /*! \name Concentric Layout Management *///---------------------------- + //@{ + public: + + //! . + virtual void layout( Graph& graph, QGraphicsScene* scene, + QRectF r, QProgressDialog* progress = 0, int step = -1 ); + //@} + //--------------------------------------------------------------------- + }; + + + //! Layout nodes in a (logarithm) colimacon. + /*! + \nosubgrouping + */ + class Colimacon : public Layout + { + /*! \name Colimacon Constructor/Destructor *///------------------------ + //@{ + public: + + //! Colimacon constructor. + Colimacon( double azimutDelta = 15., double circleInterval = 10. ) : + Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { } + + private: + + double _azimutDelta; + + double _circleInterval; + //@} + //--------------------------------------------------------------------- + + + + /*! \name Colimacon Layout Management *///----------------------------- + //@{ + public: + + //! . + virtual void layout( Graph& graph, QGraphicsScene* scene, + QRectF r, QProgressDialog* progress = 0, int step = -1 ); + //@} + //--------------------------------------------------------------------- + }; +} // ::qan +//----------------------------------------------------------------------------- + + +#endif // qanSimpleLayout_h + ============================================================ --- libs/qanava/src/qanTreeLayout.cpp 836a7b1ecc11de2d242d63a45c72cc9e437b456e +++ libs/qanava/src/qanTreeLayout.cpp 836a7b1ecc11de2d242d63a45c72cc9e437b456e @@ -0,0 +1,386 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanTreeLayout.cpp +// \author Benoit Autheman (address@hidden) +// \date 2007 January 06 +//----------------------------------------------------------------------------- + + +// Qanava headers +#include "./qanTreeLayout.h" + + +namespace qan { // ::qan + + +/* Hierarchy Layout Generation Management *///--------------------------------- +void HierarchyTree::layout( Graph& graph, QGraphicsScene*, QRectF r, QProgressDialog* progress, int step ) +{ + // Configure the progress monitor + if ( progress != 0 ) + { + progress->setMaximum( graph.getNodeCount( ) ); + progress->setValue( 0 ); + } + + // Layout all graph subgraph + _marked.clear( ); + QRectF bbox( _origin, QSizeF( 0., 0. ) ); + foreach ( Node* root, graph.getRootNodes( ) ) + { + layout( *root, bbox, 0, progress ); + bbox.translate( _spacing.x( ), 0. ); + } + + // Transpose nodes position coordinates if the layout is horizontal + if ( _orientation == Qt::Horizontal ) + { + foreach( Node* node, graph.getNodes( ) ) + { + VectorF position = node->getPosition( ); + node->setPosition( position( 1 ), position( 0 ) ); + } + } + + if ( progress != 0 ) + progress->close( ); +} + +void HierarchyTree::layout( Node& node, QRectF& bbox, int depth, QProgressDialog* progress, int step ) +{ + if ( _marked.contains( &node ) ) + return; + _marked.insert( &node ); + + if ( progress != 0 && progress->wasCanceled( ) ) + return; + + double xStart = bbox.left( ); + + // Depth first + int laidOut = 0; + Node::Set outNodes; node.collectOutNodesSet( outNodes ); + foreach ( Node* subNode, outNodes ) + { + if ( !_marked.contains( subNode ) ) + { + if ( laidOut > 0 ) + bbox.translate( _spacing.x( ), 0. ); + + layout( *subNode, bbox, depth + 1, progress ); + laidOut++; + } + } + + double xEnd = bbox.left( ); + + // Detect leaf node + double x = 0.f; + double y = _origin.y( ) + ( _spacing.y( ) * depth ); + if ( node.isLeaf( ) ) + x = xStart; + else + x = xStart + ( ( xEnd - xStart ) / 2.f ); + node.setPosition( x, y ); + + if ( progress != 0 ) + progress->setValue( progress->value( ) + 1 ); +} +//----------------------------------------------------------------------------- + + +/* ChanTree Management *///---------------------------------------------------- +ChanTree::ChanTree( ) : Layout( ) +{ + +} + +void ChanTree::layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress, int step ) +{ + // Configure the progress monitor + if ( progress != 0 ) + { + progress->setMaximum( graph.getNodeCount( ) ); + progress->setValue( 0 ); + } + + // Layout all graph subgraph + Node::Set leafTrees; + + QMap< Node*, QRectF > bboxes; + foreach ( Node* root, graph.getRootNodes( ) ) + { + findLeafTrees( *root, leafTrees ); + layoutSubTree( *root, leafTrees, bboxes ); + + VectorF origin( 2 ); origin( 0 ) = 0.; origin( 1 ) = 0.; + transformPositions( scene, *root, origin, bboxes, leafTrees ); + } + + if ( progress != 0 ) + progress->close( ); +} + +void ChanTree::layoutSubTree( Node& node, Node::Set& leafTrees, QMap< Node*, QRectF >& bboxes ) +{ + // If we are at a leaf tree (tree of depth 2), perform a trivial layout + if ( leafTrees.contains( &node ) ) + { + trivialLayout( node, bboxes ); + return; + } + + // Get the subtrees drawn + float x = 0.; + Node::List outNodes; node.collectOutNodes( outNodes ); + foreach ( Node* subNode, outNodes ) + layoutSubTree( *subNode, leafTrees, bboxes ); + + // Split the subnodes in two equal sets + Node::List leftNodes; + Node::List rightNodes; + if ( outNodes.size( ) >= 2 ) + { + int mid = outNodes.size( ) / 2; + leftNodes = outNodes.mid( 0, mid ); + rightNodes = outNodes.mid( mid ); + assert( leftNodes.size( ) + rightNodes.size( ) == outNodes.size( ) ); + + QRectF leftBox = computeHorizontalBbox( leftNodes, bboxes ); + QRectF rightBox = computeHorizontalBbox( rightNodes, bboxes ); + if ( leftBox.height( ) <= rightBox.height( ) ) + applyLeftRule( node, leftNodes, rightNodes, bboxes ); + else + applyRightRule( node, leftNodes, rightNodes, bboxes ); + + double width = leftBox.width( ) + rightBox.width( ); + double height = leftBox.height( ) + rightBox.height( ); + computeBBox( node, bboxes ); // Force bounding box computation and caching + } + else + { + // Only zero or one subnode + double height = 0.; + foreach ( Node* subNode, outNodes ) + { + subNode->setPosition( 0., 50. ); + height = qMax( height, computeBBox( *subNode, bboxes ).height( ) ); + } + computeBBox( node, bboxes ); // Force bounding box computation and caching + } +} + +void ChanTree::applyLeftRule( Node& root, Node::List& left, Node::List& right, QMap< Node*, QRectF >& bboxes ) +{ + // Align the left subtree on the left just under the root node + QRectF leftBox = computeHorizontalBbox( left, bboxes ); + QRectF rightBox = computeHorizontalBbox( right, bboxes ); + double x = -rightBox.width( ) / 4; // Do not strictly align bboxes vertically + foreach ( Node* node, left ) + { + QRectF leftNodeBox = computeBBox( *node, bboxes ); + x -= ( leftNodeBox.width( ) / 2. ); // Placing the node at the middle of its sub tree bbox + node->setPosition( x, 25. ); + x -= ( leftNodeBox.width( ) / 2. ); // Adding the rest of the bbox and the space between subtrees + } + + // Align the right subtree under the root and below the left block + x = 0.; + foreach ( Node* node, right ) + { + QRectF rightNodeBox = computeBBox( *node, bboxes ); + x += ( rightNodeBox.width( ) / 2. ); // Placing the node at the middle of its sub tree bbox + node->setPosition( x, leftBox.height( ) ); + x += ( rightNodeBox.width( ) / 2. ); // Placing the node at the middle of its sub tree bbox + } + foreach ( Node* node, right ) + { + VectorF position = node->getPosition( ); + node->setPosition( position( 0 ) - x / 2., leftBox.height( ) ); // Convert to relative coordinates by removing mean + } +} + +void ChanTree::applyRightRule( Node& root, Node::List& left, Node::List& right, QMap< Node*, QRectF >& bboxes ) +{ + // Align the right subtree on the right just under the root node + QRectF leftBox = computeHorizontalBbox( left, bboxes ); + QRectF rightBox = computeHorizontalBbox( right, bboxes ); + double x = leftBox.width( ) / 4; + foreach ( Node* node, right ) + { + QRectF rightNodeBox = computeBBox( *node, bboxes ); + x += ( rightNodeBox.width( ) / 2. ); // Placing the node at the middle of its sub tree bbox + node->setPosition( x, 25. ); + x += ( rightNodeBox.width( ) / 2. ); // Adding the rest of the bbox and the space between subtrees + } + + // Align the left subtree under the root and below the left block + x = 0.; + foreach ( Node* node, left ) + { + QRectF leftNodeBox = computeBBox( *node, bboxes ); + x += ( leftNodeBox.width( ) / 2. ); // Placing the node at the middle of its sub tree bbox + node->setPosition( x, rightBox.height( ) ); + x += ( leftNodeBox.width( ) / 2. ); // Adding the rest of the bbox and the space between subtrees + } + foreach ( Node* node, left ) + { + VectorF position = node->getPosition( ); + node->setPosition( position( 0 ) - x / 2., rightBox.height( ) ); // Convert to relative coordinates by removing mean + } +} + +void ChanTree::trivialLayout( Node& node, QMap< Node*, QRectF >& bboxes ) +{ + // Layout sub nodes + double x = 0.; + double y = 50.; + foreach ( Edge* edge, node.getOutEdges( ) ) + { + edge->getDst( ).setPosition( x, y ); + x += 70.; + } + x -= 70.; // Do not add space after the last node + + // Use relative coordinates centered on 0 (removing the mean) + foreach ( Edge* edge, node.getOutEdges( ) ) + { + Node& subNode = edge->getDst( ); + const qan::VectorF& position = subNode.getPosition( ); + subNode.setPosition( position( 0 ) - x / 2., position( 1 ) ); + computeBBox( subNode, bboxes ); + } + + // Force bounding box computation and caching + computeBBox( node, bboxes ); +} + +bool ChanTree::findLeafTrees( Node& node, Node::Set& leafTrees ) +{ + if ( node.getOutEdges( ).size( ) == 0 ) + return true; + + bool leaf = true; + Node::List outNodes; node.collectOutNodes( outNodes ); + foreach ( Edge* edge, node.getOutEdges( ) ) + { + if ( findLeafTrees( edge->getDst( ), leafTrees ) == false ) + leaf = false; + } + if ( leaf ) // All subnode are leaf nodes, so we are at the root of a leaf subtree + leafTrees.insert( &node ); + + return false; +} + +void ChanTree::transformPositions( QGraphicsScene* scene, Node& node, VectorF current, QMap< Node*, QRectF >& bboxes, Node::Set& leafTrees ) +{ + VectorF position = node.getPosition( ) + current; + node.setPosition( position ); + + if ( bboxes.contains( &node ) /*&& node.getOutDegree( ) == 0*//* && leafTrees.contains( &node )*/ ) + { + QRectF bbox = bboxes[ &node ]; + bbox.translate( position( 0 ), position( 1 ) ); + if ( scene != 0 ) + { + QGraphicsRectItem* item = new QGraphicsRectItem( bbox, 0, scene ); + QColor colors[ 4 ]; + colors[ 0 ] = Qt::blue; + colors[ 1 ] = Qt::black; + colors[ 2 ] = Qt::green; + colors[ 3 ] = Qt::red; + item->setPen( colors[ rand( ) % 4 ] ); + } + } + + foreach ( Edge* edge, node.getOutEdges( ) ) + transformPositions( scene, edge->getDst( ), position, bboxes, leafTrees ); +} + +QRectF ChanTree::computeHorizontalBbox( Node::List& nodes, QMap< Node*, QRectF >& bboxes ) +{ + QRectF result( 0., 0., 0., 0. ); + double height = 0.; + double width = 0.; + foreach ( Node* node, nodes ) + { + QRectF bbox = computeBBox( *node, bboxes ); + width += bbox.width( ); + if ( bbox.width( ) <= 0.01 ) + width += 70.; + height = qMax( height, bbox.height( ) ); + } + result.setWidth( width ); + result.setHeight( height ); + return result; +} + +QRectF ChanTree::computeBBox( Node& node, QMap< Node*, QRectF >& bboxes ) +{ + VectorF current( 2 ); + current( 0 ) = 0.; + current( 1 ) = 0.; + return computeBBox( node, current, bboxes ); +} + +QRectF ChanTree::computeBBox( Node& node, VectorF current, QMap< Node*, QRectF >& bboxes ) +{ + // Use caching + if ( bboxes.contains( &node ) ) + return bboxes[ &node ]; + + if ( node.getOutDegree( ) == 0 ) + { + QRectF localBox( 0., 0., 70., 50. ); + return localBox; + } + + double left = 0.; + double top = 0.; + double right = 70.; + double bottom = 50.; + foreach ( Edge* edge, node.getOutEdges( ) ) + { + Node& subNode = edge->getDst( ); + QRectF subBox = computeBBox( subNode, current, bboxes ); + subBox.translate( subNode.getPosition( )( 0 ), subNode.getPosition( )( 1 ) ); + + left = qMin( subBox.left( ), left ); + top = qMin( subBox.top( ), top ); + right = qMax( subBox.right( ), right ); + bottom = qMax( subBox.bottom( ), bottom ); + } + + QRectF result( 0., 0., 0., 0. ); + result.setLeft( left ); + result.setTop( top ); + result.setRight( right ); + result.setBottom( bottom ); + bboxes[ &node ] = result; // Cache result + return result; +} +//----------------------------------------------------------------------------- + + +} // ::qan ============================================================ --- libs/qanava/src/qanTreeLayout.h f6e7e5e89f64711c30443ed60bdc794902f79aa3 +++ libs/qanava/src/qanTreeLayout.h f6e7e5e89f64711c30443ed60bdc794902f79aa3 @@ -0,0 +1,177 @@ +/* +Qanava - Graph drawing library for QT +Copyright (C) 2006 Benoit AUTHEMAN + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +//----------------------------------------------------------------------------- +// This file is a part of the Qanava software. +// +// \file qanTreeLayout.h +// \author Benoit Autheman (address@hidden) +// \date 2007 January 06 +//----------------------------------------------------------------------------- + + +#ifndef qanTreeLayout_h +#define qanTreeLayout_h + + +// Qanava headers +#include "./qanLayout.h" + + +//----------------------------------------------------------------------------- +namespace qan { // ::qan + + + //! Layout an undirected graph as a directed top-down tree. + /*! + \nosubgrouping + */ + class HierarchyTree : public Layout + { + /*! \name HierarchyTree Constructor/Destructor *///--------------------- + //@{ + public: + + + //! HierarchyTree constructor with orientation initialization. + /*! \param spacing spacing between node on x and y (ex: 120, 70 with Qt::Vertical). */ + HierarchyTree( QPointF spacing, QPointF origin = QPointF( 0., 0. ), Qt::Orientation orientation = Qt::Vertical ) : + Layout( ), _spacing( spacing ), _origin( origin ), _orientation( orientation ) + { + if ( orientation == Qt::Horizontal ) // Layout is computed for vertical, swap parameters when laying out horizontaly + { + _spacing.rx( ) = spacing.y( ); + _spacing.ry( ) = spacing.x( ); + _origin.rx( ) = origin.y( ); + _origin.ry( ) = origin.x( ); + } + } + //@} + //--------------------------------------------------------------------- + + + + /*! \name Hierarchy Layout Generation Management *///------------------ + //@{ + public: + + //! Layout a graph as a hierarchy tree. + virtual void layout( Graph& graph, QGraphicsScene* scene, + QRectF r, QProgressDialog* progress = 0, int step = -1 ); + + protected: + + //! Layout a node hierarchy as a hierarchy tree. + void layout( Node& node, QRectF& bbox, int depth, QProgressDialog* progress = 0, int step = 0 ); + + QPointF _origin; + + //! Spacing on x and y between tree nodes. + QPointF _spacing; + + //! Generated tree orientation. + Qt::Orientation _orientation; + + //! Container for already laid out nodes. + Node::Set _marked; + //@} + //--------------------------------------------------------------------- + }; + + + + /*! Layout a tree using a greedy spatial optimisation based on the binary tree layout algorithm from Chan (1999). + While this layout algorithm is stricly upward and preserve node order, two node at the + same depth might not be drawn at the same level (y). This algorithm might not be suitable for + drawing hierarchy (use the HierarchyTree algorithm instead). + + \nosubgrouping + */ + class ChanTree : public Layout + { + /*! \name HierarchyTree Constructor/Destructor *///--------------------- + //@{ + public: + + //! . + /*! */ + ChanTree( ); + //@} + //--------------------------------------------------------------------- + + + + /*! \name Hierarchy Layout Generation Management *///------------------ + //@{ + public: + + //! Layout a graph as a hierarchy tree. + virtual void layout( Graph& graph, QGraphicsScene* scene, + QRectF r, QProgressDialog* progress = 0, int step = -1 ); + + protected: + + void layoutSubTree( Node& node, Node::Set& leafTrees, QMap< Node*, QRectF >& bboxes ); + + void applyLeftRule( Node& root, Node::List& left, Node::List& right, QMap< Node*, QRectF >& bboxes ); + + void applyRightRule( Node& root, Node::List& left, Node::List& right, QMap< Node*, QRectF >& bboxes ); + + /*! Perform a simple layout for a leaf subtree (node being the root of a tree of depth 2). + See "Drawing Graphs - Methods end Models" p50 for details. + + \param node root of a tree of depth 2. + */ + void trivialLayout( Node& node, QMap< Node*, QRectF >& bboxes ); + + /*! Add all leaf tree root node to a given set. + \param leafTrees All result leaft tree root nodes will be added in this (not necessarilly empty) set. + \return return Return value is used internally for recursion control and should be ignored. + */ + bool findLeafTrees( Node& node, Node::Set& leafTrees ); + + /*! Transform all node coordinate from their local coordinate system the a global tree CS. + A VectorF( 2 ) with tree origin coordinates must be specified for the root node. + + \param node root node for the tree that must be translated. + */ + void transformPositions( QGraphicsScene* scene, Node& node, VectorF current, QMap< Node*, QRectF >& bboxes, Node::Set& leafTrees ); + + /*! Compute a bounding box enclosing all bounding boxes for a given set of nodes. + */ + QRectF computeHorizontalBbox( Node::List& nodes, QMap< Node*, QRectF >& bboxes ); + + /*! Recursively compute a bounding boxe for a given node. + Bounding box will be specified in the node local coordinate system, to obtain a bounding + box valid in the super node, it must be translated by its node position. + */ + QRectF computeBBox( Node& node, QMap< Node*, QRectF >& bboxes ); + + private: + + QRectF computeBBox( Node& node, VectorF current, QMap< Node*, QRectF >& bboxes ); + //@} + //--------------------------------------------------------------------- + }; +} // ::qan +//----------------------------------------------------------------------------- + + +#endif // qanTreeLayout_h + ============================================================ --- guitone/res/i18n/guitone_de.ts e97280e3c67f5b0693547d7d9eae8fc7b1022343 +++ guitone/res/i18n/guitone_de.ts eea6b551bbd68e41ad3bc1e2f02cd1e9f3a0e7d9 @@ -34,7 +34,7 @@ - + Please wait while the graph is being created... @@ -575,7 +575,7 @@ MainWindow - + View Ansicht @@ -585,7 +585,7 @@ Hilfe - + Workspace Arbeitsbereich @@ -600,12 +600,12 @@ Vorherige Arbeitsbereiche - + Open Workspace Arbeitsbereich öffnen - + Ctrl+O Strg+O @@ -615,22 +615,22 @@ Keine vorherigen Arbeitsbereiche verfügbar. - + Preferences.... Einstellungen... - + Ctrl+P Strg+P - + Quit Beenden - + Ctrl+Q Strg+Q @@ -640,97 +640,97 @@ Ignorierte Dateien verstecken - + Ctrl+H Strg+H - + All files Alle Dateien - + A A - + All changed files Alle geänderten Dateien - + C G - + Patched files Inhaltlich geänderte Dateien - + P P - + Added files Hinzugefügte Dateien - + N H - + Removed files Entfernte Dateien - + D E - + Renamed files Umbenannte Dateien - + R U - + Missing files Fehlende Dateien - + M F - + Unknown files Unbekannte Dateien - + U K - + Ignored files Ignorierte Dateien - + I I @@ -740,42 +740,42 @@ Baum aufklappen - + Ctrl+T Strg+T - + Switch revision Revision wechseln - + Ctrl+R Strg+R - + Key management Schlüsselverwaltung - + Ctrl+K Strg+K - + About Qt Über Qt - + About guitone Über guitone - + Show Zeige @@ -855,7 +855,7 @@ Vorherige Datenbanken - + Open Database Datenbank öffnen @@ -865,12 +865,12 @@ Keine vorherigen geöffneten Datenbanken verfügbar. - + Database Datenbank - + Ctrl+Shift+O Strg+Shift+O @@ -895,12 +895,12 @@ Keine Datenbank geladen - + Ctrl+B Strg+B - + Changeset browser Änderungen-Browser @@ -912,17 +912,53 @@ Sie können zum Arbeitsbereich-Modus jed Sie können zum Arbeitsbereich-Modus jederzeit zurückkehren, indem Sie einen Arbeitsbereich laden. - + Ancestry Graph - + Ctrl+A + Manifest + + + File + Datei + + + + Hash + + + + + ManifestDialog + + + Files in %1 + + + + + Save selected + + + + + Save all + + + + + Close + Schließen + + + Monotone ============================================================ --- guitone/src/view/dialogs/AncestryGraph.cpp 2d96f818ed011d6ff7002182a63d54ece76b96eb +++ guitone/src/view/dialogs/AncestryGraph.cpp 9694391673a672540dfd7af1a173f9149d98eef6 @@ -21,6 +21,8 @@ #include "AncestryGraph.h" #include "qanGrid.h" +#include + AncestryGraph::AncestryGraph(QWidget* parent) : Dialog(parent) { @@ -58,18 +60,13 @@ void AncestryGraph::createGraphView( ) void AncestryGraph::createGraphView( ) { - qan::VectorF origin(2); - origin(0) = 50.f; - origin(1) = 50.f; + QPointF origin(50.f, 50.f); + QPointF spacing(1200.f, 550.f); - qan::VectorF spacing(2); - spacing(0) = 1200.f; - spacing(1) = 550.f; - - qan::Layout* layout = new qan::DirectedTree( + qan::Layout* layout = new qan::HierarchyTree( origin, spacing, - qan::DirectedTree::HORIZONTAL + Qt::Horizontal ); graphItemView->setGraphLayout(layout); ============================================================ --- guitone/src/view/dialogs/AncestryGraph.h 8b3764f98c90d5c7fab0d8c529e97b92b92e4fc6 +++ guitone/src/view/dialogs/AncestryGraph.h 9c16c34d9eb82a6c4c7cd99c9f03446cf363a621 @@ -29,7 +29,7 @@ #include "Graph.h" #include "qanGraphItemView.h" -#include "qanLayout.h" +#include "qanTreeLayout.h" class AncestryGraph : public Dialog, private Ui::AncestryGraph { ============================================================ --- libs/qanava/build/qan/qan.pro d5ef733dbb9849633e57e042ad112df5df9185c9 +++ libs/qanava/build/qan/qan.pro c4e3c2e0bba796aae727c6f7cf3a7aaab6923d85 @@ -15,12 +15,15 @@ HEADERS += ../../src/qanConfig.h \ ../../src/qanGraph.hpp \ ../../src/qanGrid.h \ ../../src/qanLayout.h \ + ../../src/qanSimpleLayout.h \ + ../../src/qanTreeLayout.h \ ../../src/qanNode.h \ ../../src/qanVectorf.h \ ../../src/qanRepository.h \ ../../src/qanTimeTree.h \ ../../src/qanController.h \ - ../../src/qanItemGeom.h \ + ../../src/qanNodeItem.h \ + ../../src/qanEdgeItem.h \ ../../src/qanStyle.h \ ../../src/qanGraphicsView.h \ ../../src/qanGraphItemView.h \ @@ -33,11 +36,14 @@ SOURCES += ../../src/qanEdge.cpp \ SOURCES += ../../src/qanEdge.cpp \ ../../src/qanLayout.cpp \ + ../../src/qanSimpleLayout.cpp \ + ../../src/qanTreeLayout.cpp \ ../../src/qanNode.cpp \ ../../src/qanRepository.cpp \ ../../src/qanTimeTree.cpp \ ../../src/qanController.cpp \ - ../../src/qanItemGeom.cpp \ + ../../src/qanNodeItem.cpp \ + ../../src/qanEdgeItem.cpp \ ../../src/qanStyle.cpp \ ../../src/qanGraphicsView.cpp \ ../../src/qanGraphItemView.cpp \ @@ -47,13 +53,12 @@ SOURCES += ../../src/qanEdge.cpp \ ../../src/ui/uiStyleModel.cpp \ ../../src/ui/uiNodesItemModel.cpp -macx | unix { +macx | unix{ QMAKE_CXXFLAGS_WARN_ON += -Wno-unused-parameter UI_DIR = .ui MOC_DIR = .moc OBJECTS_DIR = .obj DEFINES += QANAVA_UNIX - CONFIG += ppc x86 } win32{ OBJECTS_DIR = ./Debug ============================================================ --- libs/qanava/src/qanGraphItemView.cpp 2650092cb13e790fe4e6e81a7476978b0fa8a2b6 +++ libs/qanava/src/qanGraphItemView.cpp 5b4cb3773030bf708e1deb4374b4f42e87b91044 @@ -384,7 +384,7 @@ void GraphItemView::rowsAboutToBeRemoved EdgeGraphicItemMap::iterator canvasEdgeIter = _edgeGraphicItemMap.find( *edgeIter ); if ( canvasEdgeIter != _edgeGraphicItemMap.end( ) ) { - ( canvasEdgeIter.value( ) )->update( 0, 0 ); + ( canvasEdgeIter.value( ) )->disconnectEdge( ); _edgeGraphicItemMap.remove( *edgeIter ); } } @@ -542,9 +542,9 @@ void GraphItemView::layoutGraph( QProgre r.setHeight( std::max( r.height( ), ( double )height( ) ) ); if ( layout != 0 ) - layout->layout( *_graph, *getGraphicsView( )->getGrid( ), r, progress, step ); + layout->layout( *_graph, _graphicsScene, r, progress, step ); else if ( _layout != 0 && getGraphicsView( )->getGrid( ) != 0 ) - _layout->layout( *_graph, *getGraphicsView( )->getGrid( ), r, progress, step ); + _layout->layout( *_graph, _graphicsScene, r, progress, step ); // Update all nodes positions { @@ -554,7 +554,10 @@ void GraphItemView::layoutGraph( QProgre const Node* node = nodeIter.key( ); AbstractNodeItem* item = nodeIter.value( ); if ( node != 0 && item != 0 && node != except ) + { item->getGraphicsItem( )->setPos( node->getPosition( )( 0 ), node->getPosition( )( 1 ) ); + item->updateEdges( ); + } } } _graphicsView->update( ); @@ -595,7 +598,7 @@ bool GraphItemView::eventFilter( QObject bool GraphItemView::eventFilter( QObject *o, QEvent *e ) { - return false; + return _graphicsView->eventFilter( o, e ); } //----------------------------------------------------------------------------- ============================================================ --- libs/qanava/src/qanGraphItemView.h 4ff6a1e3a993c364ed5dfb4eaee72c8919814ad0 +++ libs/qanava/src/qanGraphItemView.h 99f9cda323fa15286177a3277578dce9f90e5e55 @@ -34,7 +34,8 @@ Foundation, Inc., 51 Franklin Street, Fi #include "./qanNode.h" #include "./qanGraph.h" #include "./qanLayout.h" -#include "./qanItemGeom.h" +#include "./qanNodeItem.h" +#include "./qanEdgeItem.h" #include "./qanGraphicsView.h" ============================================================ --- libs/qanava/src/qanGraphicsView.cpp 97aaefe368fdc15c63d293e9d40ef1630414fbea +++ libs/qanava/src/qanGraphicsView.cpp 7e38735bec8ddf769e356b9c27d037806f57050f @@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fi // QT headers #include +#include //----------------------------------------------------------------------------- @@ -91,7 +92,7 @@ void GraphicsView::drawBackground( QPain -/* View Controller Management *///----------------------------------------------- +/* View Controller Management *///--------------------------------------------- void GraphicsView::keyPressEvent( QKeyEvent* e ) { QGraphicsView::keyPressEvent( e ); ============================================================ --- libs/qanava/src/qanGridItem.cpp a521aaca80231c4a3cc1cad98105e155687d6ec2 +++ libs/qanava/src/qanGridItem.cpp 861ccf7f2cdf191bf535eb40e9cabb49613869a3 @@ -36,10 +36,6 @@ Foundation, Inc., 51 Franklin Street, Fi #include -// STD headers -//#include - - namespace qan { // ::qan ============================================================ --- libs/qanava/src/qanGridItem.h 14da4617240de3277b84e376e7652288b1e6ab07 +++ libs/qanava/src/qanGridItem.h 79b8cd3d9adb20718b0dc0d862849c2c42980b22 @@ -32,7 +32,6 @@ Foundation, Inc., 51 Franklin Street, Fi // Qanava headers #include "./qanGrid.h" -#include "./qanItemGeom.h" #include "./qanGraphicsView.h" ============================================================ --- libs/qanava/src/qanLayout.cpp 511aa22d12419f13286818772fc60ed1968f49a9 +++ libs/qanava/src/qanLayout.cpp bc1ecd1af36c3a75f6efc1306b3d52da7a862f12 @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fi //----------------------------------------------------------------------------- // This file is a part of the Qanava software. // -// \file laLayout.cpp +// \file qanLayout.cpp // \author Benoit Autheman (address@hidden) // \date 2004 May 22 //----------------------------------------------------------------------------- @@ -28,13 +28,11 @@ Foundation, Inc., 51 Franklin Street, Fi // Qanava headers #include "./qanLayout.h" +#include "./qanSimpleLayout.h" // Std headers -#include -#include #include -#include namespace qan { // ::qan @@ -52,7 +50,7 @@ void Layout::resetNodesPositions( Graph& /* Random Layout Generation Management *///------------------------------------ -void Random::layout( Graph& graph, GridItem& gridItem, QRectF r, QProgressDialog* progress, int step ) +void Random::layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress, int step ) { if ( progress != 0 ) { @@ -81,182 +79,11 @@ void Random::layout( Graph& graph, GridI //----------------------------------------------------------------------------- - -/* Concentric Layout Management *///------------------------------------------- -void Concentric::layout( Graph& graph, GridItem& gridItem, QRectF r, QProgressDialog* progress, int step ) -{ - // Configure the progress monitor - if ( progress != 0 ) - { - progress->setMaximum( graph.getNodeCount( ) ); - progress->setValue( 0 ); - } - - QPointF center = r.center( ); - int nodesPerCircle = ( int )( 360. / _azimutDelta ); - Node::List::iterator nodeIter = graph.getNodes( ).begin( ); - for ( int n = 0; n < ( int )graph.getNodes( ).size( ); n++, nodeIter++ ) - { - Node& node = **nodeIter; - double azimutIndex = ( n % nodesPerCircle ); - double azimut = azimutIndex * _azimutDelta; - - int circleIndex = 1 + ( n / nodesPerCircle ); - double cx = sin( azimut * 3.14156 / 180. ) * ( circleIndex * _circleInterval ); - double cy = cos( azimut * 3.14156 / 180. ) * ( circleIndex * _circleInterval ); - - node.getPosition( )( 0 ) = center.x( ) + cx; - node.getPosition( )( 1 ) = center.y( ) + cy; - if ( progress != 0 ) - progress->setValue( n ); - } - if ( progress != 0 ) - progress->close( ); -} -//----------------------------------------------------------------------------- - - - -/* Colimacon Layout Management *///-------------------------------------------- -void Colimacon::layout( Graph& graph, GridItem& gridItem, QRectF r, QProgressDialog* progress, int step ) -{ - // Configure the progress monitor - if ( progress != 0 ) - { - progress->setMaximum( graph.getNodeCount( ) ); - progress->setValue( 0 ); - } - - QPointF center = r.center( ); - int nodesPerCircle = ( int )( 360. / _azimutDelta ); - Node::List::iterator nodeIter = graph.getNodes( ).begin( ); - for ( int n = 0; n < ( int )graph.getNodes( ).size( ); n++, nodeIter++ ) - { - Node& node = **nodeIter; - //double azimutIndex = ( double )( n % nodesPerCircle ); - double azimut = n * _azimutDelta; - - //int circleIndex = 1 + ( int )( n / nodesPerCircle ); - double cx = sin( azimut * 3.14156 / 180. ) * ( log( 1. + n ) * 10 * _circleInterval ); - double cy = cos( azimut * 3.14156 / 180. ) * ( log( 1. + n ) * 10 * _circleInterval ); - - node.getPosition( )( 0 ) = center.x( ) + cx; - node.getPosition( )( 1 ) = center.y( ) + cy; - - if ( progress != 0 ) - progress->setValue( n ); - } - if ( progress != 0 ) - progress->close( ); -} -//----------------------------------------------------------------------------- - - - -/* Hierarchy Layout Generation Management *///--------------------------------- -void DirectedTree::layout( Graph& graph, GridItem&, QRectF r, QProgressDialog* progress, int step ) -{ - // Configure the progress monitor - if ( progress != 0 ) - { - progress->setMaximum( graph.getNodeCount( ) ); - progress->setValue( 0 ); - } - - // Reset the graph nodes positions (If position are not resetted, nodes are all considered - // already placed - resetNodesPositions( graph ); - - // Configure tree bounding box - VectorF& bbox = *new VectorF( 4 ); - bbox( 0 ) = getXOrigin( ); - bbox( 1 ) = getYOrigin( ); - - // Layout all graph subgraph - Node::List& rootNodes = graph.getRootNodes( ); - for ( Node::List::iterator rootsIter = rootNodes.begin( ); rootsIter != rootNodes.end( ); rootsIter++ ) - { - layout( **rootsIter, bbox, 0, progress ); - bbox( 0 ) += getXSpacing( ); - } - - // Set graph oritentation - if ( _orientation == HORIZONTAL ) - transpose( graph ); - delete &bbox; - - if ( progress != 0 ) - progress->close( ); -} - -void DirectedTree::layout( Node& node, VectorF& bbox, int depth, QProgressDialog* progress, int step ) -{ - if ( _marked.find( &node ) != _marked.end( ) ) - return; - _marked.insert( &node ); - - if ( getStopRecusrion( ) ) - return; - - float xStart = bbox( 0 ); - - // Depth first - int laidOut = 0; - Node::Set outNodes; node.collectOutNodesSet( outNodes ); - for ( Node::Set::iterator outNodesIter = outNodes.begin( ); outNodesIter != outNodes.end( ); outNodesIter++ ) - { - Node& subNode = **outNodesIter; - - // Detect if the node has already been placed - if ( subNode.getPosition( )( 0 ) < 0.f && - subNode.getPosition( )( 1 ) < 0.f ) - { - // A leaf node must be drawn at x+dx if one or more nodes has previously been laid out (!=begin). - if ( laidOut > 0 ) - bbox( 0 ) += getXSpacing( ); - - layout( subNode, bbox, depth + 1, progress ); - laidOut++; - } - } - - float xEnd = bbox( 0 ); - - // Detect leaf node - float x = 0.f; - float y = getYOrigin( ) + ( getYSpacing( ) * depth ); - if ( node.isLeaf( ) ) - x = xStart; - else - x = xStart + ( ( xEnd - xStart ) / 2.f ); - node.setPosition( x, y ); - - // Updated progress monitor - if ( progress != 0 && progress->wasCanceled( ) ) - stopRecursion( ); - if ( progress != 0 ) - progress->setValue( progress->value( ) + 1 ); -} - -void DirectedTree::transpose( Graph& graph ) -{ - Node::List& nodes = graph.getNodes( ); - for ( Node::List::iterator nodeIter = nodes.begin( ); nodeIter != nodes.end( ); nodeIter++ ) - { - Node& node = **nodeIter; - VectorF position = node.getPosition( ); - node.setPosition( position( 1 ), position( 0 ) ); - } -} -//----------------------------------------------------------------------------- - - - /* Force Layout Generation Management *///------------------------------------- /*! Initial positions will be generated using a fixed layout (random or colimacon) if step is superior of 1. */ -void UndirectedGraph::layout( Graph& graph, GridItem& gridItem, QRectF r, QProgressDialog* progress, int step ) +void UndirectedGraph::layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress, int step ) { int runCount = 50; if ( step != -1 ) @@ -272,7 +99,7 @@ void UndirectedGraph::layout( Graph& gra { //Random initalLayout; Colimacon initalLayout; - initalLayout.layout( graph, gridItem, r ); + initalLayout.layout( graph, scene, r ); } // Apply the spring force algorithm ============================================================ --- libs/qanava/src/qanLayout.h 2f96b5189a86b669e54c072e9c621074ef76654f +++ libs/qanava/src/qanLayout.h 85537ab50a01625b3b95ed98b3ab237125466e74 @@ -20,14 +20,14 @@ Foundation, Inc., 51 Franklin Street, Fi //----------------------------------------------------------------------------- // This file is a part of the Qanava software. // -// \file laLayout.h +// \file qanLayout.h // \author Benoit Autheman (address@hidden) // \date 2004 May 22 //----------------------------------------------------------------------------- -#ifndef laLayout_h -#define laLayout_h +#ifndef qanLayout_h +#define qanLayout_h // Qanava headers @@ -76,7 +76,7 @@ namespace qan { // ::qan public: //! Layout nodes from a given graph using r as a clipping rect, and update grid. - virtual void layout( Graph& graph, GridItem& gridItem, + virtual void layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress = 0, int step = -1 ) = 0; protected: @@ -111,179 +111,14 @@ namespace qan { // ::qan public: //! . - virtual void layout( Graph& graph, GridItem& gridItem, + virtual void layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress = 0, int step = -1 ); //@} //--------------------------------------------------------------------- }; - //! Layout a graph as concentric circles of nodes. - /*! - \nosubgrouping - */ - class Concentric : public Layout - { - /*! \name Concentric Constructor/Destructor *///----------------------- - //@{ - public: - //! Concentric constructor. - Concentric( double azimutDelta = 45., double circleInterval = 50. ) : - Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { } - - private: - - double _azimutDelta; - - double _circleInterval; - //@} - //--------------------------------------------------------------------- - - - - /*! \name Concentric Layout Management *///---------------------------- - //@{ - public: - - //! . - virtual void layout( Graph& graph, GridItem& gridItem, - QRectF r, QProgressDialog* progress = 0, int step = -1 ); - //@} - //--------------------------------------------------------------------- - }; - - - //! Layout nodes in a (logarithm) colimacon. - /*! - \nosubgrouping - */ - class Colimacon : public Layout - { - /*! \name Colimacon Constructor/Destructor *///------------------------ - //@{ - public: - - //! Colimacon constructor. - Colimacon( double azimutDelta = 15., double circleInterval = 10. ) : - Layout( ), _azimutDelta( azimutDelta ), _circleInterval( circleInterval ) { } - - private: - - double _azimutDelta; - - double _circleInterval; - //@} - //--------------------------------------------------------------------- - - - - /*! \name Colimacon Layout Management *///----------------------------- - //@{ - public: - - //! . - virtual void layout( Graph& graph, GridItem& gridItem, - QRectF r, QProgressDialog* progress = 0, int step = -1 ); - //@} - //--------------------------------------------------------------------- - }; - - - //! Layout an undirected graph as a directed top-down tree. - /*! - \nosubgrouping - */ - class DirectedTree : public Layout - { - /*! \name DirectedTree Constructor/Destructor *///--------------------- - //@{ - public: - - //! Define layout orientation. - enum Orientation - { - //! . - NONE = 0, - - //! . - HORIZONTAL = 1, - - //! . - VERTICAL = 2 - }; - - //! DirectedTree constructor with orientation initialization. - /*! \param spacing spacing between node on x and y (ex: 120, 70 with VERTICAL). */ - DirectedTree( const VectorF& spacing, Orientation orientation ) : - Layout( ), _origin( 2 ), _spacing( spacing ), _orientation( orientation ), _stopRecursion( false ) { _origin( 0 ) = 0.f; _origin( 1 ) = 0.f; } - - //! DirectedTree constructor with origin and orientation initialization. - /*! \param spacing spacing between node on x and y (ex: 120, 70 with VERTICAL). */ - DirectedTree( const VectorF& origin, const VectorF& spacing, Orientation orientation ) : - Layout( ), _origin( origin ), _spacing( spacing ), _orientation( orientation ), _stopRecursion( false ) { } - - private: - - VectorF _origin; - //@} - //--------------------------------------------------------------------- - - - - /*! \name Hierarchy Layout Generation Management *///------------------ - //@{ - public: - - //! Layout a graph as a hierarchy tree. - virtual void layout( Graph& graph, GridItem& gridItem, - QRectF r, QProgressDialog* progress = 0, int step = -1 ); - - protected: - - //! Layout a node hierarchy as a hierarchy tree. - void layout( Node& node, VectorF& bbox, int depth, QProgressDialog* progress = 0, int step = 0 ); - - //! Invert the x/y coordinates to set the desired orientation. - static void transpose( Graph& graph ); - - //! Spacing on x and y between tree nodes. - VectorF _spacing; - - //! Generated tree orientation. - Orientation _orientation; - - //! Container for already laid out nodes. - Node::Set _marked; - - private: - - //! Get the 'x' horizontal spacing according to the current orientation. - float getXSpacing( ) const { return ( _orientation == HORIZONTAL ? _spacing( 1 ) : _spacing( 0 ) ); } - - //! Get the 'y' vertical spacing according to the current orientation. - float getYSpacing( ) const{ return ( _orientation == HORIZONTAL ? _spacing( 0 ) : _spacing( 1 ) ); } - - //! Get the 'x' horizontal origin according to the current orientation. - float getXOrigin( ) const { return ( _orientation == HORIZONTAL ? _origin( 1 ) : _origin( 0 ) ); } - - //! Get the 'y' vertical origin according to the current orientation. - float getYOrigin( ) const { return ( _orientation == HORIZONTAL ? _origin( 0 ) : _origin( 1 ) ); } - - //! Force the tree layout algorithm to stop recursion. - void stopRecursion( ) { _stopRecursion = true; } - - //! Return the value of the stop recursion flag. - bool getStopRecusrion( ) const { return _stopRecursion; } - - //! Indicate that the algorithm execution is canceled and that the layout algorithm recusrion must stop. - bool _stopRecursion; - //@} - //--------------------------------------------------------------------- - }; - - - //! Layout an undirected graph using a spring force algorithm. /*! \nosubgrouping @@ -306,7 +141,7 @@ namespace qan { // ::qan public: //! Layout 'graph' using a spring force algorithm. - virtual void layout( Graph& graph, GridItem& gridItem, + virtual void layout( Graph& graph, QGraphicsScene* scene, QRectF r, QProgressDialog* progress = 0, int step = -1 ); static void add( VectorF& a, const VectorF& b ); @@ -333,5 +168,5 @@ namespace qan { // ::qan //----------------------------------------------------------------------------- -#endif // laLayout_h +#endif // qanLayout_h ============================================================ --- libs/qanava/src/qanNode.h 5db78823a601423d53024a55532763ee5babcecd +++ libs/qanava/src/qanNode.h 48c13d1b0cbbf8703568114725bc0d5a5ed83da3